diff options
-rw-r--r-- | saga/.cvsignore | 1 | ||||
-rw-r--r-- | saga/binread.cpp | 164 | ||||
-rw-r--r-- | saga/binread.h | 70 | ||||
-rw-r--r-- | saga/gamedesc.cpp | 474 | ||||
-rw-r--r-- | saga/gamedesc.h | 142 | ||||
-rw-r--r-- | saga/gamedesc_priv.h | 121 | ||||
-rw-r--r-- | saga/module.mk | 18 | ||||
-rw-r--r-- | saga/resfile.cpp | 182 | ||||
-rw-r--r-- | saga/resfile.h | 104 | ||||
-rw-r--r-- | saga/resnames.h | 127 | ||||
-rw-r--r-- | saga/saga.cpp | 135 | ||||
-rw-r--r-- | saga/saga.h | 56 |
12 files changed, 1594 insertions, 0 deletions
diff --git a/saga/.cvsignore b/saga/.cvsignore new file mode 100644 index 0000000000..39a06683b7 --- /dev/null +++ b/saga/.cvsignore @@ -0,0 +1 @@ +.deps diff --git a/saga/binread.cpp b/saga/binread.cpp new file mode 100644 index 0000000000..06715dd730 --- /dev/null +++ b/saga/binread.cpp @@ -0,0 +1,164 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "common/stdafx.h" + +#include "binread.h" + +BinReader::BinReader() { + _buf = NULL; + _bufPtr = NULL; + _bufEnd = NULL; + _bufLen = 0; +} + +BinReader::BinReader( const byte *buf, size_t buflen ) { + _buf = buf; + _bufPtr = buf; + _bufEnd = buf + buflen; + _bufLen = buflen; +} + +BinReader::~BinReader() { + +} + +void BinReader::setBuf( const byte *buf, size_t buflen ) +{ + _buf = buf; + _bufPtr = buf; + _bufEnd = buf + buflen; + _bufLen = buflen; +} + +void BinReader::skip( size_t skip_ct ) +{ + assert(( _bufPtr + skip_ct ) <= _bufEnd ); + + _bufPtr += skip_ct; +} + +unsigned int BinReader::readUint16LE() { + + assert(( _bufPtr + 2 ) <= _bufEnd ); + + unsigned int u16_le = ((unsigned int)_bufPtr[1] << 8 ) | _bufPtr[0]; + + _bufPtr += 2; + + return u16_le; +} + +unsigned int BinReader::readUint16BE() { + + assert(( _bufPtr + 2 ) <= _bufEnd ); + + unsigned int u16_be = ((unsigned int)_bufPtr[0] << 8 ) | _bufPtr[1]; + + _bufPtr += 2; + + return u16_be; +} + +int BinReader::readSint16LE() { + + assert(( _bufPtr + 2 ) <= _bufEnd ); + + unsigned int u16_le = ((unsigned int)_bufPtr[1] << 8 ) | _bufPtr[0]; + + _bufPtr += 2; + + return u16_le; +} + +int BinReader::readSint16BE() { + + assert(( _bufPtr + 2 ) <= _bufEnd ); + + unsigned int u16_be = ((unsigned int)_bufPtr[0] << 8 ) | _bufPtr[1]; + + _bufPtr += 2; + + return u16_be; +} + + +uint32 BinReader::readUint32LE() +{ + + assert(( _bufPtr + 4 ) <= _bufEnd ); + + unsigned long u32_le = ((unsigned long)_bufPtr[3] << 24 ) | + ((unsigned long)_bufPtr[2] << 16 ) | + ((unsigned long)_bufPtr[1] << 8 ) | + _bufPtr[0]; + + _bufPtr += 4; + + return u32_le; +} + +uint32 BinReader::readUint32BE() +{ + + assert(( _bufPtr + 4 ) <= _bufEnd ); + + unsigned long u32_be = ((unsigned long)_bufPtr[0] << 24 ) | + ((unsigned long)_bufPtr[1] << 16 ) | + ((unsigned long)_bufPtr[2] << 8 ) | + _bufPtr[3]; + + _bufPtr += 4; + + return u32_be; +} + +int32 BinReader::readSint32LE() +{ + + assert(( _bufPtr + 4 ) <= _bufEnd ); + + unsigned long u32_le = ((unsigned long)_bufPtr[3] << 24 ) | + ((unsigned long)_bufPtr[2] << 16 ) | + ((unsigned long)_bufPtr[1] << 8 ) | + _bufPtr[0]; + + _bufPtr += 4; + + return u32_le; +} + +int32 BinReader::readSint32BE() +{ + + assert(( _bufPtr + 4 ) <= _bufEnd ); + + unsigned long u32_be = ((unsigned long)_bufPtr[0] << 24 ) | + ((unsigned long)_bufPtr[1] << 16 ) | + ((unsigned long)_bufPtr[2] << 8 ) | + _bufPtr[3]; + + _bufPtr += 4; + + return u32_be; +} + + diff --git a/saga/binread.h b/saga/binread.h new file mode 100644 index 0000000000..abc1a294bc --- /dev/null +++ b/saga/binread.h @@ -0,0 +1,70 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef SAGA_BINREAD_H +#define SAGA_BINREAD_H + +#include <stddef.h> +#include "common/scummsys.h" + +class BinReader { + +protected: + + const byte *_buf; + const byte *_bufPtr; + const byte *_bufEnd; + size_t _bufLen; + +public: + + BinReader(); + BinReader( const byte *buf, size_t buflen ); + virtual ~BinReader(); + + void setBuf( const byte *buf, size_t buflen ); + + size_t getOffset() const; + bool setOffset( size_t offset ); + bool setROffset( ptrdiff_t offset ); + void skip( size_t skip_ct ); + + bool setPtr( const byte *buf_pos ); + byte *getPtr() const; + + unsigned int readUint16LE(); + unsigned int readUint16BE(); + int readSint16LE(); + int readSint16BE(); + uint32 readUint32LE(); + uint32 readUint32BE(); + int32 readSint32LE(); + int32 readSint32BE(); +}; + + +#endif + + + + + + diff --git a/saga/gamedesc.cpp b/saga/gamedesc.cpp new file mode 100644 index 0000000000..b731768425 --- /dev/null +++ b/saga/gamedesc.cpp @@ -0,0 +1,474 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" + +#include "common/scummsys.h" +#include "base/engine.h" +#include "common/util.h" +#include "common/file.h" + +#include "resfile.h" +#include "resnames.h" +#include "gamedesc.h" +#include "gamedesc_priv.h" + +using namespace SagaGameDesc; + +/*--------------------------------------------------------------------------*\ + * Inherit the Earth - Demo version +\*--------------------------------------------------------------------------*/ + +R_GAME_FILEDESC ITEDEMO_GameFiles[] = { + + { "ITE.RSC", R_GAME_RESOURCEFILE }, + { "ITE.DMO", R_GAME_DEMOFILE }, + { "SCRIPTS.RSC", R_GAME_SCRIPTFILE }, + { "VOICES.RSC", R_GAME_SOUNDFILE | R_GAME_VOICEFILE } +}; + +R_GAME_FONTDESC ITEDEMO_GameFonts[] = { + + { R_GAME_FONT_SMALL, 0 }, + { R_GAME_FONT_MEDIUM, 1 } +}; + +R_GAME_SOUNDINFO ITEDEMO_GameSound = { + + R_GAME_SOUND_VOC +}; + +/*--------------------------------------------------------------------------*\ + * Inherit the Earth - Diskette version +\*--------------------------------------------------------------------------*/ + +R_GAME_FILEDESC ITEDISK_GameFiles[] = { + + { "ITE.RSC", R_GAME_RESOURCEFILE }, + { "SCRIPTS.RSC", R_GAME_SCRIPTFILE }, + { "VOICES.RSC", R_GAME_SOUNDFILE | R_GAME_VOICEFILE } +}; + +R_GAME_FONTDESC ITEDISK_GameFonts[] = { + + { R_GAME_FONT_MEDIUM, 0 }, + { R_GAME_FONT_LARGE, 1 }, + { R_GAME_FONT_SMALL, 2 } +}; + +R_GAME_DISPLAYINFO ITE_DisplayInfo = { + + 320, 200, /* Logical width and height */ + 137, /* Scene playfield height */ + 0, 0 /* Overlay palette start index and length */ +}; + +R_GAME_RESOURCEINFO ITE_Resources = +{ + ITE_SCENE_LUT, /* Scene lookup table RN */ + ITE_SCRIPT_LUT, /* Script lookup table RN */ + + ITE_OVERLAY_PAL, /* Overlay palette RN */ + + ITE_COMMAND_PANEL, + ITE_COMMAND_BUTTONSPRITES, + + ITE_DIALOGUE_PANEL, + ITE_DEFAULT_PORTRAITS, + + ITE_ACTOR_PERSONA_TBL +}; + +R_GAME_SOUNDINFO ITE_GameSound = { + + R_GAME_SOUND_VOC +}; + +/*--------------------------------------------------------------------------*\ + * Inherit the Earth - CD Enhanced version +\*--------------------------------------------------------------------------*/ + +R_GAME_FILEDESC ITECD_GameFiles[] = { + + { "ITE.RSC", R_GAME_RESOURCEFILE }, + { "SCRIPTS.RSC", R_GAME_SCRIPTFILE }, + { "SOUNDS.RSC", R_GAME_SOUNDFILE }, + { "VOICES.RSC", R_GAME_VOICEFILE } +}; + +R_GAME_FONTDESC ITECD_GameFonts[] = { + + { R_GAME_FONT_MEDIUM, 0 }, + { R_GAME_FONT_LARGE, 1 }, + { R_GAME_FONT_SMALL, 2 } +}; + +R_GAME_SOUNDINFO ITECD_GameSound = { + + R_GAME_SOUND_PCM, + 22050, + 16, + 0 +}; + +/*--------------------------------------------------------------------------*\ + * I Have No Mouth and I Must Scream - Demo version +\*--------------------------------------------------------------------------*/ + +R_GAME_FILEDESC IHNMDEMO_GameFiles[] = { + + { "SCREAM.RES", R_GAME_RESOURCEFILE }, + { "SCRIPTS.RES", R_GAME_SCRIPTFILE }, + { "SFX.RES", R_GAME_SOUNDFILE }, + { "VOICESD.RES", R_GAME_VOICEFILE } +}; + +/*--------------------------------------------------------------------------*\ + * I Have No Mouth and I Must Scream - Retail CD version +\*--------------------------------------------------------------------------*/ + +R_GAME_FILEDESC IHNMCD_GameFiles[] = { + + { "MUSICFM.RES", R_GAME_MUSICFILE }, + { "MUSICGM.RES", R_GAME_MUSICFILE }, + { "SCREAM.RES", R_GAME_RESOURCEFILE }, + { "SCRIPTS.RES", R_GAME_SCRIPTFILE }, + { "SFX.RES", R_GAME_SOUNDFILE }, + { "VOICES1.RES", R_GAME_VOICEFILE }, + { "VOICES2.RES", R_GAME_VOICEFILE }, + { "VOICES3.RES", R_GAME_VOICEFILE }, + { "VOICES4.RES", R_GAME_VOICEFILE }, + { "VOICES5.RES", R_GAME_VOICEFILE }, + { "VOICES6.RES", R_GAME_VOICEFILE }, + { "VOICESS.RES", R_GAME_VOICEFILE } +}; + +R_GAME_FONTDESC IHNMCD_GameFonts[] = { + + { R_GAME_FONT_MEDIUM, 2 }, + { R_GAME_FONT_LARGE, 3 }, + { R_GAME_FONT_SMALL, 4 }, + { R_GAME_FONT_SMALL2, 5 }, + { R_GAME_FONT_MEDIUM2, 6 }, + { R_GAME_FONT_LARGE2, 7 }, + { R_GAME_FONT_LARGE3, 8 } +}; + +R_GAME_DISPLAYINFO IHNM_DisplayInfo = { + + 640, 480, /* Logical width and height */ + 304, /* Scene playfield height */ + 248, 255 /* Overlay palette start index and length */ +}; + +R_GAME_RESOURCEINFO IHNM_Resources[] = +{ + IHNM_SCENE_LUT, /* Scene lookup table RN */ + IHNM_SCRIPT_LUT, /* Script lookup table RN */ + + IHNM_OVERLAY_PAL, /* Overlay palette RN */ + + IHNM_COMMAND_PANEL, + IHNM_COMMAND_BUTTONSPRITES, + + IHNM_DIALOGUE_PANEL, + IHNM_DEFAULT_PORTRAITS, + + IHNM_ACTOR_PERSONA_TBL +}; + + +R_GAME_SOUNDINFO IHNM_GameSound = { + + R_GAME_SOUND_WAV +}; + +R_GAMEDESC GameDescs[] = { + + /* Inherit the earth - Demo version + \*-------------------------------------------------------------*/ + { + R_GAMETYPE_ITE, + R_GAME_ITE_DEMO, /* Game id */ + "Inherit the Earth - Demo version", /* Game title */ + + &ITE_DisplayInfo, + + ITE_DEFAULT_SCENE, /* Starting scene number */ + + &ITE_Resources, + + ARRAYSIZE( ITEDEMO_GameFiles ), /* Game datafiles */ + ITEDEMO_GameFiles, + + ARRAYSIZE( ITEDEMO_GameFonts ), + ITEDEMO_GameFonts, + + &ITEDEMO_GameSound, + + 0 /* Game supported flag */ + }, + + /* Inherit the earth - Disk version + \*-------------------------------------------------------------*/ + { + R_GAMETYPE_ITE, + R_GAME_ITE_DISK, + "Inherit the Earth - Disk version", + + &ITE_DisplayInfo, + + ITE_DEFAULT_SCENE, + + &ITE_Resources, + + ARRAYSIZE( ITEDISK_GameFiles ), + ITEDISK_GameFiles, + + ARRAYSIZE( ITEDISK_GameFonts ), + ITEDISK_GameFonts, + + &ITE_GameSound, + + 1 + }, + + /* Inherit the earth - CD version + \*-------------------------------------------------------------*/ + { + R_GAMETYPE_ITE, + R_GAME_ITE_CD, + "Inherit the Earth - CD version", + + &ITE_DisplayInfo, + + ITE_DEFAULT_SCENE, + + &ITE_Resources, + + ARRAYSIZE( ITECD_GameFiles ), + ITECD_GameFiles, + + ARRAYSIZE( ITECD_GameFonts ), + ITECD_GameFonts, + + &ITECD_GameSound, + + 1 + }, + + /* I Have No Mouth And I Must Scream - Demo version + \*-------------------------------------------------------------*/ + { + R_GAMETYPE_IHNM, + R_GAME_IHNM_DEMO, + "I Have No Mouth - Demo version", + + &IHNM_DisplayInfo, + + 0, + + IHNM_Resources, + + ARRAYSIZE( IHNMDEMO_GameFiles ), + IHNMDEMO_GameFiles, + + 0, + NULL, + + &IHNM_GameSound, + + 0 + }, + + /* I Have No Mouth And I Must Scream - CD version + \*-------------------------------------------------------------*/ + { + R_GAMETYPE_IHNM, + R_GAME_IHNM_CD, + "I Have No Mouth - CD version", + + &IHNM_DisplayInfo, + + 1, + + IHNM_Resources, + + ARRAYSIZE( IHNMCD_GameFiles ), + IHNMCD_GameFiles, + + ARRAYSIZE( IHNMCD_GameFonts ), + IHNMCD_GameFonts, + + &IHNM_GameSound, + + 1 + } +}; + +static R_GAMEMODULE GameModule; + +void SagaGameDesc::setGameDirectory( const char *gamedir ) { + + assert( gamedir != NULL ); + + debug( 1, "Using game data path: %s", gamedir ); + + GameModule.game_dir = gamedir; +} + +int SagaGameDesc::detectGame() { + + File test_file; + + int game_index = 0; + + bool disqualified = false; + bool found_game = false; + + int file_n; + int file_ct; + const char *file_name; + + int game_n; + int game_ct = ARRAYSIZE( GameDescs ); + + assert( GameModule.game_dir != NULL ); + + for( game_n = 0 ; game_n < game_ct ; game_n++ ) { + + disqualified = false; + + /* Attempt to open all files for this game + * If we can open them all, then try to open all files on the + * exclude list + */ + file_ct = GameDescs[game_n].gd_filect; + + for( file_n = 0; file_n < file_ct; file_n++ ) { + + file_name = GameDescs[game_n].gd_filedescs[file_n].gf_fname; + if( !test_file.open( file_name, GameModule.game_dir )) { + disqualified = true; + break; + } + + test_file.close(); + } + + if ( disqualified ) { + continue; + } + + switch ( GameDescs[game_n].gd_game_id ) { + + case R_GAME_ITE_DEMO: + disqualified = !verifyITEDEMO(); + break; + case R_GAME_ITE_DISK: + disqualified = !verifyITEDISK(); + break; + + default: + break; + } + + if( !disqualified ) { + found_game = true; + break; + } + } + + if( found_game ) { + + debug( 1, "Found SAGA game: %s\n", GameDescs[game_n].gd_title ); + return game_n; + } + + return -1; +} + +bool SagaGameDesc::openGame() { + + int game_filect; + + if(( GameModule.game_index = detectGame() ) < 0 ) { + error( "Couldn't locate any valid SAGA games" ); + return false; + } + + assert( GameModule.game_index < ARRAYSIZE(GameDescs)); + + if( !GameModule.game_dir ) { + return false; + } + + game_filect = GameDescs[ GameModule.game_index ].gd_filect; + + GameModule.gfile_data = new R_GAME_FILEDATA[ game_filect ]; + + return true; +} + +bool verifyITEDEMO() { + return true; +} + +bool verifyITEDISK() { + + ResourceFile test_file; + int32 script_lut_rn; + int32 script_lut_len; + + /* Attempt to verify the disk version of Inherit the Earth + * by examining the length of entries in the script lookup + * table, which differs from the disk version and the CD + * version. + */ + + assert( GameModule.game_dir != NULL ); + + if ( !test_file.open( "ITE.RSC", GameModule.game_dir )) { + return false; + } + + script_lut_rn = GameDescs[ R_GAME_ITE_DISK ].gd_resource_info->script_lut_rn; + + script_lut_len = test_file.getResourceLen( script_lut_rn ); + + if( script_lut_len % R_SCR_LUT_ENTRYLEN_ITEDISK == 0 ) { + return true; + } + + return false; +} + +bool verifyITECD() { + return true; +} + +bool verifyIHNMDEMO() { + return true; +} + +bool verifyIHNMCD() { + return true; +} diff --git a/saga/gamedesc.h b/saga/gamedesc.h new file mode 100644 index 0000000000..a3b57f88f0 --- /dev/null +++ b/saga/gamedesc.h @@ -0,0 +1,142 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef SAGA_GAMEDESC_H +#define SAGA_GAMEDESC_H + +#include "resfile.h" + +/* Public stuff */ + +namespace SagaGameDesc { + +enum R_GAME_BASETYPES { + + R_GAMETYPE_ITE, + R_GAMETYPE_IHNM +}; + +enum R_GAME_IDS { + + R_GAME_ITE_DEMO = 0, + R_GAME_ITE_DISK = 1, + R_GAME_ITE_CD = 2, + R_GAME_IHNM_DEMO = 3, + R_GAME_IHNM_CD = 4 +}; + +enum R_GAME_FILETYPES { + + R_GAME_RESOURCEFILE = 0x01, + R_GAME_SCRIPTFILE = 0x02, + R_GAME_SOUNDFILE = 0x04, + R_GAME_VOICEFILE = 0x08, + R_GAME_DEMOFILE = 0x10, + R_GAME_MUSICFILE = 0x20, + + R_GAME_EXCLUDE = 0x8000 +}; + +enum R_GAME_SOUNDINFO_TYPES { + + R_GAME_SOUND_PCM = 0, + R_GAME_SOUND_VOC, + R_GAME_SOUND_WAV +}; + +enum R_GAME_FONT_IDS { + + R_GAME_FONT_SMALL = 0, + R_GAME_FONT_MEDIUM, + R_GAME_FONT_LARGE, + R_GAME_FONT_SMALL2, + R_GAME_FONT_MEDIUM2, + R_GAME_FONT_LARGE2, + R_GAME_FONT_LARGE3 +}; + +typedef struct R_GAME_DISPLAYINFO_tag { + + int logical_w; + int logical_h; + int scene_h; + + int ovl_pal_start; + int ovl_pal_end; + +} R_GAME_DISPLAYINFO; + +typedef struct R_GAMESOUND_INFO_tag { + + int res_type; + long freq; + int sample_size; + int stereo; + +} R_GAME_SOUNDINFO; + +typedef struct R_GAMEFONT_DESC_tag { + + unsigned int font_id; + unsigned long font_rn; + +} R_GAME_FONTDESC; + +typedef struct R_GAMESCENE_DESC_tag { + + unsigned long scene_lut_rn; + unsigned long first_scene; + +} R_GAME_SCENEDESC; + +typedef struct R_GAME_RESOURCEINFO_tag { + + unsigned long scene_lut_rn; + unsigned long script_lut_rn; + + unsigned long overlay_pal_rn; + + unsigned long command_panel_rn; + unsigned long command_buttons_rn; + + unsigned long dialogue_panel_rn; + unsigned long lportraits_rn; + + unsigned long actor_tbl_rn; + +} R_GAME_RESOURCEINFO; + + void setGameDirectory( const char *gamedir ); + int detectGame(); + bool openGame(); + +} // end namespace + + + + +#endif + + + + + + diff --git a/saga/gamedesc_priv.h b/saga/gamedesc_priv.h new file mode 100644 index 0000000000..a48fabdf2b --- /dev/null +++ b/saga/gamedesc_priv.h @@ -0,0 +1,121 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef SAGA_GAMEDESC_PRIV_H +#define SAGA_GAMEDESC_PRIV_H + +#include "gamedesc.h" + +using namespace SagaGameDesc; + +//------------------------------------------------------------------- +// Private stuff +//------------------------------------------------------------------- + +#define R_GAME_LANGSTR_LIMIT 3 +#define R_GAME_PATH_LIMIT 512 + +#define R_GAME_ITE_LANG_PREFIX "ite_" +#define R_GAME_LANG_EXT "lng" + +/* Script lookup table entry sizes for game verification */ +#define R_SCR_LUT_ENTRYLEN_ITECD 22 +#define R_SCR_LUT_ENTRYLEN_ITEDISK 16 + +typedef bool (ResourceFile::*R_GAME_VERIFYFUNC)(); + +typedef struct R_GAME_FILEDESC_tag { + + const char * gf_fname; + unsigned int gf_type; + +} R_GAME_FILEDESC; + +typedef struct R_GAMEDESC_tag { + + int gd_game_type; + int gd_game_id; + + const char * gd_title; + + R_GAME_DISPLAYINFO * gd_display_info; + + int gd_startscene; + + R_GAME_RESOURCEINFO * gd_resource_info; + + int gd_filect; + R_GAME_FILEDESC * gd_filedescs; + + int gd_fontct; + R_GAME_FONTDESC * gd_fontdescs; + + R_GAME_SOUNDINFO * gd_soundinfo; + + int gd_supported; + +} R_GAMEDESC; + + +typedef struct R_GAME_FILEDATA_tag { + + ResourceFile *file_ctxt; + + unsigned int file_types; + unsigned int file_flags; + +} R_GAME_FILEDATA; + + +typedef struct R_GAMEMODULE_tag { + + int game_init; + int game_index; + + R_GAMEDESC * gamedesc; + + int g_skipintro; + + const char *game_dir; + + char game_language[ R_GAME_LANGSTR_LIMIT ]; + + unsigned int gfile_n; + R_GAME_FILEDATA * gfile_data; + + unsigned int gd_fontct; + R_GAME_FONTDESC * gd_fontdescs; + + int err_n; + const char * err_str; + +} R_GAMEMODULE; + +bool verifyITEDEMO(); +bool verifyITEDISK(); +bool verifyITECD(); +bool verifyIHNMDEMO(); +bool verifyIHNMCD(); + +#endif // SAGA_GAMEDESC_PRIV_H + + + diff --git a/saga/module.mk b/saga/module.mk new file mode 100644 index 0000000000..0f7e4d3b2c --- /dev/null +++ b/saga/module.mk @@ -0,0 +1,18 @@ +MODULE := saga + +MODULE_OBJS = \ + saga/saga.o \ + saga/binread.o \ + saga/gamedesc.o \ + saga/resfile.o + +MODULE_DIRS += \ + saga + +# This module can be built as a plugin +ifdef BUILD_PLUGINS +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/common.rules diff --git a/saga/resfile.cpp b/saga/resfile.cpp new file mode 100644 index 0000000000..12b0a88c33 --- /dev/null +++ b/saga/resfile.cpp @@ -0,0 +1,182 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "common/file.h" + +#include "saga.h" + +#include "resfile.h" +#include "binread.h" + + +ResourceFile::ResourceFile() { + + _resTblOffset = 0; + _resTblCt = 0; + _resTblLoaded = false; + _resTbl = NULL; +} + +ResourceFile::~ResourceFile() { + + close(); +} + +bool +ResourceFile::open( const char *filename, const char *directory ) { + + byte * temp_tbl; + uint32 tbl_len; + + if( !File::open( filename, directory )) { + return false; + } + + /* Seek to end of file to read resource table 'trailer' */ + _file_len = size(); + + seek( _file_len - RSC_TABLEINFO_SIZE, SEEK_SET ); + + _resTblOffset = readSint32LE(); + _resTblCt = readSint32LE(); + + /* Check for sane values */ + if( _resTblOffset != _file_len - RSC_TABLEINFO_SIZE - + (RSC_TABLEENTRY_SIZE * _resTblCt)) { + return false; + } + + /* Load resource table */ + _resTbl = new Resource[_resTblCt]; + + seek( _resTblOffset, SEEK_SET ); + + tbl_len = _resTblCt * RSC_TABLEENTRY_SIZE; + temp_tbl = new byte[tbl_len]; + + if( read( temp_tbl, tbl_len ) != tbl_len ) { + delete [] _resTbl; + delete [] temp_tbl; + return false; + } + + BinReader bread( temp_tbl, tbl_len ); + + for( int i = 0 ; i < _resTblCt ; i++ ) { + + _resTbl[i].res_offset = bread.readSint32LE(); + _resTbl[i].res_len = bread.readSint32LE(); + } + + delete [] temp_tbl; + + _resTblLoaded = true; + + return true; +} + + +void ResourceFile::close() { + + if( _resTblLoaded ) { + delete [] _resTbl; + _resTblLoaded = false; + _resTbl = NULL; + } + + _resTblOffset = 0; + _resTblCt = 0; + + if( File::isOpen() ) { + File::close(); + } +} + +int32 ResourceFile::getResourceCt() { + + return (_resTblLoaded) ? _resTblCt : -1; +} + +int32 ResourceFile::getResourceOffset( int32 rn ) { + + if (!R_PBOUNDS( rn, _resTblCt )) { + return -1; + } + + return _resTbl[rn].res_offset; +} + +int32 ResourceFile::getResourceLen( int32 rn ) { + + if (!R_PBOUNDS( rn, _resTblCt )) { + return -1; + } + + return _resTbl[rn].res_len; +} + +bool ResourceFile::loadResource( int32 rn, byte **res, int32 *res_len ) { + + byte *new_res; + uint32 new_res_len; + + assert( res != NULL && res_len != NULL ); + *res = NULL; + *res_len = NULL; + + if( !R_PBOUNDS( rn, _resTblCt )) { + return false; + } + + new_res_len = _resTbl[rn].res_len; + new_res = new byte[ new_res_len ]; + if( !new_res ) { + return false; + } + + seek( _resTbl[rn].res_offset, SEEK_SET ); + + if( read( new_res, new_res_len ) != new_res_len ) { + delete [] new_res; + return false; + } + + *res = new_res; + *res_len = new_res_len; + + return true; +} + +void ResourceFile::freeResource( byte *res ) { + + delete [] res; +} + + + + + + + + + + + diff --git a/saga/resfile.h b/saga/resfile.h new file mode 100644 index 0000000000..03816fc4ce --- /dev/null +++ b/saga/resfile.h @@ -0,0 +1,104 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef SAGA_RESFILE_H +#define SAGA_RESFILE_H + +/* The 'RSC' resource file format used by SAGA is quite simple. + * At the end of the resource file is an 8 byte structure. The first + * 32 bit value specifies the offset of the resource table, the + * second specifies the number of entries in the resource table. + * Each entry in the resource table is itself 32 bytes, the first + * 32 bit value of which specifies the offset of the resource, the + * second specifies the length of the resource. + */ + +#include "common/file.h" + +class ResourceFile : public File { + +public: + + struct Resource { + int32 res_offset; + int32 res_len; + }; + +private: + + long _file_len; + +protected: + + enum ResourceConstants { + RSC_TABLEINFO_SIZE = 8, + RSC_TABLEENTRY_SIZE = 8 + }; + + const char *_resDirectory; + + int32 _resTblOffset; + int32 _resTblCt; + + bool _resTblLoaded; + Resource *_resTbl; + +public: + + ResourceFile(); + virtual ~ResourceFile(); + + bool open( const char *filename, const char *directory ); + void close(); + + inline int16 readSint16LE() { + return readUint16LE(); + } + + inline int32 readSint32LE() { + return readUint32LE(); + } + + inline int16 readSint16BE() { + return readUint16BE(); + } + + inline int32 readSint32BE() { + return readUint32BE(); + } + + int32 getResourceCt(); + int32 getResourceOffset( int32 rn ); + int32 getResourceLen( int32 rn ); + + bool loadResource( int32 rn, byte **res, int32 *res_len ); + void freeResource( byte *res ); + +}; + + + +#endif + + + + + diff --git a/saga/resnames.h b/saga/resnames.h new file mode 100644 index 0000000000..820b0e6759 --- /dev/null +++ b/saga/resnames.h @@ -0,0 +1,127 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef SAGA_RESNAMES_H +#define SAGA_RESNAMES_H + +/* Lookup tables +\*-----------------------------------------------------------------*/ +#define ITE_SCENE_LUT 1806 +#define ITE_SCRIPT_LUT 216 + +#define IHNM_SCENE_LUT 1272 +#define IHNM_SCRIPT_LUT 0 + +/* SCENES */ +#define ITE_DEFAULT_SCENE 32 + +/* FONTS */ +#define RN_MEDIUM_FONT 0 +#define RN_BIG_FONT 1 +#define RN_SMALL_FONT 2 + +#define ITE_OVERLAY_PAL ((unsigned long)-1) +#define IHNM_OVERLAY_PAL 1 + +#define ITE_ACTOR_PERSONA_TBL ((unsigned long)-1) +#define IHNM_ACTOR_PERSONA_TBL 80 + +/* Interface resources +\*-----------------------------------------------------------------*/ +#define ITE_COMMAND_PANEL 3 +#define ITE_COMMAND_BUTTONSPRITES 7 + +#define ITE_DIALOGUE_PANEL 4 +#define ITE_DEFAULT_PORTRAITS 125 + +#define ITE_SETUP_PANEL 5 + +#define IHNM_COMMAND_PANEL 9 +#define IHNM_COMMAND_BUTTONSPRITES 12 + +#define IHNM_DIALOGUE_PANEL 10 + +/* No real "default" portraits for IHNM, but provide one for now */ +#define IHNM_DEFAULT_PORTRAITS 45 + +/* ITE Scene resource numbers */ +#define ITE_INTRO_ANIM_SCENE 1538 +#define ITE_CAVE_SCENE_1 1542 +#define ITE_CAVE_SCENE_2 1545 +#define ITE_CAVE_SCENE_3 1548 +#define ITE_CAVE_SCENE_4 1551 + +#define ITE_VALLEY_SCENE 1556 +#define ITE_TREEHOUSE_SCENE 1560 +#define ITE_FAIREPATH_SCENE 1564 +#define ITE_FAIRETENT_SCENE 1567 + +#define ITE_INTRO_ANIM_STARTFRAME 1529 + +/* ITE_VOICES */ +#define CAVE_VOICE_0 0 +#define CAVE_VOICE_1 1 +#define CAVE_VOICE_2 2 +#define CAVE_VOICE_3 3 +#define CAVE_VOICE_4 4 +#define CAVE_VOICE_5 5 +#define CAVE_VOICE_6 6 +#define CAVE_VOICE_7 7 +#define CAVE_VOICE_8 8 +#define CAVE_VOICE_9 9 +#define CAVE_VOICE_10 10 +#define CAVE_VOICE_11 11 +#define CAVE_VOICE_12 12 +#define CAVE_VOICE_13 13 + +/* MUSIC */ +#define MUSIC_1 9 +#define MUSIC_2 10 +#define MUSIC_3 11 +#define MUSIC_4 12 +#define MUSIC_5 13 +#define MUSIC_6 14 +#define MUSIC_7 15 +#define MUSIC_8 16 +#define MUSIC_9 17 +#define MUSIC_10 18 +#define MUSIC_11 19 +#define MUSIC_12 20 +#define MUSIC_13 21 +#define MUSIC_14 22 +#define MUSIC_15 23 +#define MUSIC_16 24 +#define MUSIC_17 25 +#define MUSIC_18 26 +#define MUSIC_19 27 +#define MUSIC_20 28 +#define MUSIC_21 29 +#define MUSIC_22 30 +#define MUSIC_23 31 +#define MUSIC_24 32 +#define MUSIC_25 33 +#define MUSIC_26 34 + + +#endif + + + diff --git a/saga/saga.cpp b/saga/saga.cpp new file mode 100644 index 0000000000..02a233d1e5 --- /dev/null +++ b/saga/saga.cpp @@ -0,0 +1,135 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" + +#include "base/gameDetector.h" +#include "base/plugins.h" +#include "backends/fs/fs.h" + +#include "sound/mixer.h" +#include "common/file.h" +#include "common/config-manager.h" + +#include "saga.h" + +#include "gamedesc.h" + + +struct SAGAGameSettings { + const char *name; + const char *description; + byte id; + uint32 features; + const char *detectname; + GameSettings toGameSettings() const { + GameSettings dummy = { name, description, features }; + return dummy; + } +}; + +static const SAGAGameSettings saga_settings[] = { + /* Inherit the Earth - Original floppy version */ + { "ite", "Inherit the Earth (DOS)", GID_ITE, + MDT_ADLIB, "ite.rsc" }, + /* Inherit the Earth - CD version */ + { "itecd", "Inherit the Earth (DOS CD Version)", GID_ITECD, + MDT_ADLIB, "sounds.rsc" }, + /* I Have No Mouth and I Must Scream */ + { "ihnm", "I Have No Mouth and I Must Scream (DOS)", GID_IHNM, + MDT_ADLIB, "scream.res" }, + + { NULL, NULL, 0, 0, NULL } +}; + +GameList Engine_SAGA_gameList() { + const SAGAGameSettings *g = saga_settings; + GameList games; + while (g->name) { + games.push_back(g->toGameSettings()); + g++; + } + return games; +} + +DetectedGameList Engine_SAGA_detectGames(const FSList &fslist) { + DetectedGameList detectedGames; + const SAGAGameSettings *g; + + for (g = saga_settings; g->name; ++g) { + // Iterate over all files in the given directory + for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + const char *gameName = file->displayName().c_str(); + + if (0 == scumm_stricmp(g->detectname, gameName)) { + // Match found, add to list of candidates, then abort inner loop. + detectedGames.push_back(g->toGameSettings()); + break; + } + } + } + return detectedGames; +} + +Engine *Engine_SAGA_create(GameDetector *detector, OSystem *syst) { + return new SagaEngine(detector, syst); +} + +REGISTER_PLUGIN("SAGA Engine", Engine_SAGA_gameList, Engine_SAGA_create, Engine_SAGA_detectGames) + +namespace Saga { + +SagaEngine::SagaEngine(GameDetector *detector, OSystem *syst) + : Engine(syst) { + + SagaGameDesc::setGameDirectory(getGameDataPath()); + SagaGameDesc::openGame(); + + // Setup mixer + if (!_mixer->isReady()) { + warning("Sound initialization failed."); + } + + _mixer->setVolume(ConfMan.getInt("sfx_volume") * ConfMan.getInt("master_volume") / 255); + + // Initialize backend + syst->initSize(320, 240); +} + +SagaEngine::~SagaEngine() { + +} + +void SagaEngine::errorString(const char *buf1, char *buf2) { + strcpy(buf2, buf1); +} + +void SagaEngine::go() { + + +} + +void SagaEngine::shutdown() { + + _system->quit(); +} + +} diff --git a/saga/saga.h b/saga/saga.h new file mode 100644 index 0000000000..fad1295826 --- /dev/null +++ b/saga/saga.h @@ -0,0 +1,56 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef SAGA_H +#define SAGA_H + +#include "common/scummsys.h" +#include "base/engine.h" +#include "base/gameDetector.h" +#include "common/util.h" + +#include "gamedesc.h" + +#define R_PBOUNDS(n,max) (((n)>=(0))&&((n)<(max))) + +enum SAGAGameId { + GID_ITE, + GID_ITECD, + GID_IHNM +}; + +class SagaEngine : public Engine { + + void errorString( const char *buf_input, char *buf_output); + +protected: + void go(); + void shutdown(); + +public: + + SagaEngine(GameDetector *detector, OSystem *syst); + virtual ~SagaEngine(); + +}; + + +#endif |