2009-02-17 15:20:21 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
#include "common/system.h"
|
|
|
|
#include "common/config-manager.h"
|
|
|
|
|
2009-02-15 08:20:53 +00:00
|
|
|
#include "engines/advancedDetector.h"
|
2009-02-15 11:03:21 +00:00
|
|
|
#include "sci/sci.h"
|
2009-02-15 08:20:53 +00:00
|
|
|
#include "sci/include/engine.h"
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
extern gfx_driver_t gfx_driver_scummvm;
|
|
|
|
|
2009-02-20 14:45:28 +00:00
|
|
|
namespace Sci {
|
|
|
|
|
2009-02-15 06:10:59 +00:00
|
|
|
int
|
2009-02-15 22:43:13 +00:00
|
|
|
c_quit(state_t *s) {
|
2009-02-15 06:10:59 +00:00
|
|
|
script_abort_flag = 1; /* Terminate VM */
|
|
|
|
_debugstate_valid = 0;
|
|
|
|
_debug_seeking = 0;
|
|
|
|
_debug_step_running = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2009-02-15 22:43:13 +00:00
|
|
|
c_die(state_t *s) {
|
2009-02-15 06:10:59 +00:00
|
|
|
exit(0); /* Die */
|
|
|
|
return 0; /* ;-P (fixes warning) */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-02-15 22:43:13 +00:00
|
|
|
init_console() {
|
2009-02-15 06:10:59 +00:00
|
|
|
#ifdef WANT_CONSOLE
|
|
|
|
con_gfx_init();
|
|
|
|
#endif
|
|
|
|
con_hook_command(&c_quit, "quit", "", "console: Quits gracefully");
|
|
|
|
con_hook_command(&c_die, "die", "", "console: Quits ungracefully");
|
|
|
|
|
|
|
|
/*
|
|
|
|
con_hook_int(&(gfx_options.buffer_pics_nr), "buffer_pics_nr",
|
|
|
|
"Number of pics to buffer in LRU storage\n");
|
|
|
|
con_hook_int(&(gfx_options.pic0_dither_mode), "pic0_dither_mode",
|
|
|
|
"Mode to use for pic0 dithering\n");
|
|
|
|
con_hook_int(&(gfx_options.pic0_dither_pattern), "pic0_dither_pattern",
|
|
|
|
"Pattern to use for pic0 dithering\n");
|
|
|
|
con_hook_int(&(gfx_options.pic0_unscaled), "pic0_unscaled",
|
|
|
|
"Whether pic0 should be drawn unscaled\n");
|
|
|
|
con_hook_int(&(gfx_options.dirty_frames), "dirty_frames",
|
|
|
|
"Dirty frames management\n");
|
|
|
|
*/
|
|
|
|
con_hook_int(&gfx_crossblit_alpha_threshold, "alpha_threshold",
|
2009-02-15 22:43:13 +00:00
|
|
|
"Alpha threshold for crossblitting\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
con_hook_int(&sci0_palette, "sci0_palette",
|
2009-02-15 22:43:13 +00:00
|
|
|
"SCI0 palette- 0: EGA, 1:AGI/Amiga, 2:Grayscale\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
con_hook_int(&sci01_priority_table_flags, "sci01_priority_table_flags",
|
2009-02-15 22:43:13 +00:00
|
|
|
"SCI01 priority table debugging flags: 1:Disable, 2:Print on change\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
con_passthrough = 1; /* enables all sciprintf data to be sent to stdout */
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2009-02-15 22:43:13 +00:00
|
|
|
init_gamestate(state_t *gamestate, sci_version_t version) {
|
2009-02-15 06:10:59 +00:00
|
|
|
int errc;
|
|
|
|
|
|
|
|
if ((errc = script_init_engine(gamestate, version))) { /* Initialize game state */
|
|
|
|
int recovered = 0;
|
|
|
|
|
|
|
|
if (errc == SCI_ERROR_INVALID_SCRIPT_VERSION) {
|
2009-02-15 22:43:13 +00:00
|
|
|
int tversion = SCI_VERSION_FTU_NEW_SCRIPT_HEADER - ((version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER) ? 0 : 1);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
while (!recovered && tversion) {
|
|
|
|
printf("Trying version %d.%03x.%03d instead\n", SCI_VERSION_MAJOR(tversion),
|
2009-02-15 22:43:13 +00:00
|
|
|
SCI_VERSION_MINOR(tversion), SCI_VERSION_PATCHLEVEL(tversion));
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
errc = script_init_engine(gamestate, tversion);
|
|
|
|
|
|
|
|
if ((recovered = !errc))
|
|
|
|
version = tversion;
|
|
|
|
|
|
|
|
if (errc != SCI_ERROR_INVALID_SCRIPT_VERSION)
|
|
|
|
break;
|
|
|
|
|
|
|
|
switch (tversion) {
|
|
|
|
|
|
|
|
case SCI_VERSION_FTU_NEW_SCRIPT_HEADER - 1:
|
|
|
|
if (version >= SCI_VERSION_FTU_NEW_SCRIPT_HEADER)
|
|
|
|
tversion = 0;
|
|
|
|
else
|
|
|
|
tversion = SCI_VERSION_FTU_NEW_SCRIPT_HEADER;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCI_VERSION_FTU_NEW_SCRIPT_HEADER:
|
|
|
|
tversion = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (recovered)
|
|
|
|
printf("Success.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!recovered) {
|
2009-02-20 20:39:02 +00:00
|
|
|
error("Script initialization failed. Aborting...\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-17 18:16:48 +00:00
|
|
|
SciEngine::SciEngine(OSystem *syst, const SciGameDescription *desc)
|
2009-02-18 20:08:49 +00:00
|
|
|
: Engine(syst), _gameDescription(desc) {
|
2009-02-17 18:16:48 +00:00
|
|
|
// Put your engine in a sane state, but do nothing big yet;
|
|
|
|
// in particular, do not load data from files; rather, if you
|
|
|
|
// need to do such things, do them from init().
|
|
|
|
|
|
|
|
// However this is the place to specify all default directories
|
|
|
|
//File::addDefaultDirectory(_gameDataPath + "sound/");
|
|
|
|
//printf("%s\n", _gameDataPath.c_str());
|
|
|
|
|
|
|
|
// Set up the engine specific debug levels
|
2009-02-20 20:11:12 +00:00
|
|
|
Common::addDebugChannel(kDebugLevelError, "Error", "Script error debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelNodes, "Lists", "Lists and nodes debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelGraphics, "Graphics", "Graphics debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelStrings, "Strings", "Strings debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelMem, "Memory", "Memory debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelFuncCheck, "Func", "Function parameter debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelBresen, "Bresenham", "Bresenham algorithms debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelSound, "Sound", "Sound debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelGfxDriver, "Gfxdriver", "Gfx driver debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelBaseSetter, "Base", "Base Setter debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelParser, "Parser", "Parser debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelMenu, "Menu", "Menu handling debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelSaid, "Said", "Said specs debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelFile, "File", "File I/O debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelTime, "Time", "Time debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelRoom, "Room", "Room number debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelEmu, "Emu", "Alternate emulation debugging");
|
|
|
|
Common::addDebugChannel(kDebugLevelAvoidPath, "Pathfinding", "Pathfinding debugging");
|
2009-02-17 18:16:48 +00:00
|
|
|
|
|
|
|
printf("SciEngine::SciEngine\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
SciEngine::~SciEngine() {
|
|
|
|
// Dispose your resources here
|
|
|
|
printf("SciEngine::~SciEngine\n");
|
|
|
|
|
|
|
|
// Remove all of our debug levels here
|
|
|
|
//Common::clearAllSpecialDebugLevels();
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::Error SciEngine::init() {
|
|
|
|
initGraphics(320, 200, false);
|
|
|
|
|
|
|
|
//GUIErrorMessage("lalalal asfa w4 haha hreh au u<w");
|
|
|
|
|
|
|
|
// Create debugger console. It requires GFX to be initialized
|
|
|
|
//_console = new Console(this);
|
|
|
|
//_console = new Console();
|
|
|
|
|
|
|
|
// Additional setup.
|
|
|
|
printf("SciEngine::init\n");
|
|
|
|
return Common::kNoError;
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::Error SciEngine::go() {
|
|
|
|
// Your main even loop should be (invoked from) here.
|
|
|
|
|
|
|
|
/* bool end = false;
|
|
|
|
Common::EventManager *em = _system->getEventManager();
|
|
|
|
while (!end) {
|
|
|
|
Common::Event ev;
|
|
|
|
if (em->pollEvent(ev)) {
|
|
|
|
if (ev.type == Common::EVENT_KEYDOWN) {
|
|
|
|
end = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_system->delayMillis(10);
|
|
|
|
} */
|
|
|
|
|
|
|
|
// FIXME/TODO: Move some of the stuff below to init()
|
2009-02-20 15:24:22 +00:00
|
|
|
ResourceManager *resmgr;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
init_console(); /* So we can get any output */
|
|
|
|
|
|
|
|
script_debug_flag = 0;
|
|
|
|
|
|
|
|
sci_version_t version;
|
2009-02-18 09:09:37 +00:00
|
|
|
int res_version = SCI_VERSION_AUTODETECT;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 10:38:39 +00:00
|
|
|
// FIXME. An evil hack until File class will be used properly
|
|
|
|
chdir(ConfMan.get("path").c_str());
|
|
|
|
|
2009-02-18 09:09:37 +00:00
|
|
|
version = getVersion();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
char resource_dir[MAXPATHLEN+1] = "";
|
|
|
|
getcwd(resource_dir, MAXPATHLEN); /* Store resource directory */
|
|
|
|
|
2009-02-20 16:03:50 +00:00
|
|
|
resmgr = new ResourceManager(res_version, 256 * 1024);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (!resmgr) {
|
|
|
|
printf("No resources found in '%s'.\nAborting...\n",
|
2009-02-15 22:43:13 +00:00
|
|
|
resource_dir);
|
2009-02-17 18:16:48 +00:00
|
|
|
return Common::kNoGameDataFoundError;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
script_adjust_opcode_formats(resmgr->sci_version);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
printf("Mapping instruments to General Midi\n");
|
|
|
|
|
|
|
|
map_MIDI_instruments(resmgr);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
sciprintf("Imported FreeSCI, version "VERSION"\n");
|
|
|
|
|
2009-02-15 15:36:53 +00:00
|
|
|
state_t* gamestate = (state_t *) sci_malloc(sizeof(state_t));
|
|
|
|
memset(gamestate, 0, sizeof(state_t));
|
|
|
|
gamestate->resmgr = resmgr;
|
|
|
|
gamestate->gfx_state = NULL;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 15:36:53 +00:00
|
|
|
if (init_gamestate(gamestate, version))
|
2009-02-17 18:16:48 +00:00
|
|
|
return Common::kUnknownError;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
|
2009-02-15 15:36:53 +00:00
|
|
|
if (game_init(gamestate)) { /* Initialize */
|
2009-02-20 20:39:02 +00:00
|
|
|
error("Game initialization failed: Aborting...\n");
|
2009-02-17 18:16:48 +00:00
|
|
|
// TODO: Add an "init failed" error?
|
|
|
|
return Common::kUnknownError;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the savegame dir */
|
2009-02-15 15:36:53 +00:00
|
|
|
script_set_gamestate_save_dir(gamestate, ConfMan.get("savepath").c_str());
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
// Originally, work_dir tried to be ~/.freesci/game_name
|
2009-02-15 15:36:53 +00:00
|
|
|
gamestate->work_dir = sci_strdup(ConfMan.get("savepath").c_str());
|
|
|
|
gamestate->resource_dir = resource_dir;
|
|
|
|
gamestate->port_serial = 0;
|
|
|
|
gamestate->have_mouse_flag = 1;
|
|
|
|
gamestate->animation_delay = 5;
|
|
|
|
gamestate->animation_granularity = 4;
|
2009-02-15 06:10:59 +00:00
|
|
|
gfx_crossblit_alpha_threshold = 0x90;
|
|
|
|
|
|
|
|
gfx_state_t gfx_state;
|
|
|
|
gfx_state.driver = &gfx_driver_scummvm;
|
|
|
|
gfx_state.version = resmgr->sci_version;
|
2009-02-15 15:36:53 +00:00
|
|
|
gamestate->gfx_state = &gfx_state;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:43:13 +00:00
|
|
|
/**** Default config: */
|
2009-02-15 06:10:59 +00:00
|
|
|
gfx_options_t gfx_options;
|
|
|
|
gfx_options.workarounds = 0;
|
|
|
|
gfx_options.buffer_pics_nr = 0;
|
|
|
|
gfx_options.correct_rendering = 1;
|
|
|
|
gfx_options.pic0_unscaled = 1;
|
|
|
|
gfx_options.pic0_dither_mode = GFXR_DITHER_MODE_D256;
|
|
|
|
gfx_options.pic0_dither_pattern = GFXR_DITHER_PATTERN_SCALED;
|
|
|
|
gfx_options.pic0_brush_mode = GFX_BRUSH_MODE_RANDOM_ELLIPSES;
|
|
|
|
gfx_options.pic0_line_mode = GFX_LINE_MODE_CORRECT;
|
|
|
|
gfx_options.cursor_xlate_filter = GFX_XLATE_FILTER_NONE;
|
|
|
|
gfx_options.view_xlate_filter = GFX_XLATE_FILTER_NONE;
|
|
|
|
gfx_options.pic_xlate_filter = GFX_XLATE_FILTER_NONE;
|
|
|
|
gfx_options.text_xlate_filter = GFX_XLATE_FILTER_NONE;
|
|
|
|
gfx_options.dirty_frames = GFXOP_DIRTY_FRAMES_CLUSTERS;
|
|
|
|
gfx_options.pic0_antialiasing = GFXR_ANTIALIASING_NONE;
|
2009-02-15 22:43:13 +00:00
|
|
|
gfx_options.pic_port_bounds = gfx_rect(0, 10, 320, 190);
|
2009-02-15 06:10:59 +00:00
|
|
|
for (int i = 0; i < GFX_RESOURCE_TYPES_NR; i++) {
|
|
|
|
gfx_options.res_conf.assign[i] = NULL;
|
|
|
|
gfx_options.res_conf.mod[i] = NULL;
|
|
|
|
}
|
2009-02-15 22:43:13 +00:00
|
|
|
/**** Default config ends */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (gfxop_init_default(&gfx_state, &gfx_options, resmgr)) {
|
2009-02-20 20:39:02 +00:00
|
|
|
error("Graphics initialization failed. Aborting...\n");
|
2009-02-17 18:16:48 +00:00
|
|
|
return Common::kUnknownError;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-15 15:36:53 +00:00
|
|
|
if (game_init_graphics(gamestate)) { /* Init interpreter graphics */
|
2009-02-20 20:39:02 +00:00
|
|
|
error("Game initialization failed: Error in GFX subsystem. Aborting...\n");
|
2009-02-17 18:16:48 +00:00
|
|
|
return Common::kUnknownError;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-15 15:36:53 +00:00
|
|
|
if (game_init_sound(gamestate, 0)) {
|
2009-02-20 20:39:02 +00:00
|
|
|
error("Game initialization failed: Error in sound subsystem. Aborting...\n");
|
2009-02-17 18:16:48 +00:00
|
|
|
return Common::kUnknownError;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
printf("Emulating SCI version %d.%03d.%03d\n",
|
2009-02-15 22:43:13 +00:00
|
|
|
SCI_VERSION_MAJOR(gamestate->version),
|
|
|
|
SCI_VERSION_MINOR(gamestate->version),
|
|
|
|
SCI_VERSION_PATCHLEVEL(gamestate->version));
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 15:36:53 +00:00
|
|
|
game_run(&gamestate); /* Run the game */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 15:36:53 +00:00
|
|
|
game_exit(gamestate);
|
|
|
|
script_free_engine(gamestate); /* Uninitialize game state */
|
|
|
|
script_free_breakpoints(gamestate);
|
2009-02-17 13:51:52 +00:00
|
|
|
free(gamestate->work_dir);
|
|
|
|
free(gamestate);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-20 16:03:50 +00:00
|
|
|
delete resmgr;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
close_console_file();
|
|
|
|
|
|
|
|
gfxop_exit(&gfx_state);
|
|
|
|
|
2009-02-15 08:20:53 +00:00
|
|
|
return Common::kNoError;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-20 14:45:28 +00:00
|
|
|
const char* SciEngine::getGameID() const {
|
|
|
|
return _gameDescription->desc.gameid;
|
|
|
|
}
|
|
|
|
|
|
|
|
int SciEngine::getVersion() const {
|
|
|
|
return _gameDescription->version;
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::Language SciEngine::getLanguage() const {
|
|
|
|
return _gameDescription->desc.language;
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::Platform SciEngine::getPlatform() const {
|
|
|
|
return _gameDescription->desc.platform;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 SciEngine::getFlags() const {
|
|
|
|
return _gameDescription->desc.flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // End of namespace Sci
|