/* 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$ * */ #include "common/system.h" #include "common/config-manager.h" #include "engines/advancedDetector.h" #include "sci/sci.h" #include "sci/include/engine.h" //namespace Sci { extern gfx_driver_t gfx_driver_scummvm; int c_quit(state_t *s) { script_abort_flag = 1; /* Terminate VM */ _debugstate_valid = 0; _debug_seeking = 0; _debug_step_running = 0; return 0; } int c_die(state_t *s) { exit(0); /* Die */ return 0; /* ;-P (fixes warning) */ } static void init_console() { #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", "Alpha threshold for crossblitting\n"); con_hook_int(&sci0_palette, "sci0_palette", "SCI0 palette- 0: EGA, 1:AGI/Amiga, 2:Grayscale\n"); con_hook_int(&sci01_priority_table_flags, "sci01_priority_table_flags", "SCI01 priority table debugging flags: 1:Disable, 2:Print on change\n"); con_passthrough = 1; /* enables all sciprintf data to be sent to stdout */ } static int init_gamestate(state_t *gamestate, sci_version_t version) { int errc; if ((errc = script_init_engine(gamestate, version))) { /* Initialize game state */ int recovered = 0; if (errc == SCI_ERROR_INVALID_SCRIPT_VERSION) { int tversion = SCI_VERSION_FTU_NEW_SCRIPT_HEADER - ((version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER) ? 0 : 1); while (!recovered && tversion) { printf("Trying version %d.%03x.%03d instead\n", SCI_VERSION_MAJOR(tversion), SCI_VERSION_MINOR(tversion), SCI_VERSION_PATCHLEVEL(tversion)); 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) { fprintf(stderr, "Script initialization failed. Aborting...\n"); return 1; } } return 0; } static void detect_versions(sci_version_t *version, int *res_version) { sci_version_t exe_version; sci_version_t hash_version; int hash_res_version; guint32 code; int got_exe_version; const char *game_name; sciprintf("Detecting interpreter and resource versions...\n"); got_exe_version = !version_detect_from_executable(&exe_version); if (got_exe_version) { sciprintf("Interpreter version: %d.%03d.%03d (by executable scan)\n", SCI_VERSION_MAJOR(exe_version), SCI_VERSION_MINOR(exe_version), SCI_VERSION_PATCHLEVEL(exe_version)); if (SCI_VERSION_MAJOR(exe_version) >= 1) { sciprintf("FIXME: Implement version mapping (results of executable scan ignored)\n"); got_exe_version = 0; } } game_name = version_guess_from_hashcode(&hash_version, &hash_res_version, &code); if (game_name) { sciprintf("Interpreter version: %d.%03d.%03d (by hash code %08X)\n", SCI_VERSION_MAJOR(hash_version), SCI_VERSION_MINOR(hash_version), SCI_VERSION_PATCHLEVEL(hash_version), code); if (got_exe_version && exe_version != hash_version) sciprintf("UNEXPECTED INCONSISTENCY: Hash code %08X indicates interpreter version\n" " %d.%03d.%03d, but analysis of the executable yields %d.%03d.%03d (for game\n" " '%s'). Please report this!\n", code, SCI_VERSION_MAJOR(hash_version), SCI_VERSION_MINOR(hash_version), SCI_VERSION_PATCHLEVEL(hash_version), SCI_VERSION_MAJOR(exe_version), SCI_VERSION_MINOR(exe_version), SCI_VERSION_PATCHLEVEL(exe_version), game_name); if (hash_res_version != SCI_VERSION_AUTODETECT) sciprintf("Resource version: %d (by hash code)\n", hash_res_version); sciprintf("Game identified as '%s'\n", game_name); } else { sciprintf("Could not identify game by hash code: %08X\n", code); if (got_exe_version) sciprintf("Please report the preceding two lines and the name of the game you were trying\n" "to run to the FreeSCI development team to help other users!\n", code); } if (game_name) *version = hash_version; else if (got_exe_version) *version = exe_version; else *version = 0; if (game_name) *res_version = hash_res_version; else *res_version = SCI_VERSION_AUTODETECT; if (*version) sciprintf("Using interpreter version %d.%03d.%03d\n", SCI_VERSION_MAJOR(*version), SCI_VERSION_MINOR(*version), SCI_VERSION_PATCHLEVEL(*version)); if (*res_version != SCI_VERSION_AUTODETECT) sciprintf("Using resource version %d\n", *res_version); } int main_() { resource_mgr_t *resmgr; init_console(); /* So we can get any output */ script_debug_flag = 0; sci_version_t version; int res_version; // FIXME. An evil hack until File class will be used properly chdir(ConfMan.get("path").c_str()); detect_versions(&version, &res_version); char resource_dir[MAXPATHLEN+1] = ""; getcwd(resource_dir, MAXPATHLEN); /* Store resource directory */ resmgr = scir_new_resource_manager(resource_dir, res_version, 1, 256 * 1024); if (!resmgr) { printf("No resources found in '%s'.\nAborting...\n", resource_dir); exit(1); } 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"); state_t* gamestate = (state_t *) sci_malloc(sizeof(state_t)); memset(gamestate, 0, sizeof(state_t)); gamestate->resmgr = resmgr; gamestate->gfx_state = NULL; if (init_gamestate(gamestate, version)) return 1; if (game_init(gamestate)) { /* Initialize */ fprintf(stderr, "Game initialization failed: Aborting...\n"); return 1; } /* Set the savegame dir */ script_set_gamestate_save_dir(gamestate, ConfMan.get("savepath").c_str()); // Originally, work_dir tried to be ~/.freesci/game_name 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; gfx_crossblit_alpha_threshold = 0x90; gfx_state_t gfx_state; gfx_state.driver = &gfx_driver_scummvm; gfx_state.version = resmgr->sci_version; gamestate->gfx_state = &gfx_state; /**** Default config: */ 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; gfx_options.pic_port_bounds = gfx_rect(0, 10, 320, 190); for (int i = 0; i < GFX_RESOURCE_TYPES_NR; i++) { gfx_options.res_conf.assign[i] = NULL; gfx_options.res_conf.mod[i] = NULL; } /**** Default config ends */ if (gfxop_init_default(&gfx_state, &gfx_options, resmgr)) { fprintf(stderr, "Graphics initialization failed. Aborting...\n"); return 1; } if (game_init_graphics(gamestate)) { /* Init interpreter graphics */ fprintf(stderr, "Game initialization failed: Error in GFX subsystem. Aborting...\n"); return 1; } if (game_init_sound(gamestate, 0)) { fprintf(stderr, "Game initialization failed: Error in sound subsystem. Aborting...\n"); return 1; } printf("Emulating SCI version %d.%03d.%03d\n", SCI_VERSION_MAJOR(gamestate->version), SCI_VERSION_MINOR(gamestate->version), SCI_VERSION_PATCHLEVEL(gamestate->version)); game_run(&gamestate); /* Run the game */ game_exit(gamestate); script_free_engine(gamestate); /* Uninitialize game state */ script_free_breakpoints(gamestate); free(gamestate->work_dir); free(gamestate); scir_free_resource_manager(resmgr); close_console_file(); gfxop_exit(&gfx_state); return 0; } SciEngine::SciEngine(OSystem *syst, const SciGameDescription *desc) : Engine(syst) { // 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 //Common::addSpecialDebugLevel(SCI_DEBUG_RESOURCES, "resources", "Debug the resources loading"); 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 ugetEventManager(); while (!end) { Common::Event ev; if (em->pollEvent(ev)) { if (ev.type == Common::EVENT_KEYDOWN) { end = true; } } _system->delayMillis(10); } */ main_(); return Common::kNoError; } //} // End of namespace Sci