diff options
42 files changed, 584 insertions, 188 deletions
diff --git a/backends/events/dinguxsdl/dinguxsdl-events.cpp b/backends/events/dinguxsdl/dinguxsdl-events.cpp index 6f9f2a7748..cc15f2666c 100644 --- a/backends/events/dinguxsdl/dinguxsdl-events.cpp +++ b/backends/events/dinguxsdl/dinguxsdl-events.cpp @@ -26,18 +26,48 @@ #include "backends/events/dinguxsdl/dinguxsdl-events.h" +#ifndef GCW0 #define PAD_UP SDLK_UP #define PAD_DOWN SDLK_DOWN #define PAD_LEFT SDLK_LEFT #define PAD_RIGHT SDLK_RIGHT #define BUT_A SDLK_LCTRL #define BUT_B SDLK_LALT -#define BUT_X SDLK_SPACE -#define BUT_Y SDLK_LSHIFT +#define BUT_X SDLK_SPACE // BUT_Y in GCW0 +#define BUT_Y SDLK_LSHIFT // BUT_X in GCW0 #define BUT_SELECT SDLK_ESCAPE #define BUT_START SDLK_RETURN #define TRIG_L SDLK_TAB #define TRIG_R SDLK_BACKSPACE +#else // GCW0 + +/****** + * GCW0 keymap + * Dingoo button + * A -> Left Button BUT_Y + * B -> right button BUT_B + * X -> ' ' BUT_A '0' + * Y -> '.' BUT_X + * Select -> ESC TRIG_R + * Start -> F5 TRIG_L + * L -> Shift BUT_START + * R -> VK BUT_SELECT + */ + +#define PAD_UP SDLK_UP +#define PAD_DOWN SDLK_DOWN +#define PAD_LEFT SDLK_LEFT +#define PAD_RIGHT SDLK_RIGHT +#define BUT_A SDLK_LSHIFT +#define BUT_B SDLK_LALT +#define BUT_X SDLK_SPACE +#define BUT_Y SDLK_LCTRL +#define BUT_SELECT SDLK_BACKSPACE +#define BUT_START SDLK_TAB +#define TRIG_L SDLK_RETURN +#define TRIG_R SDLK_ESCAPE + +#endif bool DINGUXSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) { if (ev.key.keysym.sym == PAD_UP) { diff --git a/backends/keymapper/action.h b/backends/keymapper/action.h index ed4bb86ce6..17b1153c77 100644 --- a/backends/keymapper/action.h +++ b/backends/keymapper/action.h @@ -37,7 +37,7 @@ namespace Common { struct HardwareInput; class Keymap; -#define ACTION_ID_SIZE (4) +#define ACTION_ID_SIZE (5) struct KeyActionEntry { const KeyState ks; diff --git a/backends/platform/dingux/dingux.mk b/backends/platform/dingux/dingux.mk index 48a9347143..1333e89ff8 100644 --- a/backends/platform/dingux/dingux.mk +++ b/backends/platform/dingux/dingux.mk @@ -1,6 +1,7 @@ DINGUX_EXE_STRIPPED := scummvm_stripped$(EXEEXT) bundle_name = dingux-dist/scummvm +gcw0_bundle = gcw0-opk all: $(DINGUX_EXE_STRIPPED) @@ -30,3 +31,37 @@ endif $(CP) $(srcdir)/backends/platform/dingux/scummvm.gpe $(bundle_name)/ $(CP) $(srcdir)/backends/platform/dingux/README.DINGUX $(bundle_name)/ $(CP) $(srcdir)/backends/platform/dingux/scummvm.png $(bundle_name)/ + +# Special target for generationg GCW-Zero OPK bundle +$(gcw0_bundle): all + $(MKDIR) $(gcw0_bundle) + $(CP) $(DIST_FILES_DOCS) $(gcw0_bundle)/ + $(MKDIR) $(gcw0_bundle)/themes + $(CP) $(DIST_FILES_THEMES) $(gcw0_bundle)/themes/ +ifdef DIST_FILES_ENGINEDATA + $(MKDIR) $(gcw0_bundle)/engine-data + $(CP) $(DIST_FILES_ENGINEDATA) $(gcw0_bundle)/engine-data/ +endif +ifdef DYNAMIC_MODULES + $(MKDIR) $(gcw0_bundle)/plugins + $(CP) $(PLUGINS) $(gcw0_bundle)/plugins/ +endif + $(CP) $(EXECUTABLE) $(gcw0_bundle)/scummvm + + $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(gcw0_bundle)/ + $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_small.zip $(gcw0_bundle)/ + + $(CP) $(srcdir)/dists/gcw0/scummvm.png $(gcw0_bundle)/ + $(CP) $(srcdir)/dists/gcw0/default.gcw0.desktop $(gcw0_bundle)/ + $(CP) $(srcdir)/dists/gcw0/scummvmrc $(gcw0_bundle)/ + $(CP) $(srcdir)/dists/gcw0/scummvm.sh $(gcw0_bundle)/ + +gcw0-opk-unstripped: $(gcw0_bundle) + $(CP) $(PLUGINS) $(gcw0_bundle)/plugins/ + $(CP) $(EXECUTABLE) $(gcw0_bundle)/scummvm + ./dists/gcw0/opk_make.sh -d $(gcw0_bundle) -o scummvm + +gcw-opk: $(gcw0_bundle) + $(STRIP) $(gcw0_bundle)/plugins/* + $(STRIP) $(gcw0_bundle)/scummvm + ./dists/gcw0/opk_make.sh -d $(gcw0_bundle) -o scummvm diff --git a/backends/platform/wii/osystem_events.cpp b/backends/platform/wii/osystem_events.cpp index 0563639de3..13f5d1fbe0 100644 --- a/backends/platform/wii/osystem_events.cpp +++ b/backends/platform/wii/osystem_events.cpp @@ -70,73 +70,73 @@ #endif #ifdef USE_WII_KBD -static int keymap[][2] = { - { KS_Return, Common::KEYCODE_RETURN }, - { KS_Up, Common::KEYCODE_UP }, - { KS_Down, Common::KEYCODE_DOWN }, - { KS_Left, Common::KEYCODE_LEFT }, - { KS_Right, Common::KEYCODE_RIGHT }, - { KS_Shift_L, Common::KEYCODE_LSHIFT }, - { KS_Shift_R, Common::KEYCODE_RSHIFT }, - { KS_Control_L, Common::KEYCODE_LCTRL }, - { KS_Control_R, Common::KEYCODE_RCTRL }, - { KS_Alt_L, Common::KEYCODE_LALT }, - { KS_Alt_R, Common::KEYCODE_RALT }, - { KS_Meta_L, Common::KEYCODE_LMETA }, - { KS_Meta_R, Common::KEYCODE_RMETA }, - { KS_KP_0, Common::KEYCODE_KP0 }, - { KS_KP_1, Common::KEYCODE_KP1 }, - { KS_KP_2, Common::KEYCODE_KP2 }, - { KS_KP_3, Common::KEYCODE_KP3 }, - { KS_KP_4, Common::KEYCODE_KP4 }, - { KS_KP_5, Common::KEYCODE_KP5 }, - { KS_KP_6, Common::KEYCODE_KP6 }, - { KS_KP_7, Common::KEYCODE_KP7 }, - { KS_KP_8, Common::KEYCODE_KP8 }, - { KS_KP_9, Common::KEYCODE_KP9 }, - { KS_Home, Common::KEYCODE_HOME }, - { KS_Insert, Common::KEYCODE_INSERT }, - { KS_End, Common::KEYCODE_END }, - { KS_Prior, Common::KEYCODE_PAGEUP }, - { KS_Next, Common::KEYCODE_PAGEDOWN }, - { KS_f1, Common::KEYCODE_F1 }, - { KS_f2, Common::KEYCODE_F2 }, - { KS_f3, Common::KEYCODE_F3 }, - { KS_f4, Common::KEYCODE_F4 }, - { KS_f5, Common::KEYCODE_F5 }, - { KS_f6, Common::KEYCODE_F6 }, - { KS_f7, Common::KEYCODE_F7 }, - { KS_f8, Common::KEYCODE_F8 }, - { KS_f9, Common::KEYCODE_F9 }, - { KS_f10, Common::KEYCODE_F10 }, - { KS_f11, Common::KEYCODE_F11 }, - { KS_f12, Common::KEYCODE_F12 }, - { KS_f13, Common::KEYCODE_F13 }, - { KS_f14, Common::KEYCODE_F14 }, - { KS_f15, Common::KEYCODE_F15 }, - { KS_F1, Common::KEYCODE_F1 }, - { KS_F2, Common::KEYCODE_F2 }, - { KS_F3, Common::KEYCODE_F3 }, - { KS_F4, Common::KEYCODE_F4 }, - { KS_F5, Common::KEYCODE_F5 }, - { KS_F6, Common::KEYCODE_F6 }, - { KS_F7, Common::KEYCODE_F7 }, - { KS_F8, Common::KEYCODE_F8 }, - { KS_F9, Common::KEYCODE_F9 }, - { KS_F10, Common::KEYCODE_F10 }, - { KS_F11, Common::KEYCODE_F11 }, - { KS_F12, Common::KEYCODE_F12 }, - { KS_F13, Common::KEYCODE_F13 }, - { KS_F14, Common::KEYCODE_F14 }, - { KS_F15, Common::KEYCODE_F15 }, - { KS_KP_Separator, Common::KEYCODE_KP_PERIOD }, - { KS_KP_Subtract, Common::KEYCODE_KP_DIVIDE }, - { KS_KP_Multiply, Common::KEYCODE_KP_MULTIPLY }, - { KS_KP_Add, Common::KEYCODE_KP_PLUS }, - { KS_KP_Subtract, Common::KEYCODE_KP_MINUS }, - { KS_KP_Equal, Common::KEYCODE_KP_EQUALS }, - { KS_KP_Enter, Common::KEYCODE_KP_ENTER }, - { 0, 0 } +static int keymap[][3] = { + { KS_Return, Common::KEYCODE_RETURN, Common::ASCII_RETURN }, + { KS_Up, Common::KEYCODE_UP, 0 }, + { KS_Down, Common::KEYCODE_DOWN, 0 }, + { KS_Left, Common::KEYCODE_LEFT, 0 }, + { KS_Right, Common::KEYCODE_RIGHT, 0 }, + { KS_Shift_L, Common::KEYCODE_LSHIFT, 0 }, + { KS_Shift_R, Common::KEYCODE_RSHIFT, 0 }, + { KS_Control_L, Common::KEYCODE_LCTRL, 0 }, + { KS_Control_R, Common::KEYCODE_RCTRL, 0 }, + { KS_Alt_L, Common::KEYCODE_LALT, 0 }, + { KS_Alt_R, Common::KEYCODE_RALT, 0 }, + { KS_Meta_L, Common::KEYCODE_LMETA, 0 }, + { KS_Meta_R, Common::KEYCODE_RMETA, 0 }, + { KS_KP_0, Common::KEYCODE_KP0, '0' }, + { KS_KP_1, Common::KEYCODE_KP1, '1' }, + { KS_KP_2, Common::KEYCODE_KP2, '2' }, + { KS_KP_3, Common::KEYCODE_KP3, '3' }, + { KS_KP_4, Common::KEYCODE_KP4, '4' }, + { KS_KP_5, Common::KEYCODE_KP5, '5' }, + { KS_KP_6, Common::KEYCODE_KP6, '6' }, + { KS_KP_7, Common::KEYCODE_KP7, '7' }, + { KS_KP_8, Common::KEYCODE_KP8, '8' }, + { KS_KP_9, Common::KEYCODE_KP9, '9' }, + { KS_Home, Common::KEYCODE_HOME, 0 }, + { KS_Insert, Common::KEYCODE_INSERT, 0 }, + { KS_End, Common::KEYCODE_END, 0 }, + { KS_Prior, Common::KEYCODE_PAGEUP, 0 }, + { KS_Next, Common::KEYCODE_PAGEDOWN, 0 }, + { KS_f1, Common::KEYCODE_F1, Common::ASCII_F1 }, + { KS_f2, Common::KEYCODE_F2, Common::ASCII_F2 }, + { KS_f3, Common::KEYCODE_F3, Common::ASCII_F3 }, + { KS_f4, Common::KEYCODE_F4, Common::ASCII_F4 }, + { KS_f5, Common::KEYCODE_F5, Common::ASCII_F5 }, + { KS_f6, Common::KEYCODE_F6, Common::ASCII_F6 }, + { KS_f7, Common::KEYCODE_F7, Common::ASCII_F7 }, + { KS_f8, Common::KEYCODE_F8, Common::ASCII_F8 }, + { KS_f9, Common::KEYCODE_F9, Common::ASCII_F9 }, + { KS_f10, Common::KEYCODE_F10, Common::ASCII_F10 }, + { KS_f11, Common::KEYCODE_F11, Common::ASCII_F11 }, + { KS_f12, Common::KEYCODE_F12, Common::ASCII_F12 }, + { KS_f13, Common::KEYCODE_F13, 0 }, + { KS_f14, Common::KEYCODE_F14, 0 }, + { KS_f15, Common::KEYCODE_F15, 0 }, + { KS_F1, Common::KEYCODE_F1, Common::ASCII_F1 }, + { KS_F2, Common::KEYCODE_F2, Common::ASCII_F2 }, + { KS_F3, Common::KEYCODE_F3, Common::ASCII_F3 }, + { KS_F4, Common::KEYCODE_F4, Common::ASCII_F4 }, + { KS_F5, Common::KEYCODE_F5, Common::ASCII_F5 }, + { KS_F6, Common::KEYCODE_F6, Common::ASCII_F6 }, + { KS_F7, Common::KEYCODE_F7, Common::ASCII_F7 }, + { KS_F8, Common::KEYCODE_F8, Common::ASCII_F8 }, + { KS_F9, Common::KEYCODE_F9, Common::ASCII_F9 }, + { KS_F10, Common::KEYCODE_F10, Common::ASCII_F10 }, + { KS_F11, Common::KEYCODE_F11, Common::ASCII_F11 }, + { KS_F12, Common::KEYCODE_F12, Common::ASCII_F12 }, + { KS_F13, Common::KEYCODE_F13, 0 }, + { KS_F14, Common::KEYCODE_F14, 0 }, + { KS_F15, Common::KEYCODE_F15, 0 }, + { KS_KP_Separator, Common::KEYCODE_KP_PERIOD, '.' }, + { KS_KP_Divide, Common::KEYCODE_KP_DIVIDE, '/' }, + { KS_KP_Multiply, Common::KEYCODE_KP_MULTIPLY, '*' }, + { KS_KP_Add, Common::KEYCODE_KP_PLUS, '+' }, + { KS_KP_Subtract, Common::KEYCODE_KP_MINUS, '-' }, + { KS_KP_Equal, Common::KEYCODE_KP_EQUALS, '=' }, + { KS_KP_Enter, Common::KEYCODE_KP_ENTER, Common::ASCII_RETURN }, + { 0, 0, 0 } }; #endif @@ -262,7 +262,7 @@ bool OSystem_Wii::pollKeyboard(Common::Event &event) { while (keymap[i][0] != 0) { if (keymap[i][0] == kbdEvent.symbol) { event.kbd.keycode = static_cast<Common::KeyCode>(keymap[i][1]); - event.kbd.ascii = 0; + event.kbd.ascii = keymap[i][2]; return true; } diff --git a/base/version.cpp b/base/version.cpp index ef02ff9d21..fcb2740de9 100644 --- a/base/version.cpp +++ b/base/version.cpp @@ -146,4 +146,12 @@ const char *gScummVMFeatures = "" #ifdef USE_PNG "PNG " #endif + +#ifdef ENABLE_KEYMAPPER + "keymapper " +#endif + +#ifdef ENABLE_VKEYBD + "virtual keyboard " +#endif ; @@ -822,9 +822,9 @@ Usage: $0 [OPTIONS]... Configuration: -h, --help display this help and exit - --backend=BACKEND backend to build (android, tizen, dc, dingux, ds, gph, - iphone, linuxmoto, maemo, n64, null, openpandora, ps2, - psp, samsungtv, sdl, webos, wii, wince) [sdl] + --backend=BACKEND backend to build (android, tizen, dc, dingux, ds, gcw0, + gph, iphone, linuxmoto, maemo, n64, null, openpandora, + ps2, psp, samsungtv, sdl, webos, wii, wince) [sdl] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX @@ -859,6 +859,7 @@ Special configuration feature: dreamcast for Sega Dreamcast ds for Nintendo DS gamecube for Nintendo GameCube + gcw0 for GCW Zero gp2x for GP2X gp2xwiz for GP2X Wiz iphone for Apple iPhone @@ -1298,7 +1299,7 @@ caanoo) _host_cpu=arm _host_alias=arm-none-linux-gnueabi ;; -dingux) +dingux | gcw0) _host_os=linux _host_cpu=mipsel _host_alias=mipsel-linux @@ -2588,6 +2589,25 @@ if test -n "$_host"; then add_line_to_config_h "/* #define DEBUG_WII_GDB */" add_line_to_config_h "#define USE_WII_DI" ;; + gcw0) + DEFINES="$DEFINES -DDINGUX -DGCW0" + DEFINES="$DEFINES -DREDUCE_MEMORY_USAGE" + ASFLAGS="$ASFLAGS" + CXXFLAGS="$CXXFLAGS -mips32" + _backend="dingux" + _mt32emu=no + _optimization_level=-O3 + # Disable alsa midi to get the port build on OpenDingux toolchain + _alsa=no + _vkeybd=yes + _build_hq_scalers=no + _keymapper=yes + # Force disable vorbis on dingux, it has terrible performance compared to tremor + _vorbis=no + # Force disable seq on dingux, no way to use it and it would get enabled by default with configure + _seq_midi=no + _port_mk="backends/platform/dingux/dingux.mk" + ;; gp2x) DEFINES="$DEFINES -DGP2X" CXXFLAGS="$CXXFLAGS -march=armv4t" diff --git a/dists/gcw0/default.gcw0.desktop b/dists/gcw0/default.gcw0.desktop new file mode 100644 index 0000000000..46bd2be092 --- /dev/null +++ b/dists/gcw0/default.gcw0.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +Name=ScummVM +Comment=Interpreter for several adventure games +Comment[pl]=Interpreter graficznych gier przygodowych +Comment[sv]=Tolk för flera äventyrsspel +Comment[he]=פרשן למספר משחקי הרפתקאות +Comment[de]=Interpreter für diverse Abenteuerspiele +Comment[es]=Intérprete para varias aventuras gráficas +Comment[ca]=Intèrpret per diverses aventures gràfiques +Exec=scummvm.sh +Icon=scummvm +Terminal=false +Type=Application +Categories=games +StartupNotify=false +X-OD-Manual=README diff --git a/dists/gcw0/opk_make.sh b/dists/gcw0/opk_make.sh new file mode 100755 index 0000000000..b1bfd03efb --- /dev/null +++ b/dists/gcw0/opk_make.sh @@ -0,0 +1,111 @@ +#!/bin/bash +# +# opk_make.sh +# +# This script is meant to ease generation of a opk file. Please consult the output +# when running --help for a list of available parameters and an explaination of +# those. +# +# Required tools when running the script: +# bash +# echo, cat, mv, rm, mksquashfs + +check_for_tool() +{ + which $1 &> /dev/null + if [ "$?" -ne "0" ]; + then + cecho "ERROR: Could not find the program '$1'. Please make sure +that it is available in your PATH since it is required to complete your request." $red + exit 1 + fi +} + +print_help() +{ + cat << EOSTREAM +opk_make.sh - A script to package "something" into a OPK. + +Usage: + $(basename ${0}) {--directory|-d} <folder> {--opk|-o} <file> [{--help|-h}] + + +Switches: + --directory / -d Sets the folder that is to be used for the resulting opk + to <folder>. This option is mandatory for the script to + function correctly. + + --help / -h Displays this help text. + + --opkname / -o Sets the output filename of the resulting opk to <file>. + This option is mandatory for the script to function + correctly. + +A version >=4.0 of squashfs is required to be available in your PATH. +EOSTREAM +} + + +# Parse command line parameters +while [ "${1}" != "" ]; do + if [ "${1}" = "--directory" ] || [ "${1}" = "-d" ]; + then + FOLDER=$2 + shift 2 + elif [ "${1}" = "--help" ] || [ "${1}" = "-h" ]; + then + print_help + exit 0 + elif [ "${1}" = "--opkname" ] || [ "${1}" = "-o" ]; + then + OPKNAME=$2 + shift 2 + else + echo "ERROR: '$1' is not a known argument. Printing --help and aborting." + print_help + exit 1 + fi +done + + +# Probe if required variables were set +echo "Checking if all required variables were set." +if [ ! $OPKNAME ] || [ ! $FOLDER ]; +then + echo "ERROR: Not all required options were set! Please see the --help information below." + print_help + exit 1 +else + echo "OPKNAME set to '$OPKNAME'." +fi +# Check if the selected folder actually exists +if [ ! -d $FOLDER ]; +then + echo "ERROR: '$FOLDER' doesn't exist or is not a folder." + exit 1 +else + echo "FOLDER set to '$FOLDER'." +fi + +# Make iso from folder +echo "Creating an iso file based on '$FOLDER'." + +check_for_tool mksquashfs +if [ $(mksquashfs -version | awk 'BEGIN{r=0} $3>=4{r=1} END{print r}') -eq 0 ]; +then + echo "ERROR: Your squashfs version is older then version 4, please upgrade to 4.0 or later" + exit 1 +fi +mksquashfs $FOLDER $OPKNAME.opk -noappend -no-exports -no-xattrs + +# Final message +if [ -f $OPKNAME ]; +then + echo "Successfully finished creating the opk '$OPKNAME'." +else + echo "There seems to have been a problem and '$OPKNAME' was not created. Please check +the output above for any error messages. A possible cause for this is that there was +not enough space available." + exit 1 +fi + diff --git a/dists/gcw0/scummvm.png b/dists/gcw0/scummvm.png Binary files differnew file mode 100644 index 0000000000..128e59efc4 --- /dev/null +++ b/dists/gcw0/scummvm.png diff --git a/dists/gcw0/scummvm.sh b/dists/gcw0/scummvm.sh new file mode 100755 index 0000000000..c12a3030cc --- /dev/null +++ b/dists/gcw0/scummvm.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +cd `dirname $0` + +if [ ! -f $HOME/.scummvmrc ] ; then + cp ./scummvmrc $HOME/.scummvmrc +fi + +exec ./scummvm diff --git a/dists/gcw0/scummvmrc b/dists/gcw0/scummvmrc new file mode 100644 index 0000000000..c2087c222a --- /dev/null +++ b/dists/gcw0/scummvmrc @@ -0,0 +1,9 @@ +[scummvm] +fullscreen=true +gfx_mode=1x +aspect_ratio=true +themepath=./themes +browser_lastpath=/media +extrapath=./engine-data +pluginspath=./plugins +joystick_num=0 diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 40134bbf17..676564a9fb 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1124,8 +1124,6 @@ void Inter_v1::o1_palLoad(OpFuncParams ¶ms) { _vm->_draw->_vgaPalette[i].green = _vm->_game->_script->readByte(); _vm->_draw->_vgaPalette[i].blue = _vm->_game->_script->readByte(); } - - memcpy(_vm->_draw->_vgaPalette, _vm->_draw->_vgaPalette, 16 * 3); break; case 53: diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp index 9f0e0adb6d..2b999fa305 100644 --- a/engines/mads/animation.cpp +++ b/engines/mads/animation.cpp @@ -340,9 +340,6 @@ void Animation::startAnimation(int endTrigger) { _unkIndex = -1; //SpriteAsset *asset = _scene->_sprites[_spriteListIndexes[_header._spritesIndex]]; - // TODO: Weird stuff with _unkList. Seems like it's treated as pointers - // here, but in processText, it's used as POINTs? - loadFrame(1); } diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp index 5ea8fb115c..5e38f34fc6 100644 --- a/engines/mads/dialogs.cpp +++ b/engines/mads/dialogs.cpp @@ -457,6 +457,7 @@ void FullScreenDialog::display() { _vm->_palette->setLowRange(); _vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2); _vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2); + _vm->_screen.resetClipBounds(); _vm->_screen.copyRectToScreen(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT)); // Restrict the screen to the area between the two lines diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index b544eff2db..63a7e40d1b 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -433,8 +433,6 @@ void Game::handleKeypress(const Common::Event &event) { default: break; } - - warning("TODO: handleKeypress - %d", (int)event.kbd.keycode); } void Game::synchronize(Common::Serializer &s, bool phase1) { diff --git a/engines/mads/menu_views.cpp b/engines/mads/menu_views.cpp index 857db68fa6..03afc70c3e 100644 --- a/engines/mads/menu_views.cpp +++ b/engines/mads/menu_views.cpp @@ -80,6 +80,15 @@ bool MenuView::onEvent(Common::Event &event) { return false; } +Common::String MenuView::getResourceName() { + Common::String s(_filename); + s.toLowercase(); + while (s.contains('.')) + s.deleteLastChar(); + + return s; +} + /*------------------------------------------------------------------------*/ char TextView::_resourceName[100]; @@ -112,12 +121,17 @@ TextView::TextView(MADSEngine *vm) : MenuView(vm) { } TextView::~TextView() { + // Turn off palette cycling as well as any playing sound + Scene &scene = _vm->_game->_scene; + scene._cyclingActive = false; + _vm->_sound->stop(); } void TextView::load() { Common::String scriptName(_resourceName); scriptName += ".txr"; + _filename = scriptName; if (!_script.open(scriptName)) error("Could not open resource %s", _resourceName); @@ -491,6 +505,7 @@ void AnimationView::load() { if (!resName.hasSuffix(".")) resName += ".res"; + _filename = resName; if (!_script.open(resName)) error("Could not open resource %s", resName.c_str()); @@ -750,40 +765,4 @@ int AnimationView::getParameter() { return result; } -void AnimationView::checkResource(const Common::String &resourceName) { - //bool hasSuffix = false; - -} - -int AnimationView::scanResourceIndex(const Common::String &resourceName) { - int foundIndex = -1; - - if (_v1) { - const char *chP = strchr(resourceName.c_str(), '\\'); - if (!chP) { - chP = strchr(resourceName.c_str(), '*'); - } - - Common::String resName = chP ? Common::String(chP + 1) : resourceName; - - if (_v2 != 3) { - assert(_resIndex.size() == 0); - } - - // Scan for the resource name - for (uint resIndex = 0; resIndex < _resIndex.size(); ++resIndex) { - ResIndexEntry &resEntry = _resIndex[resIndex]; - if (resEntry._resourceName.compareToIgnoreCase(resourceName)) { - foundIndex = resIndex; - break; - } - } - } - - if (foundIndex >= 0) { - // TODO - } - return -1; -} - } // End of namespace MADS diff --git a/engines/mads/menu_views.h b/engines/mads/menu_views.h index 6faa665bff..cc5a13006f 100644 --- a/engines/mads/menu_views.h +++ b/engines/mads/menu_views.h @@ -36,6 +36,7 @@ class MenuView: public FullScreenDialog { protected: bool _breakFlag; bool _redrawFlag; + Common::String _filename; virtual void doFrame() = 0; @@ -51,6 +52,8 @@ public: virtual ~MenuView() {} virtual void show(); + + Common::String getResourceName(); }; struct TextLine { @@ -107,11 +110,6 @@ private: int getParameter(const char **paramP); /** - * Called when the script is finished - */ - void scriptDone(); - - /** * Reset the game palette */ void resetPalette(); @@ -119,6 +117,11 @@ protected: virtual void display(); virtual void doFrame(); + + /** + * Called when the script is finished + */ + virtual void scriptDone(); public: /** * Queue the given text resource for display @@ -189,10 +192,6 @@ private: int _animFrameNumber; bool _nextCyclingActive; private: - void checkResource(const Common::String &resourceName); - - int scanResourceIndex(const Common::String &resourceName); - void load(); void processLines(); @@ -201,8 +200,6 @@ private: int getParameter(); - void scriptDone(); - void loadNextResource(); protected: virtual void display(); @@ -210,6 +207,8 @@ protected: virtual void doFrame(); virtual bool onEvent(Common::Event &event); + + virtual void scriptDone(); public: /** * Queue the given text resource for display diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp index 0cb4530a84..39824bac4b 100644 --- a/engines/mads/msurface.cpp +++ b/engines/mads/msurface.cpp @@ -87,7 +87,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo // rectangle is always 0, 0 assert(clipRect.top == 0 && clipRect.left == 0); - // TODO: Put err* and scaled* into SpriteInfo int errX = info.hotX * info.scaleX % 100; int errY = info.hotY * info.scaleY % 100; int scaledWidth = scaleValue(info.width, info.scaleX, errX); @@ -160,7 +159,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo if (status == kStatusDraw && clipY == 0) { // Draw previously scaled line - // TODO Implement different drawing types (depth, shadow etc.) byte *tempDst = dst; for (int lineX = 0; lineX < scaledWidth; lineX++) { byte pixel = scaledLineBuf[lineX]; @@ -186,8 +184,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo } dst += pitch; heightAmt--; - // TODO depth etc. - //depthAddress += Destination -> Width; errY += 100; if (errY >= 0) diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index 86244bd3bb..f51d046951 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -314,13 +314,13 @@ void DialogsNebular::showDialog() { break; } case DIALOG_TEXTVIEW: { - TextView *dlg = new TextView(_vm); + TextView *dlg = new RexTextView(_vm); dlg->show(); delete dlg; break; } case DIALOG_ANIMVIEW: { - AnimationView *dlg = new AnimationView(_vm); + AnimationView *dlg = new RexAnimationView(_vm); dlg->show(); delete dlg; break; @@ -594,6 +594,9 @@ GameDialog::GameDialog(MADSEngine *vm) : FullScreenDialog(vm) { _vm->_events->waitCursor(); scene.clearVocab(); scene._dynamicHotspots.clear(); + // Clear scene sprites and objects + scene._spriteSlots.reset(); + _vm->_game->_screenObjects.clear(); _vm->_dialogs->_defaultPosition = Common::Point(-1, -1); _menuSpritesIndex = 0; } @@ -1061,6 +1064,14 @@ void OptionsDialog::display() { void OptionsDialog::show() { Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game; + + // Previous options, restored when cancel is selected + bool prevEasyMouse = _vm->_easyMouse; + bool prevInvObjectsAnimated = _vm->_invObjectsAnimated; + bool prevTextWindowStill = _vm->_textWindowStill; + ScreenFade prevScreenFade = _vm->_screenFade; + StoryMode prevStoryMode = game._storyMode; + do { _selectedLine = 0; GameDialog::show(); @@ -1105,10 +1116,15 @@ void OptionsDialog::show() { switch (_selectedLine) { case 8: // Done - // TODO: Copy from temporary config + // New options will be applied break; case 9: // Cancel - // TODO: Ignore all changes to temporary config + // Revert all options from the saved ones + _vm->_easyMouse = prevEasyMouse; + _vm->_invObjectsAnimated = prevInvObjectsAnimated; + _vm->_textWindowStill = prevTextWindowStill; + _vm->_screenFade = prevScreenFade; + game._storyMode = prevStoryMode; break; default: break; diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp index 902f42507a..eae74d6da0 100644 --- a/engines/mads/nebular/game_nebular.cpp +++ b/engines/mads/nebular/game_nebular.cpp @@ -27,6 +27,7 @@ #include "mads/game.h" #include "mads/screen.h" #include "mads/msurface.h" +#include "mads/menu_views.h" #include "mads/nebular/game_nebular.h" #include "mads/nebular/dialogs_nebular.h" #include "mads/nebular/globals_nebular.h" @@ -309,6 +310,31 @@ void GameNebular::setSectionHandler() { } void GameNebular::checkShowDialog() { + // Handling to start endgame sequences if the win/lose type has been set + switch (_winStatus) { + case 1: + // No shields failure ending + AnimationView::execute(_vm, "rexend1"); + break; + case 2: + // Shields, but no targetting failure ending + AnimationView::execute(_vm, "rexend2"); + break; + case 3: + // Completed game successfully, so activate quotes item on the main menu + ConfMan.setBool("ShowQuotes", true); + ConfMan.flushToDisk(); + + AnimationView::execute(_vm, "rexend3"); + break; + case 4: + // Decompression ending + TextView::execute(_vm, "ending4"); + break; + } + _winStatus = 0; + + // Loop for showing dialogs, if any need to be shown if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globals[kCopyProtectFailed]) { _player.releasePlayerSprites(); diff --git a/engines/mads/nebular/game_nebular.h b/engines/mads/nebular/game_nebular.h index da607d47ee..efa21a2e73 100644 --- a/engines/mads/nebular/game_nebular.h +++ b/engines/mads/nebular/game_nebular.h @@ -133,18 +133,16 @@ public: virtual void synchronize(Common::Serializer &s, bool phase1); }; - +// Section handlers aren't needed in ScummVM implementation class Section1Handler : public SectionHandler { public: Section1Handler(MADSEngine *vm) : SectionHandler(vm) {} - // TODO: Properly implement handler methods virtual void preLoadSection() {} virtual void sectionPtr2() {} virtual void postLoadSection() {} }; -// TODO: Properly implement handler classes typedef Section1Handler Section2Handler; typedef Section1Handler Section3Handler; typedef Section1Handler Section4Handler; diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index 717e3f6cf9..f2f90e2291 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -21,6 +21,7 @@ */ #include "common/scummsys.h" +#include "common/config-manager.h" #include "mads/game.h" #include "mads/mads.h" #include "mads/menu_views.h" @@ -62,6 +63,10 @@ MainMenu::~MainMenu() { scene._spriteSlots.reset(); } +bool MainMenu::shouldShowQuotes() { + return ConfMan.hasKey("ShowQuotes") && ConfMan.getBool("ShowQuotes"); +} + void MainMenu::display() { MenuView::display(); Scene &scene = _vm->_game->_scene; @@ -101,6 +106,9 @@ void MainMenu::doFrame() { handleAction((MADSGameAction)_selectedIndex); } else { for (_menuItemIndex = 0; _menuItemIndex < 6; ++_menuItemIndex) { + if (_menuItemIndex == 4 && !shouldShowQuotes()) + continue; + if (_menuItemIndex != _selectedIndex) { addSpriteSlot(); } @@ -120,6 +128,9 @@ void MainMenu::doFrame() { if (_skipFlag && _menuItemIndex >= 0) { // Quickly loop through all the menu items to display each's final frame for (; _menuItemIndex < 6; ++_menuItemIndex) { + if (_menuItemIndex == 4 && !shouldShowQuotes()) + continue; + // Draw the final frame of the menuitem _frameIndex = 0; addSpriteSlot(); @@ -129,9 +140,12 @@ void MainMenu::doFrame() { } else { if ((_menuItemIndex == -1) || (_frameIndex == 0)) { if (++_menuItemIndex == 6) { + // Reached end of display animation _vm->_events->showCursor(); return; + } else if (_menuItemIndex == 4 && !shouldShowQuotes()) { + ++_menuItemIndex; } _frameIndex = _menuItems[_menuItemIndex]->getCount() - 1; @@ -375,6 +389,21 @@ bool AdvertView::onEvent(Common::Event &event) { return false; } +/*------------------------------------------------------------------------*/ + +void RexAnimationView::scriptDone() { + AnimationView::scriptDone(); + + Common::String s = getResourceName(); + if (s == "rexend1") { + TextView::execute(_vm, "ending1"); + } else if (s == "rexend2") { + TextView::execute(_vm, "ending2"); + } else if (s == "rexend3") { + TextView::execute(_vm, "credits"); + } +} + } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h index 29777a7a7c..77b8b6fc6e 100644 --- a/engines/mads/nebular/menu_nebular.h +++ b/engines/mads/nebular/menu_nebular.h @@ -80,6 +80,8 @@ private: * Add a sprite slot for the current menuitem frame */ void addSpriteSlot(); + + bool shouldShowQuotes(); protected: /** * Display the menu @@ -128,6 +130,18 @@ public: void show(); }; +class RexAnimationView : public AnimationView { +protected: + virtual void scriptDone(); +public: + RexAnimationView(MADSEngine *vm) : AnimationView(vm) {} +}; + +class RexTextView : public TextView { +public: + RexTextView(MADSEngine *vm) : TextView(vm) {} +}; + } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/nebular/sound_nebular.cpp b/engines/mads/nebular/sound_nebular.cpp index c540eb4382..0a054440b2 100644 --- a/engines/mads/nebular/sound_nebular.cpp +++ b/engines/mads/nebular/sound_nebular.cpp @@ -24,6 +24,7 @@ #include "audio/decoders/raw.h" #include "common/algorithm.h" #include "common/debug.h" +#include "common/md5.h" #include "common/memstream.h" #include "mads/sound.h" #include "mads/nebular/sound_nebular.h" @@ -218,6 +219,32 @@ ASound::~ASound() { _mixer->stopHandle(_soundHandle); } +void ASound::validate() { + Common::File f; + static const char *const MD5[] = { + "205398468de2c8873b7d4d73d5be8ddc", + "f9b2d944a2fb782b1af5c0ad592306d3", + "7431f8dad77d6ddfc24e6f3c0c4ac7df", + "eb1f3f5a4673d3e73d8ac1818c957cf4", + "f936dd853073fa44f3daac512e91c476", + "3dc139d3e02437a6d9b732072407c366", + "af0edab2934947982e9a405476702e03", + "8cbc25570b50ba41c9b5361cad4fbedc", + "a31e4783e098f633cbb6689adb41dd4f" + }; + + for (int i = 1; i <= 9; ++i) { + Common::String filename = Common::String::format("ASOUND.00%d", i); + if (!f.open(filename)) + error("Could not process - %s", filename.c_str()); + Common::String md5str = Common::computeStreamMD5AsString(f, 8192); + f.close(); + + if (md5str != MD5[i - 1]) + error("Invalid sound file - %s", filename.c_str()); + } +} + void ASound::adlibInit() { write(4, 0x60); write(4, 0x80); diff --git a/engines/mads/nebular/sound_nebular.h b/engines/mads/nebular/sound_nebular.h index abb6516030..ccfd40ad52 100644 --- a/engines/mads/nebular/sound_nebular.h +++ b/engines/mads/nebular/sound_nebular.h @@ -318,6 +318,11 @@ public: virtual ~ASound(); /** + * Validates the Adlib sound files + */ + static void validate(); + + /** * Execute a player command. Most commands represent sounds to play, but some * low number commands also provide control operations. * @param commandId Player ommand to execute. diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index ad24dd4f60..18ceb3c813 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -360,6 +360,9 @@ void Scene::loop() { if (_vm->_dialogs->_pendingDialog != DIALOG_NONE && !_vm->_game->_trigger && _vm->_game->_player._stepEnabled) _reloadSceneFlag = true; + + if (_vm->_game->_winStatus) + break; } } diff --git a/engines/mads/sound.cpp b/engines/mads/sound.cpp index d0aa770a4d..1652550ba3 100644 --- a/engines/mads/sound.cpp +++ b/engines/mads/sound.cpp @@ -39,6 +39,15 @@ SoundManager::SoundManager(MADSEngine *vm, Audio::Mixer *mixer) { _opl = OPL::Config::create(); _opl->init(11025); + + // Validate sound files + switch (_vm->getGameID()) { + case GType_RexNebular: + Nebular::ASound::validate(); + break; + default: + break; + } } SoundManager::~SoundManager() { diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp index 6cb55aaeee..fd73930475 100644 --- a/engines/mads/sprites.cpp +++ b/engines/mads/sprites.cpp @@ -404,9 +404,9 @@ void SpriteSets::remove(int idx) { delete (*this)[idx]; (*this)[idx] = nullptr; } else { - while (size() > 0 && (*this)[size() - 1] == nullptr) { + do { remove_at(size() - 1); - } + } while (size() > 0 && (*this)[size() - 1] == nullptr); } if (_assetCount > 0) diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 06fba25ba9..146470f6b7 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -54,7 +54,7 @@ Hero::~Hero() { bool Hero::loadAnimSet(uint32 animSetNr) { _animSetNr = animSetNr; - if (animSetNr > sizeof(heroSetTable)) { + if (animSetNr >= ARRAYSIZE(heroSetTable)) { return false; } diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 29c434e9c9..b0f2cd5056 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -730,8 +730,8 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) { debugEngine("Loading wav %s slot %d", streamName.c_str(), slot); - if (slot > kMaxTexts) { - error("Text slot bigger than MAXTEXTS %d", kMaxTexts); + if (slot >= kMaxTexts) { + error("Text slot bigger than MAXTEXTS %d", kMaxTexts - 1); return false; } @@ -1901,29 +1901,29 @@ void PrinceEngine::blackPalette() { void PrinceEngine::setPalette(const byte *palette) { if (palette != nullptr) { - byte *blackPalette = (byte *)malloc(256 * 3); + byte *blackPalette_ = (byte *)malloc(256 * 3); int fadeStep = 0; for (int i = 0; i <= kFadeStep; i++) { for (int j = 0; j < 256; j++) { - blackPalette[3 * j] = palette[3 * j] * fadeStep / 4; - blackPalette[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4; - blackPalette[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4; + blackPalette_[3 * j] = palette[3 * j] * fadeStep / 4; + blackPalette_[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4; + blackPalette_[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4; } fadeStep++; - _graph->setPalette(blackPalette); + _graph->setPalette(blackPalette_); _system->updateScreen(); Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); eventMan->pollEvent(event); if (shouldQuit()) { _graph->setPalette(palette); - free(blackPalette); + free(blackPalette_); return; } pause(); } _graph->setPalette(palette); - free(blackPalette); + free(blackPalette_); } } diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 0e9dd27877..d1a0034940 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -391,10 +391,10 @@ bool Script::loadAllMasks(Common::Array<Mask> &maskList, int offset) { debug("Can't load %s", msStreamName.c_str()); delete msStream; } else { - uint32 dataSize = msStream->size(); + int32 dataSize = msStream->size(); if (dataSize != -1) { tempMask._data = (byte *)malloc(dataSize); - if (msStream->read(tempMask._data, dataSize) != dataSize) { + if (msStream->read(tempMask._data, dataSize) != (uint32)dataSize) { free(tempMask._data); delete msStream; return false; @@ -477,7 +477,7 @@ uint32 Interpreter::step(uint32 opcodePC) { // Get the current opcode _lastOpcode = readScript16(); - if (_lastOpcode > kNumOpcodes) + if (_lastOpcode >= kNumOpcodes) error( "Trying to execute unknown opcode @0x%04X: %02d", _currentInstruction, diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 4f28738508..85ff1c0062 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -563,31 +563,28 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles, // If these files aren't found, it can't be SCI - if (!foundResMap && !foundRes000) { + if (!foundResMap && !foundRes000) return 0; - } ResourceManager resMan; - resMan.addAppropriateSources(fslist); - resMan.init(true); + resMan.addAppropriateSourcesForDetection(fslist); + resMan.initForDetection(); // TODO: Add error handling. #ifndef ENABLE_SCI32 // Is SCI32 compiled in? If not, and this is a SCI32 game, // stop here - if (getSciVersion() >= SCI_VERSION_2) { - return (const ADGameDescription *)&s_fallbackDesc; - } + if (getSciVersionForDetection() >= SCI_VERSION_2) + return 0; #endif ViewType gameViews = resMan.getViewType(); // Have we identified the game views? If not, stop here - // Can't be SCI (or unsupported SCI views). Pinball Creep by sierra also uses resource.map/resource.000 files - // but doesnt share sci format at all, if we dont return 0 here we will detect this game as SCI - if (gameViews == kViewUnknown) { + // Can't be SCI (or unsupported SCI views). Pinball Creep by Sierra also uses resource.map/resource.000 files + // but doesn't share SCI format at all + if (gameViews == kViewUnknown) return 0; - } // Set the platform to Amiga if the game is using Amiga views if (gameViews == kViewAmiga) @@ -597,9 +594,8 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles, Common::String sierraGameId = resMan.findSierraGameId(); // If we don't have a game id, the game is not SCI - if (sierraGameId.empty()) { + if (sierraGameId.empty()) return 0; - } Common::String gameId = convertSierraGameId(sierraGameId, &s_fallbackDesc.flags, resMan); strncpy(s_fallbackGameIdBuf, gameId.c_str(), sizeof(s_fallbackGameIdBuf) - 1); diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 61fb717567..c56eb09482 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -37,6 +37,7 @@ #include "sci/engine/state.h" #include "sci/engine/kernel.h" #include "sci/engine/savegame.h" +#include "sci/graphics/menu.h" #include "sci/sound/audio.h" #include "sci/console.h" @@ -913,6 +914,25 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { // code concerning this via script patch. s->variables[VAR_GLOBAL][0xB3].setOffset(SAVEGAMEID_OFFICIALRANGE_START + savegameId); break; + case GID_JONES: + // HACK: The code that enables certain menu items isn't called when a game is restored from the + // launcher, or the "Restore game" option in the game's main menu - bugs #6537 and #6723. + // These menu entries are disabled when the game is launched, and are enabled when a new game is + // started. The code for enabling these entries is is all in script 1, room1::init, but that code + // path is never followed in these two cases (restoring game from the menu, or restoring a game + // from the ScummVM launcher). Thus, we perform the calls to enable the menus ourselves here. + // These two are needed when restoring from the launcher + // FIXME: The original interpreter saves and restores the menu state, so these attributes + // are automatically reset there. We may want to do the same. + g_sci->_gfxMenu->kernelSetAttribute(257 >> 8, 257 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Sierra -> About Jones + g_sci->_gfxMenu->kernelSetAttribute(258 >> 8, 258 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Sierra -> Help + // The rest are normally enabled from room1::init + g_sci->_gfxMenu->kernelSetAttribute(769 >> 8, 769 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Options -> Delete current player + g_sci->_gfxMenu->kernelSetAttribute(513 >> 8, 513 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Save Game + g_sci->_gfxMenu->kernelSetAttribute(515 >> 8, 515 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Restore Game + g_sci->_gfxMenu->kernelSetAttribute(1025 >> 8, 1025 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Statistics + g_sci->_gfxMenu->kernelSetAttribute(1026 >> 8, 1026 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Goals + break; default: break; } diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index cdcdcc41e5..9decc4cef6 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -844,6 +844,8 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const Common::Strin if (voc) voc->saveLoadWithSerializer(ser); + // TODO: SSCI (at least JonesCD, presumably more) also stores the Menu state + return true; } diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp index 511d2014bd..b1c002413d 100644 --- a/engines/sci/event.cpp +++ b/engines/sci/event.cpp @@ -262,7 +262,7 @@ SciEvent EventManager::getScummVMEvent() { // Scancodify if appropriate if (modifiers & Common::KBD_ALT) input.character = altify(input.character); - else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27) + if (getSciVersion() <= SCI_VERSION_1_MIDDLE && (modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27) input.character += 96; // 0x01 -> 'a' // If no actual key was pressed (e.g. if only a modifier key was pressed), diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp index f3f352e5b8..a88546e68c 100644 --- a/engines/sci/graphics/view.cpp +++ b/engines/sci/graphics/view.cpp @@ -283,6 +283,7 @@ void GfxView::initData(GuiResourceId resourceId) { _isScaleable = false; break; case 0x40: + case 0x4F: // LSL6 Polish, seems to be garbage - bug #6718 case 0: break; // don't do anything, we already have _isScaleable set default: diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 17195c14b8..d155792853 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -55,6 +55,11 @@ SciVersion getSciVersion() { return s_sciVersion; } +SciVersion getSciVersionForDetection() { + assert(!g_sci); + return s_sciVersion; +} + const char *getSciVersionDesc(SciVersion version) { switch (version) { case SCI_VERSION_NONE: @@ -88,9 +93,6 @@ const char *getSciVersionDesc(SciVersion version) { ////////////////////////////////////////////////////////////////////// - -#undef SCI_REQUIRE_RESOURCE_FILES - //#define SCI_VERBOSE_RESMAN 1 static const char *const s_errorDescriptions[] = { @@ -639,7 +641,7 @@ int ResourceManager::addAppropriateSources() { return 1; } -int ResourceManager::addAppropriateSources(const Common::FSList &fslist) { +int ResourceManager::addAppropriateSourcesForDetection(const Common::FSList &fslist) { ResourceSource *map = 0; Common::Array<ResourceSource *> sci21Maps; @@ -858,7 +860,7 @@ void ResourceManager::freeResourceSources() { ResourceManager::ResourceManager() { } -void ResourceManager::init(bool initFromFallbackDetector) { +void ResourceManager::init() { _memoryLocked = 0; _memoryLRU = 0; _LRU.clear(); @@ -890,25 +892,24 @@ void ResourceManager::init(bool initFromFallbackDetector) { debugC(1, kDebugLevelResMan, "resMan: Detected volume version %d: %s", _volVersion, versionDescription(_volVersion)); if ((_mapVersion == kResVersionUnknown) && (_volVersion == kResVersionUnknown)) { - warning("Volume and map version not detected, assuming that this is not a sci game"); + warning("Volume and map version not detected, assuming that this is not a SCI game"); _viewType = kViewUnknown; return; } scanNewSources(); - if (!initFromFallbackDetector) { - if (!addAudioSources()) { - // FIXME: This error message is not always correct. - // OTOH, it is nice to be able to detect missing files/sources - // So we should definitely fix addAudioSources so this error - // only pops up when necessary. Disabling for now. - //error("Somehow I can't seem to find the sound files I need (RESOURCE.AUD/RESOURCE.SFX), aborting"); - } - addScriptChunkSources(); - scanNewSources(); + if (!addAudioSources()) { + // FIXME: This error message is not always correct. + // OTOH, it is nice to be able to detect missing files/sources + // So we should definitely fix addAudioSources so this error + // only pops up when necessary. Disabling for now. + //error("Somehow I can't seem to find the sound files I need (RESOURCE.AUD/RESOURCE.SFX), aborting"); } + addScriptChunkSources(); + scanNewSources(); + detectSciVersion(); debugC(1, kDebugLevelResMan, "resMan: Detected %s", getSciVersionDesc(getSciVersion())); @@ -943,6 +944,22 @@ void ResourceManager::init(bool initFromFallbackDetector) { } } +void ResourceManager::initForDetection() { + assert(!g_sci); + + _memoryLocked = 0; + _memoryLRU = 0; + _LRU.clear(); + _resMap.clear(); + _audioMapSCI1 = NULL; + + _mapVersion = detectMapVersion(); + _volVersion = detectVolVersion(); + + scanNewSources(); + detectSciVersion(); +} + ResourceManager::~ResourceManager() { // freeing resources ResourceMap::iterator itr = _resMap.begin(); @@ -1645,6 +1662,9 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { do { type = fileStream->readByte() & 0x1F; resMap[type].wOffset = fileStream->readUint16LE(); + if (fileStream->eos()) + return SCI_ERROR_RESMAP_NOT_FOUND; + resMap[prevtype].wSize = (resMap[type].wOffset - resMap[prevtype].wOffset) / nEntrySize; prevtype = type; diff --git a/engines/sci/resource.h b/engines/sci/resource.h index e90f52a3ce..62f3c584ac 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -312,10 +312,22 @@ public: /** * Initializes the resource manager. */ - void init(bool initFromFallbackDetector = false); + void init(); + /** + * Similar to the function above, only called from the fallback detector + */ + void initForDetection(); + + /** + * Adds all of the resource files for a game + */ int addAppropriateSources(); - int addAppropriateSources(const Common::FSList &fslist); // TODO: Switch from FSList to Common::Archive? + + /** + * Similar to the function above, only called from the fallback detector + */ + int addAppropriateSourcesForDetection(const Common::FSList &fslist); // TODO: Switch from FSList to Common::Archive? /** * Looks up a resource's data. diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 48bc4819d2..2377386c72 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -429,6 +429,12 @@ extern SciEngine *g_sci; SciVersion getSciVersion(); /** + * Same as above, but this version doesn't assert on unknown SCI versions. + * Only used by the fallback detector + */ +SciVersion getSciVersionForDetection(); + +/** * Convenience function converting an SCI version into a human-readable string. */ const char *getSciVersionDesc(SciVersion version); diff --git a/engines/zvision/fonts/truetype_font.cpp b/engines/zvision/fonts/truetype_font.cpp index ba4d72bde8..45eaeeb2b4 100644 --- a/engines/zvision/fonts/truetype_font.cpp +++ b/engines/zvision/fonts/truetype_font.cpp @@ -95,6 +95,7 @@ Graphics::Surface *TruetypeFont::drawTextToSurface(const Common::String &text, u lines.pop_back(); } if (lines.size() == 0) { + delete surface; return nullptr; } diff --git a/graphics/transform_tools.h b/graphics/transform_tools.h index a51c8ee229..ec739f9ad0 100644 --- a/graphics/transform_tools.h +++ b/graphics/transform_tools.h @@ -28,7 +28,7 @@ namespace Graphics { - static const float kEpsilon = 0.00001; // arbitrarily taken number + static const float kEpsilon = 0.00001f; // arbitrarily taken number struct FloatPoint { float x; @@ -12,6 +12,8 @@ install: $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.6" "$(DESTDIR)$(mandir)/man6/scummvm.6" $(INSTALL) -d "$(DESTDIR)$(datarootdir)/pixmaps/" $(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.xpm" "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm" + $(INSTALL) -d "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/" + $(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/scummvm.svg" $(INSTALL) -d "$(DESTDIR)$(docdir)" $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)" $(INSTALL) -d "$(DESTDIR)$(datadir)" @@ -28,6 +30,8 @@ install-strip: $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.6" "$(DESTDIR)$(mandir)/man6/scummvm.6" $(INSTALL) -d "$(DESTDIR)$(datarootdir)/pixmaps/" $(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.xpm" "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm" + $(INSTALL) -d "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/" + $(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/scummvm.svg" $(INSTALL) -d "$(DESTDIR)$(docdir)" $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)" $(INSTALL) -d "$(DESTDIR)$(datadir)" @@ -41,6 +45,7 @@ uninstall: rm -f "$(DESTDIR)$(bindir)/$(EXECUTABLE)" rm -f "$(DESTDIR)$(mandir)/man6/scummvm.6" rm -f "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm" + rm -f "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/scummvm.svg" rm -rf "$(DESTDIR)$(docdir)" rm -rf "$(DESTDIR)$(datadir)" ifdef DYNAMIC_MODULES |