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 616c1b122ab..7ef38caa533 100644 Binary files a/gui/themes/modern.zip and b/gui/themes/modern.zip differ diff --git a/gui/themes/modern/modern_gfx.stx b/gui/themes/modern/modern_gfx.stx index 9d94aaba312..258e90dff58 100644 --- a/gui/themes/modern/modern_gfx.stx +++ b/gui/themes/modern/modern_gfx.stx @@ -106,16 +106,28 @@ + + + @@ -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