From 697ed424474ae0ddee2b2f722609583b792a6a63 Mon Sep 17 00:00:00 2001 From: Pawel Kolodziejski Date: Mon, 11 Apr 2011 11:41:07 +0200 Subject: [PATCH] synced with scummvm svn rev 51000 --- Makefile | 4 +- backends/events/default/default-events.cpp | 4 +- backends/midi/alsa.cpp | 24 +- backends/midi/camd.cpp | 13 +- backends/midi/coreaudio.cpp | 13 +- backends/midi/coremidi.cpp | 13 +- backends/midi/dmedia.cpp | 13 +- backends/midi/seq.cpp | 15 +- backends/midi/stmidi.cpp | 14 +- backends/midi/timidity.cpp | 13 +- backends/midi/windows.cpp | 51 +- backends/platform/sdl/events.cpp | 5 + backends/platform/sdl/graphics.cpp | 6 + backends/platform/sdl/main.cpp | 1 + backends/platform/sdl/sdl.cpp | 1 + backends/plugins/win32/win32-provider.cpp | 1 + backends/vkeybd/virtual-keyboard.cpp | 2 - base/commandLine.cpp | 6 +- base/main.cpp | 23 +- common/events.h | 9 +- common/hashmap.h | 3 - common/macresman.cpp | 10 +- common/messages.cpp | 117 +- common/str.cpp | 12 +- common/str.h | 3 + common/textconsole.cpp | 14 +- common/translation.cpp | 129 +- common/translation.h | 33 +- common/unzip.cpp | 49 +- common/unzip.h | 4 - common/util.cpp | 135 +- common/util.h | 8 +- configure | 113 +- engines/advancedDetector.cpp | 2 +- engines/dialogs.cpp | 32 +- engines/engine.cpp | 3 +- graphics/fontman.cpp | 28 +- gui/GuiManager.cpp | 2 +- gui/ListWidget.cpp | 5 - gui/ThemeEngine.cpp | 48 +- gui/ThemeEngine.h | 1 + gui/ThemeParser.cpp | 6 +- gui/about.cpp | 19 +- gui/console.cpp | 8 +- gui/debugger.cpp | 61 +- gui/debugger.h | 116 +- gui/launcher.cpp | 2 +- gui/options.cpp | 143 +- gui/options.h | 12 +- gui/saveload.cpp | 2 +- gui/themes/default.inc | 1574 ++++++++++---------- gui/themes/modern.zip | Bin 57678 -> 57761 bytes gui/themes/modern/modern_gfx.stx | 20 +- gui/themes/modern/modern_layout.stx | 18 +- gui/themes/modern/modern_layout_lowres.stx | 24 +- gui/widget.cpp | 15 +- po/POTFILES | 11 +- po/module.mk | 7 +- ports.mk | 1 + sound/decoders/vorbis.cpp | 2 +- sound/fmopl.cpp | 5 +- sound/mididrv.cpp | 438 +++--- sound/mididrv.h | 151 +- sound/midiparser.cpp | 4 +- sound/musicplugin.cpp | 20 +- sound/musicplugin.h | 32 +- sound/null.cpp | 58 +- sound/null.h | 56 + sound/rate_arm_asm.s | 30 - sound/softsynth/adlib.cpp | 16 +- sound/softsynth/fluidsynth.cpp | 13 +- sound/softsynth/mt32.cpp | 25 +- sound/softsynth/opl/mame.cpp | 4 +- sound/softsynth/pcspk.cpp | 57 + sound/softsynth/ym2612.cpp | 16 +- 75 files changed, 2104 insertions(+), 1844 deletions(-) create mode 100644 sound/null.h diff --git a/Makefile b/Makefile index 9ada8bca3e1..dc6c7f9a58d 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ ifeq "$(HAVE_GCC)" "1" # Turn off some annoying and not-so-useful warnings CXXFLAGS+= -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder # Enable even more warnings... - CXXFLAGS+= -Wpointer-arith -Wcast-qual -Wcast-align + CXXFLAGS+= -Wpointer-arith -Wcast-qual CXXFLAGS+= -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings # Currently we disable this gcc flag, since it will also warn in cases, @@ -34,7 +34,7 @@ ifeq "$(HAVE_GCC)" "1" # being helpful. #CXXFLAGS+= -Wmissing-format-attribute - # Disable RTTI, and enable checking of pointers returned by "new" + # Disable exceptions, and enable checking of pointers returned by "new" CXXFLAGS+= -fno-exceptions -fcheck-new endif diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp index bea811e69fa..c16597eb890 100644 --- a/backends/events/default/default-events.cpp +++ b/backends/events/default/default-events.cpp @@ -95,13 +95,11 @@ bool DefaultEventManager::pollEvent(Common::Event &event) { case Common::EVENT_KEYDOWN: _modifierState = event.kbd.flags; // init continuous event stream - // not done on PalmOS because keyboard is emulated and keyup is not generated -#if !defined(PALMOS_MODE) _currentKeyDown.ascii = event.kbd.ascii; _currentKeyDown.keycode = event.kbd.keycode; _currentKeyDown.flags = event.kbd.flags; _keyRepeatTime = time + kKeyRepeatInitialDelay; -#endif + // Global Main Menu if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_F5) { if (g_engine && !g_engine->isPaused()) { diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index 5cb586cf229..e78e7800f93 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -150,10 +150,13 @@ int MidiDriver_ALSA::open() { } void MidiDriver_ALSA::close() { - _isOpen = false; - MidiDriver_MPU401::close(); - if (seq_handle) - snd_seq_close(seq_handle); + if (_isOpen) { + _isOpen = false; + MidiDriver_MPU401::close(); + if (seq_handle) + snd_seq_close(seq_handle); + } else + warning("MidiDriver_ALSA: Closing the driver before opening it"); } void MidiDriver_ALSA::send(uint32 b) { @@ -269,7 +272,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; #define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) @@ -315,21 +318,12 @@ MusicDevices AlsaMusicPlugin::getDevices() const { return devices; } -Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_ALSA(); return Common::kNoError; } -MidiDriver *MidiDriver_ALSA_create() { - MidiDriver *mididriver; - - AlsaMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(ALSA) //REGISTER_PLUGIN_DYNAMIC(ALSA, PLUGIN_TYPE_MUSIC, AlsaMusicPlugin); //#else diff --git a/backends/midi/camd.cpp b/backends/midi/camd.cpp index 03c887141a0..d00b9e7e091 100644 --- a/backends/midi/camd.cpp +++ b/backends/midi/camd.cpp @@ -177,7 +177,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices CamdMusicPlugin::getDevices() const { @@ -188,21 +188,12 @@ MusicDevices CamdMusicPlugin::getDevices() const { return devices; } -Common::Error CamdMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error CamdMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_CAMD(); return Common::kNoError; } -MidiDriver *MidiDriver_CAMD_create() { - MidiDriver *mididriver; - - CamdMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(CAMD) //REGISTER_PLUGIN_DYNAMIC(CAMD, PLUGIN_TYPE_MUSIC, CamdMusicPlugin); //#else diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp index 8f795278eed..f2ae91aabff 100644 --- a/backends/midi/coreaudio.cpp +++ b/backends/midi/coreaudio.cpp @@ -218,7 +218,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices CoreAudioMusicPlugin::getDevices() const { @@ -229,21 +229,12 @@ MusicDevices CoreAudioMusicPlugin::getDevices() const { return devices; } -Common::Error CoreAudioMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error CoreAudioMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_CORE(); return Common::kNoError; } -MidiDriver *MidiDriver_CORE_create() { - MidiDriver *mididriver; - - CoreAudioMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(COREAUDIO) //REGISTER_PLUGIN_DYNAMIC(COREAUDIO, PLUGIN_TYPE_MUSIC, CoreAudioMusicPlugin); //#else diff --git a/backends/midi/coremidi.cpp b/backends/midi/coremidi.cpp index e37058b0367..217f3799836 100644 --- a/backends/midi/coremidi.cpp +++ b/backends/midi/coremidi.cpp @@ -190,7 +190,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices CoreMIDIMusicPlugin::getDevices() const { @@ -201,21 +201,12 @@ MusicDevices CoreMIDIMusicPlugin::getDevices() const { return devices; } -Common::Error CoreMIDIMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error CoreMIDIMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_CoreMIDI(); return Common::kNoError; } -MidiDriver *MidiDriver_CoreMIDI_create() { - MidiDriver *mididriver; - - CoreMIDIMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(COREMIDI) //REGISTER_PLUGIN_DYNAMIC(COREMIDI, PLUGIN_TYPE_MUSIC, CoreMIDIMusicPlugin); //#else diff --git a/backends/midi/dmedia.cpp b/backends/midi/dmedia.cpp index ee1bc9a4909..1087de630f9 100644 --- a/backends/midi/dmedia.cpp +++ b/backends/midi/dmedia.cpp @@ -199,7 +199,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices DMediaMusicPlugin::getDevices() const { @@ -224,21 +224,12 @@ MusicDevices DMediaMusicPlugin::getDevices() const { return devices; } -Common::Error DMediaMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error DMediaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_DMEDIA(); return Common::kNoError; } -MidiDriver *MidiDriver_DMEDIA_create() { - MidiDriver *mididriver; - - DMediaMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(DMEDIA) //REGISTER_PLUGIN_DYNAMIC(DMEDIA, PLUGIN_TYPE_MUSIC, DMediaMusicPlugin); //#else diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp index f077028dcde..a85b47d1057 100644 --- a/backends/midi/seq.cpp +++ b/backends/midi/seq.cpp @@ -28,7 +28,7 @@ * both the QuickTime support and (vkeybd http://www.alsa-project.org/~iwai/alsa.html) */ -#if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) && !defined(__MINT__) +#if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) && !defined(__MINT__) && !defined(__ANDROID__) #include "common/util.h" #include "sound/musicplugin.h" @@ -184,7 +184,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices SeqMusicPlugin::getDevices() const { @@ -195,21 +195,12 @@ MusicDevices SeqMusicPlugin::getDevices() const { return devices; } -Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_SEQ(); return Common::kNoError; } -MidiDriver *MidiDriver_SEQ_create() { - MidiDriver *mididriver; - - SeqMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(SEQ) //REGISTER_PLUGIN_DYNAMIC(SEQ, PLUGIN_TYPE_MUSIC, SeqMusicPlugin); //#else diff --git a/backends/midi/stmidi.cpp b/backends/midi/stmidi.cpp index 8432d35d510..ca47d5e77ef 100644 --- a/backends/midi/stmidi.cpp +++ b/backends/midi/stmidi.cpp @@ -127,8 +127,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) - const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices StMidiMusicPlugin::getDevices() const { @@ -139,21 +138,12 @@ MusicDevices StMidiMusicPlugin::getDevices() const { return devices; } -Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_STMIDI(); return Common::kNoError; } -MidiDriver *MidiDriver_STMIDI_create() { - MidiDriver *mididriver; - - StMidiMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(STMIDI) //REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); //#else diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp index fa6b7839146..fccbd6f2b5e 100644 --- a/backends/midi/timidity.cpp +++ b/backends/midi/timidity.cpp @@ -530,7 +530,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices TimidityMusicPlugin::getDevices() const { @@ -539,21 +539,12 @@ MusicDevices TimidityMusicPlugin::getDevices() const { return devices; } -Common::Error TimidityMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error TimidityMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_TIMIDITY(); return Common::kNoError; } -MidiDriver *MidiDriver_TIMIDITY_create() { - MidiDriver *mididriver; - - TimidityMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(TIMIDITY) //REGISTER_PLUGIN_DYNAMIC(TIMIDITY, PLUGIN_TYPE_MUSIC, TimidityMusicPlugin); //#else diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp index 58d0e299ca4..81aa328b63a 100644 --- a/backends/midi/windows.cpp +++ b/backends/midi/windows.cpp @@ -24,12 +24,15 @@ #if defined(WIN32) && !defined(_WIN32_WCE) +#define WIN32_LEAN_AND_MEAN #include // winnt.h defines ARRAYSIZE, but we want our own one... #undef ARRAYSIZE #include "sound/musicplugin.h" #include "sound/mpu401.h" +#include "common/config-manager.h" +#include "common/translation.h" #include @@ -46,11 +49,12 @@ private: HANDLE _streamEvent; HMIDIOUT _mo; bool _isOpen; + int _device; void check_error(MMRESULT result); public: - MidiDriver_WIN() : _isOpen(false) { } + MidiDriver_WIN(int deviceIndex) : _isOpen(false), _device(deviceIndex) { } int open(); void close(); void send(uint32 b); @@ -62,7 +66,7 @@ int MidiDriver_WIN::open() { return MERR_ALREADY_OPEN; _streamEvent = CreateEvent(NULL, true, true, NULL); - MMRESULT res = midiOutOpen((HMIDIOUT *)&_mo, MIDI_MAPPER, (DWORD_PTR)_streamEvent, 0, CALLBACK_EVENT); + MMRESULT res = midiOutOpen((HMIDIOUT *)&_mo, _device, (DWORD_PTR)_streamEvent, 0, CALLBACK_EVENT); if (res != MMSYSERR_NOERROR) { check_error(res); CloseHandle(_streamEvent); @@ -150,7 +154,7 @@ void MidiDriver_WIN::check_error(MMRESULT result) { class WindowsMusicPlugin : public MusicPluginObject { public: const char *getName() const { - return "Windows MIDI"; + return _s("Windows MIDI"); } const char *getId() const { @@ -158,32 +162,43 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices WindowsMusicPlugin::getDevices() const { MusicDevices devices; - // TODO: Return a different music type depending on the configuration - // TODO: List the available devices - devices.push_back(MusicDevice(this, "", MT_GM)); + int numDevs = midiOutGetNumDevs(); + MIDIOUTCAPS tmp; + + for (int i = 0; i < numDevs; i++) { + if (midiOutGetDevCaps(i, &tmp, sizeof(MIDIOUTCAPS)) != MMSYSERR_NOERROR) + break; + // There is no way to detect the "MusicType" so I just set it to MT_GM + // The user will have to manually select his MT32 type device and his GM type device. + devices.push_back(MusicDevice(this, tmp.szPname, MT_GM)); + } return devices; } -Common::Error WindowsMusicPlugin::createInstance(MidiDriver **mididriver) const { - *mididriver = new MidiDriver_WIN(); +Common::Error WindowsMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle dev) const { + int devIndex = 0; + bool found = false; + if (dev) { + MusicDevices i = getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (d->getCompleteId().equals(MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId))) { + found = true; + break; + } + devIndex++; + } + } + + *mididriver = new MidiDriver_WIN(found ? devIndex : 0); return Common::kNoError; } -MidiDriver *MidiDriver_WIN_create() { - MidiDriver *mididriver; - - WindowsMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(WINDOWS) //REGISTER_PLUGIN_DYNAMIC(WINDOWS, PLUGIN_TYPE_MUSIC, WindowsMusicPlugin); //#else diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp index c7ef55aad09..ab1146a97ab 100644 --- a/backends/platform/sdl/events.cpp +++ b/backends/platform/sdl/events.cpp @@ -256,6 +256,7 @@ bool OSystem_SDL::handleKeyDown(SDL_Event &ev, Common::Event &event) { else displayMessageOnOSD("Windowed mode"); #endif + return false; }*/ @@ -340,6 +341,10 @@ bool OSystem_SDL::handleKeyUp(SDL_Event &ev, Common::Event &event) { // Set the scroll lock sticky flag if (_scrollLock) event.kbd.flags |= Common::KBD_SCRL; +/* Residual doesn't support this + if (isScalerHotkey(event)) + // Swallow these key up events + return false;*/ return true; } diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp index cdbf23c2a2d..01e7ffbb6e6 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/platform/sdl/graphics.cpp @@ -25,6 +25,7 @@ #include "backends/platform/sdl/sdl.h" #include "common/mutex.h" +#include "common/translation.h" #include "common/util.h" #ifdef USE_RGB_COLOR #include "common/list.h" @@ -410,6 +411,10 @@ void OSystem_SDL::warpMouse(int x, int y) { /* Residual doesn't support this int y1 = y; + // Don't change mouse position, when mouse is outside of our window (in case of windowed mode) + if (!(SDL_GetAppState( ) & SDL_APPMOUSEFOCUS)) + return; + if (_videoMode.aspectRatioCorrection && !_overlayVisible) y1 = real2Aspect(y); @@ -499,6 +504,7 @@ void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, _mouseData = (byte *)malloc(w * h); memcpy(_mouseData, buf, w * h); #endif + blitCursor();*/ } diff --git a/backends/platform/sdl/main.cpp b/backends/platform/sdl/main.cpp index 85ca9ca6637..c96baea3e18 100644 --- a/backends/platform/sdl/main.cpp +++ b/backends/platform/sdl/main.cpp @@ -28,6 +28,7 @@ // otherwise we will get errors about the windows headers redefining // "ARRAYSIZE" for example. #if defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32_LEAN_AND_MEAN #include // winnt.h defines ARRAYSIZE, but we want our own one... #undef ARRAYSIZE diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 829660238a6..60ce56b0ac2 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -24,6 +24,7 @@ */ #if defined(WIN32) +#define WIN32_LEAN_AND_MEAN #include // winnt.h defines ARRAYSIZE, but we want our own one... - this is needed before including util.h #undef ARRAYSIZE diff --git a/backends/plugins/win32/win32-provider.cpp b/backends/plugins/win32/win32-provider.cpp index 87fb791b774..24077b2dcac 100644 --- a/backends/plugins/win32/win32-provider.cpp +++ b/backends/plugins/win32/win32-provider.cpp @@ -30,6 +30,7 @@ #include "common/debug.h" #include "common/fs.h" +#define WIN32_LEAN_AND_MEAN #include diff --git a/backends/vkeybd/virtual-keyboard.cpp b/backends/vkeybd/virtual-keyboard.cpp index 8aec8736b63..fcf31b4fbaf 100644 --- a/backends/vkeybd/virtual-keyboard.cpp +++ b/backends/vkeybd/virtual-keyboard.cpp @@ -90,7 +90,6 @@ bool VirtualKeyboard::openPack(const String &packName, const FSNode &node) { return true; } -#ifdef USE_ZLIB if (node.getChild(packName + ".zip").exists()) { // compressed keyboard pack _fileArchive = makeZipArchive(node.getChild(packName + ".zip")); @@ -109,7 +108,6 @@ bool VirtualKeyboard::openPack(const String &packName, const FSNode &node) { return true; } -#endif return false; } diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 77ab03fd822..bba2eed897a 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -32,8 +32,6 @@ #include "common/system.h" #include "common/fs.h" -#include "sound/mididrv.h" - #include "gui/ThemeEngine.h" #define DETECTOR_TESTING_HACK @@ -51,7 +49,7 @@ static const char USAGE_STRING[] = ; // DONT FIXME: DO NOT ORDER ALPHABETICALLY, THIS IS ORDERED BY IMPORTANCE/CATEGORY! :) -#if defined(PALMOS_MODE) || defined(__SYMBIAN32__) || defined(__GP32__) +#if defined(__SYMBIAN32__) || defined(__GP32__) || defined(ANDROID) static const char HELP_STRING[] = "NoUsageString"; // save more data segment space #else static const char HELP_STRING[] = @@ -284,8 +282,6 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha END_OPTION DO_OPTION('e', "music-driver") - if (MidiDriver::findMusicDriver(option) == 0) - usage("Unrecognized music driver '%s'", option); END_OPTION DO_LONG_OPTION_INT("output-rate") diff --git a/base/main.cpp b/base/main.cpp index 278c2b93b10..179ecf9a967 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -54,6 +54,7 @@ #include "gui/error.h" #include "sound/audiocd.h" +#include "sound/mididrv.h" #include "backends/keymapper/keymapper.h" @@ -102,20 +103,20 @@ static const EnginePlugin *detectPlugin() { ConfMan.set("gameid", gameid); // Query the plugins and find one that will handle the specified gameid - printf(_t("User picked target '%s' (gameid '%s')...\n"), ConfMan.getActiveDomainName().c_str(), gameid.c_str()); - printf("%s", _t(" Looking for a plugin supporting this gameid... ")); + printf("User picked target '%s' (gameid '%s')...\n", ConfMan.getActiveDomainName().c_str(), gameid.c_str()); + printf("%s", " Looking for a plugin supporting this gameid... "); GameDescriptor game = EngineMan.findGame(gameid, &plugin); if (plugin == 0) { - printf("%s", _t("failed\n")); - warning(_t("%s is an invalid gameid. Use the --list-games option to list supported gameid"), gameid.c_str()); + printf("failed\n"); + warning("%s is an invalid gameid. Use the --list-games option to list supported gameid", gameid.c_str()); return 0; } else { printf("%s\n", plugin->getName()); } // FIXME: Do we really need this one? - printf(_t(" Starting '%s'\n"), game.description().c_str()); + printf(" Starting '%s'\n", game.description().c_str()); return plugin; } @@ -144,7 +145,7 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const //GUI::displayErrorDialog("ScummVM could not find any game in the specified directory!"); const char *errMsg = _(Common::errorToString(err)); - warning(_t("%s failed to instantiate engine: %s (target '%s', path '%s')"), + warning("%s failed to instantiate engine: %s (target '%s', path '%s')", plugin->getName(), errMsg, ConfMan.getActiveDomainName().c_str(), @@ -327,6 +328,16 @@ extern "C" int residual_main(int argc, const char * const argv[]) { // Load the plugins. PluginManager::instance().loadPlugins(); + // If we received an invalid music parameter via command line we check this here. + // We can't check this before loading the music plugins. + // On the other hand we cannot load the plugins before we know the file paths (in case of external plugins). + if (settings.contains("music-driver")) { + if (MidiDriver::getMusicType(MidiDriver::getDeviceHandle(settings["music-driver"])) == MT_INVALID) { + warning("Unrecognized music driver '%s'. Switching to default device.", settings["music-driver"].c_str()); + settings["music-driver"] = "auto"; + } + } + // Process the remaining command line settings. Must be done after the // config file and the plugins have been loaded. Common::Error res; diff --git a/common/events.h b/common/events.h index 414e1b76cf2..ec673fb895f 100644 --- a/common/events.h +++ b/common/events.h @@ -201,13 +201,14 @@ public: * Notifies the observer of an incoming event. * * An observer is supposed to eat the event, with returning true, when - * it might want prevent other observers from preventing to receive - * the event. An usage example here is the keymapper: + * it wants to prevent other observers from receiving the event. + * An usage example here is the keymapper: * If it processes an Event, it should 'eat' it and create a new * event, which the EventDispatcher will then catch. * - * @param event the event, which is incoming. - * @return true if this observer uses this event, false otherwise. + * @param event the event, which is incoming. + * @return true if the event should not be passed to other observers, + * false otherwise. */ virtual bool notifyEvent(const Event &event) = 0; }; diff --git a/common/hashmap.h b/common/hashmap.h index 5fa3e0461d6..46946e37d7c 100644 --- a/common/hashmap.h +++ b/common/hashmap.h @@ -68,9 +68,6 @@ template class IteratorImpl; template, class EqualFunc = EqualTo > class HashMap { private: -#if defined (PALMOS_MODE) -public: -#endif typedef HashMap HM_t; diff --git a/common/macresman.cpp b/common/macresman.cpp index a882dd2a1ba..22f05ee2eb4 100644 --- a/common/macresman.cpp +++ b/common/macresman.cpp @@ -525,12 +525,10 @@ void MacResManager::convertCrsrCursor(byte *data, int datasize, byte **cursor, i int i, b; byte imageByte; byte *iconData; - int numBytes; int pixelsPerByte, bpp; int ctSize; byte bitmask; int iconRowBytes, iconBounds[4]; - int ignored; int iconDataSize; dis.readUint16BE(); // type @@ -616,21 +614,19 @@ void MacResManager::convertCrsrCursor(byte *data, int datasize, byte **cursor, i dis.readUint16BE(); // colorID[c] palette[0][c * 4 + 0] = dis.readByte(); - ignored = dis.readByte(); + dis.readByte(); palette[0][c * 4 + 1] = dis.readByte(); - ignored = dis.readByte(); + dis.readByte(); palette[0][c * 4 + 2] = dis.readByte(); - ignored = dis.readByte(); + dis.readByte(); palette[0][c * 4 + 3] = 0; } *palSize = ctSize; - numBytes = (iconBounds[2] - iconBounds[0]) * (iconBounds[3] - iconBounds[1]); - pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes; bpp = 8 / pixelsPerByte; diff --git a/common/messages.cpp b/common/messages.cpp index 9003f086b9f..bd53f177375 100644 --- a/common/messages.cpp +++ b/common/messages.cpp @@ -20,101 +20,82 @@ static struct { { NULL, NULL, NULL } }; -/* code */ +// code -static struct _po2c_msg * _po2c_lang=NULL; -static int _po2c_lang_size=0; -static const char * _po2c_charset=NULL; +static const PoMessageEntry *_currentTranslation = NULL; +static int _currentTranslationMessageEntryCount = 0; +static const char *_currentTranslationCharset = NULL; -void po2c_setlang(const char * lang) -{ - int n; +void po2c_setlang(const char *lang) { + _currentTranslation = NULL; + _currentTranslationMessageEntryCount = 0; + _currentTranslationCharset = NULL; - _po2c_lang=NULL; - _po2c_lang_size=0; - _po2c_charset=NULL; - - /* if lang is NULL or "", deactivate it */ - if(lang == NULL || *lang == '\0') + // if lang is NULL or "", deactivate it + if (lang == NULL || *lang == '\0') return; - /* searches for a valid language array */ - for(n=0;_po2c_lang == NULL && _po2c_langs[n].lang != NULL;n++) - { - if(strcmp(lang, _po2c_langs[n].lang) == 0) { - _po2c_lang=_po2c_langs[n].msgs; - _po2c_charset=_po2c_langs[n].charset; + // searches for a valid language array + for (int i = 0; _currentTranslation == NULL && _translations[i].lang != NULL; ++i) { + if (strcmp(lang, _translations[i].lang) == 0) { + _currentTranslation = _translations[i].msgs; + _currentTranslationCharset = _translations[i].charset; } } - /* try partial searches */ - for(n=0;_po2c_lang == NULL && _po2c_langs[n].lang != NULL;n++) - { - if(strncmp(lang, _po2c_langs[n].lang, 2) == 0) { - _po2c_lang=_po2c_langs[n].msgs; - _po2c_charset=_po2c_langs[n].charset; + // try partial searches + for (int i = 0; _currentTranslation == NULL && _translations[i].lang != NULL; ++i) { + if (strncmp(lang, _translations[i].lang, 2) == 0) { + _currentTranslation = _translations[i].msgs; + _currentTranslationCharset = _translations[i].charset; } } - /* if found, count entries */ - if(_po2c_lang != NULL) - { - struct _po2c_msg * m; - - for(m=_po2c_lang;m->msgid != -1;m++) - _po2c_lang_size++; + // if found, count entries + if (_currentTranslation != NULL) { + for (const PoMessageEntry *m = _currentTranslation; m->msgid != -1; ++m) + ++_currentTranslationMessageEntryCount; } } -const char * po2c_gettext(const char * msgid) -{ - struct _po2c_msg * m; - int b, t, n, c; +const char *po2c_gettext(const char *msgid) { + // if no language is set or msgid is empty, return msgid as is + if (_currentTranslation == NULL || *msgid == '\0') + return msgid; - /* if no language is set or msgid is empty, return msgid as is */ - if(_po2c_lang == NULL || *msgid == '\0') - return(msgid); + // binary-search for the msgid + int leftIndex = 0; + int rightIndex = _currentTranslationMessageEntryCount - 1; - /* binary-search for the msgid */ - b=0; t=_po2c_lang_size - 1; + while (rightIndex >= leftIndex) { + const int midIndex = (leftIndex + rightIndex) / 2; + const PoMessageEntry * const m = &_currentTranslation[midIndex]; - while(t >= b) - { - n=(b + t) / 2; - m=&_po2c_lang[n]; + const int compareResult = strcmp(msgid, _messageIds[m->msgid]); - c=strcmp(msgid, _po2c_msgids[m->msgid]); - - if(c == 0) - return(m->msgstr); + if (compareResult == 0) + return m->msgstr; + else if (compareResult < 0) + rightIndex = midIndex - 1; else - if(c < 0) - t=n - 1; - else - b=n + 1; + leftIndex = midIndex + 1; } - return(msgid); + return msgid; } -const char * po2c_getcharset(void) -{ - if (_po2c_charset) - return _po2c_charset; +const char *po2c_getcharset(void) { + if (_currentTranslationCharset) + return _currentTranslationCharset; else return "ASCII"; } -int po2c_getnumlangs(void) -{ - int n = 0; - while (_po2c_langs[n].lang) - n++; - - return n; +int po2c_getnumlangs(void) { + return ARRAYSIZE(_translations) - 1; } -const char * po2c_getlang(int num) -{ - return _po2c_langs[num].lang; +const char *po2c_getlang(const int num) { + assert(num < ARRAYSIZE(_translations)); + return _translations[num].lang; } diff --git a/common/str.cpp b/common/str.cpp index ed38a0d8ada..6681d38b329 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -105,8 +105,6 @@ String::String(char c) _storage[0] = c; _storage[1] = 0; - // TODO/FIXME: There is no reason for the following check -- we *do* - // allow strings to contain 0 bytes! _size = (c == 0) ? 0 : 1; } @@ -151,7 +149,11 @@ void String::ensureCapacity(uint32 new_size, bool keep_old) { // We need to allocate storage on the heap! // Compute a suitable new capacity limit - newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1)); + // If the current capacity is sufficient we use the same capacity + if (new_size < curCapacity) + newCapacity = curCapacity; + else + newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1)); // Allocate new storage newStorage = new char[newCapacity]; @@ -252,9 +254,11 @@ String &String::operator=(const String &str) { String &String::operator=(char c) { decRefCount(_extern._refCount); _str = _storage; - _size = 1; + _str[0] = c; _str[1] = 0; + + _size = (c == 0) ? 0 : 1; return *this; } diff --git a/common/str.h b/common/str.h index bcd3dd35ff2..e06455fc717 100644 --- a/common/str.h +++ b/common/str.h @@ -39,6 +39,9 @@ namespace Common { * Instead, small strings are stored 'inside' the string object (i.e. on * the stack, for stack allocated objects), and only for strings exceeding * a certain length do we allocate a buffer on the heap. + * + * The presence of \0 characters in the string will cause undefined + * behaviour in some operations. */ class String { protected: diff --git a/common/textconsole.cpp b/common/textconsole.cpp index 6882c21eb1a..eb7714887ad 100644 --- a/common/textconsole.cpp +++ b/common/textconsole.cpp @@ -47,6 +47,10 @@ extern bool isSmartphone(); #include #endif +#ifdef __PSP__ + #include "backends/platform/psp/trace.h" +#endif + namespace Common { static OutputFormatter s_errorOutputFormatter = 0; @@ -151,14 +155,14 @@ void NORETURN_PRE error(const char *s, ...) { __android_log_assert("Fatal error", "ScummVM", "%s", buf_output); #endif -#ifdef PALMOS_MODE - extern void PalmFatalError(const char *err); - PalmFatalError(buf_output); -#endif - #ifdef __SYMBIAN32__ Symbian::FatalError(buf_output); #endif + +#ifdef __PSP__ + PspDebugTrace(false, "%s", buf_output); // write to file +#endif + // Finally exit. quit() will terminate the program if g_system is present if (g_system) g_system->quit(); diff --git a/common/translation.cpp b/common/translation.cpp index 07cde838a91..8a193a67aef 100644 --- a/common/translation.cpp +++ b/common/translation.cpp @@ -22,16 +22,21 @@ * $Id$ */ +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +// winnt.h defines ARRAYSIZE, but we want our own one... - this is needed before including util.h +#undef ARRAYSIZE +#endif + #include "translation.h" DECLARE_SINGLETON(Common::TranslationManager) #ifdef USE_DETECTLANG +#ifndef WIN32 #include -#endif - -#ifdef USE_TERMCONV -#include +#endif // !WIN32 #endif #ifdef USE_TRANSLATION @@ -45,9 +50,37 @@ namespace Common { // Translation enabled - TranslationManager::TranslationManager() { #ifdef USE_DETECTLANG +#ifdef WIN32 + // We can not use "setlocale" (at least not for MSVC builds), since it + // will return locales like: "English_USA.1252", thus we need a special + // way to determine the locale string for Win32. + char langName[9]; + char ctryName[9]; + + const LCID languageIdentifier = GetThreadLocale(); + + // GetLocalInfo is only supported starting from Windows 2000, according to this: + // http://msdn.microsoft.com/en-us/library/dd318101%28VS.85%29.aspx + // On the other hand the locale constants used, seem to exist on Windows 98 too, + // check this for that: http://msdn.microsoft.com/en-us/library/dd464799%28v=VS.85%29.aspx + // + // I am not exactly sure what is the truth now, it might be very well that this breaks + // support for systems older than Windows 2000.... + // + // TODO: Check whether this (or ScummVM at all ;-) works on a system with Windows 98 for + // example and if it does not and we still want Windows 9x support, we should definitly + // think of another solution. + if (GetLocaleInfo(languageIdentifier, LOCALE_SISO639LANGNAME, langName, sizeof(langName)) != 0 && + GetLocaleInfo(languageIdentifier, LOCALE_SISO3166CTRYNAME, ctryName, sizeof(ctryName)) != 0) { + _syslang = langName; + _syslang += "_"; + _syslang += ctryName; + } else { + _syslang = "C"; + } +#else // WIN32 // Activating current locale settings const char *locale = setlocale(LC_ALL, ""); @@ -74,6 +107,7 @@ TranslationManager::TranslationManager() { _syslang = String(locale, length); } +#endif // WIN32 #else // USE_DETECTLANG _syslang = "C"; #endif // USE_DETECTLANG @@ -88,11 +122,6 @@ TranslationManager::TranslationManager() { } TranslationManager::~TranslationManager() { -#ifdef USE_TERMCONV - iconv_close(_conversion); - if (_convmsg) - delete[] _convmsg; -#endif // USE_TERMCONV } void TranslationManager::setLanguage(const char *lang) { @@ -100,88 +129,20 @@ void TranslationManager::setLanguage(const char *lang) { po2c_setlang(_syslang.c_str()); else po2c_setlang(lang); - -#ifdef USE_TERMCONV - // Get the locale character set (for terminal output) - const char *charset_term = nl_langinfo(CODESET); - - // Get the messages character set - const char *charset_po = po2c_getcharset(); - - // Delete previous conversion - if (_conversion) - iconv_close(_conversion); - - // Initialize the conversion - _conversion = iconv_open(charset_term, charset_po); -#endif // USE_TERMCONV } const char *TranslationManager::getTranslation(const char *message) { return po2c_gettext(message); } +const char *TranslationManager::getCurrentCharset() { + return po2c_getcharset(); +} + String TranslationManager::getTranslation(const String &message) { return po2c_gettext(message.c_str()); } -#ifdef USE_TERMCONV -bool TranslationManager::convert(const char *message) { - // Preparing conversion origin - size_t len = strlen(message) + 1; -#ifdef ICONV_USES_CONST - const char **pmsg = &message; -#else - char *msgcpy = new char[len]; - strcpy(msgcpy, message); - char *msg = msgcpy; - char **pmsg = &msg; -#endif - - // Preparing conversion destination - size_t len2 = _sizeconv; - char *conv = _convmsg; - - // Clean previous conversions - iconv(_conversion, NULL, NULL, &conv, &len2); - - // Do the real conversion - size_t result = iconv(_conversion, pmsg, &len, &conv, &len2); - -#ifndef ICONV_USES_CONST - delete[] msgcpy; -#endif - - return result != ((size_t)-1); -} -#endif // USE_TERMCONV - -const char *TranslationManager::convertTerm(const char *message) { -#ifdef USE_TERMCONV - size_t len = strlen(message) + 1; - if (!_convmsg) { - _sizeconv = len * 2; - _convmsg = new char[_sizeconv]; - } - - if (!convert(message)) { - // Resizing the buffer - delete[] _convmsg; - _sizeconv = len * 2; - _convmsg = new char[_sizeconv]; - - if (!convert(message)) { - printf("Error while converting character sets\n"); - return "Error while converting character sets"; - } - } - - return _convmsg; -#else // USE_TERMCONV - return message; -#endif // USE_TERMCONV -} - const TLangArray TranslationManager::getSupportedLanguages() const { TLangArray languages; @@ -252,10 +213,6 @@ String TranslationManager::getTranslation(const String &message) { return message; } -const char *TranslationManager::convertTerm(const char *message) { - return message; -} - const TLangArray TranslationManager::getSupportedLanguages() const { return TLangArray(); } diff --git a/common/translation.h b/common/translation.h index 6e1666e7ff3..896e1bf5066 100644 --- a/common/translation.h +++ b/common/translation.h @@ -28,10 +28,6 @@ #include "common/singleton.h" #include "common/str-array.h" -#ifdef USE_TERMCONV -#include -#endif - namespace Common { enum TranslationIDs { @@ -60,17 +56,6 @@ typedef Array TLangArray; * Message translation manager. */ class TranslationManager : public Singleton { -private: - Common::String _syslang; - -#ifdef USE_TERMCONV - iconv_t _conversion; - char *_convmsg; - int _sizeconv; - - bool convert(const char *message); -#endif // USE_TERMCONV - public: /** * The constructor detects the system language and sets default @@ -129,30 +114,30 @@ public: */ String getTranslation(const String &message); - /** - * Converts the message into the terminal character set (which may be - * different than the GUI's "native" one). - */ - const char *convertTerm(const char *message); - /** * Returns a list of supported languages. * * @return The list of supported languages. */ const TLangArray getSupportedLanguages() const; + + /** + * Returns charset specified by selected translation language + */ + const char *getCurrentCharset(); + +private: + Common::String _syslang; }; -} // End of namespace Common +} // End of namespace Common #define TransMan Common::TranslationManager::instance() #ifdef USE_TRANSLATION #define _(str) TransMan.getTranslation(str) -#define _t(str) TransMan.convertTerm(_(str)) #else #define _(str) str -#define _t(str) str #endif #define _s(str) str diff --git a/common/unzip.cpp b/common/unzip.cpp index 278fe5736d4..1628ef0cab2 100644 --- a/common/unzip.cpp +++ b/common/unzip.cpp @@ -79,6 +79,30 @@ #include #endif +#else // !USE_ZLIB + +// Even when zlib is not linked in, we can still open ZIP archives and read +// uncompressed files from them. Attempted decompression of compressed files +// will result in an error. +// +// Define the constants and types used by zlib. +#define Z_ERRNO -1 +#define Z_OK 0 +#define Z_DEFLATED 8 +typedef void *voidp; +typedef unsigned int uInt; +typedef unsigned long uLong; +typedef long z_off_t; +typedef unsigned char Byte; +typedef Byte Bytef; +typedef struct { + Bytef *next_in, *next_out; + uInt avail_in, avail_out; + uLong total_out; +} z_stream; + +#endif // !USE_ZLIB + #include "common/fs.h" #include "common/unzip.h" #include "common/file.h" @@ -1044,6 +1068,7 @@ int unzOpenCurrentFile (unzFile file) { pfile_in_zip_read_info->stream.total_out = 0; if (!Store) { +#ifdef USE_ZLIB pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; pfile_in_zip_read_info->stream.zfree = (free_func)0; pfile_in_zip_read_info->stream.opaque = (voidpf)0; @@ -1058,6 +1083,9 @@ int unzOpenCurrentFile (unzFile file) { * In unzip, i don't wait absolutely Z_STREAM_END because I known the * size of both compressed and uncompressed data */ +#else + err=UNZ_BADZIPFILE; +#endif } pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size; pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size; @@ -1068,9 +1096,8 @@ int unzOpenCurrentFile (unzFile file) { pfile_in_zip_read_info->stream.avail_in = (uInt)0; - s->pfile_in_zip_read = pfile_in_zip_read_info; - return UNZ_OK; + return err; } @@ -1143,9 +1170,11 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { for (i=0;istream.next_out+i) = *(pfile_in_zip_read_info->stream.next_in+i); +#ifdef USE_ZLIB pfile_in_zip_read_info->crc32_data = crc32(pfile_in_zip_read_info->crc32_data, pfile_in_zip_read_info->stream.next_out, uDoCopy); +#endif // otherwise leave crc32_data as is and it won't be verified at the end pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; pfile_in_zip_read_info->stream.avail_in -= uDoCopy; pfile_in_zip_read_info->stream.avail_out -= uDoCopy; @@ -1154,6 +1183,7 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { pfile_in_zip_read_info->stream.total_out += uDoCopy; iRead += uDoCopy; } else { +#ifdef USE_ZLIB uLong uTotalOutBefore,uTotalOutAfter; const Bytef *bufBefore; uLong uOutThis; @@ -1184,6 +1214,11 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { return (iRead==0) ? UNZ_EOF : iRead; if (err!=Z_OK) break; +#else + // Cannot decompress the file without zlib. + err = UNZ_BADZIPFILE; + break; +#endif } } @@ -1302,16 +1337,20 @@ int unzCloseCurrentFile(unzFile file) { return UNZ_PARAMERROR; +#ifdef USE_ZLIB + // Only verify crc32_data when zlib is linked in, because otherwise crc32() is + // not defined. if (pfile_in_zip_read_info->rest_read_uncompressed == 0) { if (pfile_in_zip_read_info->crc32_data != pfile_in_zip_read_info->crc32_wait) err=UNZ_CRCERROR; } + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); +#endif free(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; - if (pfile_in_zip_read_info->stream_initialised) - inflateEnd(&pfile_in_zip_read_info->stream); pfile_in_zip_read_info->stream_initialised = 0; free(pfile_in_zip_read_info); @@ -1466,5 +1505,3 @@ Archive *makeZipArchive(SeekableReadStream *stream) { } } // End of namespace Common - -#endif diff --git a/common/unzip.h b/common/unzip.h index 6578e2a61ab..dc93ae0fc91 100644 --- a/common/unzip.h +++ b/common/unzip.h @@ -25,8 +25,6 @@ #ifndef COMMON_UNZIP_H #define COMMON_UNZIP_H -#ifdef USE_ZLIB - namespace Common { class Archive; @@ -62,6 +60,4 @@ Archive *makeZipArchive(SeekableReadStream *stream); } // End of namespace Common -#endif // USE_ZLIB - #endif diff --git a/common/util.cpp b/common/util.cpp index 5fa6a33bd8a..317c3519bbb 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -24,6 +24,7 @@ #include "common/util.h" #include "common/system.h" +#include "common/translation.h" #include "common/config-manager.h" namespace Common { @@ -31,7 +32,7 @@ namespace Common { // // Print hexdump of the data passed in // -void hexdump(const byte * data, int len, int bytesPerLine, int startOffset) { +void hexdump(const byte *data, int len, int bytesPerLine, int startOffset) { assert(1 <= bytesPerLine && bytesPerLine <= 32); int i; byte c; @@ -106,29 +107,29 @@ bool parseBool(const Common::String &val, bool &valAsBool) { const LanguageDescription g_languages[] = { - {"zh-cn", "Chinese (China)", ZH_CNA}, - {"zh", "Chinese (Taiwan)", ZH_TWN}, - {"cz", "Czech", CZ_CZE}, - {"nl", "Dutch", NL_NLD}, - {"en", "English", EN_ANY}, // Generic English (when only one game version exist) - {"gb", "English (GB)", EN_GRB}, - {"us", "English (US)", EN_USA}, - {"fr", "French", FR_FRA}, - {"de", "German", DE_DEU}, - {"gr", "Greek", GR_GRE}, - {"he", "Hebrew", HE_ISR}, - {"hb", "Hebrew", HE_ISR}, // Deprecated - {"hu", "Hungarian", HU_HUN}, - {"it", "Italian", IT_ITA}, - {"jp", "Japanese", JA_JPN}, - {"kr", "Korean", KO_KOR}, - {"nb", "Norwegian Bokm\xE5l", NB_NOR}, - {"pl", "Polish", PL_POL}, - {"br", "Portuguese", PT_BRA}, - {"ru", "Russian", RU_RUS}, - {"es", "Spanish", ES_ESP}, - {"se", "Swedish", SE_SWE}, - {0, 0, UNK_LANG} + { "zh-cn", "Chinese (China)", ZH_CNA }, + { "zh", "Chinese (Taiwan)", ZH_TWN }, + { "cz", "Czech", CZ_CZE }, + { "nl", "Dutch", NL_NLD }, + { "en", "English", EN_ANY }, // Generic English (when only one game version exist) + { "gb", "English (GB)", EN_GRB }, + { "us", "English (US)", EN_USA }, + { "fr", "French", FR_FRA }, + { "de", "German", DE_DEU }, + { "gr", "Greek", GR_GRE }, + { "he", "Hebrew", HE_ISR }, + { "hb", "Hebrew", HE_ISR }, // Deprecated + { "hu", "Hungarian", HU_HUN }, + { "it", "Italian", IT_ITA }, + { "jp", "Japanese", JA_JPN }, + { "kr", "Korean", KO_KOR }, + { "nb", "Norwegian Bokm\xE5l", NB_NOR }, + { "pl", "Polish", PL_POL }, + { "br", "Portuguese", PT_BRA }, + { "ru", "Russian", RU_RUS }, + { "es", "Spanish", ES_ESP }, + { "se", "Swedish", SE_SWE }, + { 0, 0, UNK_LANG } }; Language parseLanguage(const String &str) { @@ -167,32 +168,32 @@ const char *getLanguageDescription(Language id) { const PlatformDescription g_platforms[] = { - {"2gs", "2gs", "2gs", "Apple IIgs", kPlatformApple2GS}, - {"3do", "3do", "3do", "3DO", kPlatform3DO}, - {"acorn", "acorn", "acorn", "Acorn", kPlatformAcorn}, - {"amiga", "ami", "amiga", "Amiga", kPlatformAmiga}, - {"atari", "atari-st", "st", "Atari ST", kPlatformAtariST}, - {"c64", "c64", "c64", "Commodore 64", kPlatformC64}, - {"pc", "dos", "ibm", "DOS", kPlatformPC}, - {"pc98", "pc98", "pc98", "PC-98", kPlatformPC98}, - {"wii", "wii", "wii", "Nintendo Wii", kPlatformWii}, - {"coco3", "coco3", "coco3", "CoCo3", kPlatformCoCo3}, + { "2gs", "2gs", "2gs", "Apple IIgs", kPlatformApple2GS }, + { "3do", "3do", "3do", "3DO", kPlatform3DO }, + { "acorn", "acorn", "acorn", "Acorn", kPlatformAcorn }, + { "amiga", "ami", "amiga", "Amiga", kPlatformAmiga }, + { "atari", "atari-st", "st", "Atari ST", kPlatformAtariST }, + { "c64", "c64", "c64", "Commodore 64", kPlatformC64 }, + { "pc", "dos", "ibm", "DOS", kPlatformPC }, + { "pc98", "pc98", "pc98", "PC-98", kPlatformPC98 }, + { "wii", "wii", "wii", "Nintendo Wii", kPlatformWii }, + { "coco3", "coco3", "coco3", "CoCo3", kPlatformCoCo3 }, // The 'official' spelling seems to be "FM-TOWNS" (e.g. in the Indy4 demo). // However, on the net many variations can be seen, like "FMTOWNS", // "FM TOWNS", "FmTowns", etc. - {"fmtowns", "towns", "fm", "FM-TOWNS", kPlatformFMTowns}, + { "fmtowns", "towns", "fm", "FM-TOWNS", kPlatformFMTowns }, - {"linux", "linux", "linux", "Linux", kPlatformLinux}, - {"macintosh", "mac", "mac", "Macintosh", kPlatformMacintosh}, - {"pce", "pce", "pce", "PC-Engine", kPlatformPCEngine}, - {"nes", "nes", "nes", "NES", kPlatformNES}, - {"segacd", "segacd", "sega", "SegaCD", kPlatformSegaCD}, - {"windows", "win", "win", "Windows", kPlatformWindows}, - {"playstation", "psx", "psx", "Sony PlayStation", kPlatformPSX}, - {"cdi", "cdi", "cdi", "Phillips CD-i", kPlatformCDi}, + { "linux", "linux", "linux", "Linux", kPlatformLinux }, + { "macintosh", "mac", "mac", "Macintosh", kPlatformMacintosh }, + { "pce", "pce", "pce", "PC-Engine", kPlatformPCEngine }, + { "nes", "nes", "nes", "NES", kPlatformNES }, + { "segacd", "segacd", "sega", "SegaCD", kPlatformSegaCD }, + { "windows", "win", "win", "Windows", kPlatformWindows }, + { "playstation", "psx", "psx", "Sony PlayStation", kPlatformPSX }, + { "cdi", "cdi", "cdi", "Phillips CD-i", kPlatformCDi }, - {0, 0, 0, "Default", kPlatformUnknown} + { 0, 0, 0, "Default", kPlatformUnknown } }; Platform parsePlatform(const String &str) { @@ -250,11 +251,11 @@ const char *getPlatformDescription(Platform id) { const RenderModeDescription g_renderModes[] = { - {"hercGreen", "Hercules Green", kRenderHercG}, - {"hercAmber", "Hercules Amber", kRenderHercA}, - {"cga", "CGA", kRenderCGA}, - {"ega", "EGA", kRenderEGA}, - {"amiga", "Amiga", kRenderAmiga}, + { "hercGreen", _s("Hercules Green"), kRenderHercG }, + { "hercAmber", _s("Hercules Amber"), kRenderHercA }, + { "cga", "CGA", kRenderCGA }, + { "ega", "EGA", kRenderEGA }, + { "amiga", "Amiga", kRenderAmiga }, {0, 0, kRenderDefault} }; @@ -293,19 +294,22 @@ const struct GameOpt { uint32 option; const char *desc; } g_gameOptions[] = { - { GUIO_NOSUBTITLES, "sndNoSubs" }, - { GUIO_NOMUSIC, "sndNoMusic" }, - { GUIO_NOSPEECH, "sndNoSpeech" }, - { GUIO_NOSFX, "sndNoSFX" }, - { GUIO_NOMIDI, "sndNoMIDI" }, + { GUIO_NOSUBTITLES, "sndNoSubs" }, + { GUIO_NOMUSIC, "sndNoMusic" }, + { GUIO_NOSPEECH, "sndNoSpeech" }, + { GUIO_NOSFX, "sndNoSFX" }, + { GUIO_NOMIDI, "sndNoMIDI" }, + { GUIO_NOLAUNCHLOAD, "launchNoLoad" }, - { GUIO_MIDIPCSPK, "midiPCSpk" }, - { GUIO_MIDICMS, "midiCMS" }, - { GUIO_MIDIPCJR, "midiPCJr" }, - { GUIO_MIDIADLIB, "midiAdLib" }, - { GUIO_MIDITOWNS, "midiTowns" }, - { GUIO_MIDI, "midiMidi" }, + { GUIO_MIDIPCSPK, "midiPCSpk" }, + { GUIO_MIDICMS, "midiCMS" }, + { GUIO_MIDIPCJR, "midiPCJr" }, + { GUIO_MIDIADLIB, "midiAdLib" }, + { GUIO_MIDITOWNS, "midiTowns" }, + { GUIO_MIDIPC98, "midiPC98" }, + { GUIO_MIDIMT32, "midiMt32" }, + { GUIO_MIDIGM, "midiGM" }, { GUIO_NONE, 0 } }; @@ -361,12 +365,15 @@ const String getGameGUIOptionsDescription(uint32 options) { return res; } -void updateGameGUIOptions(const uint32 options) { +void updateGameGUIOptions(const uint32 options, const String &langOption) { + const String newOptionString = getGameGUIOptionsDescription(options) + " " + langOption; + if ((options && !ConfMan.hasKey("guioptions")) || - (ConfMan.hasKey("guioptions") && options != parseGameGUIOptions(ConfMan.get("guioptions")))) { - ConfMan.set("guioptions", getGameGUIOptionsDescription(options)); + (ConfMan.hasKey("guioptions") && ConfMan.get("guioptions") != newOptionString)) { + ConfMan.set("guioptions", newOptionString); ConfMan.flushToDisk(); } } -} // End of namespace Common +} // End of namespace Common + diff --git a/common/util.h b/common/util.h index 3dab87929db..8be05f421ce 100644 --- a/common/util.h +++ b/common/util.h @@ -226,8 +226,10 @@ enum GameGUIOption { GUIO_MIDICMS = (1 << 7), GUIO_MIDIPCJR = (1 << 8), GUIO_MIDIADLIB = (1 << 9), - GUIO_MIDITOWNS = (1 << 10), - GUIO_MIDI = (1 << 11) + GUIO_MIDITOWNS = (1 << 10), + GUIO_MIDIPC98 = (1 << 11), + GUIO_MIDIMT32 = (1 << 12), + GUIO_MIDIGM = (1 << 13) }; bool checkGameGUIOption(GameGUIOption option, const String &str); @@ -241,7 +243,7 @@ const String getGameGUIOptionsDescriptionLanguage(Language lang); * domain, when they differ to the ones passed as * parameter. */ -void updateGameGUIOptions(const uint32 options); +void updateGameGUIOptions(const uint32 options, const String &langOption); } // End of namespace Common diff --git a/configure b/configure index 2c2c81575a1..af10d66518e 100755 --- a/configure +++ b/configure @@ -305,7 +305,7 @@ get_system_exe_extension() { arm-riscos) _exeext=",ff8" ;; - dreamcast | gamecube | nds | ps2 | psp | wii) + dreamcast | gamecube | ds | ps2 | psp | wii) _exeext=".elf" ;; gp2x-linux) @@ -859,8 +859,8 @@ motomagx) _host_cpu=arm _host_alias=arm-linux-gnueabi ;; -nds) - _host_os=nds +ds) + _host_os=ds _host_cpu=arm _host_alias=arm-eabi ;; @@ -917,7 +917,7 @@ wince) android) _host_os=android _host_cpu=arm - _host_alias=arm-android-eabi + _host_alias=arm-oe-linux-androideabi ;; *) if test -n "$_host"; then @@ -952,7 +952,9 @@ fi if test "$_release_build" = yes; then # Release mode enabled: enable optimizations. This also # makes it possible to use -Wuninitialized, so let's do that. - CXXFLAGS="$CXXFLAGS -O2 -Wuninitialized" + # We will also add a define, which indicates we are doing + # an build for a release version. + CXXFLAGS="$CXXFLAGS -O2 -Wuninitialized -DRELEASE_BUILD" fi @@ -978,7 +980,7 @@ esac # Platform specific sanity checks # case $_host_os in -gamecube | nds | wii) +gamecube | ds | wii) if test -z "$DEVKITPRO"; then echo "Please set DEVKITPRO in your environment. export DEVKITPRO=" exit 1 @@ -1046,9 +1048,12 @@ else CXX= for compiler in $compilers; do if test_compiler $compiler; then + echo "success testing compiler: $1" >> "$TMPLOG" CXX=$compiler echo $CXX break + else + echo "failure testing compiler: $1" >> "$TMPLOG" fi done fi @@ -1337,9 +1342,14 @@ case $_host_os in mint*) DEFINES="$DEFINES -DUNIX -DSYSTEM_NOT_SUPPORTING_D_TYPE" ;; - nds) - # TODO nds + ds) + # TODO Nintendo DS DEFINES="$DEFINES -D__DS__ -DNDS -DARM9 -DARM -DNONSTANDARD_PORT" + CXXFLAGS="$CXXFLAGS -isystem $DEVKITPRO/libnds/include -isystem $DEVKITPRO/devkitARM/arm-eabi/include" + CXXFLAGS="$CXXFLAGS -mthumb-interwork -ffunction-sections -fdata-sections -fno-strict-aliasing" + LDFLAGS="$LDFLAGS -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt -Wl,--gc-sections" + LDFLAGS="$LDFLAGS -L$DEVKITPRO/libnds/lib" + LIBS="$LIBS -lnds9" ;; os2-emx*) DEFINES="$DEFINES -DUNIX" @@ -1507,22 +1517,21 @@ if test -n "$_host"; then _vkeybd="yes" _port_mk="backends/platform/linuxmoto/linuxmoto.mk" ;; - nds) + ds) # TODO: complete this - # TODO: Maybe rename nds -> ds (would be more consistent with other backends) DEFINES="$DEFINES -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555" DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER" - DEFINES="$DEFINES -DREDUCE_MEMORY_USAGE" + DEFINES="$DEFINES -DREDUCE_MEMORY_USAGE -DSTREAM_AUDIO_FROM_DISK" + DEFINES="$DEFINES -DDISABLE_DOSBOX_OPL" DEFINES="$DEFINES -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE" _need_memalign=yes - _backend="nds" + add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' + add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' + add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' + _backend="ds" _build_hq_scalers="no" _mt32emu="no" _port_mk="backends/platform/ds/ds.mk" - # TODO: Enable more ARM optimizations -- requires testing! - add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' - add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' - #add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' ;; neuros) DEFINES="$DEFINES -DUNIX -DNEUROS" @@ -1616,7 +1625,6 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' _backend="android" _port_mk="backends/platform/android/android.mk" - _build_hq_scalers="no" ;; *) echo "WARNING: Unknown target, continuing with auto-detected values" @@ -1825,7 +1833,7 @@ PLUGIN_SUFFIX := .plg PLUGIN_EXTRA_DEPS = $(EXECUTABLE) CXXFLAGS += -DDYNAMIC_MODULES LDFLAGS += -Wl,-T$(srcdir)/backends/platform/psp/main_prog.ld -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/psp/plugin.syms,-T$(srcdir)/backends/platform/psp/plugin.ld -lstdc++ -lc -lm +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/psp/plugin.syms,-T$(srcdir)/backends/platform/psp/plugin.ld -lstdc++ -lc -lm -Wl,--wrap,memcpy PRE_OBJS_FLAGS := -Wl,--whole-archive POST_OBJS_FLAGS := -Wl,--no-whole-archive ' @@ -1856,7 +1864,7 @@ add_to_config_mk_if_yes "$_mt32emu" 'USE_MT32EMU = 1' cat > $TMPC << EOF int main(void) { return 0; } EOF -cc_check -lm && LDFLAGS="$LDFLAGS -lm" +cc_check -lm && LIBS="$LIBS -lm" # # Check for Ogg Vorbis @@ -2166,36 +2174,7 @@ EOF add_to_config_h_if_yes $_detectlang '#define USE_DETECTLANG' if test "$_detectlang" = yes ; then - echo_n "with runtime language detection, " - - cat > $TMPC << EOF -#include -#include -int main(void) { nl_langinfo(CODESET); iconv_open(0, 0); return 0; } -EOF - _termconv=no - cc_check_no_clean $LDFLAGS $CXXFLAGS && _termconv=yes - cc_check $LDFLAGS $CXXFLAGS -liconv && LIBS="$LIBS -liconv" && _termconv=yes - - add_to_config_mk_if_yes $_termconv 'USE_TERMCONV = 1' - add_to_config_h_if_yes $_termconv '#define USE_TERMCONV' - if test "$_termconv" = yes ; then - uses_const=no - cat > $TMPC << EOF -#include -int main(int argc, char **argv) { - iconv_t iconvP; - const char **inbuf = 0; - iconv(iconvP, inbuf, 0, 0, 0); - return 0; -} -EOF - cc_check $LDFLAGS $LIBS $CXXFLAGS && uses_const=yes - add_to_config_h_if_yes $uses_const '#define ICONV_USES_CONST' - echo "with terminal conversion)" - else - echo "without terminal conversion)" - fi + echo "with runtime language detection)" else echo "without runtime language detection)" fi @@ -2278,8 +2257,11 @@ case $_backend in LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`" DEFINES="$DEFINES -DSDL_BACKEND -DLINUXMOTO" ;; - nds) - # TODO nds + ds) + # TODO ds + INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/ds/arm9/source' + INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/ds/commoninclude' + INCLUDES="$INCLUDES "'-Ibackends/platform/ds/arm9/data' ;; null) DEFINES="$DEFINES -DUSE_NULL_DRIVER" @@ -2295,6 +2277,7 @@ case $_backend in psp) DEFINES="$DEFINES -D__PSP__ -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DDISABLE_DOSBOX_OPL" LIBS="$LIBS -lpng -Wl,-Map,mapfile.txt" + LDFLAGS="$LDFLAGS -Wl,--wrap,memcpy" ;; samsungtv) find_sdlconfig @@ -2326,12 +2309,36 @@ case $_backend in LIBS="$LIBS -static -lSDL" ;; android) + static_libs='' + system_libs='' + for lib in $LIBS; do + case $lib in + -lz|-lm) + system_libs="$system_libs $lib" + ;; + *) + static_libs="$static_libs $lib" + ;; + esac + done + # -lgcc is carefully placed here - we want to catch # all toolchain symbols in *our* libraries rather # than pick up anything unhygenic from the Android libs. - LIBS="$LIBS -lgcc -lstdc++ -llog -lGLESv1_CM -lEGL" + LIBS="-Wl,-Bstatic $static_libs -Wl,-Bdynamic -lgcc $system_libs -lstdc++ -llog -lGLESv1_CM" DEFINES="$DEFINES -D__ANDROID__ -DANDROID_BACKEND -DREDUCE_MEMORY_USAGE" add_line_to_config_mk 'PLUGIN_LDFLAGS += $(LDFLAGS) -Wl,-shared,-Bsymbolic' + + # Work around an Android 2.0+ run-time linker bug: + # The linker doesn't actually look in previously + # loaded libraries when trying to resolve symbols - + # effectively turning all dlopen(RTLD_GLOBAL) calls + # into dlopen(RTLD_LOCAL). It *does* look in + # DT_NEEDED libraries, so the workaround is to add an + # (otherwise unnecessary) dependency from plugins back + # to the main libscummvm.so. + add_line_to_config_mk 'PLUGIN_LDFLAGS += -Lbuild.tmp -lscummvm' + add_line_to_config_mk 'PLUGIN_EXTRA_DEPS += build.tmp/libscummvm.so' ;; *) echo "support for $_backend backend not implemented in configure script yet" @@ -2348,7 +2355,7 @@ if test "$have_gcc" = yes ; then case $_host_os in # newlib-based system include files suppress non-C89 function # declarations under __STRICT_ANSI__ - mingw* | dreamcast | wii | gamecube | psp | wince | amigaos* | android) + mingw* | dreamcast | wii | gamecube | ds | psp | wince | amigaos* | android) CXXFLAGS="$CXXFLAGS -W -Wno-unused-parameter" ;; *) diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index c4961747c23..1e3632365a0 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -306,7 +306,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) // If the GUI options were updated, we catch this here and update them in the users config // file transparently. - Common::updateGameGUIOptions(agdDesc->guioptions | params.guioptions); + Common::updateGameGUIOptions(agdDesc->guioptions | params.guioptions, getGameGUIOptionsDescriptionLanguage(agdDesc->language)); debug(2, "Running %s", toGameDescriptor(*agdDesc, params.list).description().c_str()); if (!createInstance(syst, engine, agdDesc)) diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp index 6f206b9e679..33d305aaba0 100644 --- a/engines/dialogs.cpp +++ b/engines/dialogs.cpp @@ -275,8 +275,36 @@ enum { // "" as value for the domain, and in fact provide a somewhat better user // experience at the same time. ConfigDialog::ConfigDialog(bool subtitleControls) - : GUI::OptionsDialog("", "") { - // Not in Residual + : GUI::OptionsDialog("", "GlobalConfig") { + + // + // Sound controllers + // + + addVolumeControls(this, "GlobalConfig."); + setVolumeSettingsState(true); // could disable controls by GUI options + + // + // Subtitle speed and toggle controllers + // + + if (subtitleControls) { + // Global talkspeed range of 0-255 + addSubtitleControls(this, "GlobalConfig.", 255); + setSubtitleSettingsState(true); // could disable controls by GUI options + } + + // + // Add the buttons + // + + new GUI::ButtonWidget(this, "GlobalConfig.Ok", _("~O~K"), 0, GUI::kOKCmd); + new GUI::ButtonWidget(this, "GlobalConfig.Cancel", _("~C~ancel"), 0, GUI::kCloseCmd); + +#ifdef SMALL_SCREEN_DEVICE + new GUI::ButtonWidget(this, "GlobalConfig.Keys", _("~K~eys"), 0, kKeysCmd); + _keysDialog = NULL; +#endif } ConfigDialog::~ConfigDialog() { diff --git a/engines/engine.cpp b/engines/engine.cpp index 7f7f2534a2d..cc9b9860779 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -23,6 +23,7 @@ */ #if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) +#define WIN32_LEAN_AND_MEAN #include #include // winnt.h defines ARRAYSIZE, but we want our own one... @@ -77,7 +78,7 @@ static void defaultErrorHandler(const char *msg) { if (isSmartphone()) debugger = 0; #endif - if (debugger && !debugger->isAttached()) { + if (debugger && !debugger->isActive()) { debugger->attach(msg); debugger->onFrame(); } diff --git a/graphics/fontman.cpp b/graphics/fontman.cpp index 05c304bd141..5775a6aee41 100644 --- a/graphics/fontman.cpp +++ b/graphics/fontman.cpp @@ -57,18 +57,28 @@ FontManager::~FontManager() { g_consolefont = 0; } -const char *builtinFontNames[] = { - "builtinOSD", - "builtinConsole", - "builtinGUI", - "builtinBigGUI", - 0 +const struct { + const char *name; + FontManager::FontUsage id; +} builtinFontNames[] = { + { "builtinOSD", FontManager::kOSDFont }, + { "builtinConsole", FontManager::kConsoleFont }, + { "fixed5x8.bdf", FontManager::kConsoleFont }, + { "fixed5x8-iso-8859-1.bdf", FontManager::kConsoleFont }, + { "fixed5x8-ascii.bdf", FontManager::kConsoleFont }, + { "clR6x12.bdf", FontManager::kGUIFont }, + { "clR6x12-iso-8859-1.bdf", FontManager::kGUIFont }, + { "clR6x12-ascii.bdf", FontManager::kGUIFont }, + { "helvB12.bdf", FontManager::kBigGUIFont }, + { "helvB12-iso-8859-1.bdf", FontManager::kBigGUIFont }, + { "helvB12-ascii.bdf", FontManager::kBigGUIFont }, + { 0, FontManager::kOSDFont } }; const Font *FontManager::getFontByName(const Common::String &name) const { - for (int i = 0; builtinFontNames[i]; i++) - if (!strcmp(name.c_str(), builtinFontNames[i])) - return getFontByUsage((FontUsage)i); + for (int i = 0; builtinFontNames[i].name; i++) + if (!strcasecmp(name.c_str(), builtinFontNames[i].name)) + return getFontByUsage(builtinFontNames[i].id); if (!_fontMap.contains(name)) return 0; diff --git a/gui/GuiManager.cpp b/gui/GuiManager.cpp index 479c05409f2..42ffac663a2 100644 --- a/gui/GuiManager.cpp +++ b/gui/GuiManager.cpp @@ -73,7 +73,7 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), // Loading the theme failed, try to load the built-in theme if (!loadNewTheme("builtin", gfxMode)) { // Loading the built-in theme failed as well. Bail out - error("%s", _t("Failed to load any GUI theme, aborting")); + error("Failed to load any GUI theme, aborting"); } } diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp index 86c8d6cd315..b6546f8c06f 100644 --- a/gui/ListWidget.cpp +++ b/gui/ListWidget.cpp @@ -439,11 +439,6 @@ bool ListWidget::handleKeyDown(Common::KeyState state) { _scrollBar->draw(); } -#if !defined(PALMOS_MODE) - // not done on PalmOS because keyboard is emulated and keyup is not generated - _currentKeyDown = state.keycode; -#endif - return handled; } diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index f978f1006cf..82d87a9978d 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -397,17 +397,12 @@ bool ThemeEngine::init() { if (!_themeArchive && !_themeFile.empty()) { Common::FSNode node(_themeFile); if (node.getName().hasSuffix(".zip") && !node.isDirectory()) { -#ifdef USE_ZLIB Common::Archive *zipArchive = Common::makeZipArchive(node); if (!zipArchive) { warning("Failed to open Zip archive '%s'.", node.getPath().c_str()); } _themeArchive = zipArchive; -#else - warning("Trying to load theme '%s' in a Zip archive without zLib support", _themeFile.c_str()); - return false; -#endif } else if (node.isDirectory()) { _themeArchive = new Common::FSDirectory(node); } @@ -568,10 +563,17 @@ bool ThemeEngine::addFont(TextData textId, const Common::String &file) { if (file == "default") { _texts[textId]->_fontPtr = _font; } else { - _texts[textId]->_fontPtr = FontMan.getFontByName(file); + Common::String localized = genLocalizedFontFilename(file.c_str()); + // Try built-in fonts + _texts[textId]->_fontPtr = FontMan.getFontByName(localized); if (!_texts[textId]->_fontPtr) { - _texts[textId]->_fontPtr = loadFont(file); + // First try to load localized font + _texts[textId]->_fontPtr = loadFont(localized); + + // Fallback to non-localized font + if (!_texts[textId]->_fontPtr) + _texts[textId]->_fontPtr = loadFont(file); if (!_texts[textId]->_fontPtr) error("Couldn't load font '%s'", file.c_str()); @@ -1494,6 +1496,34 @@ Common::String ThemeEngine::genCacheFilename(const char *filename) { return Common::String(); } +Common::String ThemeEngine::genLocalizedFontFilename(const char *filename) { +#ifndef USE_TRANSLATION + return Common::String(filename); +#else + + Common::String result; + bool pointPassed = false; + + for (const char *p = filename; *p != 0; p++) { + if (!pointPassed) { + if (*p != '.') { + result += *p; + } else { + result += "-"; + result += TransMan.getCurrentCharset(); + result += *p; + + pointPassed = true; + } + } else { + result += *p; + } + } + + return result; +#endif +} + /********************************************************** * Static Theme XML functions @@ -1527,7 +1557,6 @@ bool ThemeEngine::themeConfigUsable(const Common::FSNode &node, Common::String & bool foundHeader = false; if (node.getName().hasSuffix(".zip") && !node.isDirectory()) { -#ifdef USE_ZLIB Common::Archive *zipArchive = Common::makeZipArchive(node); if (zipArchive && zipArchive->hasFile("THEMERC")) { // Open THEMERC from the ZIP file. @@ -1540,7 +1569,6 @@ bool ThemeEngine::themeConfigUsable(const Common::FSNode &node, Common::String & // reference to zipArchive anywhere. This could change if we // ever modify ZipArchive::createReadStreamForMember. delete zipArchive; -#endif } else if (node.isDirectory()) { Common::FSNode headerfile = node.getChild("THEMERC"); if (!headerfile.exists() || !headerfile.isReadable() || headerfile.isDirectory()) @@ -1636,7 +1664,6 @@ void ThemeEngine::listUsableThemes(const Common::FSNode &node, Common::ListaddDrawData(node->values["id"], cached) == false) return parserError("Error adding Draw Data set: Invalid DrawData name."); - if (_defaultStepLocal) { - delete _defaultStepLocal; - _defaultStepLocal = 0; - } + delete _defaultStepLocal; + _defaultStepLocal = 0; return true; } diff --git a/gui/about.cpp b/gui/about.cpp index cdc7e9dde32..b160becc085 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -93,22 +93,25 @@ AboutDialog::AboutDialog() version += gResidualVersion; _lines.push_back(version); - Common::String date(_s("C2""(built on ")); - date += gResidualBuildDate; - date += ')'; - _lines.push_back(date); + Common::String date = Common::String::printf(_("(built on %s)"), gResidualBuildDate); + _lines.push_back("C2" + date); for (i = 0; i < ARRAYSIZE(copyright_text); i++) addLine(copyright_text[i]); - addLine(_s("C1""Features compiled in:")); - Common::String features("C0"); - features += gResidualFeatures; + Common::String features("C1"); + features += _("Features compiled in:"); addLine(features.c_str()); + Common::String featureList("C0"); + featureList += gResidualFeatures; + addLine(featureList.c_str()); _lines.push_back(""); - addLine(_s("C1""Available engines:")); + Common::String engines("C1"); + engines += _("Available engines:"); + addLine(engines.c_str()); + const EnginePlugin::List &plugins = EngineMan.getPlugins(); EnginePlugin::List::const_iterator iter = plugins.begin(); for (; iter != plugins.end(); ++iter) { diff --git a/gui/console.cpp b/gui/console.cpp index 4021daf33fa..a038b6c7f01 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -156,7 +156,9 @@ void ConsoleDialog::open() { _slideMode = kDownSlideMode; Dialog::open(); - if (_promptStartPos == -1) { + if ((_promptStartPos == -1) || (_currentPos > _promptEndPos)) { + // we print a prompt, if this is the first time we are called or if the + // engine wrote onto us since the last call print(PROMPT); _promptStartPos = _promptEndPos = _currentPos; } @@ -667,11 +669,7 @@ int ConsoleDialog::printf(const char *format, ...) { } int ConsoleDialog::vprintf(const char *format, va_list argptr) { -#ifdef PALMOS_MODE - char buf[256]; -#else char buf[2048]; -#endif #if defined(WIN32) int count = _vsnprintf(buf, sizeof(buf), format, argptr); diff --git a/gui/debugger.cpp b/gui/debugger.cpp index bfb09e7d710..3d415fccff8 100644 --- a/gui/debugger.cpp +++ b/gui/debugger.cpp @@ -39,9 +39,8 @@ namespace GUI { Debugger::Debugger() { - _frame_countdown = 0; - _detach_now = false; - _isAttached = false; + _frameCountdown = 0; + _isActive = false; _errStr = NULL; _firstTime = true; #ifndef USE_TEXT_CONSOLE @@ -50,6 +49,10 @@ Debugger::Debugger() { _debuggerDialog->setCompletionCallback(debuggerCompletionCallback, this); #endif + // Register variables + DVar_Register("debug_countdown", &_frameCountdown, DVAR_INT, 0); + + // Register commands //DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); DCmd_Register("exit", WRAP_METHOD(Debugger, Cmd_Exit)); DCmd_Register("quit", WRAP_METHOD(Debugger, Cmd_Exit)); @@ -84,40 +87,32 @@ int Debugger::DebugPrintf(const char *format, ...) { } void Debugger::attach(const char *entry) { - g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); - if (entry) { - _errStr = strdup(entry); - } + // Set error string (if any) + free(_errStr); + _errStr = entry ? strdup(entry) : 0; - _frame_countdown = 1; - _detach_now = false; - _isAttached = true; + // Reset frame countdown (i.e. attach immediately) + _frameCountdown = 1; } void Debugger::detach() { g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); - - _detach_now = false; - _isAttached = false; } // Temporary execution handler void Debugger::onFrame() { - if (_frame_countdown == 0) - return; - --_frame_countdown; - - if (!_frame_countdown) { - - preEnter(); - enter(); - postEnter(); - - // Detach if we're finished with the debugger - if (_detach_now) - detach(); + // Count down until 0 is reached + if (_frameCountdown > 0) { + --_frameCountdown; + if (_frameCountdown == 0) { + _isActive = true; + preEnter(); + enter(); + postEnter(); + _isActive = false; + } } } @@ -250,8 +245,8 @@ bool Debugger::parseCommand(const char *inputOrig) { } else { int element = atoi(chr+1); int32 *var = *(int32 **)_dvars[i].variable; - if (element >= _dvars[i].optional) { - DebugPrintf("%s is out of range (array is %d elements big)\n", param[0], _dvars[i].optional); + if (element >= _dvars[i].arraySize) { + DebugPrintf("%s is out of range (array is %d elements big)\n", param[0], _dvars[i].arraySize); } else { var[element] = atoi(param[1]); DebugPrintf("(int)%s = %d\n", param[0], var[element]); @@ -281,8 +276,8 @@ bool Debugger::parseCommand(const char *inputOrig) { } else { int element = atoi(chr+1); const int32 *var = *(const int32 **)_dvars[i].variable; - if (element >= _dvars[i].optional) { - DebugPrintf("%s is out of range (array is %d elements big)\n", param[0], _dvars[i].optional); + if (element >= _dvars[i].arraySize) { + DebugPrintf("%s is out of range (array is %d elements big)\n", param[0], _dvars[i].arraySize); } else { DebugPrintf("(int)%s = %d\n", param[0], var[element]); } @@ -383,7 +378,7 @@ char *Debugger::readlineComplete(const char *input, int state) { #endif // Variable registration function -void Debugger::DVar_Register(const Common::String &varname, void *pointer, int type, int optional) { +void Debugger::DVar_Register(const Common::String &varname, void *pointer, VarType type, int arraySize) { // TODO: Filter out duplicates // TODO: Sort this list? Then we can do binary search later on when doing lookups. assert(pointer); @@ -392,7 +387,7 @@ void Debugger::DVar_Register(const Common::String &varname, void *pointer, int t tmp.name = varname; tmp.type = type; tmp.variable = pointer; - tmp.optional = optional; + tmp.arraySize = arraySize; _dvars.push_back(tmp); } @@ -406,7 +401,7 @@ void Debugger::DCmd_Register(const Common::String &cmdname, Debuglet *debuglet) // Detach ("exit") the debugger bool Debugger::Cmd_Exit(int argc, const char **argv) { - _detach_now = true; + detach(); return false; } diff --git a/gui/debugger.h b/gui/debugger.h index 697cd04a841..64da4666f94 100644 --- a/gui/debugger.h +++ b/gui/debugger.h @@ -43,20 +43,46 @@ public: int DebugPrintf(const char *format, ...); + /** + * The onFrame() method should be invoked by the engine at regular + * intervals (usually once per main loop iteration) whenever the + * debugger is attached. + * This will open up the console and accept user input if certain + * preconditions are met, such as the frame countdown having + * reached zero. + * + * Subclasses can override this to e.g. check for breakpoints being + * triggered. + */ virtual void onFrame(); + /** + * 'Attach' the debugger. This ensures that the next time onFrame() + * is invoked, the debugger will activate and accept user input. + */ virtual void attach(const char *entry = 0); - bool isAttached() const { return _isAttached; } + + /** + * Return true if the debugger is currently active (i.e. executing + * a command or waiting for use input). + */ + bool isActive() const { return _isActive; } protected: typedef Common::Functor2 Debuglet; - // Convenience macro for registering a method of a debugger class - // as the current command. + /** + * Convenience macro that makes it either to register a method + * of a debugger subclass as a command. + * Usage example: + * DCmd_Register("COMMAND", WRAP_METHOD(MyDebugger, MyCmd)); + * would register the method MyDebugger::MyCmd(int, const char **) + * under the command name "COMMAND". + */ #define WRAP_METHOD(cls, method) \ new Common::Functor2Mem(this, &cls::method) - enum { + enum VarType { DVAR_BYTE, DVAR_INT, DVAR_BOOL, @@ -67,50 +93,100 @@ protected: struct DVar { Common::String name; void *variable; - int type; - int optional; + VarType type; + int arraySize; }; - int _frame_countdown; - bool _detach_now; + + /** + * Register a variable with the debugger. This allows the user to read and modify + * this variable. + * @param varname the identifier with which the user may access the variable + * @param variable pointer to the actual storage of the variable + * @param type the type of the variable (byte, int, bool, ...) + * @paral arraySize for type DVAR_INTARRAY this specifies the size of the array + * + * @todo replace this single method by type safe variants. + */ + void DVar_Register(const Common::String &varname, void *variable, VarType type, int arraySize); + void DCmd_Register(const Common::String &cmdname, Debuglet *debuglet); + private: + /** + * The frame countdown specifies a number of frames that must pass + * until the console will show up. This value is decremented by one + * each time onFrame() is called, until it reaches 0, at which point + * onFrame() will open the console and handle input into it. + * + * The user can modify this value using the debug_countdown command. + * + * Note: The console must be in *attached* state, otherwise, it + * won't show up (and the countdown won't count down either). + */ + uint _frameCountdown; + Common::Array _dvars; typedef Common::HashMap, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CommandsMap; CommandsMap _cmds; - bool _isAttached; + /** + * True if the debugger is currently active (i.e. executing + * a command or waiting for use input). + */ + bool _isActive; + char *_errStr; + + /** + * Initially true, set to false when Debugger::enter is called + * the first time. We use this flag to show a greeting message + * to the user once, when he opens the debugger for the first + * time. + */ bool _firstTime; + #ifndef USE_TEXT_CONSOLE GUI::ConsoleDialog *_debuggerDialog; #endif protected: - // Hook for subclasses: Called just before enter() is run + /** + * Hook for subclasses which is called just before enter() is run. + * A typical usage example is pausing music and sound effects. + */ virtual void preEnter() {} - // Hook for subclasses: Called just after enter() was run + /** + * Hook for subclasses which is called just after enter() was run. + * A typical usage example is resuming music and sound effects. + */ virtual void postEnter() {} - // Hook for subclasses: Process the given command line. - // Should return true if and only if argv[0] is a known command and was - // handled, false otherwise. - virtual bool handleCommand(int argc, const char **argv, bool &keepRunning); - + /** + * Subclasses should invoke the detach() method in their Cmd_FOO methods + * if that command will resume execution of the program (as opposed to + * executing, say, a "single step through code" command). + * + * This currently only hides the virtual keyboard, if any. + */ + void detach(); private: - void detach(); void enter(); bool parseCommand(const char *input); bool tabComplete(const char *input, Common::String &completion) const; -protected: - void DVar_Register(const Common::String &varname, void *pointer, int type, int optional); - void DCmd_Register(const Common::String &cmdname, Debuglet *debuglet); + /** + * Process the given command line. + * Returns true if and only if argv[0] is a known command and was + * handled, false otherwise. + */ + virtual bool handleCommand(int argc, const char **argv, bool &keepRunning); +protected: bool Cmd_Exit(int argc, const char **argv); bool Cmd_Help(int argc, const char **argv); bool Cmd_DebugFlagsList(int argc, const char **argv); diff --git a/gui/launcher.cpp b/gui/launcher.cpp index bab101c7a62..4f494fb9d58 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -704,7 +704,7 @@ void LauncherDialog::addGame() { Common::FSNode dir(_browser->getResult()); Common::FSList files; if (!dir.getChildren(files, Common::FSNode::kListAll)) { - MessageDialog alert("Residual couldn't open the specified directory!"); + MessageDialog alert(_("Residual couldn't open the specified directory!")); alert.runModal(); return; } diff --git a/gui/options.cpp b/gui/options.cpp index e4b3cfea47a..a0ca7aa6b50 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -40,6 +40,7 @@ #include "graphics/scaler.h" #include "sound/mididrv.h" +#include "sound/musicplugin.h" #include "sound/mixer.h" #include "sound/fmopl.h" @@ -99,6 +100,8 @@ void OptionsDialog::init() { _aspectCheckbox = 0; _enableAudioSettings = false; _midiPopUp = 0; + _mt32DevicePopUp = 0; + _gmDevicePopUp = 0; _oplPopUp = 0; _outputRatePopUp = 0; _enableMIDISettings = false; @@ -147,10 +150,25 @@ void OptionsDialog::open() { } // Audio options - if (_midiPopUp) { - // Music driver - MidiDriverType id = MidiDriver::parseMusicDriver(ConfMan.get("music_driver", _domain)); - _midiPopUp->setSelectedTag(id); + if (!loadMusicDeviceSetting(_midiPopUp, "music_driver")) + _midiPopUp->setSelected(0); + + if (!loadMusicDeviceSetting(_mt32DevicePopUp, "mt32_device")) { + if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { + if (!loadMusicDeviceSetting(_mt32DevicePopUp, Common::String(), MT_MT32)) + _mt32DevicePopUp->setSelected(0); + } else { + _mt32DevicePopUp->setSelected(0); + } + } + + if (!loadMusicDeviceSetting(_gmDevicePopUp, "gm_device")) { + if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { + if (!loadMusicDeviceSetting(_gmDevicePopUp, Common::String(), MT_GM)) + _gmDevicePopUp->setSelected(0); + } else { + _gmDevicePopUp->setSelected(0); + } } if (_oplPopUp) { @@ -231,15 +249,13 @@ void OptionsDialog::close() { // Audio options if (_midiPopUp) { if (_enableAudioSettings) { - const MidiDriverDescription *md = MidiDriver::getAvailableMidiDrivers(); - while (md->name && md->id != (int)_midiPopUp->getSelectedTag()) - md++; - if (md->name) - ConfMan.set("music_driver", md->name, _domain); - else - ConfMan.removeKey("music_driver", _domain); + saveMusicDeviceSetting(_midiPopUp, "music_driver"); + saveMusicDeviceSetting(_mt32DevicePopUp, "mt32_device"); + saveMusicDeviceSetting(_gmDevicePopUp, "gm_device"); } else { ConfMan.removeKey("music_driver", _domain); + ConfMan.removeKey("mt32_device", _domain); + ConfMan.removeKey("gm_device", _domain); } } @@ -346,14 +362,17 @@ void OptionsDialog::setGraphicSettingsState(bool enabled) { void OptionsDialog::setAudioSettingsState(bool enabled) { _enableAudioSettings = enabled; - _midiPopUpDesc->setEnabled(enabled); _midiPopUp->setEnabled(enabled); + _mt32DevicePopUpDesc->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _mt32DevicePopUp->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _gmDevicePopUpDesc->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _gmDevicePopUp->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); - uint32 allFlags = MidiDriver::midiDriverFlags2GUIO((uint32)-1); + uint32 allFlags = MidiDriver::musicType2GUIO((uint32)-1); if (_domain != Common::ConfigManager::kApplicationDomain && // global dialog - (_guioptions & allFlags) && // No flags are specified + (_guioptions & allFlags) && // No flags are specified !(_guioptions & Common::GUIO_MIDIADLIB)) { _oplPopUpDesc->setEnabled(false); _oplPopUp->setEnabled(false); @@ -444,19 +463,40 @@ void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &pr void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &prefix) { // The MIDI mode popup & a label - _midiPopUpDesc = new StaticTextWidget(boss, prefix + "auMidiPopupDesc", _("Music driver:"), _("Specifies output sound device or sound card emulator")); + _midiPopUpDesc = new StaticTextWidget(boss, prefix + "auMidiPopupDesc", _domain == Common::ConfigManager::kApplicationDomain ? _("Preferred Device:") : _("Music Device:"), _domain == Common::ConfigManager::kApplicationDomain ? _("Specifies preferred sound device or sound card emulator") : _("Specifies output sound device or sound card emulator")); _midiPopUp = new PopUpWidget(boss, prefix + "auMidiPopup", _("Specifies output sound device or sound card emulator")); - // Populate it - const MidiDriverDescription *md = MidiDriver::getAvailableMidiDrivers(); - uint32 allFlags = MidiDriver::midiDriverFlags2GUIO((uint32)-1); + _mt32DevicePopUpDesc = new StaticTextWidget(boss, prefix + "auPrefMt32PopupDesc", _("MT-32 Device:"), _("Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output")); + _mt32DevicePopUp = new PopUpWidget(boss, prefix + "auPrefMt32Popup"); + _gmDevicePopUpDesc = new StaticTextWidget(boss, prefix + "auPrefGmPopupDesc", _("GM Device:"), _("Specifies default sound device for General MIDI output")); + _gmDevicePopUp = new PopUpWidget(boss, prefix + "auPrefGmPopup"); - while (md->name) { - if (_domain == Common::ConfigManager::kApplicationDomain || // global dialog - !(_guioptions & allFlags) || // No flags are specified - _guioptions & (MidiDriver::midiDriverFlags2GUIO(md->flags))) // flag is present - _midiPopUp->appendEntry(_(md->description), md->id); - md++; + // Populate it + uint32 allFlags = MidiDriver::musicType2GUIO((uint32)-1); + + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if ((_domain == Common::ConfigManager::kApplicationDomain && d->getMusicType() != MT_TOWNS) // global dialog - skip useless FM-Towns option there + || (_domain != Common::ConfigManager::kApplicationDomain && !(_guioptions & allFlags)) // No flags are specified + || _guioptions & (MidiDriver::musicType2GUIO(d->getMusicType())) // flag is present + || d->getMusicDriverId() == "auto" || d->getMusicDriverId() == "null") // always add default and null device + _midiPopUp->appendEntry(d->getCompleteName(), d->getHandle()); + + if (d->getMusicType() >= MT_GM || d->getMusicDriverId() == "auto") { + _mt32DevicePopUp->appendEntry(d->getCompleteName(), d->getHandle()); + if (d->getMusicType() != MT_MT32) + _gmDevicePopUp->appendEntry(d->getCompleteName(), d->getHandle()); + } + } + } + + if (!_domain.equals(Common::ConfigManager::kApplicationDomain)) { + _mt32DevicePopUpDesc->setEnabled(false); + _mt32DevicePopUp->setEnabled(false); + _gmDevicePopUpDesc->setEnabled(false); + _gmDevicePopUp->setEnabled(false); } // The OPL emulator popup & a label @@ -563,6 +603,49 @@ void OptionsDialog::addVolumeControls(GuiObject *boss, const Common::String &pre _enableVolumeSettings = true; } +bool OptionsDialog::loadMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MusicType preferredType) { + if (!popup || !popup->isEnabled()) + return true; + + if (_domain != Common::ConfigManager::kApplicationDomain || ConfMan.hasKey(setting, _domain) || preferredType) { + const Common::String drv = ConfMan.get(setting, (_domain != Common::ConfigManager::kApplicationDomain && !ConfMan.hasKey(setting, _domain)) ? Common::ConfigManager::kApplicationDomain : _domain); + const MusicPlugin::List p = MusicMan.getPlugins(); + + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (setting.empty() ? (preferredType == d->getMusicType()) : (drv == d->getCompleteId())) { + popup->setSelectedTag(d->getHandle()); + return popup->getSelected() == -1 ? false : true; + } + } + } + } + + return false; +} + +void OptionsDialog::saveMusicDeviceSetting(PopUpWidget *popup, Common::String setting) { + if (!popup || !_enableAudioSettings) + return; + + const MusicPlugin::List p = MusicMan.getPlugins(); + bool found = false; + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end() && !found; ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getHandle() == popup->getSelectedTag()) { + ConfMan.set(setting, d->getCompleteId(), _domain); + found = true; + break; + } + } + } + + if (!found) + ConfMan.removeKey(setting, _domain); +} + int OptionsDialog::getSubtitleMode(bool subtitles, bool speech_mute) { if (_guioptions & Common::GUIO_NOSUBTITLES) return kSubtitlesSpeech; // Speech only @@ -685,7 +768,17 @@ GlobalOptionsDialog::GlobalOptionsDialog() _guiLanguagePopUp->appendEntry(lang->name, lang->id); lang++; } - _guiLanguagePopUp->setSelectedTag(TransMan.parseLanguage(ConfMan.get("gui_language").c_str())); + + // Select the currently configured language or default/English if + // nothing is specified. + if (ConfMan.hasKey("gui_language")) + _guiLanguagePopUp->setSelectedTag(TransMan.parseLanguage(ConfMan.get("gui_language"))); + else +#ifdef USE_DETECTLANG + _guiLanguagePopUp->setSelectedTag(Common::kTranslationAutodetectId); +#else // !USE_DETECTLANG + _guiLanguagePopUp->setSelectedTag(Common::kTranslationBuiltinId); +#endif // USE_DETECTLANG #endif // USE_TRANSLATION diff --git a/gui/options.h b/gui/options.h index f4520047278..14bde6ea3d9 100644 --- a/gui/options.h +++ b/gui/options.h @@ -28,6 +28,7 @@ #include "gui/dialog.h" #include "gui/TabWidget.h" #include "common/str.h" +#include "sound/musicplugin.h" #ifdef SMALL_SCREEN_DEVICE #include "gui/KeysDialog.h" @@ -78,6 +79,9 @@ protected: void setVolumeSettingsState(bool enabled); void setSubtitleSettingsState(bool enabled); + bool loadMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MusicType preferredType = MT_AUTO); + void saveMusicDeviceSetting(PopUpWidget *popup, Common::String setting); + TabWidget *_tabWidget; int _graphicsTabId; @@ -104,6 +108,13 @@ private: StaticTextWidget *_outputRatePopUpDesc; PopUpWidget *_outputRatePopUp; + StaticTextWidget *_mt32DevicePopUpDesc; + PopUpWidget *_mt32DevicePopUp; + StaticTextWidget *_gmDevicePopUpDesc; + PopUpWidget *_gmDevicePopUp; + + + // // MIDI controls // @@ -125,7 +136,6 @@ private: RadiobuttonWidget *_subToggleSubOnly; RadiobuttonWidget *_subToggleSpeechOnly; RadiobuttonWidget *_subToggleSubBoth; - int _subMode; static const char *_subModeDesc[]; static const char *_lowresSubModeDesc[]; StaticTextWidget *_subSpeedDesc; diff --git a/gui/saveload.cpp b/gui/saveload.cpp index 1c3f411fc4b..27f2747ba09 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -182,7 +182,7 @@ void SaveLoadChooser::reflowLayout() { error("Error when loading position data for Save/Load Thumbnails."); int thumbW = kThumbnailWidth; - int thumbH = ((g_system->getHeight() % 200 && g_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1); + int thumbH = kThumbnailHeight2; int thumbX = x + (w >> 1) - (thumbW >> 1); int thumbY = y + kLineHeight; diff --git a/gui/themes/default.inc b/gui/themes/default.inc index a360c95a00d..086fecc123f 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1,4 +1,781 @@ "" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " " " " " " " +" " " " +" " " " +" " " " " " " " " " +" " +" " +" " +" " +" " +" " +" " +" " " " @@ -1179,764 +1984,3 @@ " " " " " " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " diff --git a/gui/themes/modern.zip b/gui/themes/modern.zip index 616c1b122ab391c9182fa892c39bd5170d617925..7ef38caa53361931cf10c966e3c3142fa6962d7f 100644 GIT binary patch delta 8892 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 delta 8786 zcmY+~MN}MYuqI%f#wEC0;}YBq919_-I-n0In7sh|rOCHuAd#?vERFLE203r9Tf{8eQHplS=I?hjeUpC1pr60$8- zt)zmNTL$&GR8gFnFVi8MH2(iK_Op|HX;ax??wszD-B({vTaCbP;N5#8M8tz=hV3|d zIz)2?1oE+z8NyrGX>)o)eehcl$4ee-|{mJSklgg?`um!$cPEIF0Vmlb&GSThH}0vOuU*CG zN1j(f_}xL2Fo`o|ParWk8)-*D^{O>ANcSdj$=H98>P2M$+$<4FQ(Gpz3&f(t?m>vk z1N`!l)r%9ulNSA2Wo69$44V<0iy?A6WJ#ko72`E}6F7hH6QyqS5{(f2BK<*NWDwW8 z>E~;QO1Z;4 zy0J&RJW-GX;{kc=x`{EynJyi0Gp$2U-zm7BJMX#Wg*}IR!UJsf(c1ypgXo01UtJx>dy^|Ii2N_yHIGX#nI&^k?q{js5WNXC3i}J zZR#yQot_>KmPU@>lhNy|MD*j8rm`Ffn_1pZ71HO)sZVzZSc~@I-^GVe@C(WGF`Q2r zugspo8Zn6MT@$`vC0i(ri_GEGD#1&X?^{p=_e#;O{x`VI{39UwwZ8gIHA0#E&n(r5 zSf6E%QdCBBQbLAZ4ia3TFd}xmIZIevFV??)1M~#womKMt9rbsy?lP%8Y8pX)ab<=< zY*V{T_aWDDvgTr3z9%s*MKxYuXQO*K#a(`$J0Q1TF+{8Z ziq4s}`^4%I%*9{SU94vZ-yIJz>5}BeG(%`@mH3^A1k7e~SjhCyv+BId@`w=R z&;C)(pk2ze?8QPgtI4x7=B&BS*?2|?Z~0KoMUmdj3U5m>PLn+hS&+rGDWTd=NZzka zEjsd>RE_>~3rfgWjdvV*?r!>rxGB&CHmHr(2h_aRWrvWy+;DiY!2tR66vdA^N1DGV z9bIdP)F0QHr+M6~P<|UO!{>JgNpnKSBI~EU)B}lmA^Lx_t3-}s4;G>+4^=P_RowqH zR&!K_+CvIfb~U3nlCaMOIrK8)xx$hC+qa58-1}4P7eVH0 z!~qxD+@WHRFY?Zu%-!t*D+HmhM&~`&tQwYuG#SHo>eI6JEAl$iYsFjZHvS7+17++q}nU!Ig`Kph)dg8f{B zc(#ia5JiKmDJU;%(7=OJb3o2rl>S7F;_Nk0jxTilSfaKvPK zx&JX+SL%zF?n14$ZL9Er$g56XTdgSk zTKzgYNp%GlS-jlR*uG2IeA%7M&T5MODyNw2Vm`WL zE*+XN=wS}0LRC~s+mDPPRJBtrws%b-5=XJCYG9#^jlsde3jg^8b%6;Uz>&( znpXwQj>6lc8%w7Rh>n!Juh|knyGt8lhl!Tek`A335r)QW$C-wR9uQ*9T$@&w0V-f`Fv)Z6(I``k;8}=zrQH} z;n-SPn$+`kznRNL{6{paU3XJGt>S;g zkCn2vRY!nwC>`97o@X6L(U)FAgS~6(V@m1KJkS+{5sO!6weg>@D)O*!I8ZQ90I0wJ znf0I|3Xd8E3aVc>Ie(A>eC|Zlj`x|J`Ut+MW^}2Q1SH6m6J14j70F|>CV2cU=io%B zLN`0OJ*Wr2llcaEdyjQ}AHQl*geA+%o1GketQQ{b6`p0j|K276iCaIBDAN4A*#Lvz z51)-XJIj+Tn8GsdQ-&b>0nS6%b;&30lewDmr_T9Tg z`(lu2SI0R9&P#?a97H8=F_9@UDz_{{oMmU!gq0TtLu_t6`nI47+E0luSN3Q$8#A9E zhR*l|#m9t|qYe#x`EQj1d7!0zH09ZPL_r`RF|5Wx?kJE`WqK-6ZIUg$_30#OH8e!p z=W47F;Y=-L75x@2;?bg<6TU`cwkM#|R9g6iNai_zhoeH=fqACd?y}jR`@Vp=s~Wdt_??x|KiYyCEri zdp=&iA_Vy{og#e3wTtA2d0U=>{!5+LPge-X+@T1P97p9GI*Zn*)|?0vTv2^Xu70QF zeM9KZ)(~rOGXlq*YuRJw{ zb{l0H^CqwrCa)3jv;+VOs00*&a0FK75ii`FuQFq2yre&zc!(bUj0AM6Nj^5Zw%~^?+G@KqMCbTl=y_BLcdOf|NWJ~<;M7#n}ztm`0u^_rThij z+9RG0kJw}~G0!tzkwf}t2CQs}yn|XNl^X{xE`6gul|1n@@_Nj2w{gqdQnjypQL`ZR zPJ;*H%$PDk1Ug>nd?IS;MR|(+Nf{pvbizisoE66#P|99%4aDModo~gXcFupaDvMnL@D8AJ*I9H^3?8DxA(a4^ zCGNE`RI8+!=IuQh9|h#tu&BAt=IVuNLAL!{`x;*kbc|z^%)wPR%OPQrs!X%rpd6^H z4|wiXgn4@NWK=vT%ec^2FmsfmZq0^rx!u-uug#Jh5@%K#&D>2eUrVF$R6zEbJJS>3 zxJp11#zc8idyT z+nb3qau;`KImN^dU=v=tvoK@L6*%61lm?66Ay zgQ84W4sg1a6OO=JbxC`Y?W@$eeVC_%y{W(H% z4RLr($EL#NjITafaSt=4lxpRr^c8&MhDiWZC@zE?GB=aAx%k%){hy(Ybaa%DgA1#a z11RftfkX1tnQo8kZJ5M}XRct9xu+MVU`1`1B$5JAfr5ThT@s+@n@zRL`EvG`kzjbu zvGrYJ$N})zDvu^;hxoR?j9pop*%He(=<*gH585NmkD{N#F4~oE;jJJdQWhOw_6LuI0=l@YeE||94Ck| zy_Gg?`@2f^H`=#h<6xBWr0}8ay~ikp$ut^gDCUSU_O^IVy70)VJgvapyHGEoUHlpg z?^|jVm96*%7n8V;^lRX1cL6QSunmlg-iCag@5*@^%_X)?Oc?3T+9s7h^F&k#dtWP_ zzi9PIydY7-_z;zplpz=z?I@IBQEK_H61f)t3e2!OJW5&6N#A_heMm9L32vcX8ZiIf~%mJa54Xk9>0-!T`N@1wnBVkmfrsj|Cwqlm>ptn zYJo+q-)085@Q)!R{Bcq1{BJEYFtx>xa}rTY1RNKInr%+NK4y6fHKgoNb`Ew<<5BS`(k%uFDPN=6d#pYe+l>;B|Ry&%WZSUvty=o|=wpK|R>A9@KO@JQE#M{qQR{Y&hd~O<6-d zGHR+~0$*gs{JvE%z;g0vw*F{J@l3y`7~KKg!9Q24r1URJHx<}OO+I~^?LMgk2hwQS za!Bg*r{TGi&O1E7Bi|95tc=NTJ}UsFx`k=Fc)3nUvl(ZrxA$nY=Z%+($`c+XI6`Kr zloecEBuy4R?G-c4&0_0#PGdYdrb6T)=beU>f)?c_RrOL@x13tj`dcfH@2X0ONoqdg zkD}Nlu{+Sj3Qg+Q6xpIIfB%UUOXkNBA~ERf!pY}?y|(3p9|t1tFfWn#(10#=)^fg3 z)q|mlinFFX=9(gM{3m>x0Iq;Jop!F`_=>}?8?@kt7Urmj zV@JQI`I3E+M@%f`Xg@?7@ZjodgDC5hO1#66o@_Ehwb8mLKN{XZWy7A zDu^}ie3-=Pp<{Hq&2T`e)32y(3rji1Vm#S+f43xd^04+=6&L)u_Ag7pxSKH7ldqrs zX{+{pvs1@tLr2_2>DbP$(Pq;0VNdt@gYN&EdgMP-zuHzJb^m8-bNytZ*>7MnJ*9#7 z^QSR{x1=~DN?FfqhjnAO00A~qQdt?1*S9LWlSFME3xug8O zT(@I2MZe%1kvO2{Jh1AdFs;C-gz-wuM^LB|M9uuVm@!;)D%1q)dgjv1x2Y$^zM?O# zyhNP`oE2Eb;=VCTq)I>TC0}54p+$K>%)lEUV14zg2o_7=YGWXOQnt$4Iak^W4}R#P)}n ze+A|sZSKxoua_-b;Q8qSupLi7R!cwM4q;6D<{b$O6GcFWxav~8NZH&)}^Haq^5 zUL+*=hP>|<+a}|+XdiR}bp1p;hpc2N0^y;M~Hy?w;FU}YK^Kwyc0oU0{8~k+L ztvc+NSbj{XG432O#1$elP0}3BteB$^R@)Z6>Z5@3y0wa;SCp zTlo8WgFEDJh}@Q_<}Hw;cvJv%^ZTI3-_tChv=a*m+qYK^UJVgFVx3Y)gInD&iOzav~k&q{2vRXn$V z=YCZ4iz(2oIIA8VW=z0_9Qc$t)M%AN-#Wc0U`q}UDDkuYfw};&A^xuSi{SzT;_W0| z_DG4@`T-GltEZTlW$;a#E0HBZBr-{DC>YSFp56+~zm`2iQNq z{%WVN0cbHEesRvl;b{rc4_xE`;3F|dirQS2X)7$2@*N?Ko^~tUxZ#HEwgN6?@*Tjj zoJ+BG+@$}q%O`0vEIl&x-ss8cM~SU|dN^y#$WX#(lRlRRK9{L|4?gPQthP)g0-Gkd zh_{%;{Az)L#H#+qIVqutWK&Fs$#lV*vIX2RCYBFyI`U&a!e%!GVcb$9+!sWAc`{>X z^X9k^j#4?t&LykKW7!OPJzx z{uDVfXXIk?7HJ7fpBrt2ofU3*jrOyq1$e=JMvv)j+-LH!F66K}O2)I0v2Sk?algG$ zAW0OP1rK(8%{_WUY758iJgErtNthzR?Td{>zdZ{B8Ui(eI_@j@Y-5LDFiGYY5f1U- zykPPf^saVs5tnSei}Cmw;&jKX5g#=hdjzzqKes*#Wk0rg8sVhp$_1k$MUfWA@Pjq9 z{ga=Y5(&)F557xG;UB67i&1Ia+vF67<|$rf8gDu?D?~5gud498yz&%lvodS?Lab3b zQhuE-m-)JkMoS$H2{HfT28WTp=dH&OA6*^K#NO?X3>*bBx}Jw-^7uViw8~1l_nSL% zzJZia#Bi`=scr0nHIIJ>mcymV#e2)z14~WED+I^CL6;FIIP2)D!l?h)!om{V$CV|4 zVxj<{*4Sl9?j{~SBYb@mqGX+|wv$=xN>wDwFO(=b?@RhzA*Wj<1goTK?r}qxwF)ZL zfp{;pXs(D(S>y#rI?5BVj+Tc82zHppa{Dqb73l0mR=(>H@_sW*#J*B zba77>H?Y*FnRIDifTJN7s)T$z8bi|Vem2Z5MF-q($P9a;u88Z=*pJ!fE3(?P*J|MX zH4tzeHhZB1HukBQpZ8v?NC>~8>q9>yiBTaBv3U0z2?oz_dv4{dy-frGL$+k&eJEG= z0)gO(!DGOCv4NJPgN*sg*Ok(c2+U1(CijHh{>wcIYX6dQFca)Qg(Wo<#lD@0%Op(R zeLpBc5J|mcXa5o)tOceW^798R(_htrAcuX7h)b#u9a(y;kbSUmk-`ty)F_(Z9%~Zs z9I0D#G1FtEc1aKDt@J6a+06k9^Zz?aOhXn|UyNAGwJ=l14ERb4>Y_gm2USkRymz%( zM_zB0oxnf43t3(ZnT}B4S=a)T?F7*lXF?D6=Go8gh^>J~v!W)BI`G{)sPgl&G9m+)H>W`C&A!YYKbsVL@t}F`H4M zMdbuwZk-w)kew*K6O5#z^X5raWG+`3?9ch5KAE}OlzZ(_YZ$b=fGfuKr_5Vvy1{vo2ubjGa-P2LRM?!y%W3l>s^vh8(r9EKe^aQO~0 zPDt3~jz`6WHj;^plw1WMri|V2`}1QeeK{?2fsBoq38lt_Epm)C=MB3IDi(LxhjLAa zv8=m^n)j|D#aLeOTEdf3`uWyV|8nnK>+phaI?fwAKsD;0_q%C&U{|?D$}Zuh8))ST zzxxC;n=@;A%D}wmU4=k&KQ)pI{Pww>Ty~Qy>1LkIh4QCzrcC=f!Q0=qn@+Sjz9-mp zT9;<_^{AWw>^-Mj%J35C&xBeSuK3LOBei!0ygJjil>^9QtfQDdWl9W*=tH|Y!Cn+5 zR;sxL-IoWI7t=Pocjz#{9aw9T%8Tb_c5zo@r{-prO~dOB#{IxCBYtG)=UEu9saM}ihb zdnSUNoCa!k^joHK_JY>WaeAaVnmd}NS?;{uZDQPCd|ulUBu2OB)ZM~azT6{sY#pVh z2|D*M+b!qhtZTUHwmzgVv7WdnuHhKmxngA~k6Nx!@g42bDMBJ-wtds_&djgUI)>W< zE_(C`L_YBwkvF#C(Es->NAlA)EBXKaDu;q1`0u>qe+n9k;=k^iEV)BR@xSR01%>rL wf&c3NWhQ5mV|IjLTGx{&c6eY~H^avM!{wMr@0C3L + + + @@ -246,6 +246,22 @@ type = 'PopUp' /> + + + + + + + + - + - + - + @@ -132,7 +132,7 @@ height = 'Globals.Button.Height' /> - + @@ -227,6 +227,22 @@ type = 'PopUp' /> + + + + + + + + pixels) return; + if (gfx->w > _w || gfx->h > _h) { + warning("GraphicsWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h); + return; + } + // TODO: add conversion to OverlayColor _gfx.copyFrom(*gfx); } @@ -596,7 +601,7 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) { _gfx.free(); _gfx.create(w, h, sizeof(OverlayColor)); - OverlayColor *dst = (OverlayColor*)_gfx.pixels; + OverlayColor *dst = (OverlayColor *)_gfx.pixels; Graphics::PixelFormat overlayFormat = g_system->getOverlayFormat(); OverlayColor fillCol = overlayFormat.RGBToColor(r, g, b); while (h--) { @@ -607,8 +612,12 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) { } void GraphicsWidget::drawWidget() { - if (sizeof(OverlayColor) == _gfx.bytesPerPixel && _gfx.pixels) - g_gui.theme()->drawSurface(Common::Rect(_x, _y, _x+_w, _y+_h), _gfx, _state, _alpha, _transparency); + if (sizeof(OverlayColor) == _gfx.bytesPerPixel && _gfx.pixels) { + const int x = _x + (_w - _gfx.w) / 2; + const int y = _y + (_h - _gfx.h) / 2; + + g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency); + } } #pragma mark - diff --git a/po/POTFILES b/po/POTFILES index d2afe71f539..dc0ce544b68 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -16,9 +16,18 @@ gui/ThemeEngine.cpp base/main.cpp common/error.cpp +common/util.cpp engines/dialogs.cpp -sound/mididrv.cpp +sound/fmopl.cpp +sound/musicplugin.cpp +sound/null.h +sound/null.cpp +sound/softsynth/adlib.cpp +sound/softsynth/mt32.cpp +sound/softsynth/pcspk.cpp +sound/softsynth/ym2612.cpp backends/keymapper/remap-dialog.cpp +backends/midi/windows.cpp diff --git a/po/module.mk b/po/module.mk index 93d8e26197d..89b968c570a 100644 --- a/po/module.mk +++ b/po/module.mk @@ -32,11 +32,12 @@ updatepot: mv -f $@.new $@; \ fi; -$(srcdir)/common/messages.cpp: $(POFILES) - perl $(srcdir)/tools/po2c $^ > $(srcdir)/common/messages.cpp +#$(srcdir)/common/messages.cpp: $(POFILES) +# perl $(srcdir)/tools/po2c $^ > $(srcdir)/common/messages.cpp -update-translations: updatepot $(POFILES) $(srcdir)/common/messages.cpp +update-translations: updatepot $(POFILES) @$(foreach file, $(POFILES), echo -n $(notdir $(basename $(file)))": ";msgfmt --statistic $(file);) @rm -f messages.mo + perl $(srcdir)/tools/po2c $(POFILES) > $(srcdir)/common/messages.cpp .PHONY: updatepot update-translations diff --git a/ports.mk b/ports.mk index b8b3b01b932..ff63c3a83cd 100644 --- a/ports.mk +++ b/ports.mk @@ -120,6 +120,7 @@ residual-static: $(OBJS) -framework CoreMIDI \ $(OSX_STATIC_LIBS) \ $(OSX_ZLIB) \ + $(OSX_ICONV) \ -lSystemStubs # Special target to create a static linked binary for the iPhone diff --git a/sound/decoders/vorbis.cpp b/sound/decoders/vorbis.cpp index 332ee1baf19..7e883f3eda6 100644 --- a/sound/decoders/vorbis.cpp +++ b/sound/decoders/vorbis.cpp @@ -35,7 +35,7 @@ #include "sound/audiocd.h" #ifdef USE_TREMOR -#if defined(ANDROID) || defined(__GP32__) // custom libtremor locations +#if defined(__GP32__) // custom libtremor locations #include #else #include diff --git a/sound/fmopl.cpp b/sound/fmopl.cpp index 49b6f7ee431..f0340e7d50b 100644 --- a/sound/fmopl.cpp +++ b/sound/fmopl.cpp @@ -28,6 +28,7 @@ #include "sound/softsynth/opl/mame.h" #include "common/config-manager.h" +#include "common/translation.h" namespace OPL { @@ -47,9 +48,9 @@ OPL::OPL() { const Config::EmulatorDescription Config::_drivers[] = { { "auto", "", kAuto, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 }, - { "mame", "MAME OPL emulator", kMame, kFlagOpl2 }, + { "mame", _s("MAME OPL emulator"), kMame, kFlagOpl2 }, #ifndef DISABLE_DOSBOX_OPL - { "db", "DOSBox OPL emulator", kDOSBox, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 }, + { "db", _s("DOSBox OPL emulator"), kDOSBox, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 }, #endif { 0, 0, 0, 0 } }; diff --git a/sound/mididrv.cpp b/sound/mididrv.cpp index 6e511067cc4..fa5a7e552be 100644 --- a/sound/mididrv.cpp +++ b/sound/mididrv.cpp @@ -27,96 +27,10 @@ #include "common/config-manager.h" #include "common/str.h" #include "common/system.h" -#include "common/translation.h" #include "common/util.h" #include "sound/mididrv.h" - -static const uint32 GUIOMapping[] = { - MDT_PCSPK, Common::GUIO_MIDIPCSPK, - MDT_CMS, Common::GUIO_MIDICMS, - MDT_PCJR, Common::GUIO_MIDIPCJR, - MDT_ADLIB, Common::GUIO_MIDIADLIB, - MDT_TOWNS, Common::GUIO_MIDITOWNS, - MDT_MIDI, Common::GUIO_MIDI, - 0, 0 -}; - -uint32 MidiDriver::midiDriverFlags2GUIO(uint32 flags) { - uint32 res = 0; - - for (int i = 0; GUIOMapping[i] || GUIOMapping[i + 1]; i += 2) { - if (flags & GUIOMapping[i]) - res |= GUIOMapping[i + 1]; - } - - return res; -} - -/** Internal list of all available 'midi' drivers. */ -static const MidiDriverDescription s_musicDrivers[] = { - - // The flags for the "auto" & "null" drivers indicate that they are anything - // you want it to be. - {"auto", _s(""), MD_AUTO, MDT_MIDI | MDT_PCSPK | MDT_ADLIB | MDT_TOWNS}, - {"null", _s("No music"), MD_NULL, MDT_MIDI | MDT_PCSPK | MDT_ADLIB | MDT_TOWNS}, - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - {"windows", _s("Windows MIDI"), MD_WINDOWS, MDT_MIDI}, -#endif - -#if defined(UNIX) && defined(USE_ALSA) - {"alsa", _s("ALSA"), MD_ALSA, MDT_MIDI}, -#endif - -#if defined(__MINT__) - {"stmidi", _s("Atari ST MIDI"), MD_STMIDI, MDT_MIDI}, -#endif - -#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOSX) && !defined(__MAEMO__) && !defined(__MINT__) - {"seq", _s("SEQ"), MD_SEQ, MDT_MIDI}, -#endif - -#if defined(IRIX) - {"dmedia", _s("DMedia"), MD_DMEDIA, MDT_MIDI}, -#endif - -#if defined(__amigaos4__) - {"camd", _s("CAMD"), MD_CAMD, MDT_MIDI}, -#endif - -#if defined(MACOSX) - {"core", _s("CoreAudio"), MD_COREAUDIO, MDT_MIDI}, -// {"coreaudio", "CoreAudio", MD_COREAUDIO, MDT_MIDI}, - {"coremidi", _s("CoreMIDI"), MD_COREMIDI, MDT_MIDI}, -#endif - -#if defined(PALMOS_MODE) -# if defined(COMPILE_CLIE) - {"ypa1", _s("Yamaha Pa1"), MD_YPA1, MDT_MIDI}, -# elif defined(COMPILE_ZODIAC) && (!defined(ENABLE_SCUMM) || !defined(PALMOS_ARM)) - {"zodiac", _s("Tapwave Zodiac"), MD_ZODIAC, MDT_MIDI}, -# endif -#endif - -#ifdef USE_FLUIDSYNTH - {"fluidsynth", _s("FluidSynth"), MD_FLUIDSYNTH, MDT_MIDI}, -#endif -#ifdef USE_MT32EMU - {"mt32", _s("MT-32 Emulation"), MD_MT32, MDT_MIDI}, -#endif - - // The flags for the "adlib" driver indicates that it can do AdLib and MIDI. - {"adlib", _s("AdLib"), MD_ADLIB, MDT_ADLIB}, - {"pcspk", _s("PC Speaker"), MD_PCSPK, MDT_PCSPK}, - {"pcjr", _s("IBM PCjr"), MD_PCJR, MDT_PCSPK | MDT_PCJR}, - {"cms", _s("Creative Music System"), MD_CMS, MDT_CMS}, - {"towns", _s("FM Towns"), MD_TOWNS, MDT_TOWNS}, -#if defined(UNIX) - {"timidity", _s("TiMidity"), MD_TIMIDITY, MDT_MIDI}, -#endif - - {0, 0, MD_NULL, MDT_NONE} -}; +#include "sound/musicplugin.h" +#include "common/translation.h" const byte MidiDriver::_mt32ToGm[128] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F @@ -142,169 +56,221 @@ const byte MidiDriver::_gmToMt32[128] = { 101, 103, 100, 120, 117, 113, 99, 128, 128, 128, 128, 124, 123, 128, 128, 128, // 7x }; -const MidiDriverDescription *MidiDriver::getAvailableMidiDrivers() { - return s_musicDrivers; +static const uint32 GUIOMapping[] = { + MT_PCSPK, Common::GUIO_MIDIPCSPK, + /*MDT_CMS, Common::GUIO_MIDICMS,*/ + MT_PCJR, Common::GUIO_MIDIPCJR, + MT_ADLIB, Common::GUIO_MIDIADLIB, + MT_TOWNS, Common::GUIO_MIDITOWNS, + MT_GM, Common::GUIO_MIDIGM, + MT_MT32, Common::GUIO_MIDIMT32, + 0, 0 +}; + +uint32 MidiDriver::musicType2GUIO(uint32 musicType) { + uint32 res = 0; + + for (int i = 0; GUIOMapping[i] || GUIOMapping[i + 1]; i += 2) { + if (musicType == GUIOMapping[i] || musicType == (uint32)-1) + res |= GUIOMapping[i + 1]; + } + + return res; } -const MidiDriverDescription *MidiDriver::findMusicDriver(const Common::String &str) { - if (str.empty()) - return 0; +bool MidiDriver::_forceTypeMT32 = false; - const char *s = str.c_str(); - int len = 0; - const MidiDriverDescription *md = s_musicDrivers; +MusicType MidiDriver::getMusicType(MidiDriver::DeviceHandle handle) { + if (_forceTypeMT32) + return MT_MT32; - // Scan for string end or a colon - while (s[len] != 0 && s[len] != ':') - len++; - - while (md->name) { - // Compare the string passed to us with the current table entry. - // We ignore any characters following an (optional) colon ':' - // contained in str. - if (!strncasecmp(md->name, s, len)) { - return md; + if (handle) { + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (handle == d->getHandle()) + return d->getMusicType(); + } + } + } + + return MT_INVALID; +} + +Common::String MidiDriver::getDeviceString(DeviceHandle handle, DeviceStringType type) { + if (handle) { + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (handle == d->getHandle()) { + if (type == kDriverName) + return d->getMusicDriverName(); + else if (type == kDriverId) + return d->getMusicDriverId(); + else if (type == kDeviceId) + return d->getCompleteId(); + else + return Common::String("auto"); + } + } + } + } + + return Common::String("auto"); +} + +MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { + // Query the selected music device (defaults to MT_AUTO device). + DeviceHandle hdl = getDeviceHandle(ConfMan.get("music_driver")); + + _forceTypeMT32 = false; + + // Check whether the selected music driver is compatible with the + // given flags. + switch (getMusicType(hdl)) { + case MT_PCSPK: + if (flags & MDT_PCSPK) + return hdl; + break; + + case MT_PCJR: + if (flags & MDT_PCJR) + return hdl; + break; + + case MT_CMS: + if (flags & MDT_CMS) + return hdl; + break; + + case MT_ADLIB: + if (flags & MDT_ADLIB) + return hdl; + break; + + case MT_TOWNS: + if (flags & MDT_TOWNS) + return hdl; + break; + + case MT_PC98: + if (flags & MDT_PC98) + return hdl; + break; + + case MT_GM: + case MT_GS: + case MT_MT32: + if (flags & MDT_MIDI) + return hdl; + break; + + case MT_NULL: + return hdl; + + default: + break; + } + + // If the selected driver did not match the flags setting, + // we try to determine a suitable and "optimal" music driver. + const MusicPlugin::List p = MusicMan.getPlugins(); + // If only MDT_MIDI but not MDT_PREFER_MT32 or MDT_PREFER_GM is set we prefer the other devices (which will always be + // detected since they are hard coded and cannot be disabled. + for (int l = (flags & (MDT_PREFER_GM | MDT_PREFER_MT32)) ? 1 : 0; l < 2; ++l) { + if ((flags & MDT_MIDI) && (l == 1)) { + // If a preferred MT32 or GM device has been selected that device gets returned + if (flags & MDT_PREFER_MT32) + hdl = getDeviceHandle(ConfMan.get("mt32_device")); + else if (flags & MDT_PREFER_GM) + hdl = getDeviceHandle(ConfMan.get("gm_device")); + else + hdl = getDeviceHandle("auto"); + + const MusicType type = getMusicType(hdl); + if (type != MT_AUTO && type != MT_INVALID) { + if (flags & MDT_PREFER_MT32) + // If we have a preferred MT32 device we disable the gm/mt32 mapping (more about this in mididrv.h) + _forceTypeMT32 = true; + + return hdl; + } + + // If we have no specific device selected (neither in the scummvm nor in the game domain) + // and no preferred MT32 or GM device selected we arrive here. + // If MT32 is preferred we try for the first available device with music type 'MT_MT32' (usually the mt32 emulator) + if (flags & MDT_PREFER_MT32) { + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getMusicType() == MT_MT32) + return d->getHandle(); + } + } + } + + // Now we default to the first available device with music type 'MT_GM' + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getMusicType() == MT_GM || d->getMusicType() == MT_GS) + return d->getHandle(); + } + } + } + + MusicType tp = MT_AUTO; + if (flags & MDT_TOWNS) + tp = MT_TOWNS; + else if (flags & MDT_ADLIB) + tp = MT_ADLIB; + else if (flags & MDT_PCSPK) + tp = MT_PCSPK; + else if (l == 0) + // if we haven't tried to find a MIDI device yet we do this now. + continue; + else + tp = MT_AUTO; + + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getMusicType() == tp) + return d->getHandle(); + } } - md++; } return 0; } -static MidiDriverType getDefaultMIDIDriver() { -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - return MD_WINDOWS; -#elif defined(MACOSX) - return MD_COREAUDIO; -#elif defined(PALMOS_MODE) - #if defined(COMPILE_CLIE) - return MD_YPA1; - #elif defined(COMPILE_ZODIAC) - return MD_ZODIAC; - #else - return MD_NULL; - #endif -#else - return MD_NULL; -#endif +MidiDriver *MidiDriver::createMidi(MidiDriver::DeviceHandle handle) { + MidiDriver *driver = 0; + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + if (getDeviceString(handle, MidiDriver::kDriverId).equals((**m)->getId())) + (**m)->createInstance(&driver, handle); + } + + return driver; } -MidiDriverType MidiDriver::parseMusicDriver(const Common::String &str) { - const MidiDriverDescription *md = findMusicDriver(str); - if (md) - return md->id; - return MD_AUTO; -} +MidiDriver::DeviceHandle MidiDriver::getDeviceHandle(const Common::String &identifier) { + const MusicPlugin::List p = MusicMan.getPlugins(); -MidiDriverType MidiDriver::detectMusicDriver(int flags) { - MidiDriverType musicDriver; + if (p.begin() == p.end()) + error("Music plugins must be loaded prior to calling this method."); - // Query the selected music driver (defaults to MD_AUTO). - const MidiDriverDescription *md = findMusicDriver(ConfMan.get("music_driver")); - - // Check whether the selected music driver is compatible with the - // given flags. - if (!md || !(md->flags & flags)) - musicDriver = MD_AUTO; - else - musicDriver = md->id; - - // If the selected driver is MD_AUTO, we try to determine - // a suitable and "optimal" music driver. - if (musicDriver == MD_AUTO) { - - if (flags & MDT_PREFER_MIDI) { - // A MIDI music driver is preferred. Of course this implies - // that MIDI is actually listed in flags, so we verify that. - assert(flags & MDT_MIDI); - - // Query the default MIDI driver. It's possible that there - // is none, in which case we revert to AUTO mode. - musicDriver = getDefaultMIDIDriver(); - if (musicDriver == MD_NULL) - musicDriver = MD_AUTO; - } - - if (musicDriver == MD_AUTO) { - // MIDI is not preferred, or no default MIDI device is available. - // In this case we first try the alternate drivers before checking - // for a 'real' MIDI driver. - - if (flags & MDT_TOWNS) - musicDriver = MD_TOWNS; - else if (flags & MDT_ADLIB) - musicDriver = MD_ADLIB; - else if (flags & MDT_PCSPK) - musicDriver = MD_PCJR; - else if (flags & MDT_MIDI) - musicDriver = getDefaultMIDIDriver(); - else - musicDriver = MD_NULL; + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (identifier.equals(d->getCompleteId()) || identifier.equals(d->getCompleteName())) { + return d->getHandle(); + } } } - return musicDriver; -} - -MidiDriver *MidiDriver::createMidi(MidiDriverType midiDriver) { - switch (midiDriver) { - case MD_NULL: return MidiDriver_NULL_create(); - - case MD_ADLIB: return MidiDriver_ADLIB_create(); - - case MD_TOWNS: return MidiDriver_YM2612_create(); - - // Right now PC Speaker and PCjr are handled - // outside the MidiDriver architecture, so - // don't create anything for now. - case MD_PCSPK: - case MD_CMS: - case MD_PCJR: return NULL; - -#ifdef USE_FLUIDSYNTH - case MD_FLUIDSYNTH: return MidiDriver_FluidSynth_create(); -#endif - -#ifdef USE_MT32EMU - case MD_MT32: return MidiDriver_MT32_create(); -#endif - -#if defined(PALMOS_MODE) -#if defined(COMPILE_CLIE) - case MD_YPA1: return MidiDriver_YamahaPa1_create(); -#elif defined(COMPILE_ZODIAC) && (!defined(ENABLE_SCUMM) || !defined(PALMOS_ARM)) - case MD_ZODIAC: return MidiDriver_Zodiac_create(); -#endif -#endif - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - case MD_WINDOWS: return MidiDriver_WIN_create(); -#endif -#if defined(__MINT__) - case MD_STMIDI: return MidiDriver_STMIDI_create(); -#endif -#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOSX) && !defined(__MAEMO__) && !defined(__MINT__) - case MD_SEQ: return MidiDriver_SEQ_create(); -#endif -#if defined(UNIX) - case MD_TIMIDITY: return MidiDriver_TIMIDITY_create(); -#endif -#if defined(IRIX) - case MD_DMEDIA: return MidiDriver_DMEDIA_create(); -#endif -#if defined(MACOSX) - case MD_COREAUDIO: return MidiDriver_CORE_create(); - case MD_COREMIDI: return MidiDriver_CoreMIDI_create(); -#endif -#if defined(UNIX) && defined(USE_ALSA) - case MD_ALSA: return MidiDriver_ALSA_create(); -#endif -#if defined(__amigaos4__) - case MD_CAMD: return MidiDriver_CAMD_create(); -#endif - default: - error("Invalid midi driver selected"); - } - - return NULL; + return 0; } diff --git a/sound/mididrv.h b/sound/mididrv.h index 619560541b4..3defc2a6b56 100644 --- a/sound/mididrv.h +++ b/sound/mididrv.h @@ -30,6 +30,8 @@ #include "common/timer.h" class MidiChannel; +class MusicDevice; + namespace Audio { class Mixer; } @@ -43,56 +45,32 @@ namespace Common { class String; } * * @todo Rename MidiDriverType to MusicDriverType */ -enum MidiDriverType { - // Pseudo drivers - MD_AUTO, - MD_NULL, - // Windows - MD_WINDOWS, - - // Atari ST - MD_STMIDI, - - // Linux - MD_ALSA, - MD_SEQ, - - // Mac OS X - MD_QTMUSIC, - MD_COREAUDIO, - MD_COREMIDI, - - // PalmOS - MD_YPA1, - MD_ZODIAC, - - // IRIX - MD_DMEDIA, - - // AMIGAOS4 - MD_CAMD, - - // MIDI softsynths - MD_FLUIDSYNTH, - MD_MT32, - - // "Fake" MIDI devices - MD_ADLIB, - MD_PCSPK, - MD_CMS, - MD_PCJR, - MD_TOWNS, - MD_TIMIDITY +/** + * Music types that music drivers can implement and engines can rely on. + */ +enum MusicType { + MT_INVALID = -1, // Invalid output + MT_AUTO = 0, // Auto + MT_NULL, // Null + MT_PCSPK, // PC Speaker + MT_PCJR, // PCjr + MT_CMS, // CMS + MT_ADLIB, // AdLib + MT_TOWNS, // FM-TOWNS + MT_PC98, // PC98 + MT_GM, // General MIDI + MT_MT32, // MT-32 + MT_GS // Roland GS }; /** - * A set of flags to be passed to detectMusicDriver() which can be used to + * A set of flags to be passed to detectDevice() which can be used to * specify what kind of music driver is preferred / accepted. * - * The flags (except for MDT_PREFER_MIDI) indicate whether a given driver + * The flags (except for MDT_PREFER_MT32 and MDT_PREFER_GM) indicate whether a given driver * type is acceptable. E.g. the TOWNS music driver could be returned by - * detectMusicDriver if and only if MDT_TOWNS is specified. + * detectDevice if and only if MDT_TOWNS is specified. * * @todo Rename MidiDriverFlags to MusicDriverFlags */ @@ -101,10 +79,12 @@ enum MidiDriverFlags { MDT_PCSPK = 1 << 0, // PC Speaker: Maps to MD_PCSPK and MD_PCJR MDT_CMS = 1 << 1, // Creative Music System / Gameblaster: Maps to MD_CMS MDT_PCJR = 1 << 2, // Tandy/PC Junior driver - MDT_ADLIB = 1 << 3, // AdLib: Maps to MD_ADLIB - MDT_TOWNS = 1 << 4, // FM-TOWNS: Maps to MD_TOWNS - MDT_MIDI = 1 << 5, // Real MIDI - MDT_PREFER_MIDI = 1 << 6 // Real MIDI output is preferred + MDT_ADLIB = 1 << 3, // AdLib: Maps to MT_ADLIB + MDT_TOWNS = 1 << 4, // FM-TOWNS: Maps to MT_TOWNS + MDT_PC98 = 1 << 5, // FM-TOWNS: Maps to MT_PC98 + MDT_MIDI = 1 << 6, // Real MIDI + MDT_PREFER_MT32 = 1 << 7, // MT-32 output is preferred + MDT_PREFER_GM = 1 << 8 // GM output is preferred }; /** @@ -114,12 +94,6 @@ enum MidiDriverFlags { * * @todo Rename MidiDriverType to MusicDriverType */ -struct MidiDriverDescription { - const char *name; - const char *description; - MidiDriverType id; // A unique ID for each driver - int flags; // Capabilities of this driver -}; /** * Abstract MIDI Driver Class @@ -128,24 +102,45 @@ struct MidiDriverDescription { */ class MidiDriver { public: - /** Find the music driver matching the given driver name/description. */ - static const MidiDriverDescription *findMusicDriver(const Common::String &str); - - /** Get the id of the music driver matching the given driver name, or MD_AUTO if there is no match. */ - static MidiDriverType parseMusicDriver(const Common::String &str); - - static uint32 midiDriverFlags2GUIO(uint32 flags); - /** - * Get a list of all available MidiDriver types. - * @return list of all available midi drivers, terminated by a zero entry + * The device handle. + * + * The value 0 is reserved for an invalid device for now. + * TODO: Maybe we should use -1 (i.e. 0xFFFFFFFF) as + * invalid device? */ - static const MidiDriverDescription *getAvailableMidiDrivers(); + typedef uint32 DeviceHandle; - static MidiDriver *createMidi(MidiDriverType midiDriver); + enum DeviceStringType { + kDriverName, + kDriverId, + kDeviceId + }; - static MidiDriverType detectMusicDriver(int flags); + static uint32 musicType2GUIO(uint32 musicType); + /** Create music driver matching the given device handle, or NULL if there is no match. */ + static MidiDriver *createMidi(DeviceHandle handle); + + /** Returns device handle based on the present devices and the flags parameter. */ + static DeviceHandle detectDevice(int flags); + + /** Find the music driver matching the given driver name/description. */ + static DeviceHandle getDeviceHandle(const Common::String &identifier); + + /** Get the music type matching the given device handle, or MT_AUTO if there is no match. */ + static MusicType getMusicType(DeviceHandle handle); + + /** Get the device description string matching the given device handle and the given type. */ + static Common::String getDeviceString(DeviceHandle handle, DeviceStringType type); + +private: + // If detectDevice() detects MT32 and we have a preferred MT32 device + // we use this to force getMusicType() to return MT_MT32 so that we don't + // have to rely on the 'True Roland MT-32' config manager setting (since nobody + // would possibly think about activating 'True Roland MT-32' when he has set + // 'Music Driver' to '') + static bool _forceTypeMT32; public: virtual ~MidiDriver() { } @@ -274,28 +269,4 @@ public: virtual void sysEx_customInstrument(uint32 type, const byte *instr) = 0; }; - -// Factory functions, for faster compile -extern MidiDriver *MidiDriver_NULL_create(); -extern MidiDriver *MidiDriver_ADLIB_create(); -extern MidiDriver *MidiDriver_WIN_create(); -extern MidiDriver *MidiDriver_STMIDI_create(); -extern MidiDriver *MidiDriver_SEQ_create(); -extern MidiDriver *MidiDriver_TIMIDITY_create(); -extern MidiDriver *MidiDriver_QT_create(); -extern MidiDriver *MidiDriver_CORE_create(); -extern MidiDriver *MidiDriver_CoreMIDI_create(); -extern MidiDriver *MidiDriver_ALSA_create(); -extern MidiDriver *MidiDriver_DMEDIA_create(); -extern MidiDriver *MidiDriver_CAMD_create(); -extern MidiDriver *MidiDriver_YM2612_create(); -#ifdef USE_FLUIDSYNTH -extern MidiDriver *MidiDriver_FluidSynth_create(); -#endif -#ifdef USE_MT32EMU -extern MidiDriver *MidiDriver_MT32_create(); -#endif -extern MidiDriver *MidiDriver_YamahaPa1_create(); -extern MidiDriver *MidiDriver_Zodiac_create(); - #endif diff --git a/sound/midiparser.cpp b/sound/midiparser.cpp index 5c56a2fdd63..d54a85e7331 100644 --- a/sound/midiparser.cpp +++ b/sound/midiparser.cpp @@ -333,7 +333,7 @@ void MidiParser::hangAllActiveNotes() { uint32 advance_tick = _position._last_event_tick; while (true) { - int i, j; + int i; for (i = 0; i < 128; ++i) if (temp_active[i] != 0) break; @@ -349,7 +349,7 @@ void MidiParser::hangAllActiveNotes() { } else if (_next_event.event == 0xFF && _next_event.ext.type == 0x2F) { // warning("MidiParser::hangAllActiveNotes(): Hit End of Track with active notes left"); for (i = 0; i < 128; ++i) { - for (j = 0; j < 16; ++j) { + for (int j = 0; j < 16; ++j) { if (temp_active[i] & (1 << j)) { activeNote(j, i, false); sendToDriver(0x80 | j, i, 0); diff --git a/sound/musicplugin.cpp b/sound/musicplugin.cpp index d108dbac6d9..56360b011c2 100644 --- a/sound/musicplugin.cpp +++ b/sound/musicplugin.cpp @@ -24,10 +24,12 @@ */ #include "sound/musicplugin.h" +#include "common/hash-str.h" +#include "common/translation.h" MusicDevice::MusicDevice(MusicPluginObject const *musicPlugin, Common::String name, MusicType mt) : - _musicDriverName(musicPlugin->getName()), _musicDriverId(musicPlugin->getId()), - _name(name), _type(mt) { + _musicDriverName(_(musicPlugin->getName())), _musicDriverId(musicPlugin->getId()), + _name(_(name)), _type(mt) { } Common::String MusicDevice::getCompleteName() { @@ -46,3 +48,17 @@ Common::String MusicDevice::getCompleteName() { return name; } + +Common::String MusicDevice::getCompleteId() { + Common::String id = _musicDriverId; + if (!_name.empty()) { + id += "_"; + id += _name; + } + + return id; +} + +MidiDriver::DeviceHandle MusicDevice::getHandle() { + return (MidiDriver::DeviceHandle)Common::hashit(getCompleteId().c_str()); +} diff --git a/sound/musicplugin.h b/sound/musicplugin.h index c3706dfbda9..1b6199aee83 100644 --- a/sound/musicplugin.h +++ b/sound/musicplugin.h @@ -29,19 +29,6 @@ #include "sound/mididrv.h" #include "common/list.h" -/** - * Music types that music drivers can implement and engines can rely on. - */ -enum MusicType { - MT_PCSPK = 1, // PC Speaker - MT_PCJR = 2, // PCjr - MT_ADLIB = 3, // AdLib - MT_TOWNS = 4, // FM-TOWNS - MT_GM = 5, // General MIDI - MT_MT32 = 6, // MT-32 - MT_GS = 7 // Roland GS -}; - class MusicPluginObject; /** @@ -63,6 +50,14 @@ public: * device name (if it isn't the default one) and the name of the driver. */ Common::String getCompleteName(); + + /** + * Returns a user readable string that contains the name of the current + * device name (if it isn't the default one) and the id of the driver. + */ + Common::String getCompleteId(); + + MidiDriver::DeviceHandle getHandle(); private: Common::String _name; @@ -94,15 +89,18 @@ public: virtual MusicDevices getDevices() const = 0; /** - * Tries to instantiate a MIDI Driver instance based on the settings of - * the currently active ConfMan target. That is, the MusicPluginObject - * should query the ConfMan singleton for the device name, port, etc. + * Tries to instantiate a MIDI Driver instance based on the device + * previously detected via MidiDriver::detectDevice() * * @param mididriver Pointer to a pointer which the MusicPluginObject sets * to the newly create MidiDriver, or 0 in case of an error + * + * @param dev Pointer to a device to be used then creating the driver instance. + * Default value of zero for driver types without devices. + * * @return a Common::Error describing the error which occurred, or kNoError */ - virtual Common::Error createInstance(MidiDriver **mididriver) const = 0; + virtual Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const = 0; }; diff --git a/sound/null.cpp b/sound/null.cpp index 71b2fc6856d..cc615fd8cbb 100644 --- a/sound/null.cpp +++ b/sound/null.cpp @@ -22,34 +22,9 @@ * $Id$ */ -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "sound/null.h" -/* NULL driver */ -class MidiDriver_NULL : public MidiDriver_MPU401 { -public: - int open() { return 0; } - void send(uint32 b) { } -}; - - -// Plugin interface - -class NullMusicPlugin : public MusicPluginObject { -public: - const char *getName() const { - return "No music"; - } - - const char *getId() const { - return "null"; - } - - MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; -}; - -Common::Error NullMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error NullMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_NULL(); return Common::kNoError; @@ -57,28 +32,31 @@ Common::Error NullMusicPlugin::createInstance(MidiDriver **mididriver) const { MusicDevices NullMusicPlugin::getDevices() const { MusicDevices devices; - // TODO: return a different music type? - devices.push_back(MusicDevice(this, "", MT_GM)); + devices.push_back(MusicDevice(this, "", MT_NULL)); return devices; } -MidiDriver *MidiDriver_NULL_create() { - MidiDriver *mididriver; +class AutoMusicPlugin : public NullMusicPlugin { +public: + const char *getName() const { + return _s(""); + } - NullMusicPlugin p; - p.createInstance(&mididriver); + const char *getId() const { + return "auto"; + } + MusicDevices getDevices() const; +}; - return mididriver; +MusicDevices AutoMusicPlugin::getDevices() const { + MusicDevices devices; + devices.push_back(MusicDevice(this, "", MT_AUTO)); + return devices; } -#ifdef DISABLE_ADLIB -MidiDriver *MidiDriver_ADLIB_create() { - return MidiDriver_NULL_create(); -} -#endif - //#if PLUGIN_ENABLED_DYNAMIC(NULL) //REGISTER_PLUGIN_DYNAMIC(NULL, PLUGIN_TYPE_MUSIC, NullMusicPlugin); //#else + REGISTER_PLUGIN_STATIC(AUTO, PLUGIN_TYPE_MUSIC, AutoMusicPlugin); REGISTER_PLUGIN_STATIC(NULL, PLUGIN_TYPE_MUSIC, NullMusicPlugin); //#endif diff --git a/sound/null.h b/sound/null.h new file mode 100644 index 00000000000..cc806a4c770 --- /dev/null +++ b/sound/null.h @@ -0,0 +1,56 @@ +/* Residual - A 3D game interpreter + * + * Residual is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the AUTHORS + * 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$ + */ + +#ifndef SOUND_NULL_H +#define SOUND_NULL_H + +#include "sound/musicplugin.h" +#include "sound/mpu401.h" +#include "common/translation.h" + +/* NULL driver */ +class MidiDriver_NULL : public MidiDriver_MPU401 { +public: + int open() { return 0; } + void send(uint32 b) { } +}; + + +// Plugin interface + +class NullMusicPlugin : public MusicPluginObject { +public: + virtual const char *getName() const { + return _s("No music"); + } + + virtual const char *getId() const { + return "null"; + } + + virtual MusicDevices getDevices() const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; +}; + +#endif diff --git a/sound/rate_arm_asm.s b/sound/rate_arm_asm.s index 24c1cf12fd5..e285f7062fe 100644 --- a/sound/rate_arm_asm.s +++ b/sound/rate_arm_asm.s @@ -212,9 +212,6 @@ SimpleRate_M_end: SimpleRate_M_read: LDR r0, [r13,#8] @ r0 = sr (8 = 4*2) ADD r0, r0, #16 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf @@ -229,9 +226,6 @@ SimpleRate_M_read: SUBS r1, r0, #1 @ r1 = inLen-1 LDMFD r13!,{r0,r2-r3,r12,r14} BLT SimpleRate_M_end - .ifdef PALMOS_MODE - MOV r10,#0 - .endif SUBS r2, r2, #1 @ r2 = opos-- ADDGE r0, r0, #2 @ if (r2 >= 0) { sr.inPtr++ BGE SimpleRate_M_loop @ and loop } @@ -297,9 +291,6 @@ SimpleRate_S_end: SimpleRate_S_read: LDR r0, [r13,#8] @ r0 = sr (8 = 4*2) ADD r0, r0, #16 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5) @@ -313,9 +304,6 @@ SimpleRate_S_read: SUBS r1, r0, #2 @ r1 = inLen-2 LDMFD r13!,{r0,r2-r3,r12,r14} BLT SimpleRate_S_end - .ifdef PALMOS_MODE - MOV r10,#0 - .endif SUBS r2, r2, #1 @ r2 = opos-- ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2 BGE SimpleRate_S_loop @ and loop } @@ -382,9 +370,6 @@ SimpleRate_R_end: SimpleRate_R_read: LDR r0, [r13,#8] @ r0 = sr (8 = 4*2) ADD r0, r0, #16 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf @@ -399,9 +384,6 @@ SimpleRate_R_read: SUBS r1, r0, #2 @ r1 = inLen-2 LDMFD r13!,{r0,r2-r3,r12,r14} BLT SimpleRate_R_end - .ifdef PALMOS_MODE - MOV r10,#0 - .endif SUBS r2, r2, #1 @ r2 = opos-- ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2 BGE SimpleRate_R_loop @ and loop } @@ -484,9 +466,6 @@ LinearRate_M_end: LDMFD r13!,{r4-r11,PC} LinearRate_M_read: ADD r0, r2, #28 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf @@ -501,9 +480,6 @@ LinearRate_M_read: SUBS r1, r0, #1 @ r1 = inLen-1 LDMFD r13!,{r0,r2-r3,r12,r14} BLT LinearRate_M_end - .ifdef PALMOS_MODE - MOV r10,#0 - .endif B LinearRate_M_read_return _ARM_LinearRate_S: @@ -592,9 +568,6 @@ LinearRate_S_end: LDMFD r13!,{r4-r11,PC} LinearRate_S_read: ADD r0, r2, #28 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf @@ -697,9 +670,6 @@ LinearRate_R_end: LDMFD r13!,{r4-r11,PC} LinearRate_R_read: ADD r0, r2, #28 @ r0 = inPtr = inBuf - .ifdef PALMOS_MODE - LDR r10,[r13,#4*8] @ restore r10 - .endif STMFD r13!,{r0,r2-r3,r12,r14} MOV r1, r0 @ r1 = inBuf diff --git a/sound/softsynth/adlib.cpp b/sound/softsynth/adlib.cpp index edbfc17f2c5..b14951d9463 100644 --- a/sound/softsynth/adlib.cpp +++ b/sound/softsynth/adlib.cpp @@ -27,6 +27,7 @@ #include "common/util.h" #include "sound/fmopl.h" #include "sound/musicplugin.h" +#include "common/translation.h" #ifdef DEBUG_ADLIB static int tick; @@ -1586,7 +1587,7 @@ void MidiDriver_ADLIB::adlib_note_on(int chan, byte note, int mod) { class AdLibEmuMusicPlugin : public MusicPluginObject { public: const char *getName() const { - return "AdLib Emulator"; + return _s("AdLib Emulator"); } const char *getId() const { @@ -1594,7 +1595,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices AdLibEmuMusicPlugin::getDevices() const { @@ -1603,21 +1604,12 @@ MusicDevices AdLibEmuMusicPlugin::getDevices() const { return devices; } -Common::Error AdLibEmuMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error AdLibEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_ADLIB(g_system->getMixer()); return Common::kNoError; } -MidiDriver *MidiDriver_ADLIB_create() { - MidiDriver *mididriver; - - AdLibEmuMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(ADLIB) //REGISTER_PLUGIN_DYNAMIC(ADLIB, PLUGIN_TYPE_MUSIC, AdLibEmuMusicPlugin); //#else diff --git a/sound/softsynth/fluidsynth.cpp b/sound/softsynth/fluidsynth.cpp index a1a12ed3f37..809aebc1ba8 100644 --- a/sound/softsynth/fluidsynth.cpp +++ b/sound/softsynth/fluidsynth.cpp @@ -230,7 +230,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices FluidSynthMusicPlugin::getDevices() const { @@ -239,21 +239,12 @@ MusicDevices FluidSynthMusicPlugin::getDevices() const { return devices; } -Common::Error FluidSynthMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error FluidSynthMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_FluidSynth(g_system->getMixer()); return Common::kNoError; } -MidiDriver *MidiDriver_FluidSynth_create() { - MidiDriver *mididriver; - - FluidSynthMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(FLUIDSYNTH) //REGISTER_PLUGIN_DYNAMIC(FLUIDSYNTH, PLUGIN_TYPE_MUSIC, FluidSynthMusicPlugin); //#else diff --git a/sound/softsynth/mt32.cpp b/sound/softsynth/mt32.cpp index 3d1516de963..b3c7514323e 100644 --- a/sound/softsynth/mt32.cpp +++ b/sound/softsynth/mt32.cpp @@ -39,6 +39,7 @@ #include "common/system.h" #include "common/util.h" #include "common/archive.h" +#include "common/translation.h" #include "graphics/fontman.h" #include "graphics/surface.h" @@ -166,7 +167,7 @@ static void drawProgress(float progress) { // TODO implement in Residual //screen->fillRect(r, col); - //g_system->copyRectToScreen((byte *)surf.pixels, surf.pitch, x, y, surf.w, surf.h); + //g_system->unlockScreen(); //g_system->updateScreen(); } @@ -326,7 +327,7 @@ int MidiDriver_MT32::open() { } _initialising = true; - drawMessage(-1, "Initialising MT-32 Emulator"); + drawMessage(-1, _s("Initialising MT-32 Emulator")); if (!_synth->open(prop)) return MERR_DEVICE_NOT_AVAILABLE; _initialising = false; @@ -541,7 +542,7 @@ void MidiDriver_ThreadedMT32::onTimer() { class MT32EmuMusicPlugin : public MusicPluginObject { public: const char *getName() const { - return "MT-32 Emulator"; + return _s("MT-32 Emulator"); } const char *getId() const { @@ -549,7 +550,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices MT32EmuMusicPlugin::getDevices() const { @@ -558,23 +559,13 @@ MusicDevices MT32EmuMusicPlugin::getDevices() const { return devices; } -Common::Error MT32EmuMusicPlugin::createInstance(MidiDriver **mididriver) const { - *mididriver = new MidiDriver_MT32(g_system->getMixer()); - - return Common::kNoError; -} - -MidiDriver *MidiDriver_MT32_create() { - // HACK: It will stay here until engine plugin loader overhaul +Common::Error MT32EmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { if (ConfMan.hasKey("extrapath")) SearchMan.addDirectory("extrapath", ConfMan.get("extrapath")); - MidiDriver *mididriver; + *mididriver = new MidiDriver_MT32(g_system->getMixer()); - MT32EmuMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; + return Common::kNoError; } //#if PLUGIN_ENABLED_DYNAMIC(MT32) diff --git a/sound/softsynth/opl/mame.cpp b/sound/softsynth/opl/mame.cpp index 529552e03ae..79a5803aec3 100644 --- a/sound/softsynth/opl/mame.cpp +++ b/sound/softsynth/opl/mame.cpp @@ -33,7 +33,7 @@ #include "mame.h" -#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__) +#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__) #include "common/config-manager.h" #endif @@ -1212,7 +1212,7 @@ FM_OPL *makeAdLibOPL(int rate) { // We need to emulate one YM3812 chip int env_bits = FMOPL_ENV_BITS_HQ; int eg_ent = FMOPL_EG_ENT_HQ; -#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__) +#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__) || defined(__N64__) if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) { env_bits = FMOPL_ENV_BITS_HQ; eg_ent = FMOPL_EG_ENT_HQ; diff --git a/sound/softsynth/pcspk.cpp b/sound/softsynth/pcspk.cpp index 911a6623647..052c8fbaba6 100644 --- a/sound/softsynth/pcspk.cpp +++ b/sound/softsynth/pcspk.cpp @@ -24,6 +24,7 @@ */ #include "sound/softsynth/pcspk.h" +#include "sound/null.h" namespace Audio { @@ -128,3 +129,59 @@ int8 PCSpeaker::generateTriangle(uint32 x, uint32 oscLength) { } } // End of namespace Audio + + +// Plugin interface +// (This can only create a null driver since pc speaker support is not part of the +// midi driver architecture. But we need the plugin for the options menu in the launcher +// and for MidiDriver::detectDevice() which is more or less used by all engines.) + +class PCSpeakerMusicPlugin : public NullMusicPlugin { +public: + const char *getName() const { + return _s("PC Speaker Emulator"); + } + + const char *getId() const { + return "pcspk"; + } + + MusicDevices getDevices() const; +}; + +MusicDevices PCSpeakerMusicPlugin::getDevices() const { + MusicDevices devices; + devices.push_back(MusicDevice(this, "", MT_PCSPK)); + return devices; +} + +class PCjrMusicPlugin : public NullMusicPlugin { +public: + const char *getName() const { + return _s("IBM PCjr Emulator"); + } + + const char *getId() const { + return "pcjr"; + } + + MusicDevices getDevices() const; +}; + +MusicDevices PCjrMusicPlugin::getDevices() const { + MusicDevices devices; + devices.push_back(MusicDevice(this, "", MT_PCJR)); + return devices; +} + +//#if PLUGIN_ENABLED_DYNAMIC(PCSPK) + //REGISTER_PLUGIN_DYNAMIC(PCSPK, PLUGIN_TYPE_MUSIC, PCSpeakerMusicPlugin); +//#else + REGISTER_PLUGIN_STATIC(PCSPK, PLUGIN_TYPE_MUSIC, PCSpeakerMusicPlugin); +//#endif + +//#if PLUGIN_ENABLED_DYNAMIC(PCJR) + //REGISTER_PLUGIN_DYNAMIC(PCJR, PLUGIN_TYPE_MUSIC, PCjrMusicPlugin); +//#else + REGISTER_PLUGIN_STATIC(PCJR, PLUGIN_TYPE_MUSIC, PCjrMusicPlugin); +//#endif diff --git a/sound/softsynth/ym2612.cpp b/sound/softsynth/ym2612.cpp index c135af09e13..d8aad99c9d6 100644 --- a/sound/softsynth/ym2612.cpp +++ b/sound/softsynth/ym2612.cpp @@ -27,6 +27,7 @@ #include "sound/softsynth/ym2612.h" #include "common/util.h" #include "sound/musicplugin.h" +#include "common/translation.h" //////////////////////////////////////// // @@ -758,7 +759,7 @@ void MidiDriver_YM2612::removeLookupTables() { class TownsEmuMusicPlugin : public MusicPluginObject { public: const char *getName() const { - return "FM Towns Emulator"; + return _s("FM Towns Emulator"); } const char *getId() const { @@ -766,7 +767,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices TownsEmuMusicPlugin::getDevices() const { @@ -775,21 +776,12 @@ MusicDevices TownsEmuMusicPlugin::getDevices() const { return devices; } -Common::Error TownsEmuMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error TownsEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_YM2612(g_system->getMixer()); return Common::kNoError; } -MidiDriver *MidiDriver_YM2612_create() { - MidiDriver *mididriver; - - TownsEmuMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(TOWNS) //REGISTER_PLUGIN_DYNAMIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin); //#else