diff options
178 files changed, 14852 insertions, 8160 deletions
@@ -339,6 +339,12 @@ Other contributions Russian: Eugene Sandulenko + Spanish: + Tomas Maidagan + + Ukrainian: + Lubomyr Lisen + Websites (design) ----------------- Dobo Balazs - Website design diff --git a/backends/audiocd/audiocd.h b/backends/audiocd/audiocd.h index 70eabf650b..5ea5bfcfd4 100644 --- a/backends/audiocd/audiocd.h +++ b/backends/audiocd/audiocd.h @@ -27,6 +27,7 @@ #define BACKENDS_AUDIOCD_ABSTRACT_H #include "common/noncopyable.h" +#include "common/scummsys.h" /** * Abstract Audio CD manager class. Subclasses implement the actual @@ -45,6 +46,8 @@ public: int start; int duration; int numLoops; + int volume; + int balance; }; /** @@ -72,6 +75,16 @@ public: virtual bool isPlaying() const = 0; /** + * Set the audio volume + */ + virtual void setVolume(byte volume) = 0; + + /** + * Set the speakers balance + */ + virtual void setBalance(int8 balance) = 0; + + /** * Stop CD or emulated audio playback. */ virtual void stop() = 0; diff --git a/backends/audiocd/default/default-audiocd.cpp b/backends/audiocd/default/default-audiocd.cpp index 0e7dc66ba1..56e737d359 100644 --- a/backends/audiocd/default/default-audiocd.cpp +++ b/backends/audiocd/default/default-audiocd.cpp @@ -33,6 +33,8 @@ DefaultAudioCDManager::DefaultAudioCDManager() { _cd.start = 0; _cd.duration = 0; _cd.numLoops = 0; + _cd.volume = Audio::Mixer::kMaxChannelVolume; + _cd.balance = 0; _mixer = g_system->getMixer(); _emulating = false; assert(_mixer); @@ -70,7 +72,7 @@ void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int du */ _emulating = true; _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, - Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops)); + Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance); } else { _emulating = false; if (!only_emulate) @@ -100,6 +102,38 @@ bool DefaultAudioCDManager::isPlaying() const { } } +void DefaultAudioCDManager::setVolume(byte volume) { + _cd.volume = volume; + if (_emulating) { + // Audio CD emulation + if (_mixer->isSoundHandleActive(_handle)) + _mixer->setChannelVolume(_handle, _cd.volume); + } else { + // Real Audio CD + + // Unfortunately I can't implement this atm + // since SDL doesn't seem to offer an interface method for this. + + // g_system->setVolumeCD(_cd.volume); + } +} + +void DefaultAudioCDManager::setBalance(int8 balance) { + _cd.balance = balance; + if (_emulating) { + // Audio CD emulation + if (isPlaying()) + _mixer->setChannelBalance(_handle, _cd.balance); + } else { + // Real Audio CD + + // Unfortunately I can't implement this atm + // since SDL doesn't seem to offer an interface method for this. + + // g_system->setBalanceCD(_cd.balance); + } +} + void DefaultAudioCDManager::update() { if (_emulating) { // Check whether the audio track stopped playback diff --git a/backends/audiocd/default/default-audiocd.h b/backends/audiocd/default/default-audiocd.h index ec209d9eb5..3f9df0bbbb 100644 --- a/backends/audiocd/default/default-audiocd.h +++ b/backends/audiocd/default/default-audiocd.h @@ -40,6 +40,8 @@ public: void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false); void stop(); bool isPlaying() const; + void setVolume(byte volume); + void setBalance(int8 balance); void update(); virtual Status getStatus() const; // Subclasses should override for better status results diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index fac50178b4..eedf75c256 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -205,7 +205,6 @@ CXX = arm-eabi-g++ LD = arm-eabi-g++ CFLAGS = -Wno-multichar -Wall\ - -Wno-multichar -mcpu=arm9tdmi -mtune=arm9tdmi \ -mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer\ -mthumb-interwork -DUSE_ARM_COSTUME_ASM=1 -DDISABLE_SID @@ -281,7 +280,6 @@ PORT_OBJS := \ $(portdir)/source/blitters_arm.o \ $(portdir)/source/cdaudio.o \ $(portdir)/source/dsmain.o \ - $(portdir)/../../../fs/ds/ds-fs.o \ $(portdir)/source/gbampsave.o \ $(portdir)/source/scummhelp.o \ $(portdir)/source/osystem_ds.o \ @@ -297,14 +295,14 @@ ifdef USE_PROFILER endif -DATA_OBJS := +DATA_OBJS := \ $(portdir)/data/icons.o \ $(portdir)/data/keyboard.o \ $(portdir)/data/keyboard_pal.o \ $(portdir)/data/default_font.o \ $(portdir)/data/8x8font_tga.o -FAT_OBJS := +FAT_OBJS := \ $(portdir)/source/fat/disc_io.o \ $(portdir)/source/fat/gba_nds_fat.o \ $(portdir)/source/fat/io_fcsr.o \ diff --git a/backends/platform/ds/arm9/source/portdefs.h b/backends/platform/ds/arm9/source/portdefs.h index bdb42993d1..cc38d66a73 100644 --- a/backends/platform/ds/arm9/source/portdefs.h +++ b/backends/platform/ds/arm9/source/portdefs.h @@ -26,6 +26,9 @@ #ifndef _PORTDEFS_H_ #define _PORTDEFS_H_ +// Include ndstypes.h for uint16 etc. typedefs +#include "nds/ndstypes.h" + // Somebody removed these from scummsys.h, but they're still required, so I'm // adding them here in the hope that they'll stay. #include <stdio.h> @@ -49,6 +52,7 @@ #define STREAM_AUDIO_FROM_DISK #endif +// FIXME: What is "NO_DEBUG_MSGS" good for? #define NO_DEBUG_MSGS // This is defined in dsmain.cpp @@ -65,16 +69,22 @@ void consolePrintf(const char *format, ...); #undef assert #endif +#ifdef NDEBUG + +#define assert(e) ((void)0) + +#else + +// FIXME: Shouldn't assert() also bail out / exit / halt the program? Right now we just +// print an error message... #define assert(s) \ do { \ - if (!(s)) \ + if (!(s)) { \ consolePrintf("Assertion failed: '##s##' at file %s, line %d\n", __FILE__, __LINE__); \ + } \ } while (0) -//#include "ds-fs.h" - -//#define debug(fmt, ...) consolePrintf(fmt, ##__VA_ARGS__) -//#define debug(fmt, ...) debug(0, fmt, ##__VA_ARGS__) +#endif // FIXME: Since I can't change the engine at the moment (post lockdown) this define can go here. // This define changes the mouse-relative motion which doesn't make sense on a touch screen to diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk index 97f104c391..a9ed3e0096 100644 --- a/backends/platform/ds/ds.mk +++ b/backends/platform/ds/ds.mk @@ -75,7 +75,7 @@ endif # Compiler options for files which should be optimised for speed -OPT_SPEED := -O3 +OPT_SPEED := -O3 -mno-thumb # Compiler options for files which should be optimised for space OPT_SIZE := -Os -mthumb @@ -83,31 +83,46 @@ OPT_SIZE := -Os -mthumb # By default optimize for size CXXFLAGS += $(OPT_SIZE) -# Files listed below will be optimisied for speed, otherwise they will be optimised for space -# TODO: speed original list contained three more files that should be optimized -# for speed: actor.cpp gfx.cpp sprite.cpp -- but there are many files with these -# names, which are the "right" ones? +# Files listed below will be optimisied for speed, otherwise they will be optimised for space. +# TODO: Several of these files probably should not be optimized for speed, but for now +# we replicate the *precise* list from the old DS makefile, to ensure full compatibility. +# Eventually, we should tune this list. +$(ndsdir)/arm9/source/blitters.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) $(ndsdir)/arm9/source/dsmain.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) $(ndsdir)/arm9/source/osystem_ds.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -$(ndsdir)/arm9/source/blitters.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -$(ndsdir)/arm9/source/ds_main.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/saga/isomap.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +base/main.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) sound/rate.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/saga/actor_walk.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +sound/softsynth/opl/mame.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/agi/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/agos/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/agos/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/cine/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/cruise/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/cruise/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/draci/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/draci/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/gob/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/groovie/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/kyra/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/m4/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/m4/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/m4/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/made/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) engines/saga/actor_path.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/saga/image.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -sound/fmopl.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/saga/actor_walk.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) engines/saga/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/scumm/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/m4/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/scumm/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/cine/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/agos/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) engines/saga/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/saga/image.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/saga/isomap.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/saga/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) engines/saga/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/m4/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -engines/agi/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) -# TODO: Fingolfin says: optimizing staticres for size would +engines/sci/engine/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/scumm/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/scumm/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/scumm/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/sword2/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +engines/teenagent/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) +# TODO: Fingolfin says: optimizing kyra/staticres.o for size would # save about 30k, so maybe consider that? #engines/kyra/staticres.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED) diff --git a/backends/platform/ds/setup-builddirs.sh b/backends/platform/ds/setup-builddirs.sh new file mode 100755 index 0000000000..11aacc1233 --- /dev/null +++ b/backends/platform/ds/setup-builddirs.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# TODO: Allow specifying (a list of) build ids (a, b, ...) on the command line. +# TODO: Allow overriding the LOGO variable + +# TODO: Computer srcdir in a better way +srcdir=../../../`dirname $0`/.. + +BASE_PARAM="--host=ds --disable-translation --disable-debug --disable-all-engines" + +for build in a b c d e f g h i k; do + echo "--- Setting up build $build ---" + mkdir -p build-$build && cd build-$build + case $build in + a) + EXTRA_PARAM="--enable-scumm" + ;; + b) + EXTRA_PARAM="--enable-sky --enable-queen" + ;; + c) + EXTRA_PARAM="--enable-agos" + ;; + d) + EXTRA_PARAM="--enable-gob --enable-cine --enable-agi" + ;; + e) + EXTRA_PARAM="--enable-saga --disable-mad" + ;; + f) + EXTRA_PARAM="--enable-kyra --disable-mad" + ;; + g) + EXTRA_PARAM="--enable-lure" + ;; + h) + EXTRA_PARAM="--enable-parallaction" + ;; + i) + EXTRA_PARAM="--enable-made --disable-mad" + ;; + k) + EXTRA_PARAM="--enable-cruise --disable-mad" + ;; + *) + echo "Invalid build $build selected" + exit 1 + ;; + esac + + defname="DS_BUILD_`echo $build | tr '[a-z]' '[A-Z]'`" + CPPFLAGS="$CPPFLAGS -D$defname" + $srcdir/configure $BASE_PARAM $EXTRA_PARAM + cd .. + echo DONE + echo +done diff --git a/backends/platform/iphone/iphone_video.m b/backends/platform/iphone/iphone_video.m index faa0719b6c..cd8b38acb3 100644 --- a/backends/platform/iphone/iphone_video.m +++ b/backends/platform/iphone/iphone_video.m @@ -276,7 +276,7 @@ uint getSizeNextPOT(uint size) { glGenTextures(1, &_screenTexture); glBindTexture(GL_TEXTURE_2D, _screenTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (_textureBuffer) { free(_textureBuffer); diff --git a/backends/platform/n64/README.N64 b/backends/platform/n64/README.N64 index 1cdd82e1e9..276436b676 100644 --- a/backends/platform/n64/README.N64 +++ b/backends/platform/n64/README.N64 @@ -13,6 +13,8 @@ Requirements Build cart images from sources ============================== +You can download hkz-libn64 sources from here: http://hkzlab.ipv7.net/consoles.html +hkz-libn64 is a library to control Nintendo64 hardware (es, video, audio, input, etc.). * TODO * Build cart images from binaries diff --git a/backends/platform/n64/module.mk b/backends/platform/n64/module.mk index 8fb6ba49ab..429b63802e 100644 --- a/backends/platform/n64/module.mk +++ b/backends/platform/n64/module.mk @@ -1,7 +1,12 @@ MODULE := backends/platform/n64 MODULE_OBJS := \ - nintendo64.o + nintendo64.o \ + osys_n64_base.o \ + osys_n64_events.o \ + osys_n64_utilities.o \ + pakfs_save_manager.o \ + framfs_save_manager.o # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) diff --git a/backends/platform/psp/audio.cpp b/backends/platform/psp/audio.cpp index bf1fb9ab41..e540733162 100644 --- a/backends/platform/psp/audio.cpp +++ b/backends/platform/psp/audio.cpp @@ -28,7 +28,6 @@ #include "common/scummsys.h" #include "backends/platform/psp/audio.h" -#include "backends/platform/psp/thread.h" //#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */ //#define __PSP_DEBUG_PRINT__ /* For debug printouts */ @@ -85,43 +84,13 @@ bool PspAudio::open(uint32 freq, uint32 numOfChannels, uint32 numOfSamples, call _init = true; _paused = true; // start in paused mode - createThread(); + threadCreateAndStart("audioThread", PRIORITY_AUDIO_THREAD, STACK_AUDIO_THREAD); // start the consumer thread return true; } -bool PspAudio::createThread() { - DEBUG_ENTER_FUNC(); - int threadId = sceKernelCreateThread("audioThread", thread, PRIORITY_AUDIO_THREAD, STACK_AUDIO_THREAD, THREAD_ATTR_USER, 0); - - if (threadId < 0) { // error - PSP_ERROR("failed to create audio thread. Error code %d\n", threadId); - return false; - } - - PspAudio *_this = this; // trick to get into context when the thread starts - - if (sceKernelStartThread(threadId, sizeof(uint32 *), &_this) < 0) { - PSP_ERROR("failed to start thread %d\n", threadId); - return false; - } - - PSP_DEBUG_PRINT("created audio thread[%x]\n", threadId); - - return true; -} - -// Static function to be called upon thread startup. Will call a non-static function -int PspAudio::thread(SceSize, void *__this) { - DEBUG_ENTER_FUNC(); - PspAudio *_this = *(PspAudio **)__this; // get our this for the context - - _this->audioThread(); - return 0; -}; - // The real thread function -void PspAudio::audioThread() { +void PspAudio::threadFunction() { assert(_callback); PSP_DEBUG_PRINT_FUNC("audio thread started\n"); @@ -129,15 +98,15 @@ void PspAudio::audioThread() { if (_paused) PSP_DEBUG_PRINT("audio thread paused\n"); while (_paused) { // delay until we stop pausing - sceKernelDelayThread(100000); // 100ms + PspThread::delayMicros(100000); // 100ms if (!_paused) PSP_DEBUG_PRINT("audio thread unpaused\n"); } - PSP_DEBUG_PRINT("remaining samples[%d]\n", remainingSamples); + PSP_DEBUG_PRINT("remaining samples[%d]\n", _remainingSamples); PSP_DEBUG_PRINT("filling buffer[%d]\n", _bufferToFill); - _callback(_userData, _buffers[_bufferToFill], _bufferSize); // ask mixer to fill in + _callback(_userData, _buffers[_bufferToFill], _bufferSize); // ask mixer to fill in data nextBuffer(_bufferToFill); PSP_DEBUG_PRINT("playing buffer[%d].\n", _bufferToPlay); @@ -151,7 +120,7 @@ void PspAudio::audioThread() { PSP_DEBUG_PRINT("audio thread exiting. ****************************\n"); } -// Much faster than using % +// Much faster than using %, especially with conditional moves (MIPS) inline void PspAudio::nextBuffer(int &bufferIdx) { DEBUG_ENTER_FUNC(); bufferIdx++; @@ -176,6 +145,6 @@ inline bool PspAudio::playBuffer() { } void PspAudio::close() { - PSP_DEBUG_PRINT("close had been called ***************\n"); + PSP_DEBUG_PRINT("close has been called ***************\n"); _init = false; } diff --git a/backends/platform/psp/audio.h b/backends/platform/psp/audio.h index 603f8f6bfc..eeba598fed 100644 --- a/backends/platform/psp/audio.h +++ b/backends/platform/psp/audio.h @@ -26,13 +26,15 @@ #ifndef PSP_AUDIO_H #define PSP_AUDIO_H -class PspAudio { +#include "backends/platform/psp/thread.h" + +class PspAudio : public PspThreadable { public: enum { NUM_BUFFERS = 2, FREQUENCY = 44100 /* only frequency we allow */ }; - typedef void (* callbackFunc)(void *userData, byte *samples, int len); + typedef void (* callbackFunc)(void *userData, byte *samples, int len); // audio callback to call PspAudio() : _pspChannel(0), _numOfChannels(0), _numOfSamples(0), _callback(0), _bufferToPlay(0), _bufferToFill(0), @@ -43,14 +45,12 @@ public: ~PspAudio() { close(); } bool playBuffer(); void nextBuffer(int &bufferIdx); - static int thread(SceSize, void *); - void audioThread(); bool open(uint32 freq, uint32 numOfChannels, uint32 numOfSamples, callbackFunc callback, void *userData); - bool createThread(); void close(); uint32 getFrequency() { return FREQUENCY; } void pause() { _paused = true; } void unpause() { _paused = false; } + virtual void threadFunction(); // actual audio thread private: int _pspChannel; // chosen hardware output channel diff --git a/backends/platform/psp/display_manager.cpp b/backends/platform/psp/display_manager.cpp index a9f33f6091..5037543f12 100644 --- a/backends/platform/psp/display_manager.cpp +++ b/backends/platform/psp/display_manager.cpp @@ -34,7 +34,6 @@ #include "backends/platform/psp/default_display_client.h" #include "backends/platform/psp/cursor.h" #include "backends/platform/psp/pspkeyboard.h" -#include "backends/platform/psp/thread.h" #define USE_DISPLAY_CALLBACK // to use callback for finishing the render #include "backends/platform/psp/display_manager.h" @@ -65,37 +64,24 @@ const OSystem::GraphicsMode DisplayManager::_supportedModes[] = { void MasterGuRenderer::setupCallbackThread() { DEBUG_ENTER_FUNC(); - int thid = sceKernelCreateThread("displayCbThread", guCallbackThread, PRIORITY_DISPLAY_THREAD, STACK_DISPLAY_THREAD, THREAD_ATTR_USER, 0); - PSP_DEBUG_PRINT("Display CB thread id is %x\n", thid); - - // We want to pass the pointer to this, but we'll have to take address of this so use a little trick - MasterGuRenderer *_this = this; - - if (thid >= 0) { - sceKernelStartThread(thid, sizeof(uint32 *), &_this); - } else - PSP_ERROR("failed to create display callback thread\n"); + // start the thread that updates the display + threadCreateAndStart("DisplayCbThread", PRIORITY_DISPLAY_THREAD, STACK_DISPLAY_THREAD); } -// thread that reacts to the callback -int MasterGuRenderer::guCallbackThread(SceSize, void *__this) { +// this function gets called by PspThread when starting the new thread +void MasterGuRenderer::threadFunction() { DEBUG_ENTER_FUNC(); - // Dereferenced the copied value which was this - MasterGuRenderer *_this = *(MasterGuRenderer **)__this; - // Create the callback. It should always get the pointer to MasterGuRenderer - _this->_callbackId = sceKernelCreateCallback("Display Callback", guCallback, _this); - if (_this->_callbackId < 0) { - PSP_ERROR("failed to create display callback\n"); - return -1; + _callbackId = sceKernelCreateCallback("Display Callback", guCallback, this); + if (_callbackId < 0) { + PSP_ERROR("failed to create display callback\n"); } PSP_DEBUG_PRINT("created callback. Going to sleep\n"); - sceKernelSleepThreadCB(); // sleep until we get a callback - return 0; + sceKernelSleepThreadCB(); // sleep until we get a callback } // This callback is called when the render is finished. It swaps the buffers diff --git a/backends/platform/psp/display_manager.h b/backends/platform/psp/display_manager.h index dbbdf2022c..1f7320902c 100644 --- a/backends/platform/psp/display_manager.h +++ b/backends/platform/psp/display_manager.h @@ -26,10 +26,12 @@ #ifndef PSP_DISPLAY_MAN_H #define PSP_DISPLAY_MAN_H +#include "backends/platform/psp/thread.h" + /** * Class used only by DisplayManager to start/stop GU rendering */ -class MasterGuRenderer { +class MasterGuRenderer : public PspThreadable { public: MasterGuRenderer() : _lastRenderTime(0), _renderFinished(true), _callbackId(-1) {} void guInit(); @@ -37,15 +39,15 @@ public: void guPostRender(); void guShutDown(); bool isRenderFinished() { return _renderFinished; } - void setupCallbackThread(); + void setupCallbackThread(); private: + virtual void threadFunction(); // for the display callback thread static uint32 _displayList[]; uint32 _lastRenderTime; // For measuring rendering time void guProgramDisplayBufferSizes(); - static int guCallbackThread(SceSize, void *); // for the graphics callbacks - static int guCallback(int, int, void *__this); + static int guCallback(int, int, void *__this); // for the display callback bool _renderFinished; // for sync with render callback - int _callbackId; // to keep track of render callback + int _callbackId; // to keep track of render callback }; class Screen; diff --git a/backends/platform/psp/memory.cpp b/backends/platform/psp/memory.cpp index 8eef223f8c..29d0482d9a 100644 --- a/backends/platform/psp/memory.cpp +++ b/backends/platform/psp/memory.cpp @@ -39,9 +39,17 @@ extern "C" { +#ifdef TEST_MEMORY_COPY /* we won't be able to run in this case b/c of printouts */ +extern void *__real_memcpy(void *dst, void *src, size_t bytes); +#endif + void *__wrap_memcpy(void *dst, void *src, size_t bytes) { +#ifdef TEST_MEMORY_COPY /* we won't be able to run in this case */ + return __real_memcpy(dst, src, bytes); +#else PspMemory::fastCopy((byte *)dst, (byte *)src, bytes); return dst; +#endif } } @@ -291,43 +299,31 @@ void PspMemory::copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, u PSP_DEBUG_PRINT("copy32Misaligned: dst32[%p], src[%p], bytes[%d], alignSrc[%d]\n", dst32, src, bytes, alignSrc); uint32 *src32 = (uint32 *)(((uint32)src) & 0xFFFFFFFC); // remove misalignment - uint32 offset; + uint32 shiftValue, lastShiftValue; switch (alignSrc) { case 1: - offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 8, 24); + shiftValue = 8; + lastShiftValue = 24; break; case 2: - offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 16, 16); + shiftValue = 16; + lastShiftValue = 16; break; default: /* 3 */ - offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 24, 8); + shiftValue = 24; + lastShiftValue = 8; break; } - - uint32 remainingBytes = bytes & 3; - - if (remainingBytes) { - byte *dst = (byte *)dst32; - src += offset; - dst += offset; - copy8(dst, src, remainingBytes); - } -} -// returns offset in dst -uint32 PspMemory::misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue) { - uint32 *origDst32 = dst32; - register uint32 dstWord, srcWord; - - PSP_DEBUG_PRINT("misaligned32Detail(): alignSrc[%d], dst32[%p], src32[%p], bytes[%d]\n", alignSrc, dst32, src32, bytes); - + uint32 dstWord, srcWord; + // Try to do groups of 4 words uint32 words4 = bytes >> 4; - srcWord = src32[0]; - - while (words4--) { + srcWord = *src32; // preload 1st word so we read ahead + + for (; words4; words4--) { dstWord = srcWord >> shiftValue; srcWord = src32[1]; dstWord |= srcWord << lastShiftValue; @@ -348,22 +344,29 @@ uint32 PspMemory::misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, dst32 += 4; } - uint32 words = (bytes & 0xF) >> 2; + uint32 words = (bytes & 0xF) >> 2; // now get remaining words // we read one word ahead of what we write // setup the first read - if (words) { - src32++; // we already loaded the value, so just increment + + for (; words ;words--) { + dstWord = srcWord >> shiftValue; + srcWord = src32[1]; // we still go one ahead + src32++; + dstWord |= srcWord << lastShiftValue; + *dst32++ = dstWord; + } + + uint32 bytesLeft = bytes & 3; // and remaining bytes - while (words--) { - dstWord = srcWord >> shiftValue; - srcWord = *src32++; - dstWord |= srcWord << lastShiftValue; - *dst32++ = dstWord; + if (bytesLeft) { + byte *dst8 = (byte *)dst32; + byte *src8 = ((byte *)src32) + ((uint32)src & 0x3); // get exact location we should be at + + for(; bytesLeft; bytesLeft--) { + *dst8++ = *src8++; } } - - return (byte *)dst32 - (byte *)origDst32; } // More challenging -- need to shift diff --git a/backends/platform/psp/memory.h b/backends/platform/psp/memory.h index c9b3d21cb6..793bc94888 100644 --- a/backends/platform/psp/memory.h +++ b/backends/platform/psp/memory.h @@ -52,7 +52,6 @@ private: static void copy32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes); static void swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format); static void copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, uint32 alignSrc); - static uint32 misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue); static void swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format); static void copy16(uint16 *dst, const uint16 *src, uint32 bytes); diff --git a/backends/platform/psp/thread.cpp b/backends/platform/psp/thread.cpp index c19ff5f9e3..916b1e553b 100644 --- a/backends/platform/psp/thread.cpp +++ b/backends/platform/psp/thread.cpp @@ -28,7 +28,50 @@ #include "backends/platform/psp/thread.h" #include "backends/platform/psp/trace.h" -// Class PspThread -------------------------------------------------- +// Class PspThreadable -------------------------------------------------- +// Inherit this to create C++ threads easily + +bool PspThreadable::threadCreateAndStart(const char *threadName, int priority, int stackSize, bool useVfpu /*= false*/) { + DEBUG_ENTER_FUNC(); + + if (_threadId != -1) { + PSP_ERROR("thread already created!\n"); + return false; + } + + _threadId = sceKernelCreateThread(threadName, __threadCallback, priority, stackSize, THREAD_ATTR_USER, 0); // add VFPU support + + if (_threadId < 0) { + PSP_ERROR("failed to create %s thread. Error code %d\n", threadName, _threadId); + return false; + } + + // We want to pass the pointer to this, but we'll have to take address of this so use a little trick + PspThreadable *_this = this; + + if (sceKernelStartThread(_threadId, sizeof(uint32 *), &_this) < 0) { + PSP_ERROR("failed to start %s thread id[%d]\n", threadName, _threadId); + return false; + } + + PSP_DEBUG_PRINT("Started %s thread with id[%x]\n", threadName, _threadId); + + return true; +} + +// Callback function to be called by PSP kernel +int PspThreadable::__threadCallback(SceSize, void *__this) { + DEBUG_ENTER_FUNC(); + + PspThreadable *_this = *(PspThreadable **)__this; // Dereference the copied value which was 'this' + + _this->threadFunction(); // call the virtual function + + return 0; +} + +// PspThread class +// Utilities to access general thread functions void PspThread::delayMillis(uint32 ms) { sceKernelDelayThread(ms * 1000); diff --git a/backends/platform/psp/thread.h b/backends/platform/psp/thread.h index 27d53903d6..de1c10a2aa 100644 --- a/backends/platform/psp/thread.h +++ b/backends/platform/psp/thread.h @@ -26,11 +26,26 @@ #ifndef PSP_THREAD_H #define PSP_THREAD_H +#include <pspthreadman.h> #include "common/scummsys.h" +// class to inherit for creating threads +class PspThreadable { +protected: + int _threadId; + virtual void threadFunction() = 0; // this function will be called when the thread starts +public: + PspThreadable() : _threadId(-1) {} // constructor + virtual ~PspThreadable() {} // destructor + static int __threadCallback(SceSize, void *__this); // used to get called by sceKernelStartThread() Don't override + bool threadCreateAndStart(const char *threadName, int priority, int stackSize, bool useVfpu = false); +}; + +// class for thread utils class PspThread { -public: - static void delayMillis(uint32 ms); +public: + // static functions + static void delayMillis(uint32 ms); // delay the current thread static void delayMicros(uint32 us); }; @@ -85,6 +100,7 @@ enum ThreadPriority { }; enum StackSizes { + STACK_DEFAULT = 4 * 1024, STACK_AUDIO_THREAD = 16 * 1024, STACK_TIMER_THREAD = 32 * 1024, STACK_DISPLAY_THREAD = 2 * 1024, diff --git a/common/algorithm.h b/common/algorithm.h index d3f518b225..9d22af4090 100644 --- a/common/algorithm.h +++ b/common/algorithm.h @@ -197,6 +197,21 @@ T sortPartition(T first, T last, T pivot, StrictWeakOrdering &comp) { /** * Simple sort function, modeled after std::sort. * It compares data with the given comparator object comp. + * + * Like std::sort this is not guaranteed to be stable. + * + * Two small quotes from wikipedia about stability: + * + * Stable sorting algorithms maintain the relative order of records with + * equal keys. + * + * Unstable sorting algorithms may change the relative order of records with + * equal keys, but stable sorting algorithms never do so. + * + * For more information on that topic check out: + * http://en.wikipedia.org/wiki/Sorting_algorithm#Stability + * + * NOTE: Actually as the time of writing our implementation is unstable. */ template<typename T, class StrictWeakOrdering> void sort(T first, T last, StrictWeakOrdering comp) { diff --git a/common/messages.cpp b/common/messages.cpp index fe87b5f642..b21454d02d 100644 --- a/common/messages.cpp +++ b/common/messages.cpp @@ -128,193 +128,195 @@ static const char * const _messageIds[] = { /* 124 */ "MAME OPL emulator", /* 125 */ "MIDI", /* 126 */ "MIDI gain:", - /* 127 */ "MT-32 Device:", - /* 128 */ "MT-32 Emulator", - /* 129 */ "Main screen scaling:", - /* 130 */ "Map", - /* 131 */ "Mass Add...", - /* 132 */ "Menu", - /* 133 */ "Misc", - /* 134 */ "Mixed AdLib/MIDI mode", - /* 135 */ "Mount DVD", - /* 136 */ "Mount SMB", - /* 137 */ "Mouse click", - /* 138 */ "Multi Function", - /* 139 */ "Music Device:", - /* 140 */ "Music volume:", - /* 141 */ "Mute All", - /* 142 */ "Name:", - /* 143 */ "Network down", - /* 144 */ "Network not initialsed (%d)", - /* 145 */ "Network up", - /* 146 */ "Network up, share mounted", - /* 147 */ "Never", - /* 148 */ "No", - /* 149 */ "No date saved", - /* 150 */ "No music", - /* 151 */ "No playtime saved", - /* 152 */ "No time saved", - /* 153 */ "None", - /* 154 */ "Normal (no scaling)", - /* 155 */ "OK", - /* 156 */ "Output rate:", - /* 157 */ "Override global MIDI settings", - /* 158 */ "Override global audio settings", - /* 159 */ "Override global graphic settings", - /* 160 */ "Override global volume settings", - /* 161 */ "PC Speaker Emulator", - /* 162 */ "Password:", - /* 163 */ "Path not a directory", - /* 164 */ "Path not a file", - /* 165 */ "Path not exists", - /* 166 */ "Paths", - /* 167 */ "Pause", - /* 168 */ "Pick the game:", - /* 169 */ "Platform the game was originally designed for", - /* 170 */ "Platform:", - /* 171 */ "Playtime: ", - /* 172 */ "Please select an action", - /* 173 */ "Plugins Path:", - /* 174 */ "Preferred Device:", - /* 175 */ "Press the key to associate", - /* 176 */ "Quit", - /* 177 */ "Quit ScummVM", - /* 178 */ "Read permission denied", - /* 179 */ "Reading failed", - /* 180 */ "Remap keys", - /* 181 */ "Remove game from the list. The game data files stay intact", - /* 182 */ "Render mode:", - /* 183 */ "Right", - /* 184 */ "Right Click", - /* 185 */ "Right click", - /* 186 */ "Rotate", - /* 187 */ "SFX volume:", - /* 188 */ "SMB", - /* 189 */ "Save", - /* 190 */ "Save Path:", - /* 191 */ "Save Path: ", - /* 192 */ "Save game:", - /* 193 */ "Scan complete!", - /* 194 */ "Scanned %d directories ...", - /* 195 */ "ScummVM Main Menu", - /* 196 */ "ScummVM could not find any engine capable of running the selected game!", - /* 197 */ "ScummVM could not find any game in the specified directory!", - /* 198 */ "ScummVM couldn't open the specified directory!", - /* 199 */ "Search in game list", - /* 200 */ "Search:", - /* 201 */ "Select SoundFont", - /* 202 */ "Select a Theme", - /* 203 */ "Select additional game directory", - /* 204 */ "Select an action and click 'Map'", - /* 205 */ "Select directory for GUI themes", - /* 206 */ "Select directory for extra files", - /* 207 */ "Select directory for plugins", - /* 208 */ "Select directory for saved games", - /* 209 */ "Select directory for savegames", - /* 210 */ "Select directory with game data", - /* 211 */ "Sensitivity", - /* 212 */ "Server:", - /* 213 */ "Share:", - /* 214 */ "Short game identifier used for referring to savegames and running the game from the command line", - /* 215 */ "Show Keyboard", - /* 216 */ "Show mouse cursor", - /* 217 */ "Show subtitles and play speech", - /* 218 */ "Show/Hide Cursor", - /* 219 */ "Skip", - /* 220 */ "Skip line", - /* 221 */ "Skip text", - /* 222 */ "Snap to edges", - /* 223 */ "Software scale (good quality, but slower)", - /* 224 */ "Sound on/off", - /* 225 */ "SoundFont is supported by some audio cards, Fluidsynth and Timidity", - /* 226 */ "SoundFont:", - /* 227 */ "Spch", - /* 228 */ "Special dithering modes supported by some games", - /* 229 */ "Special sound effects volume", - /* 230 */ "Specifies default sound device for General MIDI output", - /* 231 */ "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output", - /* 232 */ "Specifies output sound device or sound card emulator", - /* 233 */ "Specifies path to additional data used by all games or ScummVM", - /* 234 */ "Specifies path to additional data used the game", - /* 235 */ "Specifies preferred sound device or sound card emulator", - /* 236 */ "Specifies where your savegames are put", - /* 237 */ "Speech", - /* 238 */ "Speech volume:", - /* 239 */ "Standard Renderer (16bpp)", - /* 240 */ "Start selected game", - /* 241 */ "Status:", - /* 242 */ "Subs", - /* 243 */ "Subtitle speed:", - /* 244 */ "Subtitles", - /* 245 */ "Swap character", - /* 246 */ "Tap for left click, double tap right click", - /* 247 */ "Text and Speech:", - /* 248 */ "The chosen directory cannot be written to. Please select another one.", - /* 249 */ "Theme Path:", - /* 250 */ "Theme:", - /* 251 */ "This game ID is already taken. Please choose another one.", - /* 252 */ "This game does not support loading games from the launcher.", - /* 253 */ "Time: ", - /* 254 */ "Timeout while initialising network", - /* 255 */ "Touch X Offset", - /* 256 */ "Touch Y Offset", - /* 257 */ "Touchpad mode disabled.", - /* 258 */ "Touchpad mode enabled.", - /* 259 */ "True Roland MT-32 (disable GM emulation)", - /* 260 */ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack", - /* 261 */ "Unknown", - /* 262 */ "Unknown Error", - /* 263 */ "Unmount DVD", - /* 264 */ "Unmount SMB", - /* 265 */ "Unscaled (you must scroll left and right)", - /* 266 */ "Unsupported Color Mode", - /* 267 */ "Untitled savestate", - /* 268 */ "Up", - /* 269 */ "Use both MIDI and AdLib sound generation", - /* 270 */ "Use laptop trackpad-style cursor control", - /* 271 */ "Username:", - /* 272 */ "Using SDL driver ", - /* 273 */ "Vertical underscan:", - /* 274 */ "Video", - /* 275 */ "Virtual keyboard", - /* 276 */ "Volume", - /* 277 */ "Windows MIDI", - /* 278 */ "Write permission denied", - /* 279 */ "Writing data failed", - /* 280 */ "Yes", - /* 281 */ "You have to restart ScummVM to take the effect.", - /* 282 */ "Zone", - /* 283 */ "Zoom down", - /* 284 */ "Zoom up", - /* 285 */ "every 10 mins", - /* 286 */ "every 15 mins", - /* 287 */ "every 30 mins", - /* 288 */ "every 5 mins", - /* 289 */ "~A~bout", - /* 290 */ "~A~dd Game...", - /* 291 */ "~C~ancel", - /* 292 */ "~C~lose", - /* 293 */ "~E~dit Game...", - /* 294 */ "~H~elp", - /* 295 */ "~I~ndy fight controls", - /* 296 */ "~K~eys", - /* 297 */ "~L~eft handed mode", - /* 298 */ "~L~oad", - /* 299 */ "~L~oad...", - /* 300 */ "~N~ext", - /* 301 */ "~O~K", - /* 302 */ "~O~ptions", - /* 303 */ "~O~ptions...", - /* 304 */ "~P~revious", - /* 305 */ "~Q~uit", - /* 306 */ "~R~emove Game", - /* 307 */ "~R~esume", - /* 308 */ "~R~eturn to Launcher", - /* 309 */ "~S~ave", - /* 310 */ "~S~tart", - /* 311 */ "~T~ransitions Enabled", - /* 312 */ "~W~ater Effect Enabled", - /* 313 */ "~Z~ip Mode Activated", + /* 127 */ "MT-32", + /* 128 */ "MT-32 Device:", + /* 129 */ "MT-32 Emulator", + /* 130 */ "Main screen scaling:", + /* 131 */ "Map", + /* 132 */ "Mass Add...", + /* 133 */ "Menu", + /* 134 */ "Misc", + /* 135 */ "Mixed AdLib/MIDI mode", + /* 136 */ "Mount DVD", + /* 137 */ "Mount SMB", + /* 138 */ "Mouse click", + /* 139 */ "Multi Function", + /* 140 */ "Music Device:", + /* 141 */ "Music volume:", + /* 142 */ "Mute All", + /* 143 */ "Name:", + /* 144 */ "Network down", + /* 145 */ "Network not initialsed (%d)", + /* 146 */ "Network up", + /* 147 */ "Network up, share mounted", + /* 148 */ "Never", + /* 149 */ "No", + /* 150 */ "No date saved", + /* 151 */ "No music", + /* 152 */ "No playtime saved", + /* 153 */ "No time saved", + /* 154 */ "None", + /* 155 */ "Normal (no scaling)", + /* 156 */ "OK", + /* 157 */ "Output rate:", + /* 158 */ "Override global MIDI settings", + /* 159 */ "Override global MT-32 settings", + /* 160 */ "Override global audio settings", + /* 161 */ "Override global graphic settings", + /* 162 */ "Override global volume settings", + /* 163 */ "PC Speaker Emulator", + /* 164 */ "Password:", + /* 165 */ "Path not a directory", + /* 166 */ "Path not a file", + /* 167 */ "Path not exists", + /* 168 */ "Paths", + /* 169 */ "Pause", + /* 170 */ "Pick the game:", + /* 171 */ "Platform the game was originally designed for", + /* 172 */ "Platform:", + /* 173 */ "Playtime: ", + /* 174 */ "Please select an action", + /* 175 */ "Plugins Path:", + /* 176 */ "Preferred Device:", + /* 177 */ "Press the key to associate", + /* 178 */ "Quit", + /* 179 */ "Quit ScummVM", + /* 180 */ "Read permission denied", + /* 181 */ "Reading failed", + /* 182 */ "Remap keys", + /* 183 */ "Remove game from the list. The game data files stay intact", + /* 184 */ "Render mode:", + /* 185 */ "Right", + /* 186 */ "Right Click", + /* 187 */ "Right click", + /* 188 */ "Rotate", + /* 189 */ "SFX volume:", + /* 190 */ "SMB", + /* 191 */ "Save", + /* 192 */ "Save Path:", + /* 193 */ "Save Path: ", + /* 194 */ "Save game:", + /* 195 */ "Scan complete!", + /* 196 */ "Scanned %d directories ...", + /* 197 */ "ScummVM Main Menu", + /* 198 */ "ScummVM could not find any engine capable of running the selected game!", + /* 199 */ "ScummVM could not find any game in the specified directory!", + /* 200 */ "ScummVM couldn't open the specified directory!", + /* 201 */ "Search in game list", + /* 202 */ "Search:", + /* 203 */ "Select SoundFont", + /* 204 */ "Select a Theme", + /* 205 */ "Select additional game directory", + /* 206 */ "Select an action and click 'Map'", + /* 207 */ "Select directory for GUI themes", + /* 208 */ "Select directory for extra files", + /* 209 */ "Select directory for plugins", + /* 210 */ "Select directory for saved games", + /* 211 */ "Select directory for savegames", + /* 212 */ "Select directory with game data", + /* 213 */ "Sensitivity", + /* 214 */ "Server:", + /* 215 */ "Share:", + /* 216 */ "Short game identifier used for referring to savegames and running the game from the command line", + /* 217 */ "Show Keyboard", + /* 218 */ "Show mouse cursor", + /* 219 */ "Show subtitles and play speech", + /* 220 */ "Show/Hide Cursor", + /* 221 */ "Skip", + /* 222 */ "Skip line", + /* 223 */ "Skip text", + /* 224 */ "Snap to edges", + /* 225 */ "Software scale (good quality, but slower)", + /* 226 */ "Sound on/off", + /* 227 */ "SoundFont is supported by some audio cards, Fluidsynth and Timidity", + /* 228 */ "SoundFont:", + /* 229 */ "Spch", + /* 230 */ "Special dithering modes supported by some games", + /* 231 */ "Special sound effects volume", + /* 232 */ "Specifies default sound device for General MIDI output", + /* 233 */ "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output", + /* 234 */ "Specifies output sound device or sound card emulator", + /* 235 */ "Specifies path to additional data used by all games or ScummVM", + /* 236 */ "Specifies path to additional data used the game", + /* 237 */ "Specifies preferred sound device or sound card emulator", + /* 238 */ "Specifies where your savegames are put", + /* 239 */ "Speech", + /* 240 */ "Speech volume:", + /* 241 */ "Standard Renderer (16bpp)", + /* 242 */ "Start selected game", + /* 243 */ "Status:", + /* 244 */ "Subs", + /* 245 */ "Subtitle speed:", + /* 246 */ "Subtitles", + /* 247 */ "Swap character", + /* 248 */ "Tap for left click, double tap right click", + /* 249 */ "Text and Speech:", + /* 250 */ "The chosen directory cannot be written to. Please select another one.", + /* 251 */ "Theme Path:", + /* 252 */ "Theme:", + /* 253 */ "This game ID is already taken. Please choose another one.", + /* 254 */ "This game does not support loading games from the launcher.", + /* 255 */ "Time: ", + /* 256 */ "Timeout while initialising network", + /* 257 */ "Touch X Offset", + /* 258 */ "Touch Y Offset", + /* 259 */ "Touchpad mode disabled.", + /* 260 */ "Touchpad mode enabled.", + /* 261 */ "True Roland MT-32 (disable GM emulation)", + /* 262 */ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack", + /* 263 */ "Unknown", + /* 264 */ "Unknown Error", + /* 265 */ "Unmount DVD", + /* 266 */ "Unmount SMB", + /* 267 */ "Unscaled (you must scroll left and right)", + /* 268 */ "Unsupported Color Mode", + /* 269 */ "Untitled savestate", + /* 270 */ "Up", + /* 271 */ "Use both MIDI and AdLib sound generation", + /* 272 */ "Use laptop trackpad-style cursor control", + /* 273 */ "Username:", + /* 274 */ "Using SDL driver ", + /* 275 */ "Vertical underscan:", + /* 276 */ "Video", + /* 277 */ "Virtual keyboard", + /* 278 */ "Volume", + /* 279 */ "Windows MIDI", + /* 280 */ "Write permission denied", + /* 281 */ "Writing data failed", + /* 282 */ "Yes", + /* 283 */ "You have to restart ScummVM to take the effect.", + /* 284 */ "Zone", + /* 285 */ "Zoom down", + /* 286 */ "Zoom up", + /* 287 */ "every 10 mins", + /* 288 */ "every 15 mins", + /* 289 */ "every 30 mins", + /* 290 */ "every 5 mins", + /* 291 */ "~A~bout", + /* 292 */ "~A~dd Game...", + /* 293 */ "~C~ancel", + /* 294 */ "~C~lose", + /* 295 */ "~E~dit Game...", + /* 296 */ "~H~elp", + /* 297 */ "~I~ndy fight controls", + /* 298 */ "~K~eys", + /* 299 */ "~L~eft handed mode", + /* 300 */ "~L~oad", + /* 301 */ "~L~oad...", + /* 302 */ "~N~ext", + /* 303 */ "~O~K", + /* 304 */ "~O~ptions", + /* 305 */ "~O~ptions...", + /* 306 */ "~P~revious", + /* 307 */ "~Q~uit", + /* 308 */ "~R~emove Game", + /* 309 */ "~R~esume", + /* 310 */ "~R~eturn to Launcher", + /* 311 */ "~S~ave", + /* 312 */ "~S~tart", + /* 313 */ "~T~ransitions Enabled", + /* 314 */ "~W~ater Effect Enabled", + /* 315 */ "~Z~ip Mode Activated", NULL }; @@ -324,7 +326,7 @@ struct PoMessageEntry { }; static const PoMessageEntry _translation_ru_RU[] = { - { 0, "Project-Id-Version: ScummVM VERSION\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-12 17:44+0200\nPO-Revision-Date: 2010-06-13 20:55+0300\nLast-Translator: Eugene Sandulenko <sev@scummvm.org>\nLanguage-Team: Russian\nLanguage: \nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-5\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" }, + { 0, "Project-Id-Version: ScummVM VERSION\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-30 22:14+0100\nPO-Revision-Date: 2010-06-13 20:55+0300\nLast-Translator: Eugene Sandulenko <sev@scummvm.org>\nLanguage-Team: Russian\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-5\nContent-Transfer-Encoding: 8bit\nLanguage: Russian\nPlural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" }, { 1, " \262\353 \343\322\325\340\325\335\353, \347\342\336 \345\336\342\330\342\325 \322\353\331\342\330? " }, { 2, " (\260\332\342\330\322\335\320\357)" }, { 3, " (\270\323\340\353)" }, @@ -343,7 +345,7 @@ static const PoMessageEntry _translation_ru_RU[] = { { 16, "\315\334\343\333\357\342\336\340 AdLib" }, { 17, "\315\334\343\333\357\342\336\340 AdLib:" }, { 18, "\267\322\343\332\336\322\320\357 \332\320\340\342\320 AdLib \330\341\337\336\333\354\327\343\325\342\341\357 \334\335\336\323\330\334\330 \330\323\340\320\334\330" }, - { 19, "\275\336\322. \330\323\340\320..." }, + { 19, "\275\336\322\320\357 \330\323\340\320..." }, { 20, "\300\320\341\342\325\340\330\327\320\342\336\340 \341\336 \341\323\333\320\326\330\322\320\335\330\325\334 (16bpp)" }, { 21, "\272\336\340\340\325\332\346\330\357 \341\336\336\342\335\336\350\325\335\330\357 \341\342\336\340\336\335" }, { 22, "\275\320\327\335\320\347\325\335\335\320\357 \332\333\320\322\330\350\320 : %s" }, @@ -406,20 +408,20 @@ static const PoMessageEntry _translation_ru_RU[] = { { 79, "\277\336\333\335\336\325 \335\320\327\322\320\335\330\325 \330\323\340\353" }, { 80, "\277\336\333\335\336\355\332\340\320\335\335\353\331 \340\325\326\330\334" }, { 81, "\303\341\332\336\340\325\335\330\325 GC \337\320\324\320:" }, - { 82, "\307\343\322\341\342\320\330\342\325\333\354\335\336\341\342\354 GC \337\320\324\320:" }, + { 82, "\307\343\322\341\342\322\330\342\325\333\354\335\336\341\342\354 GC \337\320\324\320:" }, { 83, "\263\340\344" }, - { 84, "\303\341\342\340\336\331\342\341\322\336 GM:" }, - { 85, "\317\327\353\332 \330\335\342\325\340\344\325\331\341\320:" }, - { 86, "\300\320\341\342\325\340\330\327\320\342\336\340 GUI:" }, + { 84, "\303\341\342\340\336\331\341\342\322\336 GM:" }, + { 85, "\317\327\353\332 GUI:" }, + { 86, "\300\330\341\336\322\320\333\332\320 GUI:" }, { 87, "\270\323\340\320" }, { 88, "\275\325\342 \344\320\331\333\336\322 \330\323\340\353" }, { 89, "Game Id \335\325 \337\336\324\324\325\340\326\330\322\320\325\342\341\357" }, - { 90, "\277\343\342\354 \332 \330\323\340\325: " }, + { 90, "\263\324\325 \330\323\340\320: " }, { 91, "\263\333\336\321\320\333\354\335\336\325 \334\325\335\356" }, { 92, "\277\325\340\325\331\342\330 \335\320 \324\330\340\325\332\342\336\340\330\356 \343\340\336\322\335\325\334 \322\353\350\325" }, { 93, "\262\322\325\340\345" }, { 94, "\263\340\320\344\330\332\320" }, - { 95, "\263\340\320\344\330\347\325\341\332\330\331 \340\325\326\330\334:" }, + { 95, "\263\340\320\344. \340\325\326\330\334:" }, { 96, "\305\320\340\324\322\320\340\335\336\325 \334\320\341\350\342\320\321\330\340\336\322\320\335\330\325 (\321\353\341\342\340\336, \335\336 \335\330\327\332\336\323\336 \332\320\347\325\341\342\322\320)" }, { 97, "Hercules \317\335\342\320\340\335\353\331" }, { 98, "Hercules \267\325\333\325\335\353\331" }, @@ -448,201 +450,581 @@ static const PoMessageEntry _translation_ru_RU[] = { { 121, "\267\320\323\340\343\327\330\342\354" }, { 122, "\267\320\323\340\343\327\330\342\354 \330\323\340\343:" }, { 123, "\267\320\323\340\343\327\330\342\354 \341\336\345\340\335\325\335\330\325 \324\333\357 \322\353\321\340\320\335\335\336\331 \330\323\340\353" }, - { 124, "\315\334\343\333\357\342\336\340 MAME OPL:" }, + { 124, "\315\334\343\333\357\342\336\340 MAME OPL" }, { 125, "MIDI" }, { 126, "\303\341\330\333\325\335\330\325 MIDI:" }, - { 127, "\303\341\342\340\336\331\341\342\322\336 MT32:" }, - { 128, "\315\334\343\333\357\342\336\340 MT-32" }, - { 129, "\274\320\341\350\342\320\321 \323\333\320\322\335\336\323\336 \355\332\340\320\335\320:" }, - { 130, "\275\320\327\335\320\347\330\342\354" }, - { 131, "\264\336\321. \334\335\336\323\336..." }, - { 132, "\274\325\335\356" }, - { 133, "\300\320\327\335\336\325" }, - { 134, "\301\334\325\350\320\335\335\353\331 \340\325\326\330\334 AdLib/MIDI" }, - { 135, "\277\336\324\332\333\356\347\330\342\354 DVD" }, - { 136, "\277\336\324\332\333\356\347\330\342\354 SMB" }, - { 137, "\272\333\330\332 \334\353\350\354\356" }, - { 138, "\274\343\333\354\342\330\344\343\335\332\346\330\357" }, - { 139, "\303\341\342\340\336\331\342\341\322\336 GM:" }, - { 140, "\263\340\336\334\332\336\341\342\354 \334\343\327\353\332\330:" }, - { 141, "\262\353\332\333\356\347\330\342\354 \322\341\361" }, - { 142, "\275\320\327\322\320\335\330\325:" }, - { 143, "\301\325\342\354 \322\353\332\333\356\347\325\335\320" }, - { 144, "\301\325\342\354 \335\325 \335\320\341\342\340\336\325\335\320 (%d)" }, - { 145, "\301\325\342\354 \340\320\321\336\342\320\325\342" }, - { 146, "\301\325\342\354 \340\320\321\336\342\320\325\342, \337\320\337\332\320 \337\336\324\332\333\356\347\325\335\320" }, - { 147, "\275\330\332\336\323\324\320" }, - { 148, "\275\325\342" }, - { 149, "\264\320\342\320 \335\325 \327\320\337\330\341\320\335\320" }, - { 150, "\261\325\327 \334\343\327\353\332\330" }, - { 151, "\262\340\325\334\357 \330\323\340\353 \335\325 \327\320\337\330\341\320\335\336" }, - { 152, "\262\340\325\334\357 \335\325 \327\320\337\330\341\320\335\336" }, - { 153, "\275\325 \327\320\324\320\335" }, - { 154, "\261\325\327 \343\322\325\333\330\347\325\335\330\357" }, - { 155, "OK" }, - { 156, "\262\353\345\336\324\335\320\357 \347\320\341\342\336\342\320:" }, - { 157, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 MIDI" }, - { 158, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 \320\343\324\330\336" }, - { 159, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 \323\340\320\344\330\332\330" }, - { 160, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 \323\340\336\334\332\336\341\342\330" }, - { 161, "\315\334\343\333\357\342\336\340 PC \341\337\330\332\325\340\320" }, - { 162, "\277\320\340\336\333\354:" }, - { 163, "\277\343\342\354 \335\325 \357\322\333\357\325\342\341\357 \324\330\340\325\332\342\336\340\330\325\331" }, - { 164, "\277\343\342\354 \335\325 \357\322\333\357\325\342\341\357 \344\320\331\333\336\334" }, - { 165, "\277\343\342\354 \335\325 \335\320\331\324\325\335" }, - { 166, "\277\343\342\330" }, - { 167, "\277\320\343\327\320" }, - { 168, "\262\353\321\325\340\330\342\325 \330\323\340\343:" }, - { 169, "\277\333\320\342\344\336\340\334\320, \324\333\357 \332\336\342\336\340\336\331 \330\323\340\320 \321\353\333\320 \330\327\335\320\347\320\333\354\335\336 \340\320\327\340\320\321\336\342\320\335\320" }, - { 170, "\277\333\320\342\344\336\340\334\320:" }, - { 171, "\262\340\325\334\357 \330\323\340\353: " }, - { 172, "\277\336\326\320\333\343\331\341\342\320, \322\353\321\325\340\330\342\325 \324\325\331\341\342\322\330\325" }, - { 173, "\277\343\342\354 \332 \337\333\320\323\330\335\320\334:" }, - { 174, "\277\340\325\324\337\336\347\330\342\320\325\334\336\325 \343\341\342\340\336\331\341\342\322\336:" }, - { 175, "\275\320\326\334\330\342\325 \332\333\320\322\330\350\343 \324\333\357 \335\320\327\335\320\347\325\335\330\357" }, - { 176, "\262\353\345\336\324" }, - { 177, "\262\353\345\336\324 \330\327 ScummVM" }, - { 178, "\275\325\324\336\341\342\320\342\336\347\335\336 \337\340\320\322 \324\333\357 \347\342\325\335\330\357" }, - { 179, "\276\350\330\321\332\320 \347\342\325\335\330\357" }, - { 180, "\277\325\340\325\335\320\327\335\320\347\330\342\354 \332\333\320\322\330\350\330" }, - { 181, "\303\324\320\333\330\342\354 \330\323\340\343 \330\327 \341\337\330\341\332\320. \275\325 \343\324\320\333\357\325\342 \330\323\340\343 \341 \326\325\341\342\332\336\323\336 \324\330\341\332\320" }, - { 182, "\300\325\326\330\334 \340\320\341\342\340\330\340\336\322\320\335\330\357:" }, - { 183, "\262\337\340\320\322\336" }, - { 184, "\277\340\320\322\353\331 \351\325\333\347\336\332" }, - { 185, "\277\340\320\322\353\331 \351\325\333\347\336\332" }, - { 186, "\277\336\322\325\340\335\343\342\354" }, - { 187, "\263\340\336\334\332\336\341\342\354 \355\344\344\325\332\342\336\322:" }, - { 188, "SMB" }, - { 189, "\267\320\337\330\341\320\342\354" }, - { 190, "\277\343\342\354 \341\336\345\340.: " }, - { 191, "\277\343\342\354 \324\333\357 \341\336\345\340\320\335\325\335\330\331: " }, - { 192, "\301\336\345\340\320\335\330\342\354 \330\323\340\343: " }, - { 193, "\277\336\330\341\332 \327\320\332\336\335\347\325\335!" }, - { 194, "\277\340\336\341\334\336\342\340\325\335\336 %d \324\330\340\325\332\342\336\340\330\331 ..." }, - { 195, "\263\333\320\322\335\336\325 \334\325\335\356 ScummVM" }, - { 196, "ScummVM \335\325 \341\334\336\323 \335\320\331\342\330 \324\322\330\326\336\332 \324\333\357 \327\320\337\343\341\332\320 \322\353\321\340\320\335\335\336\331 \330\323\340\353!" }, - { 197, "ScummVM \335\325 \334\336\326\325\342 \335\320\331\342\330 \330\323\340\343 \322 \343\332\320\327\320\335\335\336\331 \324\330\340\325\332\342\336\340\330\330!" }, - { 198, "ScummVM \335\325 \334\336\326\325\342 \336\342\332\340\353\342\354 \343\332\320\327\320\335\335\343\356 \324\330\340\325\332\342\336\340\330\356!" }, - { 199, "\277\336\330\341\332 \322 \341\337\330\341\332\325 \330\323\340" }, - { 200, "\277\336\330\341\332:" }, - { 201, "\262\353\321\325\340\330\342\325 SoundFont" }, - { 202, "\262\353\321\325\340\330\342\325 \342\325\334\343" }, - { 203, "\262\353\321\325\340\330\342\325 \324\336\337\336\333\335\330\342\325\333\354\335\343\356 \324\330\340\325\332\342\336\340\330\356 \330\323\340\353" }, - { 204, "\262\353\321\325\340\330\342\325 \324\325\331\341\342\322\330\325 \330 \332\333\330\332\335\330\342\325 '\275\320\327\335\320\347\330\342\354'" }, - { 205, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \324\333\357 \342\325\334 GUI" }, - { 206, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \341 \324\336\337\336\333\335\330\342\325\333\354\335\353\334\330 \344\320\331\333\320\334\330" }, - { 207, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \341 \337\333\320\323\330\335\320\334\330" }, - { 208, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \324\333\357 \341\336\345\340\320\335\325\335\330\331" }, - { 209, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \324\333\357 \341\336\345\340\320\335\325\335\330\331" }, - { 210, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \341 \344\320\331\333\320\334\330 \330\323\340\353" }, - { 211, "\307\343\322\341\342\322\330\342\325\333\354\335\336\341\342\354" }, - { 212, "\301\325\340\322\325\340:" }, - { 213, "\301\325\342\325\322\320\357 \337\320\337\332\320:" }, - { 214, "\272\336\340\336\342\332\330\331 \330\324\325\335\342\330\344\330\332\320\342\336\340, \330\341\337\336\333\354\327\343\325\334\353\331 \324\333\357 \330\334\325\335 \341\336\345\340\320\335\325\335\330\331 \330\323\340 \330 \324\333\357 \327\320\337\343\341\332\320 \330\327 \332\336\334\320\335\324\335\336\331 \341\342\340\336\332\330" }, - { 215, "\277\336\332\320\327\320\342\354 \332\333\320\322\330\320\342\343\340\343" }, - { 216, "\277\336\332\320\327\353\322\320\342\354 \332\343\340\341\336\340 \334\353\350\330" }, - { 217, "\277\336\332\320\327\353\322\320\342\354 \341\343\321\342\330\342\340\353 \330 \322\336\341\337\340\336\330\327\322\336\324\330\342\354 \340\325\347\354" }, - { 218, "\277\336\332\320\327\320\342\354/\303\321\340\320\342\354 \332\343\340\341\336\340" }, - { 219, "\277\340\336\337\343\341\342\330\342\354" }, - { 220, "\277\340\336\337\343\341\342\330\342\354 \341\342\340\336\332\343" }, - { 221, "\277\340\336\337\343\341\342\330\342\354 \342\325\332\341\342" }, - { 222, "\277\340\330\332\340\325\337\330\342\354 \332 \323\340\320\335\330\346\320\334" }, - { 223, "\277\340\336\323\340\320\334\334\335\336\325 \334\320\341\350\342\320\321\330\340\336\322\320\335\330\325 (\345\336\340\336\350\325\325 \332\320\347\325\341\342\322\336, \335\336 \334\325\324\333\325\335\335\325\325)" }, - { 224, "\267\322\343\332 \322\332\333/\322\353\332\333" }, - { 225, "SoundFont\353 \337\336\324\324\325\340\324\326\330\322\320\356\342\341\357 \335\325\332\336\342\336\340\353\334\330 \327\322\343\332\336\322\353\334\330 \332\320\340\342\320\334\330, Fluidsynth \330 Timidity" }, - { 226, "SoundFont:" }, - { 227, "\276\327\322" }, - { 228, "\301\337\325\346\330\320\333\354\335\353\325 \340\325\326\330\334\353 \340\325\335\324\325\340\330\335\323\320, \337\336\324\324\325\340\326\330\322\320\325\334\353\325 \335\325\332\336\342\336\340\353\334\330 \330\323\340\320\334\330" }, - { 229, "\263\340\336\334\332\336\341\342\354 \341\337\325\346\330\320\333\354\335\353\345 \327\322\343\332\336\322\353\345 \355\344\344\325\332\342\336\322" }, - { 230, "\303\332\320\327\353\322\320\325\342 \322\353\345\336\324\335\336\325 \327\322\343\332\336\322\336\325 \343\341\342\340\336\331\341\342\322\336 \324\333\357 MIDI" }, - { 231, "\303\332\320\327\353\322\320\325\342 \327\322\343\332\336\322\336\325 \343\341\342\340\336\331\341\342\322\336 \337\336 \343\334\336\333\347\320\335\330\357 \324\333\357 \322\353\322\336\324\320 \335\320 Roland MT-32/LAPC1/CM32l/CM64" }, - { 232, "\303\332\320\327\353\322\320\325\342 \322\353\345\336\324\335\336\325 \327\322\343\332\336\322\336\325 \343\341\342\340\336\331\341\342\322\336 \330\333\330 \355\334\343\333\357\342\336\340 \327\322\343\332\336\322\336\331 \332\320\340\342\353" }, - { 233, "\303\332\320\327\353\322\320\325\342 \337\343\342\354 \332 \324\336\337\336\333\335\330\342\325\333\354\335\353\334 \344\320\331\333\320\334 \324\320\335\335\353\345, \330\341\337\336\333\354\327\343\325\334\353\345 \322\341\325\334\330 \330\323\340\320\334\330, \333\330\321\336 ScummVM" }, - { 234, "\303\332\320\327\353\322\320\325\342 \337\343\342\354 \332 \324\336\337\336\333\335\330\342\325\333\354\335\353\334 \344\320\331\333\320\334 \324\320\335\335\353\345 \324\333\357 \330\323\340\353" }, - { 235, "\303\332\320\327\353\322\320\325\342 \322\353\345\336\324\335\336\325 \327\322\343\332\336\322\336\325 \343\341\342\340\336\331\341\342\322\336 \330\333\330 \355\334\343\333\357\342\336\340 \327\322\343\332\336\322\336\331 \332\320\340\342\353" }, - { 236, "\303\332\320\327\353\322\320\325\342 \337\343\342\354 \332 \341\336\345\340\320\335\325\335\330\357\334 \330\323\340\353" }, - { 237, "\276\327\322\343\347\332\320" }, - { 238, "\263\340\336\334\332\336\341\342\354 \336\327\322\343\347\332\330:" }, - { 239, "\301\342\320\335\324\320\340\342\335\353\331 \340\320\341\342\325\340\330\327\320\342\336\340 (16bpp)" }, - { 240, "\267\320\337\343\341\342\330\342\354 \322\353\321\340\320\335\335\343\356 \330\323\340\343" }, - { 241, "\301\336\341\342\336\357\335\330\325:" }, - { 242, "\301\343\321" }, - { 243, "\301\332\336\340\336\341\342\354 \341\343\321\342\330\342\340\336\322:" }, - { 244, "\301\343\321\342\330\342\340\353" }, - { 245, "\301\334\325\335\330\342\354 \323\325\340\336\357" }, - { 246, "\302\320\337 \324\333\357 \333\325\322\336\323\336 \351\325\333\347\332\320, \324\322\336\331\335\336\331 \342\320\337 \324\333\357 \337\340\320\322\336\323\336 \351\325\333\347\332\320" }, - { 247, "\302\325\332\341\342 \330 \336\327\322\343\347\332\320:" }, - { 248, "\275\325 \334\336\323\343 \337\330\341\320\342\354 \322 \322\353\321\340\320\335\335\343\356 \324\330\340\325\332\342\336\340\330\356. \277\336\326\320\333\343\331\341\342\320, \343\332\320\326\330\342\325 \324\340\343\323\343\356." }, - { 249, "\277\343\342\354 \332 \342\325\334\320\334:" }, - { 250, "\302\325\334\320:" }, - { 251, "\315\342\336\342 ID \330\323\340\353 \343\326\325 \330\341\337\336\333\354\327\343\325\342\341\357. \277\336\326\320\333\343\331\341\342\320, \322\353\321\325\340\330\342\325 \324\340\343\323\336\331." }, - { 252, "\315\342\320 \330\323\340\320 \335\325 \337\336\324\324\325\340\326\330\322\320\325\342 \327\320\323\340\343\327\332\343 \341\336\345\340\320\335\325\335\330\331 \347\325\340\325\327 \323\333\320\322\335\336\325 \334\325\335\356." }, - { 253, "\262\340\325\334\357: " }, - { 254, "\262\340\325\334\357 \337\336\324\332\333\356\347\325\335\330\357 \332 \341\325\342\330 \330\341\342\325\332\333\336" }, - { 255, "\301\334\325\351\325\335\330\325 \332\320\341\320\335\330\331 \337\336 \336\341\330 X" }, - { 256, "\301\334\325\351\325\335\330\325 \332\320\341\320\335\330\331 \337\336 \336\341\330 Y" }, - { 257, "\300\325\326\330\334 \342\320\347\337\320\324\320 \322\353\332\333\356\347\325\335." }, - { 258, "\300\325\326\330\334 \342\320\347\337\320\324\320 \322\332\333\356\347\325\335." }, - { 259, "\275\320\341\342\336\357\351\330\331 Roland MT-32 (\327\320\337\340\325\342\330\342\354 \355\334\343\333\357\346\330\356 GM)" }, - { 260, "\262\353\332\333\356\347\320\325\342 \334\320\337\337\330\335\323 General MIDI \324\333\357 \330\323\340 \341 \327\322\343\332\336\322\336\331 \324\336\340\336\326\332\336\331 \324\333\357 Roland MT-32" }, - { 261, "\275\325\330\327\322\325\341\342\335\336" }, - { 262, "\275\325\330\327\322\325\341\342\335\320\357 \336\350\330\321\332\320" }, - { 263, "\276\342\332\333\356\347\330\342\354 DVD" }, - { 264, "\276\342\332\333\356\347\342\354 SMB" }, - { 265, "\261\325\327 \334\320\341\350\342\320\321\330\340\336\322\320\335\330\357 (\335\343\326\335\336 \321\343\324\325\342 \337\340\336\332\340\343\347\330\322\320\342\354 \322\333\325\322\336 \330 \322\337\340\320\322\336)" }, - { 266, "\275\325\337\336\324\324\325\340\326\330\322\320\325\334\353\331 \340\325\326\330\334 \346\322\325\342\320" }, - { 267, "\301\336\345\340\320\335\325\335\330\325 \321\325\327 \330\334\325\335\330" }, - { 268, "\262\322\325\340\345" }, - { 269, "\270\341\337\336\333\354\327\336\322\320\342\354 \330 MIDI \330 AdLib \324\333\357 \323\325\335\325\340\320\346\330\330 \327\322\343\332\320" }, - { 270, "\270\341\337\336\333\354\327\336\322\320\342\354 \343\337\340\320\322\333\325\335\330\325 \332\343\340\341\336\340\336\334 \332\320\332 \335\320 \342\340\325\332\337\320\324\325 \333\325\337\342\336\337\336\322" }, - { 271, "\277\336\333\354\327\336\322\320\342\325\333\354:" }, - { 272, "\270\341\337\336\333\354\327\343\356 \324\340\320\331\322\325\340 SDL " }, - { 273, "\262\325\340\342\330\332\320\333\354\335\353\331 underscan:" }, - { 274, "\262\330\324\325\336" }, - { 275, "\262\330\340\342\343\320\333\354\335\320\357 \332\333\320\322\330\320\342\343\340\320" }, - { 276, "\263\340\336\334\332\336\341\342\354" }, - { 277, "Windows MIDI" }, - { 278, "\275\325\324\336\341\342\320\342\336\347\335\336 \337\340\320\322 \324\333\357 \327\320\337\330\341\330" }, - { 279, "\276\350\330\321\332\320 \327\320\337\330\341\330 \324\320\335\335\353\345" }, - { 280, "\264\320" }, - { 281, "\262\353 \324\336\333\326\335\353 \337\325\340\325\327\320\337\343\341\342\330\342\354 ScummVM \347\342\336\321\353 \337\340\330\334\325\335\330\342\354 \330\327\334\325\335\325\335\330\357." }, - { 282, "\267\336\335\320" }, - { 283, "\303\334\325\335\354\350. \334\320\341\350\342\320\321" }, - { 284, "\303\322\325\333. \334\320\341\350\342\320\321" }, - { 285, "\332\320\326\324\353\325 10 \334\330\335\343\342" }, - { 286, "\332\320\326\324\353\325 15 \334\330\335\343\342" }, - { 287, "\332\320\326\324\353\325 30 \334\330\335\343\342" }, - { 288, "\332\320\326\324\353\325 5 \334\330\335\343\342" }, - { 289, "\276 \337\340\336~\323~\340\320\334\334\325" }, - { 290, "~\264~\336\321. \330\323\340\343..." }, - { 291, "\276~\342~\334\325\335\320" }, - { 292, "~\267~\320\332\340\353\342\354" }, - { 293, "\270\327~\334~. \330\323\340\343..." }, - { 294, "~\277~\336\334\336\351\354" }, - { 295, "\303\337\340\320\322\333\325\335\330\325 \321\336\357\334\330 \322 Indy" }, - { 296, "~\272~\333\320\322\330\350\330" }, - { 297, "\273\325\322\336\340\343\332\330\331 \340\325\326\330\334" }, - { 298, "~\267~\320\323\340\343\327\330\342\354" }, - { 299, "~\267~\320\323\340...." }, - { 300, "~\301~\333\325\324" }, - { 301, "~O~K" }, - { 302, "~\276~\337\346\330\330" }, - { 303, "~\276~\337\346\330\330..." }, - { 304, "~\277~\340\325\324" }, - { 305, "~\262~\353\345\336\324" }, - { 306, "~\303~\324\320\333\330\342\354 \330\323\340\343" }, - { 307, "\277\340\336\324\336\333~\326~\330\342\354" }, - { 308, "~\262~\325\340\335\343\342\354\341\357 \322 \323\333\320\322\335\336\325 \334\325\335\356" }, - { 309, "~\267~\320\337\330\341\320\342\354" }, - { 310, "\277~\343~\341\332" }, - { 311, "\277\325\340\325\345\336\324\353 \320\332\342\330\322\330\340\336\322\320\335\353" }, - { 312, "\315\344\344\325\332\342\353 \322\336\324\353 \322\332\333\356\347\325\335\353" }, - { 313, "\300\325\326\330\334 \321\353\341\342\340\336\323\336 \337\325\340\325\345\336\324\320 \320\332\342\330\322\330\340\336\322\320\335" }, + { 127, "MT-32" }, + { 128, "\303\341\342\340. MT-32:" }, + { 129, "\315\334\343\333\357\342\336\340 MT-32" }, + { 130, "\274\320\341\350\342\320\321 \323\333\320\322\335\336\323\336 \355\332\340\320\335\320:" }, + { 131, "\275\320\327\335\320\347\330\342\354" }, + { 132, "\274\335\336\323\336 \330\323\340..." }, + { 133, "\274\325\335\356" }, + { 134, "\300\320\327\335\336\325" }, + { 135, "\301\334\325\350\320\335\335\353\331 \340\325\326\330\334 AdLib/MIDI" }, + { 136, "\277\336\324\332\333\356\347\330\342\354 DVD" }, + { 137, "\277\336\324\332\333\356\347\330\342\354 SMB" }, + { 138, "\272\333\330\332 \334\353\350\354\356" }, + { 139, "\274\343\333\354\342\330\344\343\335\332\346\330\357" }, + { 140, "\267\322\343\332\336\322\336\325 \343\341\342-\322\336:" }, + { 141, "\263\340\336\334\332. \334\343\327\353\332\330:" }, + { 142, "\262\353\332\333. \322\341\361" }, + { 143, "\275\320\327\322:" }, + { 144, "\301\325\342\354 \322\353\332\333\356\347\325\335\320" }, + { 145, "\301\325\342\354 \335\325 \335\320\341\342\340\336\325\335\320 (%d)" }, + { 146, "\301\325\342\354 \340\320\321\336\342\320\325\342" }, + { 147, "\301\325\342\354 \340\320\321\336\342\320\325\342, \337\320\337\332\320 \337\336\324\332\333\356\347\325\335\320" }, + { 148, "\275\330\332\336\323\324\320" }, + { 149, "\275\325\342" }, + { 150, "\264\320\342\320 \335\325 \327\320\337\330\341\320\335\320" }, + { 151, "\261\325\327 \334\343\327\353\332\330" }, + { 152, "\262\340\325\334\357 \330\323\340\353 \335\325 \327\320\337\330\341\320\335\336" }, + { 153, "\262\340\325\334\357 \335\325 \327\320\337\330\341\320\335\336" }, + { 154, "\275\325 \327\320\324\320\335" }, + { 155, "\261\325\327 \343\322\325\333\330\347\325\335\330\357" }, + { 156, "OK" }, + { 157, "\307\320\341\342\336\342\320 \327\322\343\332\320:" }, + { 158, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 MIDI" }, + { 159, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 MT-32" }, + { 160, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 \320\343\324\330\336" }, + { 161, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 \323\340\320\344\330\332\330" }, + { 162, "\277\325\340\325\332\340\353\342\354 \323\333\336\321\320\333\354\335\353\325 \343\341\342\320\335\336\322\332\330 \323\340\336\334\332\336\341\342\330" }, + { 163, "\315\334\343\333\357\342\336\340 PC \341\337\330\332\325\340\320" }, + { 164, "\277\320\340\336\333\354:" }, + { 165, "\277\343\342\354 \335\325 \357\322\333\357\325\342\341\357 \324\330\340\325\332\342\336\340\330\325\331" }, + { 166, "\277\343\342\354 \335\325 \357\322\333\357\325\342\341\357 \344\320\331\333\336\334" }, + { 167, "\277\343\342\354 \335\325 \335\320\331\324\325\335" }, + { 168, "\277\343\342\330" }, + { 169, "\277\320\343\327\320" }, + { 170, "\262\353\321\325\340\330\342\325 \330\323\340\343:" }, + { 171, "\277\333\320\342\344\336\340\334\320, \324\333\357 \332\336\342\336\340\336\331 \330\323\340\320 \321\353\333\320 \330\327\335\320\347\320\333\354\335\336 \340\320\327\340\320\321\336\342\320\335\320" }, + { 172, "\277\333\320\342\344\336\340\334\320:" }, + { 173, "\262\340\325\334\357 \330\323\340\353: " }, + { 174, "\277\336\326\320\333\343\331\341\342\320, \322\353\321\325\340\330\342\325 \324\325\331\341\342\322\330\325" }, + { 175, "\277\343\342\354 \332 \337\333\320\323\330\335\320\334:" }, + { 176, "\267\322\343\332\336\322\336\325 \343\341\342-\322\336:" }, + { 177, "\275\320\326\334\330\342\325 \332\333\320\322\330\350\343 \324\333\357 \335\320\327\335\320\347\325\335\330\357" }, + { 178, "\262\353\345\336\324" }, + { 179, "\262\353\345\336\324 \330\327 ScummVM" }, + { 180, "\275\325\324\336\341\342\320\342\336\347\335\336 \337\340\320\322 \324\333\357 \347\342\325\335\330\357" }, + { 181, "\276\350\330\321\332\320 \347\342\325\335\330\357" }, + { 182, "\277\325\340\325\335\320\327\335\320\347\330\342\354 \332\333\320\322\330\350\330" }, + { 183, "\303\324\320\333\330\342\354 \330\323\340\343 \330\327 \341\337\330\341\332\320. \275\325 \343\324\320\333\357\325\342 \330\323\340\343 \341 \326\325\341\342\332\336\323\336 \324\330\341\332\320" }, + { 184, "\300\325\326\330\334 \340\320\341\342\340\320:" }, + { 185, "\262\337\340\320\322\336" }, + { 186, "\277\340\320\322\353\331 \351\325\333\347\336\332" }, + { 187, "\277\340\320\322\353\331 \351\325\333\347\336\332" }, + { 188, "\277\336\322\325\340\335\343\342\354" }, + { 189, "\263\340\336\334\332. SFX:" }, + { 190, "SMB" }, + { 191, "\267\320\337\330\341\320\342\354" }, + { 192, "\277\343\342\354 \341\336\345\340: " }, + { 193, "\301\336\345\340\320\335\325\335\330\357 \330\323\340:" }, + { 194, "\301\336\345\340\320\335\330\342\354 \330\323\340\343: " }, + { 195, "\277\336\330\341\332 \327\320\332\336\335\347\325\335!" }, + { 196, "\277\340\336\341\334\336\342\340\325\335\336 %d \324\330\340\325\332\342\336\340\330\331 ..." }, + { 197, "\263\333\320\322\335\336\325 \334\325\335\356 ScummVM" }, + { 198, "ScummVM \335\325 \341\334\336\323 \335\320\331\342\330 \324\322\330\326\336\332 \324\333\357 \327\320\337\343\341\332\320 \322\353\321\340\320\335\335\336\331 \330\323\340\353!" }, + { 199, "ScummVM \335\325 \334\336\326\325\342 \335\320\331\342\330 \330\323\340\343 \322 \343\332\320\327\320\335\335\336\331 \324\330\340\325\332\342\336\340\330\330!" }, + { 200, "ScummVM \335\325 \334\336\326\325\342 \336\342\332\340\353\342\354 \343\332\320\327\320\335\335\343\356 \324\330\340\325\332\342\336\340\330\356!" }, + { 201, "\277\336\330\341\332 \322 \341\337\330\341\332\325 \330\323\340" }, + { 202, "\277\336\330\341\332:" }, + { 203, "\262\353\321\325\340\330\342\325 SoundFont" }, + { 204, "\262\353\321\325\340\330\342\325 \342\325\334\343" }, + { 205, "\262\353\321\325\340\330\342\325 \324\336\337\336\333\335\330\342\325\333\354\335\343\356 \324\330\340\325\332\342\336\340\330\356 \330\323\340\353" }, + { 206, "\262\353\321\325\340\330\342\325 \324\325\331\341\342\322\330\325 \330 \332\333\330\332\335\330\342\325 '\275\320\327\335\320\347\330\342\354'" }, + { 207, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \324\333\357 \342\325\334 GUI" }, + { 208, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \341 \324\336\337\336\333\335\330\342\325\333\354\335\353\334\330 \344\320\331\333\320\334\330" }, + { 209, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \341 \337\333\320\323\330\335\320\334\330" }, + { 210, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \324\333\357 \341\336\345\340\320\335\325\335\330\331" }, + { 211, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \324\333\357 \341\336\345\340\320\335\325\335\330\331" }, + { 212, "\262\353\321\325\340\330\342\325 \324\330\340\325\332\342\336\340\330\356 \341 \344\320\331\333\320\334\330 \330\323\340\353" }, + { 213, "\307\343\322\341\342\322\330\342\325\333\354\335\336\341\342\354" }, + { 214, "\301\325\340\322\325\340:" }, + { 215, "\301\325\342\325\322\320\357 \337\320\337\332\320:" }, + { 216, "\272\336\340\336\342\332\330\331 \330\324\325\335\342\330\344\330\332\320\342\336\340, \330\341\337\336\333\354\327\343\325\334\353\331 \324\333\357 \330\334\325\335 \341\336\345\340\320\335\325\335\330\331 \330\323\340 \330 \324\333\357 \327\320\337\343\341\332\320 \330\327 \332\336\334\320\335\324\335\336\331 \341\342\340\336\332\330" }, + { 217, "\277\336\332\320\327\320\342\354 \332\333\320\322\330\320\342\343\340\343" }, + { 218, "\277\336\332\320\327\353\322\320\342\354 \332\343\340\341\336\340 \334\353\350\330" }, + { 219, "\277\336\332\320\327\353\322\320\342\354 \341\343\321\342\330\342\340\353 \330 \322\336\341\337\340\336\330\327\322\336\324\330\342\354 \340\325\347\354" }, + { 220, "\277\336\332\320\327\320\342\354/\303\321\340\320\342\354 \332\343\340\341\336\340" }, + { 221, "\277\340\336\337\343\341\342\330\342\354" }, + { 222, "\277\340\336\337\343\341\342\330\342\354 \341\342\340\336\332\343" }, + { 223, "\277\340\336\337\343\341\342\330\342\354 \342\325\332\341\342" }, + { 224, "\277\340\330\332\340\325\337\330\342\354 \332 \323\340\320\335\330\346\320\334" }, + { 225, "\277\340\336\323\340\320\334\334\335\336\325 \334\320\341\350\342\320\321\330\340\336\322\320\335\330\325 (\345\336\340\336\350\325\325 \332\320\347\325\341\342\322\336, \335\336 \334\325\324\333\325\335\335\325\325)" }, + { 226, "\267\322\343\332 \322\332\333/\322\353\332\333" }, + { 227, "SoundFont\353 \337\336\324\324\325\340\324\326\330\322\320\356\342\341\357 \335\325\332\336\342\336\340\353\334\330 \327\322\343\332\336\322\353\334\330 \332\320\340\342\320\334\330, Fluidsynth \330 Timidity" }, + { 228, "SoundFont:" }, + { 229, "\276\327\322" }, + { 230, "\301\337\325\346\330\320\333\354\335\353\325 \340\325\326\330\334\353 \340\325\335\324\325\340\330\335\323\320, \337\336\324\324\325\340\326\330\322\320\325\334\353\325 \335\325\332\336\342\336\340\353\334\330 \330\323\340\320\334\330" }, + { 231, "\263\340\336\334\332\336\341\342\354 \341\337\325\346\330\320\333\354\335\353\345 \327\322\343\332\336\322\353\345 \355\344\344\325\332\342\336\322" }, + { 232, "\303\332\320\327\353\322\320\325\342 \322\353\345\336\324\335\336\325 \327\322\343\332\336\322\336\325 \343\341\342\340\336\331\341\342\322\336 \324\333\357 MIDI" }, + { 233, "\303\332\320\327\353\322\320\325\342 \327\322\343\332\336\322\336\325 \343\341\342\340\336\331\341\342\322\336 \337\336 \343\334\336\333\347\320\335\330\357 \324\333\357 \322\353\322\336\324\320 \335\320 Roland MT-32/LAPC1/CM32l/CM64" }, + { 234, "\303\332\320\327\353\322\320\325\342 \322\353\345\336\324\335\336\325 \327\322\343\332\336\322\336\325 \343\341\342\340\336\331\341\342\322\336 \330\333\330 \355\334\343\333\357\342\336\340 \327\322\343\332\336\322\336\331 \332\320\340\342\353" }, + { 235, "\303\332\320\327\353\322\320\325\342 \337\343\342\354 \332 \324\336\337\336\333\335\330\342\325\333\354\335\353\334 \344\320\331\333\320\334 \324\320\335\335\353\345, \330\341\337\336\333\354\327\343\325\334\353\345 \322\341\325\334\330 \330\323\340\320\334\330, \333\330\321\336 ScummVM" }, + { 236, "\303\332\320\327\353\322\320\325\342 \337\343\342\354 \332 \324\336\337\336\333\335\330\342\325\333\354\335\353\334 \344\320\331\333\320\334 \324\320\335\335\353\345 \324\333\357 \330\323\340\353" }, + { 237, "\303\332\320\327\353\322\320\325\342 \322\353\345\336\324\335\336\325 \327\322\343\332\336\322\336\325 \343\341\342\340\336\331\341\342\322\336 \330\333\330 \355\334\343\333\357\342\336\340 \327\322\343\332\336\322\336\331 \332\320\340\342\353" }, + { 238, "\303\332\320\327\353\322\320\325\342 \337\343\342\354 \332 \341\336\345\340\320\335\325\335\330\357\334 \330\323\340\353" }, + { 239, "\276\327\322\343\347\332\320" }, + { 240, "\263\340\336\334\332. \336\327\322\343\347\332\330:" }, + { 241, "\301\342\320\335\324\320\340\342\335\353\331 \340\320\341\342\325\340\330\327\320\342\336\340 (16bpp)" }, + { 242, "\267\320\337\343\341\342\330\342\354 \322\353\321\340\320\335\335\343\356 \330\323\340\343" }, + { 243, "\301\336\341\342\336\357\335\330\325:" }, + { 244, "\301\343\321" }, + { 245, "\301\332\336\340\336\341\342\354 \342\330\342\340\336\322:" }, + { 246, "\301\343\321\342\330\342\340\353" }, + { 247, "\301\334\325\335\330\342\354 \323\325\340\336\357" }, + { 248, "\302\320\337 \324\333\357 \333\325\322\336\323\336 \351\325\333\347\332\320, \324\322\336\331\335\336\331 \342\320\337 \324\333\357 \337\340\320\322\336\323\336 \351\325\333\347\332\320" }, + { 249, "\302\325\332\341\342 \330 \336\327\322\343\347\332\320:" }, + { 250, "\275\325 \334\336\323\343 \337\330\341\320\342\354 \322 \322\353\321\340\320\335\335\343\356 \324\330\340\325\332\342\336\340\330\356. \277\336\326\320\333\343\331\341\342\320, \343\332\320\326\330\342\325 \324\340\343\323\343\356." }, + { 251, "\263\324\325 \342\325\334\353:" }, + { 252, "\302\325\334\320:" }, + { 253, "\315\342\336\342 ID \330\323\340\353 \343\326\325 \330\341\337\336\333\354\327\343\325\342\341\357. \277\336\326\320\333\343\331\341\342\320, \322\353\321\325\340\330\342\325 \324\340\343\323\336\331." }, + { 254, "\315\342\320 \330\323\340\320 \335\325 \337\336\324\324\325\340\326\330\322\320\325\342 \327\320\323\340\343\327\332\343 \341\336\345\340\320\335\325\335\330\331 \347\325\340\325\327 \323\333\320\322\335\336\325 \334\325\335\356." }, + { 255, "\262\340\325\334\357: " }, + { 256, "\262\340\325\334\357 \337\336\324\332\333\356\347\325\335\330\357 \332 \341\325\342\330 \330\341\342\325\332\333\336" }, + { 257, "\301\334\325\351\325\335\330\325 \332\320\341\320\335\330\331 \337\336 \336\341\330 X" }, + { 258, "\301\334\325\351\325\335\330\325 \332\320\341\320\335\330\331 \337\336 \336\341\330 Y" }, + { 259, "\300\325\326\330\334 \342\320\347\337\320\324\320 \322\353\332\333\356\347\325\335." }, + { 260, "\300\325\326\330\334 \342\320\347\337\320\324\320 \322\332\333\356\347\325\335." }, + { 261, "\275\320\341\342\336\357\351\330\331 Roland MT-32 (\327\320\337\340\325\342\330\342\354 \355\334\343\333\357\346\330\356 GM)" }, + { 262, "\262\353\332\333\356\347\320\325\342 \334\320\337\337\330\335\323 General MIDI \324\333\357 \330\323\340 \341 \327\322\343\332\336\322\336\331 \324\336\340\336\326\332\336\331 \324\333\357 Roland MT-32" }, + { 263, "\275\325\330\327\322\325\341\342\335\336" }, + { 264, "\275\325\330\327\322\325\341\342\335\320\357 \336\350\330\321\332\320" }, + { 265, "\276\342\332\333\356\347\330\342\354 DVD" }, + { 266, "\276\342\332\333\356\347\342\354 SMB" }, + { 267, "\261\325\327 \334\320\341\350\342\320\321\330\340\336\322\320\335\330\357 (\335\343\326\335\336 \321\343\324\325\342 \337\340\336\332\340\343\347\330\322\320\342\354 \322\333\325\322\336 \330 \322\337\340\320\322\336)" }, + { 268, "\275\325\337\336\324\324\325\340\326\330\322\320\325\334\353\331 \340\325\326\330\334 \346\322\325\342\320" }, + { 269, "\301\336\345\340\320\335\325\335\330\325 \321\325\327 \330\334\325\335\330" }, + { 270, "\262\322\325\340\345" }, + { 271, "\270\341\337\336\333\354\327\336\322\320\342\354 \330 MIDI \330 AdLib \324\333\357 \323\325\335\325\340\320\346\330\330 \327\322\343\332\320" }, + { 272, "\270\341\337\336\333\354\327\336\322\320\342\354 \343\337\340\320\322\333\325\335\330\325 \332\343\340\341\336\340\336\334 \332\320\332 \335\320 \342\340\325\332\337\320\324\325 \333\325\337\342\336\337\336\322" }, + { 273, "\277\336\333\354\327\336\322\320\342\325\333\354:" }, + { 274, "\270\341\337\336\333\354\327\343\356 \324\340\320\331\322\325\340 SDL " }, + { 275, "\262\325\340\342\330\332\320\333\354\335\353\331 underscan:" }, + { 276, "\262\330\324\325\336" }, + { 277, "\262\330\340\342\343\320\333\354\335\320\357 \332\333\320\322\330\320\342\343\340\320" }, + { 278, "\263\340\336\334\332\336\341\342\354" }, + { 279, "Windows MIDI" }, + { 280, "\275\325\324\336\341\342\320\342\336\347\335\336 \337\340\320\322 \324\333\357 \327\320\337\330\341\330" }, + { 281, "\276\350\330\321\332\320 \327\320\337\330\341\330 \324\320\335\335\353\345" }, + { 282, "\264\320" }, + { 283, "\262\353 \324\336\333\326\335\353 \337\325\340\325\327\320\337\343\341\342\330\342\354 ScummVM \347\342\336\321\353 \337\340\330\334\325\335\330\342\354 \330\327\334\325\335\325\335\330\357." }, + { 284, "\267\336\335\320" }, + { 285, "\303\334\325\335\354\350. \334\320\341\350\342\320\321" }, + { 286, "\303\322\325\333. \334\320\341\350\342\320\321" }, + { 287, "\332\320\326\324\353\325 10 \334\330\335\343\342" }, + { 288, "\332\320\326\324\353\325 15 \334\330\335\343\342" }, + { 289, "\332\320\326\324\353\325 30 \334\330\335\343\342" }, + { 290, "\332\320\326\324\353\325 5 \334\330\335\343\342" }, + { 291, "\276 \337\340\336~\323~\340\320\334\334\325" }, + { 292, "~\264~\336\321. \330\323\340\343..." }, + { 293, "\276~\342~\334\325\335\320" }, + { 294, "~\267~\320\332\340\353\342\354" }, + { 295, "\276~\337~\346\330\330 \330\323\340\353..." }, + { 296, "~\277~\336\334\336\351\354" }, + { 297, "\303\337\340\320\322\333\325\335\330\325 \321\336\357\334\330 \322 Indy" }, + { 298, "~\272~\333\320\322\330\350\330" }, + { 299, "\273\325\322\336\340\343\332\330\331 \340\325\326\330\334" }, + { 300, "~\267~\320\323\340\343\327\330\342\354" }, + { 301, "~\267~\320\323\340\343\327\330\342\354..." }, + { 302, "~\301~\333\325\324" }, + { 303, "~O~K" }, + { 304, "~\276~\337\346\330\330" }, + { 305, "~\276~\337\346\330\330..." }, + { 306, "~\277~\340\325\324" }, + { 307, "~\262~\353\345\336\324" }, + { 308, "~\303~\324\320\333\330\342\354 \330\323\340\343" }, + { 309, "\277\340\336\324\336\333~\326~\330\342\354" }, + { 310, "~\262~\353\331\342\330 \322 \323\333\320\322\335\336\325 \334\325\335\356" }, + { 311, "~\267~\320\337\330\341\320\342\354" }, + { 312, "\277~\343~\341\332" }, + { 313, "\277\325\340\325\345\336\324\353 \320\332\342\330\322\330\340\336\322\320\335\353" }, + { 314, "\315\344\344\325\332\342\353 \322\336\324\353 \322\332\333\356\347\325\335\353" }, + { 315, "\300\325\326\330\334 \321\353\341\342\340\336\323\336 \337\325\340\325\345\336\324\320 \320\332\342\330\322\330\340\336\322\320\335" }, + { -1, NULL } +}; + +static const PoMessageEntry _translation_it_IT[] = { + { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-30 22:14+0100\nPO-Revision-Date: 2010-06-30 23:56+0100\nLast-Translator: Maff <matteo.maff at gmail dot com>\nLanguage-Team: Italian\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\nLanguage: Italiano\n" }, + { 1, " Sei sicuro di voler uscire? " }, + { 2, " (Attivo)" }, + { 3, " (Gioco)" }, + { 4, " (Globale)" }, + { 5, "(build creata il %s)" }, + { 6, ", errore nel montare la condivisione" }, + { 7, ", condivisione non montata" }, + { 8, "... progresso ..." }, + { 9, "11kHz" }, + { 10, "22 kHz" }, + { 11, "44 kHz" }, + { 12, "48 kHz" }, + { 13, "8 kHz" }, + { 14, "<predefinito>" }, + { 15, "Informazioni su ScummVM" }, + { 16, "Emulatore AdLib" }, + { 17, "Emulatore AdLib:" }, + { 18, "AdLib \350 utilizzato per la musica in molti giochi" }, + { 19, "Aggiungi gioco..." }, + { 20, "Renderer con antialiasing (16bpp)" }, + { 21, "Correzione proporzioni" }, + { 22, "Tasto associato: %s" }, + { 23, "Tasto associato: nessuno" }, + { 24, "Audio" }, + { 25, "Autosalva:" }, + { 26, "Motori disponibili:" }, + { 27, "~I~nfo..." }, + { 28, "Associa tasti" }, + { 29, "Entrambi" }, + { 30, "Luminosit\340:" }, + { 31, "Annulla" }, + { 32, "Impossibile creare il file" }, + { 33, "Modifica le opzioni di gioco" }, + { 34, "Modifica le opzioni globali di ScummVM" }, + { 35, "Seleziona se vuoi usare il dispositivo hardware audio compatibile con Roland che \350 connesso al tuo computer" }, + { 36, "Scegli" }, + { 37, "Scegli un'azione da mappare" }, + { 38, "Cancella" }, + { 39, "Chiudi" }, + { 40, "Corregge le proporzioni dei giochi 320x200" }, + { 41, "Impossibile trovare un motore in grado di eseguire il gioco selezionato" }, + { 42, "Modalit\340 video attuale:" }, + { 43, "Cursore gi\371" }, + { 44, "Cursore a sinistra" }, + { 45, "Cursore a destra" }, + { 46, "Cursore su" }, + { 47, "Emulatore OPL DOSBox" }, + { 48, "DVD" }, + { 49, "DVD montato con successo" }, + { 50, "DVD non montato" }, + { 51, "Data: " }, + { 52, "Debugger" }, + { 53, "Predefinito" }, + { 54, "Elimina" }, + { 55, "Disattiva spegnimento in chiusura" }, + { 56, "Grafica disattivata" }, + { 57, "Rilevati %d nuovi giochi..." }, + { 58, "Rilevati %d nuovi giochi." }, + { 59, "Visualizza " }, + { 60, "Mostra tastiera" }, + { 61, "Sei sicuro di voler eliminare questo salvataggio?" }, + { 62, "Sei sicuro di voler rimuovere questa configurazione di gioco?" }, + { 63, "Vuoi davvero eseguire il rilevatore di giochi in massa? Potrebbe aggiungere un numero enorme di giochi." }, + { 64, "Vuoi caricare o salvare il gioco?" }, + { 65, "Vuoi eseguire una scansione automatica?" }, + { 66, "Sei sicuro di voler uscire?" }, + { 67, "Double-strike" }, + { 68, "Gi\371" }, + { 69, "Attiva la modalit\340 Roland GS" }, + { 70, "Il motore non supporta il livello di debug '%s'" }, + { 71, "Inglese" }, + { 72, "Errore nell'esecuzione del gioco:" }, + { 73, "Errore nel montare il DVD" }, + { 74, "Percorso extra:" }, + { 75, "Emulatore FM Towns" }, + { 76, "Modalit\340 veloce" }, + { 77, "Funzionalit\340 compilate in:" }, + { 78, "Osservazione libera" }, + { 79, "Titolo completo del gioco" }, + { 80, "Modalit\340 a schermo intero" }, + { 81, "Accelerazione pad GC:" }, + { 82, "Sensibilit\340 pad GC:" }, + { 83, "Grafica" }, + { 84, "Dispositivo GM:" }, + { 85, "Lingua GUI:" }, + { 86, "Renderer GUI:" }, + { 87, "Gioco" }, + { 88, "Dati di gioco non trovati" }, + { 89, "ID di gioco non supportato" }, + { 90, "Percorso gioco:" }, + { 91, "Menu globale" }, + { 92, "Vai alla cartella superiore" }, + { 93, "Cartella superiore" }, + { 94, "Grafica" }, + { 95, "Modalit\340:" }, + { 96, "Ridimensionamento hardware (veloce, ma di bassa qualit\340)" }, + { 97, "Hercules ambra" }, + { 98, "Hercules verde" }, + { 99, "Nascondi la barra degli strumenti" }, + { 100, "Audio ad alta qualit\340 (pi\371 lento) (riavviare)" }, + { 101, "Valori pi\371 alti restituiscono un suono di maggior qualit\340, ma potrebbero non essere supportati dalla tua scheda audio" }, + { 102, "Tieni premuto Shift per l'aggiunta in massa" }, + { 103, "Underscan orizzontale:" }, + { 104, "Emulatore IBM PCjr" }, + { 105, "ID:" }, + { 106, "Avvia rete" }, + { 107, "Schermo in primo piano:" }, + { 108, "Avvio in corso dell'emulatore MT-32" }, + { 109, "Avvio rete in corso" }, + { 110, "Input" }, + { 111, "Percorso non valido" }, + { 112, "Programmatore tasti" }, + { 113, "Tastiera" }, + { 114, "Mappa tasti:" }, + { 115, "Tasti" }, + { 116, "Lingua dell'interfaccia grafica di ScummVM" }, + { 117, "Lingua del gioco. Un gioco inglese non potr\340 risultare tradotto in italiano" }, + { 118, "Lingua:" }, + { 119, "Sinistra" }, + { 120, "Clic sinistro" }, + { 121, "Carica" }, + { 122, "Carica gioco:" }, + { 123, "Carica un salvataggio del gioco selezionato" }, + { 124, "Emulatore OPL MAME" }, + { 125, "MIDI" }, + { 126, "Guadagno MIDI:" }, + { 128, "Disposit. MT32:" }, + { 129, "Emulatore MT-32" }, + { 130, "Schermo principale:" }, + { 131, "Mappa" }, + { 132, "Agg. in massa..." }, + { 133, "Menu" }, + { 134, "Varie" }, + { 135, "Modalit\340 mista AdLib/MIDI" }, + { 136, "Monta DVD" }, + { 137, "Monta SMB" }, + { 138, "Clic del mouse" }, + { 139, "Multifunzione" }, + { 140, "Dispositivo GM:" }, + { 141, "Volume musica:" }, + { 142, "Disattiva audio" }, + { 143, "Nome:" }, + { 144, "Rete disattivata" }, + { 145, "Rete non avviata (%d)" }, + { 146, "Rete attiva" }, + { 147, "Rete attiva, condivisione montata" }, + { 148, "Mai" }, + { 149, "No" }, + { 150, "Nessuna data salvata" }, + { 151, "Nessuna musica" }, + { 152, "Nessun tempo salvato" }, + { 153, "Nessun orario salvato" }, + { 154, "Nessuno" }, + { 155, "Normale (nessun ridimensionamento)" }, + { 156, "OK" }, + { 157, "Frequenza:" }, + { 158, "Ignora le impostazioni MIDI globali" }, + { 159, "Ignora le impostazioni MIDI globali" }, + { 160, "Ignora le impostazioni audio globali" }, + { 161, "Ignora le impostazioni grafiche globali" }, + { 162, "Ignora le impostazioni globali di volume" }, + { 163, "Emulatore PC Speaker" }, + { 164, "Password:" }, + { 165, "Il percorso non \350 una cartella" }, + { 166, "Il percorso non \350 un file" }, + { 167, "Il percorso non esiste" }, + { 168, "Percorsi" }, + { 169, "Pausa" }, + { 170, "Scegli il gioco:" }, + { 171, "La piattaforma per la quale il gioco \350 stato concepito" }, + { 172, "Piattaforma:" }, + { 173, "Tempo di gioco: " }, + { 174, "Seleziona un'azione" }, + { 175, "Percorso plugin:" }, + { 176, "Disp. preferito:" }, + { 177, "Premi il tasto da associare" }, + { 178, "Esci" }, + { 179, "Chiudi ScummVM" }, + { 180, "Autorizzazione di lettura negata" }, + { 181, "Lettura fallita" }, + { 182, "Riprogramma tasti" }, + { 183, "Rimuove il gioco dalla lista. I file del gioco rimarranno intatti" }, + { 184, "Resa grafica:" }, + { 185, "Destra" }, + { 186, "Clic destro" }, + { 187, "Clic destro" }, + { 188, "Rotazione" }, + { 189, "Volume effetti:" }, + { 190, "SMB" }, + { 191, "Salva" }, + { 192, "Salvataggi:" }, + { 193, "Salvataggi:" }, + { 194, "Salva gioco:" }, + { 195, "Scansione completa!" }, + { 196, "%d cartelle analizzate..." }, + { 197, "Menu principale di ScummVM" }, + { 198, "ScummVM non ha potuto trovare un motore in grado di eseguire il gioco selezionato!" }, + { 199, "ScummVM non ha potuto trovare nessun gioco nella cartella specificata!" }, + { 200, "ScummVM non ha potuto aprire la cartella specificata!" }, + { 201, "Cerca nella lista dei giochi" }, + { 202, "Cerca:" }, + { 203, "Seleziona SoundFont" }, + { 204, "Seleziona un tema" }, + { 205, "Seleziona la cartella di gioco aggiuntiva" }, + { 206, "Seleziona un'azione e clicca 'Mappa'" }, + { 207, "Seleziona la cartella dei temi dell'interfaccia" }, + { 208, "Seleziona la cartella dei file aggiuntivi" }, + { 209, "Seleziona la cartella dei plugin" }, + { 210, "Seleziona la cartella dei salvataggi" }, + { 211, "Seleziona la cartella per i salvataggi" }, + { 212, "Seleziona la cartella contenente i file di gioco" }, + { 213, "Sensibilit\340" }, + { 214, "Server:" }, + { 215, "Condivisione:" }, + { 216, "Breve identificatore di gioco utilizzato per il riferimento a salvataggi e per l'esecuzione del gioco dalla riga di comando" }, + { 217, "Mostra tastiera" }, + { 218, "Mostra cursore del mouse" }, + { 219, "Mostra i sottotitoli e attiva le voci" }, + { 220, "Mostra/nascondi cursore" }, + { 221, "Salta" }, + { 222, "Salta battuta" }, + { 223, "Salta testo" }, + { 224, "Aggancia ai bordi" }, + { 225, "Ridimensionamento software (di buona qualit\340, ma pi\371 lento)" }, + { 226, "Suono on/off" }, + { 227, "SoundFont \350 supportato da alcune schede audio, Fluidsynth e Timidity" }, + { 228, "SoundFont:" }, + { 229, "Voci" }, + { 230, "Modalit\340 di resa grafica speciali supportate da alcuni giochi" }, + { 231, "Volume degli effetti sonori" }, + { 232, "Specifica il dispositivo audio predefinito per l'output General MIDI" }, + { 233, "Specifica il dispositivo audio predefinito per l'output Roland MT-32/LAPC1/CM32l/CM64" }, + { 234, "Specifica il dispositivo di output audio o l'emulatore della scheda audio" }, + { 235, "Specifica il percorso di ulteriori dati usati dai giochi o da ScummVM" }, + { 236, "Specifica il percorso di ulteriori dati usati dal gioco" }, + { 237, "Specifica il dispositivo audio o l'emulatore della scheda audio preferiti" }, + { 238, "Specifica dove archiviare i salvataggi" }, + { 239, "Voci" }, + { 240, "Volume voci:" }, + { 241, "Renderer standard (16bpp)" }, + { 242, "Esegue il gioco selezionato" }, + { 243, "Stato:" }, + { 244, "Sub" }, + { 245, "Velocit\340 testo:" }, + { 246, "Sottotitoli" }, + { 247, "Cambia personaggio" }, + { 248, "Un tocco per il clic sinistro, doppio tocco per il clic destro" }, + { 249, "Testo e voci:" }, + { 250, "La cartella scelta \350 in sola lettura. Si prega di sceglierne un'altra." }, + { 251, "Percorso tema:" }, + { 252, "Tema:" }, + { 253, "Questo ID di gioco \350 gi\340 in uso. Si prega di sceglierne un'altro." }, + { 254, "Questo gioco non supporta il caricamento di salvataggi dalla schermata di avvio." }, + { 255, "Ora: " }, + { 256, "Attesa per l'avvio della rete" }, + { 257, "Compensa X del tocco" }, + { 258, "Compensa Y del tocco" }, + { 259, "Modalit\340 touchpad disattivata." }, + { 260, "Modalit\340 touchpad attivata." }, + { 261, "Roland MT-32 effettivo (disattiva emulazione GM)" }, + { 262, "Disattiva la mappatura General MIDI per i giochi con colonna sonora Roland MT-32" }, + { 263, "Sconosciuto" }, + { 264, "Errore sconosciuto" }, + { 265, "Smonta DVD" }, + { 266, "Smonta SMB" }, + { 267, "Non ridimensionato (devi scorrere a sinistra e a destra)" }, + { 268, "Modalit\340 colore non supportata" }, + { 269, "Salvataggio senza titolo" }, + { 270, "Su" }, + { 271, "Utilizza generazione di suono sia MIDI che AdLib" }, + { 272, "Utilizza il controllo del cursore stile trackpad del portatile" }, + { 273, "Nome utente:" }, + { 274, "Utilizzo del driver SDL " }, + { 275, "Underscan verticale:" }, + { 276, "Video" }, + { 277, "Tastiera virtuale" }, + { 278, "Volume" }, + { 279, "MIDI Windows" }, + { 280, "Autorizzazione di scrittura negata" }, + { 281, "Scrittura dati fallita" }, + { 282, "S\354" }, + { 283, "Devi riavviare ScummVM affinch\351 le modifiche abbiano effetto." }, + { 284, "Zona" }, + { 285, "Zoom indietro" }, + { 286, "Zoom avanti" }, + { 287, "ogni 10 minuti" }, + { 288, "ogni 15 minuti" }, + { 289, "ogni 30 minuti" }, + { 290, "ogni 5 minuti" }, + { 291, "~I~nfo" }, + { 292, "~A~ggiungi gioco..." }, + { 293, "~A~nnulla" }, + { 294, "~C~hiudi" }, + { 295, "~M~odifica gioco..." }, + { 296, "~A~iuto" }, + { 297, "Controlli combattimento di ~I~ndy" }, + { 298, "~T~asti" }, + { 299, "~M~odalit\340 mancini" }, + { 300, "~C~arica" }, + { 301, "~C~arica..." }, + { 302, "~S~uccessivi" }, + { 303, "~O~K" }, + { 304, "~O~pzioni" }, + { 305, "~O~pzioni..." }, + { 306, "~P~recedenti" }, + { 307, "C~h~iudi" }, + { 308, "~R~imuovi gioco" }, + { 309, "~R~ipristina" }, + { 310, "~V~ai a schermata di avvio" }, + { 311, "~S~alva" }, + { 312, "~G~ioca" }, + { 313, "~T~ransizioni attive" }, + { 314, "~E~ffetto acqua attivo" }, + { 315, "Modalit\340 ~Z~ip attivata" }, + { -1, NULL } +}; + +static const PoMessageEntry _translation_hu_HU[] = { + { 0, "Project-Id-Version: ScummVM VERSION\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-30 22:14+0100\nPO-Revision-Date: 2009-11-25 07:42-0500\nLast-Translator: Alex Bevilacqua <alexbevi@gmail.com>\nLanguage-Team: Hungarian\nMIME-Version: 1.0\nContent-Type: text/plain; charset=cp1250\nContent-Transfer-Encoding: 8bit\nLanguage: \nPlural-Forms: nplurals=2; plural=(n != 1);\n" }, + { 14, "<alap\351rtelmezett>" }, + { 16, "AdLib vezet :" }, + { 17, "AdLib vezet :" }, + { 21, "Aspect adag korrekci\363" }, + { 24, "Hang" }, + { 25, "Automatikus ment\351s:" }, + { 28, "Kulcsok" }, + { 42, "Renderel\351si m\363d:" }, + { 53, "<alap\351rtelmezett>" }, + { 69, "K\351pess\351 Roland GS Mode" }, + { 74, "Extra \332tvonal:" }, + { 76, "Grafikus m\363d:" }, + { 80, "Teljes k\351perny s m\363d:" }, + { 86, "Lek\351pez eszk\366z GUI:" }, + { 90, "Extra \332tvonal:" }, + { 94, "Grafik\341val" }, + { 95, "Grafikus m\363d:" }, + { 115, "Kulcsok" }, + { 124, "AdLib vezet :" }, + { 126, "MIDI nyeres\351g:" }, + { 128, "Zene mennyis\351g:" }, + { 135, "Vegyes AdLib/MIDI m\363d" }, + { 140, "Zene mennyis\351g:" }, + { 141, "Zene mennyis\351g:" }, + { 142, "Muta \326sszes" }, + { 148, "Soha" }, + { 149, "Semmi" }, + { 154, "Semmi" }, + { 156, "Igen" }, + { 157, "Kimeneti teljes\355tm\351ny:" }, + { 168, "\326sv\351nyek" }, + { 169, "\326sv\351nyek" }, + { 184, "Renderel\351si m\363d:" }, + { 189, "SFX mennyis\351ge" }, + { 192, "Extra \332tvonal:" }, + { 214, "Soha" }, + { 239, "Csak a besz\351d" }, + { 240, "Besz\351d mennyis\351g:" }, + { 245, "Felirat sebess\351g:" }, + { 246, "Csak feliratok" }, + { 249, "Sz\366veg \351s besz\351d:" }, + { 252, "T\351ma:" }, + { 255, "T\351ma:" }, + { 261, "Igaz Roland MT-32 (megb\351n\355t GM emul\341ci\363)" }, + { 274, "Zenei vezet :" }, + { 278, "Volumene" }, + { 284, "Semmi" }, + { 287, "10 percenk\351nt" }, + { 288, "15 percenk\351nt" }, + { 289, "30 percenk\351nt" }, + { 290, "5 percenk\351nt" }, + { 298, "Kulcsok" }, + { 299, "Renderel\351si m\363d:" }, + { 303, "Igen" }, { -1, NULL } }; static const PoMessageEntry _translation_fr_FR[] = { - { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-12 17:44+0200\nPO-Revision-Date: 2010-07-09 18:17+0100\nLast-Translator: Thierry Crozat <criezy@scummvm.org>\nLanguage-Team: French <scummvm-devel@lists.sf.net>\nLanguage: Francais\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=n>1;\n" }, + { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-30 22:14+0100\nPO-Revision-Date: 2010-07-30 22:18+0100\nLast-Translator: Thierry Crozat <criezy@scummvm.org>\nLanguage-Team: French <scummvm-devel@lists.sf.net>\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\nLanguage: Francais\nPlural-Forms: nplurals=2; plural=n>1;\n" }, { 1, "Voulez-vous vraiment quitter?" }, { 2, "(Actif)" }, { 3, "(Jeu)" }, @@ -769,516 +1151,520 @@ static const PoMessageEntry _translation_fr_FR[] = { { 124, "\311mulateur MAME OPL" }, { 125, "MIDI" }, { 126, "Gain MIDI:" }, - { 127, "Sortie MT-32:" }, - { 128, "\311mulateur MT-32" }, - { 129, "\311chelle de l'\351cran principal" }, - { 130, "Affecter" }, - { 131, "Ajout Massif..." }, - { 132, "Menu" }, - { 133, "Divers" }, - { 134, "Mode mixe AdLib/MIDI" }, - { 135, "Monter le DVD" }, - { 136, "Monter SMB" }, - { 137, "Clic de souris" }, - { 138, "Fonction Multiple" }, - { 139, "Sortie Audio:" }, - { 140, "Volume Musique:" }, - { 141, "Silence" }, - { 142, "Nom:" }, - { 143, "R\351seau d\351connect\351" }, - { 144, "R\351seau non initialis\351 (%d)" }, - { 145, "R\351seau connect\351" }, - { 146, "R\351seau connect\351, disque partag\351 mont\351" }, - { 147, "Jamais" }, - { 148, "Non" }, - { 149, "Date non sauv\351e" }, - { 150, "Pas de musique" }, - { 151, "Dur\351e de jeu non sauv\351e" }, - { 152, "Heure non sauv\351e" }, - { 153, "Aucun" }, - { 154, "Normal (\351chelle d'origine)" }, - { 155, "OK" }, - { 156, "Fr\351quence:" }, - { 157, "Utiliser des r\351glages MIDI sp\351cifiques \340 ce jeux" }, - { 158, "Utiliser des r\351glages audio sp\351cifiques \340 ce jeux" }, - { 159, "Utiliser des r\351glages graphiques sp\351cifiques \340 ce jeux" }, - { 160, "Utiliser des r\351glages de volume sonore sp\351cifiques \340 ce jeux" }, - { 161, "\311mulateur Haut Parleur PC" }, - { 162, "Mot de passe:" }, - { 163, "Chemin n'est pas un r\351pertoire" }, - { 164, "Chemin n'est pas un fichier" }, - { 165, "Chemin inexistant" }, - { 166, "Chemins" }, - { 167, "Mettre en pause" }, - { 168, "Choisissez le jeu:" }, - { 169, "Plateforme pour laquelle votre jeu a \351t\351 con\347u" }, - { 170, "Plateforme:" }, - { 171, "Dur\351e de jeu:" }, - { 172, "Selectionnez une action" }, - { 173, "Plugins:" }, - { 174, "Sortie Pr\351f\351r\351:" }, - { 175, "Appuyez sur la touche \340 associer" }, - { 176, "Quitter" }, - { 177, "Quitter ScummVM" }, - { 178, "V\351roulli\351 en lecture" }, - { 179, "Echec de la lecture" }, - { 180, "Changer l'affectation des touches" }, - { 181, "Supprime le jeu de la liste. Les fichiers sont conserv\351s" }, - { 182, "Mode de rendu:" }, - { 183, "Droite" }, - { 184, "Clic Droit" }, - { 185, "Clic droit" }, - { 186, "Pivoter" }, - { 187, "Volume Bruitage:" }, - { 188, "SMB" }, - { 189, "Sauver" }, - { 190, "Sauvegardes:" }, - { 191, "Sauvegardes:" }, - { 192, "Sauvegarde:" }, - { 193, "Examen termin\351!" }, - { 194, "%d r\351pertoires examin\351s ..." }, - { 195, "Menu Principal ScummVM" }, - { 196, "ScummVM n'a pas pu trouv\351 de moteur pour lancer le jeu s\351lectionn\351." }, - { 197, "ScummVM n'a pas trouv\351 de jeux dans le r\351pertoire s\351lectionn\351." }, - { 198, "ScummVM n'a pas pu ouvrir le r\351pertoire s\351lectionn\351." }, - { 199, "Recherche dans la liste de jeux" }, - { 200, "Filtre:" }, - { 201, "Choisir une banque de sons" }, - { 202, "S\351lectionnez un Th\350me" }, - { 203, "S\351lectionner un r\351pertoire suppl\351mentaire" }, - { 204, "Selectionez une action et cliquez 'Affecter'" }, - { 205, "S\351lectionner le r\351pertoire des th\350mes d'interface" }, - { 206, "S\351lectionner le r\351pertoire pour les fichiers supl\351mentaires" }, - { 207, "S\351lectionner le r\351pertoire des plugins" }, - { 208, "S\351lectionner le r\351pertoire pour les sauvegardes" }, - { 209, "S\351lectionner le r\351pertoire pour les sauvegardes" }, - { 210, "S\351lectionner le r\351pertoire contenant les donn\351es du jeu" }, - { 211, "Sensibilit\351" }, - { 212, "Serveur:" }, - { 213, "Disque partag\351:" }, - { 214, "ID compact du jeu utilis\351 pour identifier les sauvegardes et d\351marrer le jeu depuis la ligne de commande" }, - { 215, "Afficher le clavier" }, - { 216, "Afficher le curseur de la souris" }, - { 217, "Affiche les sous-titres et joue les dialogues audio" }, - { 218, "Afficher/Cacher le curseur" }, - { 219, "Passer" }, - { 220, "Passer la phrase" }, - { 221, "Sauter le texte" }, - { 222, "Aligner sur les bords" }, - { 223, "Mise \340 l'\351chelle logicielle (bonne qualit\351 mais plus lent)" }, - { 224, "Audio marche/arr\352t" }, - { 225, "La banque de sons est utilis\351e par certaines cartes audio, Fluidsynth et Timidity" }, - { 226, "Banque de sons:" }, - { 227, "Audio" }, - { 228, "Mode sp\351cial de tramage support\351 par certains jeux" }, - { 229, "Volume des effets sp\351ciaux sonores" }, - { 230, "Sp\351cifie le p\351riph\351rique audio par d\351faut pour la sortie General MIDI" }, - { 231, "Sp\351cifie le p\351riph\351rique audio par d\351faut pour la sortie Roland MT-32/LAPC1/CM32l/CM64" }, - { 232, "Sp\351cifie le p\351riph\351rique de sortie audio ou l'\351mulateur de carte audio" }, - { 233, "Sp\351cifie un chemin vers des donn\351es suppl\351mentaires utilis\351es par tous les jeux ou ScummVM" }, - { 234, "D\351finie un chemin vers des donn\351es supl\351mentaires utilis\351es par le jeu" }, - { 235, "Sp\351cifie le p\351riph\351rique de sortie audio ou l'\351mulateur de carte audio pr\351f\351r\351" }, - { 236, "D\351finie l'emplacement o\371 les fichiers de sauvegarde sont cr\351\351s" }, - { 237, "Audio" }, - { 238, "Volume Dialogues:" }, - { 239, "Standard (16bpp)" }, - { 240, "D\351marre le jeu s\351lectionn\351" }, - { 241, "Status:" }, - { 242, "Subs" }, - { 243, "Vitesse des ST:" }, - { 244, "Sous-titres" }, - { 245, "Changement de personnage" }, - { 246, "Toucher pour un clic gauche, toucher deux fois pour un clic droit" }, - { 247, "Dialogue:" }, - { 248, "Le r\351pertoire s\351lectionn\351 est v\351rouill\351 en \351criture. S\351lectionnez un autre r\351pertoire." }, - { 249, "Th\350mes:" }, - { 250, "Th\350me:" }, - { 251, "Cet ID est d\351j\340 utilis\351 par un autre jeu. Choisissez en un autre svp." }, - { 252, "Le chargement de sauvegarde depuis le lanceur n'est pas support\351 pour ce jeu." }, - { 253, "Heure:" }, - { 254, "D\351passement du d\351lai lors de l'initialisation du r\351seau" }, - { 255, "D\351calage X du toucher" }, - { 256, "D\351callage Y du toucher" }, - { 257, "Mode touchpad d\351sactiv\351" }, - { 258, "Mode touchpad activ\351" }, - { 259, "Roland MT-32 exacte (d\351sactive l'\351mulation GM)" }, - { 260, "D\351sactiver la conversion des pistes MT-32 en General MIDI" }, - { 261, "Inconue" }, - { 262, "Erreur inconnue" }, - { 263, "D\351monter le DVD" }, - { 264, "D\351monter SMB" }, - { 265, "Sans changement d'\351chelle (vous devez faire d\351filer l'\351cran)" }, - { 266, "Mode de couleurs non support\351" }, - { 267, "Sauvegarde sans nom" }, - { 268, "Haut" }, - { 269, "Utiliser \340 la fois MIDI et AdLib" }, - { 270, "Activer le contr\364le du curseur de type trackpad" }, - { 271, "Nom d'utilisateur:" }, - { 272, "Utilise le pilote SDL" }, - { 273, "Underscan vertical:" }, - { 274, "Vid\351o" }, - { 275, "Clavier virtuel" }, - { 276, "Volume" }, - { 277, "MIDI Windows" }, - { 278, "Verrouill\351 en \351criture" }, - { 279, "Echec de l'\351criture des donn\351es" }, - { 280, "Oui" }, - { 281, "Vous devez relancer ScummVM pour que le changement soit pris en compte." }, - { 282, "Zone" }, - { 283, "Zoomer" }, - { 284, "D\351zoomer" }, - { 285, "Toutes les 10 mins" }, - { 286, "Toutes les 15 mins" }, - { 287, "Toutes les 30 mins" }, - { 288, "Toutes les 5 mins" }, - { 289, "\300 ~P~ropos" }, - { 290, "~A~jouter..." }, - { 291, "~A~nnuler" }, - { 292, "~F~ermer" }, - { 293, "~E~diter..." }, - { 294, "~A~ide" }, - { 295, "Contr\364le des combats d'~I~ndy" }, - { 296, "~T~ouches" }, - { 297, "Mode ~G~aucher" }, - { 298, "~C~harger" }, - { 299, "~C~harger" }, - { 300, "~S~uivant" }, - { 301, "~O~K" }, - { 302, "~O~ptions" }, - { 303, "~O~ptions..." }, - { 304, "~P~r\351c\351dent" }, - { 305, "~Q~uitter" }, - { 306, "~S~upprimer" }, - { 307, "~R~eprendre" }, - { 308, "Retour au ~L~anceur" }, - { 309, "~S~auver" }, - { 310, "~D~\351marrer" }, - { 311, "T~r~ansitions activ\351" }, - { 312, "~E~ffets de l'Eau Activ\351s" }, - { 313, "Mode ~Z~ip Activ\351" }, + { 127, "MT-32" }, + { 128, "Sortie MT-32:" }, + { 129, "\311mulateur MT-32" }, + { 130, "\311chelle de l'\351cran principal" }, + { 131, "Affecter" }, + { 132, "Ajout Massif..." }, + { 133, "Menu" }, + { 134, "Divers" }, + { 135, "Mode mixe AdLib/MIDI" }, + { 136, "Monter le DVD" }, + { 137, "Monter SMB" }, + { 138, "Clic de souris" }, + { 139, "Fonction Multiple" }, + { 140, "Sortie Audio:" }, + { 141, "Volume Musique:" }, + { 142, "Silence" }, + { 143, "Nom:" }, + { 144, "R\351seau d\351connect\351" }, + { 145, "R\351seau non initialis\351 (%d)" }, + { 146, "R\351seau connect\351" }, + { 147, "R\351seau connect\351, disque partag\351 mont\351" }, + { 148, "Jamais" }, + { 149, "Non" }, + { 150, "Date non sauv\351e" }, + { 151, "Pas de musique" }, + { 152, "Dur\351e de jeu non sauv\351e" }, + { 153, "Heure non sauv\351e" }, + { 154, "Aucun" }, + { 155, "Normal (\351chelle d'origine)" }, + { 156, "OK" }, + { 157, "Fr\351quence:" }, + { 158, "Utiliser des r\351glages MIDI sp\351cifiques \340 ce jeux" }, + { 159, "Utiliser des r\351glages MT-32 sp\351cifiques \340 ce jeux" }, + { 160, "Utiliser des r\351glages audio sp\351cifiques \340 ce jeux" }, + { 161, "Utiliser des r\351glages graphiques sp\351cifiques \340 ce jeux" }, + { 162, "Utiliser des r\351glages de volume sonore sp\351cifiques \340 ce jeux" }, + { 163, "\311mulateur Haut Parleur PC" }, + { 164, "Mot de passe:" }, + { 165, "Chemin n'est pas un r\351pertoire" }, + { 166, "Chemin n'est pas un fichier" }, + { 167, "Chemin inexistant" }, + { 168, "Chemins" }, + { 169, "Mettre en pause" }, + { 170, "Choisissez le jeu:" }, + { 171, "Plateforme pour laquelle votre jeu a \351t\351 con\347u" }, + { 172, "Plateforme:" }, + { 173, "Dur\351e de jeu:" }, + { 174, "Selectionnez une action" }, + { 175, "Plugins:" }, + { 176, "Sortie Pr\351f\351r\351:" }, + { 177, "Appuyez sur la touche \340 associer" }, + { 178, "Quitter" }, + { 179, "Quitter ScummVM" }, + { 180, "V\351roulli\351 en lecture" }, + { 181, "Echec de la lecture" }, + { 182, "Changer l'affectation des touches" }, + { 183, "Supprime le jeu de la liste. Les fichiers sont conserv\351s" }, + { 184, "Mode de rendu:" }, + { 185, "Droite" }, + { 186, "Clic Droit" }, + { 187, "Clic droit" }, + { 188, "Pivoter" }, + { 189, "Volume Bruitage:" }, + { 190, "SMB" }, + { 191, "Sauver" }, + { 192, "Sauvegardes:" }, + { 193, "Sauvegardes:" }, + { 194, "Sauvegarde:" }, + { 195, "Examen termin\351!" }, + { 196, "%d r\351pertoires examin\351s ..." }, + { 197, "Menu Principal ScummVM" }, + { 198, "ScummVM n'a pas pu trouv\351 de moteur pour lancer le jeu s\351lectionn\351." }, + { 199, "ScummVM n'a pas trouv\351 de jeux dans le r\351pertoire s\351lectionn\351." }, + { 200, "ScummVM n'a pas pu ouvrir le r\351pertoire s\351lectionn\351." }, + { 201, "Recherche dans la liste de jeux" }, + { 202, "Filtre:" }, + { 203, "Choisir une banque de sons" }, + { 204, "S\351lectionnez un Th\350me" }, + { 205, "S\351lectionner un r\351pertoire suppl\351mentaire" }, + { 206, "Selectionez une action et cliquez 'Affecter'" }, + { 207, "S\351lectionner le r\351pertoire des th\350mes d'interface" }, + { 208, "S\351lectionner le r\351pertoire pour les fichiers supl\351mentaires" }, + { 209, "S\351lectionner le r\351pertoire des plugins" }, + { 210, "S\351lectionner le r\351pertoire pour les sauvegardes" }, + { 211, "S\351lectionner le r\351pertoire pour les sauvegardes" }, + { 212, "S\351lectionner le r\351pertoire contenant les donn\351es du jeu" }, + { 213, "Sensibilit\351" }, + { 214, "Serveur:" }, + { 215, "Disque partag\351:" }, + { 216, "ID compact du jeu utilis\351 pour identifier les sauvegardes et d\351marrer le jeu depuis la ligne de commande" }, + { 217, "Afficher le clavier" }, + { 218, "Afficher le curseur de la souris" }, + { 219, "Affiche les sous-titres et joue les dialogues audio" }, + { 220, "Afficher/Cacher le curseur" }, + { 221, "Passer" }, + { 222, "Passer la phrase" }, + { 223, "Sauter le texte" }, + { 224, "Aligner sur les bords" }, + { 225, "Mise \340 l'\351chelle logicielle (bonne qualit\351 mais plus lent)" }, + { 226, "Audio marche/arr\352t" }, + { 227, "La banque de sons est utilis\351e par certaines cartes audio, Fluidsynth et Timidity" }, + { 228, "Banque de sons:" }, + { 229, "Audio" }, + { 230, "Mode sp\351cial de tramage support\351 par certains jeux" }, + { 231, "Volume des effets sp\351ciaux sonores" }, + { 232, "Sp\351cifie le p\351riph\351rique audio par d\351faut pour la sortie General MIDI" }, + { 233, "Sp\351cifie le p\351riph\351rique audio par d\351faut pour la sortie Roland MT-32/LAPC1/CM32l/CM64" }, + { 234, "Sp\351cifie le p\351riph\351rique de sortie audio ou l'\351mulateur de carte audio" }, + { 235, "Sp\351cifie un chemin vers des donn\351es suppl\351mentaires utilis\351es par tous les jeux ou ScummVM" }, + { 236, "D\351finie un chemin vers des donn\351es supl\351mentaires utilis\351es par le jeu" }, + { 237, "Sp\351cifie le p\351riph\351rique de sortie audio ou l'\351mulateur de carte audio pr\351f\351r\351" }, + { 238, "D\351finie l'emplacement o\371 les fichiers de sauvegarde sont cr\351\351s" }, + { 239, "Audio" }, + { 240, "Volume Dialogues:" }, + { 241, "Standard (16bpp)" }, + { 242, "D\351marre le jeu s\351lectionn\351" }, + { 243, "Status:" }, + { 244, "Subs" }, + { 245, "Vitesse des ST:" }, + { 246, "Sous-titres" }, + { 247, "Changement de personnage" }, + { 248, "Toucher pour un clic gauche, toucher deux fois pour un clic droit" }, + { 249, "Dialogue:" }, + { 250, "Le r\351pertoire s\351lectionn\351 est v\351rouill\351 en \351criture. S\351lectionnez un autre r\351pertoire." }, + { 251, "Th\350mes:" }, + { 252, "Th\350me:" }, + { 253, "Cet ID est d\351j\340 utilis\351 par un autre jeu. Choisissez en un autre svp." }, + { 254, "Le chargement de sauvegarde depuis le lanceur n'est pas support\351 pour ce jeu." }, + { 255, "Heure:" }, + { 256, "D\351passement du d\351lai lors de l'initialisation du r\351seau" }, + { 257, "D\351calage X du toucher" }, + { 258, "D\351callage Y du toucher" }, + { 259, "Mode touchpad d\351sactiv\351" }, + { 260, "Mode touchpad activ\351" }, + { 261, "Roland MT-32 exacte (d\351sactive l'\351mulation GM)" }, + { 262, "D\351sactiver la conversion des pistes MT-32 en General MIDI" }, + { 263, "Inconue" }, + { 264, "Erreur inconnue" }, + { 265, "D\351monter le DVD" }, + { 266, "D\351monter SMB" }, + { 267, "Sans changement d'\351chelle (vous devez faire d\351filer l'\351cran)" }, + { 268, "Mode de couleurs non support\351" }, + { 269, "Sauvegarde sans nom" }, + { 270, "Haut" }, + { 271, "Utiliser \340 la fois MIDI et AdLib" }, + { 272, "Activer le contr\364le du curseur de type trackpad" }, + { 273, "Nom d'utilisateur:" }, + { 274, "Utilise le pilote SDL" }, + { 275, "Underscan vertical:" }, + { 276, "Vid\351o" }, + { 277, "Clavier virtuel" }, + { 278, "Volume" }, + { 279, "MIDI Windows" }, + { 280, "Verrouill\351 en \351criture" }, + { 281, "Echec de l'\351criture des donn\351es" }, + { 282, "Oui" }, + { 283, "Vous devez relancer ScummVM pour que le changement soit pris en compte." }, + { 284, "Zone" }, + { 285, "Zoomer" }, + { 286, "D\351zoomer" }, + { 287, "Toutes les 10 mins" }, + { 288, "Toutes les 15 mins" }, + { 289, "Toutes les 30 mins" }, + { 290, "Toutes les 5 mins" }, + { 291, "\300 ~P~ropos" }, + { 292, "~A~jouter..." }, + { 293, "~A~nnuler" }, + { 294, "~F~ermer" }, + { 295, "~E~diter..." }, + { 296, "~A~ide" }, + { 297, "Contr\364le des combats d'~I~ndy" }, + { 298, "~T~ouches" }, + { 299, "Mode ~G~aucher" }, + { 300, "~C~harger" }, + { 301, "~C~harger" }, + { 302, "~S~uivant" }, + { 303, "~O~K" }, + { 304, "~O~ptions" }, + { 305, "~O~ptions..." }, + { 306, "~P~r\351c\351dent" }, + { 307, "~Q~uitter" }, + { 308, "~S~upprimer" }, + { 309, "~R~eprendre" }, + { 310, "Retour au ~L~anceur" }, + { 311, "~S~auver" }, + { 312, "~D~\351marrer" }, + { 313, "T~r~ansitions activ\351" }, + { 314, "~E~ffets de l'Eau Activ\351s" }, + { 315, "Mode ~Z~ip Activ\351" }, { -1, NULL } }; -static const PoMessageEntry _translation_it_IT[] = { - { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-12 17:44+0200\nPO-Revision-Date: 2010-06-30 23:56+0100\nLast-Translator: Maff <matteo.maff at gmail dot com>\nLanguage-Team: Italian\nLanguage: Italiano\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\n" }, - { 1, " Sei sicuro di voler uscire? " }, - { 2, " (Attivo)" }, - { 3, " (Gioco)" }, - { 4, " (Globale)" }, - { 5, "(build creata il %s)" }, - { 6, ", errore nel montare la condivisione" }, - { 7, ", condivisione non montata" }, - { 8, "... progresso ..." }, - { 9, "11kHz" }, - { 10, "22 kHz" }, - { 11, "44 kHz" }, - { 12, "48 kHz" }, - { 13, "8 kHz" }, - { 14, "<predefinito>" }, - { 15, "Informazioni su ScummVM" }, - { 16, "Emulatore AdLib" }, - { 17, "Emulatore AdLib:" }, - { 18, "AdLib \350 utilizzato per la musica in molti giochi" }, - { 19, "Aggiungi gioco..." }, - { 20, "Renderer con antialiasing (16bpp)" }, - { 21, "Correzione proporzioni" }, - { 22, "Tasto associato: %s" }, - { 23, "Tasto associato: nessuno" }, - { 24, "Audio" }, - { 25, "Autosalva:" }, - { 26, "Motori disponibili:" }, - { 27, "~I~nfo..." }, - { 28, "Associa tasti" }, - { 29, "Entrambi" }, - { 30, "Luminosit\340:" }, - { 31, "Annulla" }, - { 32, "Impossibile creare il file" }, - { 33, "Modifica le opzioni di gioco" }, - { 34, "Modifica le opzioni globali di ScummVM" }, - { 35, "Seleziona se vuoi usare il dispositivo hardware audio compatibile con Roland che \350 connesso al tuo computer" }, - { 36, "Scegli" }, - { 37, "Scegli un'azione da mappare" }, - { 38, "Cancella" }, - { 39, "Chiudi" }, - { 40, "Corregge le proporzioni dei giochi 320x200" }, - { 41, "Impossibile trovare un motore in grado di eseguire il gioco selezionato" }, - { 42, "Modalit\340 video attuale:" }, - { 43, "Cursore gi\371" }, - { 44, "Cursore a sinistra" }, - { 45, "Cursore a destra" }, - { 46, "Cursore su" }, - { 47, "Emulatore OPL DOSBox" }, +static const PoMessageEntry _translation_uk_UA[] = { + { 0, "Project-Id-Version: ScummVM VERSION\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-30 22:14+0100\nPO-Revision-Date: 2010-07-30 22:19+0100\nLast-Translator: Lubomyr Lisen\nLanguage-Team: Ukrainian\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-5\nContent-Transfer-Encoding: 8bit\nLanguage: Ukrainian\nPlural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" }, + { 1, " \262\330 \343\337\325\322\335\325\335\366, \351\336 \345\336\347\325\342\325 \322\330\331\342\330? " }, + { 2, " (\260\332\342\330\322\335\320)" }, + { 3, " (\246\323\340\330)" }, + { 4, " (\263\333\336\321\320\333\354\335\320)" }, + { 5, "(\327\366\321\340\320\335\330\331 %s)" }, + { 6, ", \337\336\334\330\333\332\320 \337\366\324 \347\320\341 \337\366\324\332\333\356\347\325\335\335\357 \337\320\337\332\330" }, + { 7, ", \337\320\337\332\320 \335\325 \337\366\324\332\333\356\347\325\335\320" }, + { 8, "... \337\336\350\343\332 ..." }, + { 9, "11 \332\263\346" }, + { 10, "22 \332\263\346" }, + { 11, "44 \332\263\346" }, + { 12, "48 \332\263\346" }, + { 13, "8 \332\263\346" }, + { 14, "<\327\320 \343\334\336\322\347\320\335\335\357\334>" }, + { 15, "\277\340\336 ScummVM" }, + { 16, "\265\334\343\333\357\342\336\340 AdLib" }, + { 17, "\265\334\343\333\357\342\336\340 AdLib:" }, + { 18, "\267\322\343\332\336\322\320 \332\320\340\342\320 AdLib \322\330\332\336\340\330\341\342\336\322\343\364\342\354\341\357 \321\320\323\320\342\354\334\320 \366\323\340\320\334\330" }, + { 19, "\264\336\324. \323\340\343..." }, + { 20, "\300\320\341\342\325\340\330\327\320\342\336\340 \327\366 \327\323\333\320\324\326\343\322\320\335\335\357\334 (16bpp)" }, + { 21, "\272\336\340\325\332\346\366\357 \341\337\366\322\322\366\324\335\336\350\325\335\335\357 \341\342\336\340\366\335" }, + { 22, "\277\340\330\327\335\320\347\325\335\320 \332\333\320\322\366\350\320 : %s" }, + { 23, "\277\340\330\327\335\320\347\325\335\320 \332\333\320\322\366\350\320 : \335\325\334\320\364" }, + { 24, "\260\343\324\366\336" }, + { 25, "\260\322\342\336\327\321\325\340\325\326\325\335\335\357:" }, + { 26, "\264\336\341\342\343\337\335\366 \324\322\330\326\332\330:" }, + { 27, "\277\340\336 \337~\340~\336\323\340\320\334\343..." }, + { 28, "\337\340\330\327\335\320\347\330\342\330 \332\333\320\322\366\350\366" }, + { 29, "\262\341\325" }, + { 30, "\317\341\332\340\320\322\366\341\342\354:" }, + { 31, "\262\366\324\334\366\335\320" }, + { 32, "\275\325 \334\336\326\343 \341\342\322\336\340\330\342\330 \344\320\331\333" }, + { 33, "\267\334\366\335\330\342\330 \336\337\346\366\367 \323\340\330" }, + { 34, "\267\334\366\335\330\342\330 \323\333\336\321\320\333\354\335\366 \336\337\346\366\367 ScummVM" }, + { 35, "\262\366\324\334\366\342\354\342\325, \357\332\351\336 \343 \322\320\341 \337\366\324\332\333\356\347\325\335\330\331 Roland-\341\343\334\366\341\335\330\331 \327\322\343\332\336\322\330\331 \337\340\330\341\342\340\366\331 \366 \322\330 \345\336\347\325\342\325 \331\336\323\336 \322\330\332\336\340\330\341\342\320\342\330" }, + { 36, "\262\330\321\340\320\342\330" }, + { 37, "\262\330\321\325\340\366\342\354 \324\366\356 \324\333\357 \337\340\330\327\335\320\347\325\335\335\357" }, + { 38, "\276\347\330\341\342\330\342\330 \327\335\320\347\325\335\335\357" }, + { 39, "\267\320\332\340\330\342\330" }, + { 40, "\272\336\340\330\323\343\322\320\342\330 \341\337\366\322\322\366\324\335\336\350\325\335\335\357 \341\342\336\340\366\335 \324\333\357 \366\323\336\340 \327 \323\340\320\344\366\332\336\356 320x200" }, + { 41, "\275\325 \334\336\326\343 \327\335\320\331\342\330 \324\322\330\326\336\332 \324\333\357 \327\320\337\343\341\332\343 \322\330\321\340\320\335\336\367 \323\340\330" }, + { 42, "\302\325\332\343\347\330\331 \322\366\324\325\336\340\325\326\330\334:" }, + { 43, "\272\343\340\341\336\340 \322\335\330\327" }, + { 44, "\272\343\340\341\336\340 \322\333\366\322\336" }, + { 45, "\272\343\340\341\336\340 \322\337\340\320\322\336" }, + { 46, "\272\343\340\341\336\340 \322\322\325\340\345" }, + { 47, "\265\334\343\333\357\342\336\340 DOSBox OPL" }, { 48, "DVD" }, - { 49, "DVD montato con successo" }, - { 50, "DVD non montato" }, - { 51, "Data: " }, - { 52, "Debugger" }, - { 53, "Predefinito" }, - { 54, "Elimina" }, - { 55, "Disattiva spegnimento in chiusura" }, - { 56, "Grafica disattivata" }, - { 57, "Rilevati %d nuovi giochi..." }, - { 58, "Rilevati %d nuovi giochi." }, - { 59, "Visualizza " }, - { 60, "Mostra tastiera" }, - { 61, "Sei sicuro di voler eliminare questo salvataggio?" }, - { 62, "Sei sicuro di voler rimuovere questa configurazione di gioco?" }, - { 63, "Vuoi davvero eseguire il rilevatore di giochi in massa? Potrebbe aggiungere un numero enorme di giochi." }, - { 64, "Vuoi caricare o salvare il gioco?" }, - { 65, "Vuoi eseguire una scansione automatica?" }, - { 66, "Sei sicuro di voler uscire?" }, - { 67, "Double-strike" }, - { 68, "Gi\371" }, - { 69, "Attiva la modalit\340 Roland GS" }, - { 70, "Il motore non supporta il livello di debug '%s'" }, - { 71, "Inglese" }, - { 72, "Errore nell'esecuzione del gioco:" }, - { 73, "Errore nel montare il DVD" }, - { 74, "Percorso extra:" }, - { 75, "Emulatore FM Towns" }, - { 76, "Modalit\340 veloce" }, - { 77, "Funzionalit\340 compilate in:" }, - { 78, "Osservazione libera" }, - { 79, "Titolo completo del gioco" }, - { 80, "Modalit\340 a schermo intero" }, - { 81, "Accelerazione pad GC:" }, - { 82, "Sensibilit\340 pad GC:" }, - { 83, "Grafica" }, - { 84, "Dispositivo GM:" }, - { 85, "Lingua GUI:" }, - { 86, "Renderer GUI:" }, - { 87, "Gioco" }, - { 88, "Dati di gioco non trovati" }, - { 89, "ID di gioco non supportato" }, - { 90, "Percorso gioco:" }, - { 91, "Menu globale" }, - { 92, "Vai alla cartella superiore" }, - { 93, "Cartella superiore" }, - { 94, "Grafica" }, - { 95, "Modalit\340:" }, - { 96, "Ridimensionamento hardware (veloce, ma di bassa qualit\340)" }, - { 97, "Hercules ambra" }, - { 98, "Hercules verde" }, - { 99, "Nascondi la barra degli strumenti" }, - { 100, "Audio ad alta qualit\340 (pi\371 lento) (riavviare)" }, - { 101, "Valori pi\371 alti restituiscono un suono di maggior qualit\340, ma potrebbero non essere supportati dalla tua scheda audio" }, - { 102, "Tieni premuto Shift per l'aggiunta in massa" }, - { 103, "Underscan orizzontale:" }, - { 104, "Emulatore IBM PCjr" }, + { 49, "DVD \337\366\324\332\333\356\347\325\335\330\331 \343\341\337\366\350\335\336" }, + { 50, "DVD \335\325 \337\366\324\332\333\356\347\325\335\330\331" }, + { 51, "\264\320\342\320: " }, + { 52, "\262\366\324\333\320\324\347\330\332" }, + { 53, "\267\320 \343\334\336\322\347\320\335\335\357\334" }, + { 54, "\262\330\324\320\333\330\342\330" }, + { 55, "\267\320\321\336\340\336\335\330\342\330 \322\330\334\332\335\325\335\335\357" }, + { 56, "\261\325\327 \323\340\320\344\366\332\330" }, + { 57, "\267\335\320\331\324\325\335\336 %d \335\336\322\330\345 \366\323\336\340 ..." }, + { 58, "\267\335\320\331\324\325\335\336 %d \335\336\322\330\345 \366\323\336\340." }, + { 59, "\277\336\332\320\327\320\342\330 " }, + { 60, "\277\336\332\320\327\320\342\330 \332\333\320\322\366\320\342\343\340\343" }, + { 61, "\262\330 \324\366\331\341\335\336 \345\336\347\325\342\325 \322\330\324\320\333\330\342\330 \346\325 \327\321\325\340\325\326\325\335\335\357?" }, + { 62, "\262\330 \324\366\331\341\335\336 \345\336\347\325\342\325 \322\330\324\320\333\330\342\330 \343\341\342\320\335\336\322\332\330 \324\333\357 \346\366\364\367 \323\340\330?" }, + { 63, "\262\330 \324\366\331\341\335\336 \345\336\347\325\342\325 \327\320\337\343\341\342\330\342\330 \324\325\342\325\332\342\336\340 \343\341\366\345 \366\323\336\340? \306\325 \337\336\342\325\335\346\366\331\335\336 \334\336\326\325 \324\336\324\320\342\330 \322\325\333\330\332\343 \332\366\333\354\332\366\341\342\354 \366\323\336\340." }, + { 64, "\262\330 \345\336\347\325\342\325 \327\320\322\320\335\342\320\326\330\342\330 \320\321\336 \327\321\325\340\325\323\342\330 \323\340\343?" }, + { 65, "\262\330 \345\336\347\325\342\325 \327\324\366\331\341\335\330\342\330 \320\322\342\336\334\320\342\330\347\335\330\331 \337\336\350\343\332?" }, + { 66, "\262\330 \345\336\347\330\342\325 \322\330\331\342\330?" }, + { 67, "\277\336\324\322\366\331\335\330\331 \343\324\320\340" }, + { 68, "\262\335\330\327" }, + { 69, "\303\322\366\334\332\335\343\342\330 \340\325\326\330\334 Roland GS" }, + { 70, "\264\322\330\326\336\332 \335\325 \337\366\324\342\340\330\334\343\364 \340\366\322\325\335\354 \322\366\324\333\320\324\332\330 '%s'" }, + { 71, "English" }, + { 72, "\277\336\334\330\333\332\320 \327\320\337\343\341\332\343 \323\340\330:" }, + { 73, "\277\336\334\330\333\332\320 \337\366\324 \347\320\341 \337\366\324\332\333\356\347\325\335\335\357 DVD" }, + { 74, "\264\336\324. \350\333\357\345:" }, + { 75, "\265\334\343\333\357\342\336\340 FM Towns" }, + { 76, "\310\322\330\324\332\330\331 \340\325\326\330\334" }, + { 77, "\262\332\333\356\347\325\335\366 \322 \321\366\333\324 \336\337\346\366\367:" }, + { 78, "\262\366\333\354\335\330\331 \336\323\333\357\324" }, + { 79, "\277\336\322\335\320 \335\320\327\322\320 \323\340\330" }, + { 80, "\277\336\322\335\336\325\332\340\320\335\335\330\331 \340\325\326\330\334" }, + { 81, "\277\340\330\341\332\336\340\325\335\335\357 GC \337\320\324\343:" }, + { 82, "\307\343\342\333\330\322\366\341\342\354 GC \337\320\324\343:" }, + { 83, "\263\340\344" }, + { 84, "\277\340\330\341\342\340\366\331 GM:" }, + { 85, "\274\336\322\320 \366\335\342\325\340\344\325\331\341\343:" }, + { 86, "\300\320\341\342\325\340\330\327\320\342\336\340 GUI:" }, + { 87, "\263\340\320" }, + { 88, "\275\325\334\320\364 \344\320\331\333\366\322 \323\340\330" }, + { 89, "Game Id \335\325 \337\366\324\342\340\330\334\343\364\342\354\341\357" }, + { 90, "\310\333\357\345 \324\336 \323\340\330: " }, + { 91, "\263\333\336\321\320\333\354\335\325 \334\325\335\356" }, + { 92, "\277\325\340\325\331\342\330 \335\320 \337\320\337\332\343 \340\366\322\335\325\334 \322\330\351\325" }, + { 93, "\262\322\325\340\345" }, + { 94, "\263\340\320\344\366\332\320" }, + { 95, "\263\340\320\344\366\347\335\330\331 \340\325\326\330\334:" }, + { 96, "\305\320\340\324\322\320\340\335\336\325 \334\320\341\350\342\320\321\343\322\320\335\335\357 (\350\322\330\324\332\336, \320\333\325 \335\330\327\354\332\336\367 \357\332\336\341\342\366)" }, + { 97, "Hercules \317\335\342\320\340\335\330\331" }, + { 98, "Hercules \267\325\333\325\335\330\331" }, + { 99, "\267\320\345\336\322\320\342\330 \337\320\335\325\333\354 \366\335\341\342\340\343\334\325\335\342\366\322" }, + { 100, "\262\330\341\336\332\320 \357\332\366\341\342\354 \327\322\343\332\343 (\337\336\322\366\333\354\335\366\350\325) (\340\325\321\343\342)" }, + { 101, "\262\325\333\330\332\366 \327\335\320\347\325\335\335\357 \327\320\324\320\356\342\354 \332\340\320\351\343 \357\332\366\341\342\354 \327\322\343\332\343, \337\340\336\342\325 \322\336\335\330 \334\336\326\343\342\354 \335\325 \337\366\324\342\340\330\334\343\322\320\342\330\341\357 \322\320\350\336\356 \327\322\343\332\336\322\336\356 \332\320\340\342\336\356" }, + { 102, "\303\342\340\330\334\343\331\342\325 \332\333\320\322\366\350\343 Shift \324\333\357 \342\336\323\336, \351\336\321 \324\336\324\320\342\330 \324\325\332\366\333\354\332\320 \366\323\336\340" }, + { 103, "\263\336\340\330\327\336\335\342\320\333\354\335\330\331 underscan:" }, + { 104, "\265\334\343\333\357\342\336\340 IBM PCjr" }, { 105, "ID:" }, - { 106, "Avvia rete" }, - { 107, "Schermo in primo piano:" }, - { 108, "Avvio in corso dell'emulatore MT-32" }, - { 109, "Avvio rete in corso" }, - { 110, "Input" }, - { 111, "Percorso non valido" }, - { 112, "Programmatore tasti" }, - { 113, "Tastiera" }, - { 114, "Mappa tasti:" }, - { 115, "Tasti" }, - { 116, "Lingua dell'interfaccia grafica di ScummVM" }, - { 117, "Lingua del gioco. Un gioco inglese non potr\340 risultare tradotto in italiano" }, - { 118, "Lingua:" }, - { 119, "Sinistra" }, - { 120, "Clic sinistro" }, - { 121, "Carica" }, - { 122, "Carica gioco:" }, - { 123, "Carica un salvataggio del gioco selezionato" }, - { 124, "Emulatore OPL MAME" }, + { 106, "\246\335\366\346\366\320\333\366\327\320\346\366\357 \334\325\340\325\326\366" }, + { 107, "\277\336\347\320\342\332\336\322\330\331 \334\320\341\350\342\320\321 \322\325\340\345\335\354\336\323\336 \325\332\340\320\335\343:" }, + { 108, "\275\320\341\342\340\336\356\356 \325\334\343\333\357\342\336\340 MT-32" }, + { 109, "\275\320\333\320\350\342\336\322\343\356 \334\325\340\325\326\343" }, + { 110, "\262\322\366\324" }, + { 111, "\275\325\337\340\320\322\330\333\354\335\330\331 \350\333\357\345" }, + { 112, "\277\340\330\327\335\320\347\325\335\335\357 \332\333\320\322\366\350" }, + { 113, "\272\333\320\322\366\320\342\343\340\320" }, + { 114, "\302\320\321\333\330\346\357 \332\333\320\322\366\350:" }, + { 115, "\272\333\320\322\366\350\366" }, + { 116, "\274\336\322\320 \323\340\320\344\366\347\335\336\323\336 \366\335\342\325\340\344\325\331\341\343 ScummVM" }, + { 117, "\274\336\322\320 \323\340\330. \267\334\366\335\320 \346\354\336\323\336 \337\320\340\320\334\325\342\340\343 \335\325 \337\325\340\325\342\322\336\340\330\342\354 \323\340\343 \335\320 \320\335\323\333\366\331\341\354\332\366\331 \322 \343\332\340\320\367\335\341\354\332\343" }, + { 118, "\274\336\322\320:" }, + { 119, "\262\333\366\322\336" }, + { 120, "\273\366\322\330\331 \332\333\366\332" }, + { 121, "\267\320\322\320\335\342\320\326\330\342\330" }, + { 122, "\267\320\322\320\335\342\320\326\330\342\330 \323\340\343:" }, + { 123, "\267\320\322\320\335\342\320\326\330\342\330 \327\321\325\340\325\326\325\335\335\357 \324\333\357 \322\330\321\340\320\335\336\367 \323\340\330" }, + { 124, "\265\334\343\333\357\342\336\340 MAME OPL:" }, { 125, "MIDI" }, - { 126, "Guadagno MIDI:" }, - { 127, "Disposit. MT32:" }, - { 128, "Emulatore MT-32" }, - { 129, "Schermo principale:" }, - { 130, "Mappa" }, - { 131, "Agg. in massa..." }, - { 132, "Menu" }, - { 133, "Varie" }, - { 134, "Modalit\340 mista AdLib/MIDI" }, - { 135, "Monta DVD" }, - { 136, "Monta SMB" }, - { 137, "Clic del mouse" }, - { 138, "Multifunzione" }, - { 139, "Dispositivo GM:" }, - { 140, "Volume musica:" }, - { 141, "Disattiva audio" }, - { 142, "Nome:" }, - { 143, "Rete disattivata" }, - { 144, "Rete non avviata (%d)" }, - { 145, "Rete attiva" }, - { 146, "Rete attiva, condivisione montata" }, - { 147, "Mai" }, - { 148, "No" }, - { 149, "Nessuna data salvata" }, - { 150, "Nessuna musica" }, - { 151, "Nessun tempo salvato" }, - { 152, "Nessun orario salvato" }, - { 153, "Nessuno" }, - { 154, "Normale (nessun ridimensionamento)" }, - { 155, "OK" }, - { 156, "Frequenza:" }, - { 157, "Ignora le impostazioni MIDI globali" }, - { 158, "Ignora le impostazioni audio globali" }, - { 159, "Ignora le impostazioni grafiche globali" }, - { 160, "Ignora le impostazioni globali di volume" }, - { 161, "Emulatore PC Speaker" }, - { 162, "Password:" }, - { 163, "Il percorso non \350 una cartella" }, - { 164, "Il percorso non \350 un file" }, - { 165, "Il percorso non esiste" }, - { 166, "Percorsi" }, - { 167, "Pausa" }, - { 168, "Scegli il gioco:" }, - { 169, "La piattaforma per la quale il gioco \350 stato concepito" }, - { 170, "Piattaforma:" }, - { 171, "Tempo di gioco: " }, - { 172, "Seleziona un'azione" }, - { 173, "Percorso plugin:" }, - { 174, "Disp. preferito:" }, - { 175, "Premi il tasto da associare" }, - { 176, "Esci" }, - { 177, "Chiudi ScummVM" }, - { 178, "Autorizzazione di lettura negata" }, - { 179, "Lettura fallita" }, - { 180, "Riprogramma tasti" }, - { 181, "Rimuove il gioco dalla lista. I file del gioco rimarranno intatti" }, - { 182, "Resa grafica:" }, - { 183, "Destra" }, - { 184, "Clic destro" }, - { 185, "Clic destro" }, - { 186, "Rotazione" }, - { 187, "Volume effetti:" }, - { 188, "SMB" }, - { 189, "Salva" }, - { 190, "Salvataggi:" }, - { 191, "Salvataggi:" }, - { 192, "Salva gioco:" }, - { 193, "Scansione completa!" }, - { 194, "%d cartelle analizzate..." }, - { 195, "Menu principale di ScummVM" }, - { 196, "ScummVM non ha potuto trovare un motore in grado di eseguire il gioco selezionato!" }, - { 197, "ScummVM non ha potuto trovare nessun gioco nella cartella specificata!" }, - { 198, "ScummVM non ha potuto aprire la cartella specificata!" }, - { 199, "Cerca nella lista dei giochi" }, - { 200, "Cerca:" }, - { 201, "Seleziona SoundFont" }, - { 202, "Seleziona un tema" }, - { 203, "Seleziona la cartella di gioco aggiuntiva" }, - { 204, "Seleziona un'azione e clicca 'Mappa'" }, - { 205, "Seleziona la cartella dei temi dell'interfaccia" }, - { 206, "Seleziona la cartella dei file aggiuntivi" }, - { 207, "Seleziona la cartella dei plugin" }, - { 208, "Seleziona la cartella dei salvataggi" }, - { 209, "Seleziona la cartella per i salvataggi" }, - { 210, "Seleziona la cartella contenente i file di gioco" }, - { 211, "Sensibilit\340" }, - { 212, "Server:" }, - { 213, "Condivisione:" }, - { 214, "Breve identificatore di gioco utilizzato per il riferimento a salvataggi e per l'esecuzione del gioco dalla riga di comando" }, - { 215, "Mostra tastiera" }, - { 216, "Mostra cursore del mouse" }, - { 217, "Mostra i sottotitoli e attiva le voci" }, - { 218, "Mostra/nascondi cursore" }, - { 219, "Salta" }, - { 220, "Salta battuta" }, - { 221, "Salta testo" }, - { 222, "Aggancia ai bordi" }, - { 223, "Ridimensionamento software (di buona qualit\340, ma pi\371 lento)" }, - { 224, "Suono on/off" }, - { 225, "SoundFont \350 supportato da alcune schede audio, Fluidsynth e Timidity" }, - { 226, "SoundFont:" }, - { 227, "Voci" }, - { 228, "Modalit\340 di resa grafica speciali supportate da alcuni giochi" }, - { 229, "Volume degli effetti sonori" }, - { 230, "Specifica il dispositivo audio predefinito per l'output General MIDI" }, - { 231, "Specifica il dispositivo audio predefinito per l'output Roland MT-32/LAPC1/CM32l/CM64" }, - { 232, "Specifica il dispositivo di output audio o l'emulatore della scheda audio" }, - { 233, "Specifica il percorso di ulteriori dati usati dai giochi o da ScummVM" }, - { 234, "Specifica il percorso di ulteriori dati usati dal gioco" }, - { 235, "Specifica il dispositivo audio o l'emulatore della scheda audio preferiti" }, - { 236, "Specifica dove archiviare i salvataggi" }, - { 237, "Voci" }, - { 238, "Volume voci:" }, - { 239, "Renderer standard (16bpp)" }, - { 240, "Esegue il gioco selezionato" }, - { 241, "Stato:" }, - { 242, "Sub" }, - { 243, "Velocit\340 testo:" }, - { 244, "Sottotitoli" }, - { 245, "Cambia personaggio" }, - { 246, "Un tocco per il clic sinistro, doppio tocco per il clic destro" }, - { 247, "Testo e voci:" }, - { 248, "La cartella scelta \350 in sola lettura. Si prega di sceglierne un'altra." }, - { 249, "Percorso tema:" }, - { 250, "Tema:" }, - { 251, "Questo ID di gioco \350 gi\340 in uso. Si prega di sceglierne un'altro." }, - { 252, "Questo gioco non supporta il caricamento di salvataggi dalla schermata di avvio." }, - { 253, "Ora: " }, - { 254, "Attesa per l'avvio della rete" }, - { 255, "Compensa X del tocco" }, - { 256, "Compensa Y del tocco" }, - { 257, "Modalit\340 touchpad disattivata." }, - { 258, "Modalit\340 touchpad attivata." }, - { 259, "Roland MT-32 effettivo (disattiva emulazione GM)" }, - { 260, "Disattiva la mappatura General MIDI per i giochi con colonna sonora Roland MT-32" }, - { 261, "Sconosciuto" }, - { 262, "Errore sconosciuto" }, - { 263, "Smonta DVD" }, - { 264, "Smonta SMB" }, - { 265, "Non ridimensionato (devi scorrere a sinistra e a destra)" }, - { 266, "Modalit\340 colore non supportata" }, - { 267, "Salvataggio senza titolo" }, - { 268, "Su" }, - { 269, "Utilizza generazione di suono sia MIDI che AdLib" }, - { 270, "Utilizza il controllo del cursore stile trackpad del portatile" }, - { 271, "Nome utente:" }, - { 272, "Utilizzo del driver SDL " }, - { 273, "Underscan verticale:" }, - { 274, "Video" }, - { 275, "Tastiera virtuale" }, - { 276, "Volume" }, - { 277, "MIDI Windows" }, - { 278, "Autorizzazione di scrittura negata" }, - { 279, "Scrittura dati fallita" }, - { 280, "S\354" }, - { 281, "Devi riavviare ScummVM affinch\351 le modifiche abbiano effetto." }, - { 282, "Zona" }, - { 283, "Zoom indietro" }, - { 284, "Zoom avanti" }, - { 285, "ogni 10 minuti" }, - { 286, "ogni 15 minuti" }, - { 287, "ogni 30 minuti" }, - { 288, "ogni 5 minuti" }, - { 289, "~I~nfo" }, - { 290, "~A~ggiungi gioco..." }, - { 291, "~A~nnulla" }, - { 292, "~C~hiudi" }, - { 293, "~M~odifica gioco..." }, - { 294, "~A~iuto" }, - { 295, "Controlli combattimento di ~I~ndy" }, - { 296, "~T~asti" }, - { 297, "~M~odalit\340 mancini" }, - { 298, "~C~arica" }, - { 299, "~C~arica..." }, - { 300, "~S~uccessivi" }, - { 301, "~O~K" }, - { 302, "~O~pzioni" }, - { 303, "~O~pzioni..." }, - { 304, "~P~recedenti" }, - { 305, "C~h~iudi" }, - { 306, "~R~imuovi gioco" }, - { 307, "~R~ipristina" }, - { 308, "~V~ai a schermata di avvio" }, - { 309, "~S~alva" }, - { 310, "~G~ioca" }, - { 311, "~T~ransizioni attive" }, - { 312, "~E~ffetto acqua attivo" }, - { 313, "Modalit\340 ~Z~ip attivata" }, + { 126, "\277\336\341\330\333\325\335\335\357 MIDI:" }, + { 127, "MT-32" }, + { 128, "\277\340\330\341\342\340\366\331 MT-32:" }, + { 129, "\265\334\343\333\357\342\336\340 MT-32" }, + { 130, "\274\320\341\350\342\320\321 \323\336\333\336\322\335\336\323\336 \325\332\340\320\335\343:" }, + { 131, "\277\340\330\327\335\320\347\330\342\330" }, + { 132, "\264\336\324. \321\320\323\320\342\336..." }, + { 133, "\274\325\335\356" }, + { 134, "\300\366\327\335\325" }, + { 135, "\267\334\366\350\320\335\330\331 \340\325\326\330\334 AdLib/MIDI" }, + { 136, "\277\366\324\332\333\356\347\330\342\330 DVD" }, + { 137, "\277\366\324\332\333\356\347\330\342\330 SMB" }, + { 138, "\272\333\366\332 \334\330\350\332\336\356" }, + { 139, "\274\343\333\354\342\366\344\343\335\332\346\366\357" }, + { 140, "\274\343\327\330\347\335\330\331 \277\340\330\341\342\340\366\331:" }, + { 141, "\263\343\347\335\366\341\342\354 \334\343\327\330\332\330:" }, + { 142, "\262\330\334\332\335\343\342\330 \343\341\325" }, + { 143, "\275\320\327\322\320:" }, + { 144, "\274\325\340\325\326\320 \322\330\334\332\335\325\335\320" }, + { 145, "\274\325\340\325\326\320 \335\325 \335\320\333\320\323\336\324\326\325\335\320 (%d)" }, + { 146, "\274\325\340\325\326\320 \337\340\320\346\356\364" }, + { 147, "\274\325\340\325\326\320 \337\340\320\346\356\364, \337\320\337\332\320 \337\366\324\332\333\356\347\325\335\320" }, + { 148, "\275\366\332\336\333\330" }, + { 149, "\275\366" }, + { 150, "\264\320\342\320 \335\325 \327\320\337\330\341\320\335\320" }, + { 151, "\261\325\327 \334\343\327\330\332\330" }, + { 152, "\307\320\341 \323\340\330 \335\325 \327\320\337\330\341\320\335\336" }, + { 153, "\307\320\341 \335\325 \327\320\337\330\341\320\335\330\331" }, + { 154, "\275\325 \327\320\324\320\335\330\331" }, + { 155, "\261\325\327 \327\321\366\333\354\350\325\335\335\357" }, + { 156, "OK" }, + { 157, "\262\330\345\366\324\335\320 \347\320\341\342\336\342\320:" }, + { 158, "\277\325\340\325\332\340\330\342\330 \323\333\336\321\320\333\354\335\366 \343\341\342\320\335\336\322\332\330 MIDI" }, + { 159, "\277\325\340\325\332\340\330\342\330 \323\333\336\321\320\333\354\335\366 \343\341\342\320\335\336\322\332\330 MT-32" }, + { 160, "\277\325\340\325\332\340\330\342\330 \323\333\336\321\320\333\354\335\366 \343\341\342\320\335\336\322\332\330 \320\343\324\366\336" }, + { 161, "\277\325\340\325\332\340\330\342\330 \323\333\336\321\320\333\354\335\366 \343\341\342\320\335\336\322\332\330 \323\340\320\344\366\332\330" }, + { 162, "\277\325\340\325\332\340\330\342\330 \323\333\336\321\320\333\354\335\366 \343\341\342\320\335\336\322\332\330 \323\343\347\335\336\341\342\366" }, + { 163, "\265\334\343\333\357\342\336\340 PC \341\337\366\332\325\340\320" }, + { 164, "\277\320\340\336\333\354:" }, + { 165, "\310\333\357\345 \335\325 \364 \337\320\337\332\336\356" }, + { 166, "\310\333\357\345 \335\325 \364 \344\320\331\333\336\334" }, + { 167, "\310\333\357\345 \335\325 \327\335\320\331\324\325\335\330\331" }, + { 168, "\310\333\357\345\330" }, + { 169, "\277\320\343\327\320" }, + { 170, "\262\330\321\325\340\366\342\354 \323\340\343:" }, + { 171, "\277\333\320\342\344\336\340\334\320, \324\333\357 \357\332\336\367 \323\340\320 \321\343\333\320 \341\337\336\347\320\342\332\343 \340\336\327\340\336\321\333\325\335\320" }, + { 172, "\277\333\320\342\344\336\340\334\320:" }, + { 173, "\307\320\341 \323\340\330: " }, + { 174, "\261\343\324\354 \333\320\341\332\320, \322\330\321\325\340\366\342\354 \324\366\356" }, + { 175, "\310\333\357\345 \324\336 \337\333\320\323\366\335\366\322:" }, + { 176, "\277\340\330\341\342\340\366\331 \357\332\336\334\343 \322\366\324\324\320\364\342\354\341\357 \337\325\340\325\322\320\323\320:" }, + { 177, "\275\320\342\330\341\335\366\342\354 \332\333\320\322\366\350\343 \324\333\357 \337\340\330\327\335\320\347\325\335\335\357" }, + { 178, "\262\330\345\366\324" }, + { 179, "\262\330\345\366\324 \327 ScummVM" }, + { 180, "\275\325\324\336\341\342\320\342\335\354\336 \337\340\320\322 \324\333\357 \347\330\342\320\335\335\357" }, + { 181, "\277\336\334\330\333\332\320 \347\330\342\320\335\335\357" }, + { 182, "\277\325\340\325\337\340\330\327\335\320\347\330\342\330 \332\333\320\322\366\350\366" }, + { 183, "\262\330\324\320\333\330\342\330 \323\340\343 \327\366 \341\337\330\341\332\343. \275\325 \322\330\324\320\333\357\364 \323\340\343 \327 \326\336\340\341\342\332\336\323\336 \324\330\341\332\320" }, + { 184, "\300\325\326\330\334 \340\320\341\342\340\343\322\320\335\335\357:" }, + { 185, "\262\337\340\320\322\336" }, + { 186, "\277\340\320\322\330\331 \332\333\366\332" }, + { 187, "\277\340\320\322\330\331 \332\333\366\332" }, + { 188, "\277\336\322\325\340\335\343\342\330" }, + { 189, "\263\343\347\335\366\341\342\354 \325\344\325\332\342\366\322:" }, + { 190, "SMB" }, + { 191, "\267\320\337\330\341\320\342\330" }, + { 192, "\310\333\357\345 \327\321\325\340.: " }, + { 193, "\310\333\357\345 \324\333\357 \327\321\325\340\325\326\325\335\354: " }, + { 194, "\267\321\325\340\325\323\342\330 \323\340\343: " }, + { 195, "\277\336\350\343\332 \327\320\332\366\335\347\325\335\330\331!" }, + { 196, "\277\340\336\323\333\357\335\343\342\336 %d \337\320\337\336\332 ..." }, + { 197, "\263\336\333\336\322\335\325 \334\325\335\356 ScummVM" }, + { 198, "ScummVM \335\325 \327\334\366\323 \327\335\320\331\342\330 \324\322\330\326\336\332 \324\333\357 \327\320\337\343\341\332\343 \322\330\321\340\320\335\336\367 \323\340\330!" }, + { 199, "ScummVM \335\325 \334\336\326\325 \327\335\320\331\342\330 \323\340\343 \343 \322\332\320\327\320\335\366\331 \337\320\337\346\366!" }, + { 200, "ScummVM \335\325 \334\336\326\325 \322\366\324\332\340\330\342\330 \322\332\320\327\320\335\343 \337\320\337\332\343!" }, + { 201, "\277\336\350\343\332 \322 \341\337\330\341\332\343 \366\323\336\340" }, + { 202, "\277\336\350\343\332:" }, + { 203, "\262\330\321\325\340\366\342\354 SoundFont" }, + { 204, "\262\330\321\325\340\366\342\354 \342\325\334\343" }, + { 205, "\262\330\321\325\340\366\342\354 \324\336\324\320\342\332\336\322\343 \337\320\337\332\343 \323\340\330" }, + { 206, "\262\330\321\325\340\366\342\354 \324\366\356 \366 \332\333\366\332\335\366\342\354 '\277\340\330\327\335\320\347\330\342\330'" }, + { 207, "\262\330\321\325\340\366\342\354 \337\320\337\332\343 \324\333\357 \342\325\334 GUI" }, + { 208, "\262\330\321\325\340\366\342\354 \337\320\337\332\343 \327 \324\336\324\320\342\332\336\322\330\334\330 \344\320\331\333\320\334\330" }, + { 209, "\262\330\321\325\340\366\342\354 \337\320\337\332\343 \327 \337\333\320\323\330\335\320\334\330" }, + { 210, "\262\330\321\325\340\366\342\354 \337\320\337\332\343 \324\333\357 \327\321\325\340\325\326\325\335\354" }, + { 211, "\262\330\321\325\340\366\342\354 \337\320\337\332\343 \324\333\357 \327\321\325\340\325\326\325\335\354" }, + { 212, "\262\330\321\325\340\366\342\354 \337\320\337\332\343 \327 \344\320\331\333\320\334\330 \323\340\330" }, + { 213, "\307\343\342\333\330\322\366\341\342\354" }, + { 214, "\301\325\340\322\325\340:" }, + { 215, "\274\325\340\325\326\325\322\320 \337\320\337\332\320:" }, + { 216, "\272\336\340\336\342\332\330\331 \366\324\325\335\342\330\344\366\332\320\342\336\340, \357\332\330\331 \322\330\332\336\340\330\341\342\336\322\343\364\342\354\341\357 \324\333\357 \335\320\327\322 \327\321\325\340\325\326\325\335\330\345 \366\323\336\340 \366 \324\333\357 \327\320\337\343\341\332\343 \327 \332\336\334\320\335\324\335\336\367 \341\342\340\366\347\332\330" }, + { 217, "\277\336\332\320\327\320\342\330 \332\333\320\322\366\320\342\343\340\343" }, + { 218, "\277\336\332\320\327\343\322\320\342\330 \332\343\340\341\336\340 \334\330\350\366" }, + { 219, "\277\336\332\320\327\343\322\320\342\330 \341\343\321\342\330\342\340\330 \366 \322\366\324\342\322\336\340\356\322\320\342\330 \334\336\322\343" }, + { 220, "\277\336\332\320\327\320\342\330/\301\345\336\322\320\342\330 \332\343\340\341\336\340" }, + { 221, "\277\340\336\337\343\341\342\330\342\330" }, + { 222, "\277\340\336\337\343\341\342\330\342\330 \340\357\324\336\332" }, + { 223, "\277\340\336\337\343\341\342\330\342\330 \342\325\332\341\342" }, + { 224, "\277\340\330\332\340\366\337\330\342\330 \324\336 \332\340\320\367\322" }, + { 225, "\277\340\336\323\340\320\334\335\325 \334\320\341\350\342\320\321\343\322\320\335\335\357 (\345\336\340\336\350\320 \357\332\366\341\342\354, \320\333\325 \337\336\322\366\333\354\335\366\350\325)" }, + { 226, "\267\322\343\332 \343\322\366\334/\322\330\334\332" }, + { 227, "SoundFont \337\366\324\342\340\330\334\343\364\342\354\341\357 \324\325\357\332\330\334\330 \327\322\343\332\336\322\330\334\330 \332\320\340\342\320\334\330, Fluidsynth \366 Timidity" }, + { 228, "SoundFont:" }, + { 229, "\276\327\322" }, + { 230, "\301\337\325\346\366\320\333\354\335\366 \340\325\326\330\334\330 \340\325\335\324\325\340\330\335\323\343, \357\332\366 \337\366\324\342\340\330\334\343\356\342\354 \324\325\357\332\366 \366\323\340\330" }, + { 231, "\263\343\347\335\366\341\342\354 \341\337\325\346\366\320\333\354\335\330\345 \327\322\343\332\336\322\330\345 \325\344\325\332\342\366\322" }, + { 232, "\262\332\320\327\343\364 \322\330\345\366\324\335\330\331 \327\322\343\332\336\322\330\331 \337\340\330\341\342\340\366\331 \324\333\357 MIDI" }, + { 233, "\262\332\320\327\343\364 \327\322\343\332\336\322\330\331 \337\340\330\341\342\340\366\331 \337\336 \343\334\336\322\347\320\335\335\356 \324\333\357 \322\330\322\336\324\343 \335\320 Roland MT-32/LAPC1/CM32l/CM64" }, + { 234, "\262\332\320\327\343\364 \322\330\345\366\324\335\330\331 \327\322\343\332\336\322\330\331 \337\340\330\341\342\340\366\331 \320\321\336 \325\334\343\333\357\342\336\340 \327\322\343\332\336\322\336\367 \332\320\340\342\330" }, + { 235, "\262\332\320\327\343\364 \350\333\357\345 \324\336 \324\336\324\320\342\332\336\322\330\345 \344\320\331\333\366\322 \324\320\335\330\345, \322\330\332\336\340\330\341\342\336\322\343\322\320\335\330\345 \343\341\366\334\320 \366\323\340\320\334\330, \320\321\336 ScummVM" }, + { 236, "\262\332\320\327\343\364 \350\333\357\345 \324\336 \324\336\324\320\342\332\336\322\330\345 \344\320\331\333\366\322 \324\320\335\330\345 \324\333\357 \323\340\330" }, + { 237, "\262\332\320\327\343\364 \322\330\345\366\324\335\330\331 \327\322\343\332\336\322\330\331 \337\340\330\341\342\340\366\331 \320\321\336 \325\334\343\333\357\342\336\340 \327\322\343\332\336\322\336\367 \332\320\340\342\330" }, + { 238, "\262\332\320\327\343\364 \350\333\357\345 \324\336 \327\321\325\340\325\326\325\335\354 \323\340\330" }, + { 239, "\276\327\322\343\347\325\335\335\357" }, + { 240, "\263\343\347\335\366\341\342\354 \336\327\322\343\347\325\335\335\357:" }, + { 241, "\301\342\320\335\324\320\340\342\335\330\331 \340\320\341\342\325\340\330\327\320\342\336\340 (16bpp)" }, + { 242, "\267\320\337\343\341\342\330\342\330 \322\330\321\340\320\335\343 \323\340\343" }, + { 243, "\301\342\320\335:" }, + { 244, "\301\343\321" }, + { 245, "\310\322\330\324\332\366\341\342\354 \341\343\321\342\330\342\340\366\322:" }, + { 246, "\301\343\321\342\330\342\340\330" }, + { 247, "\267\334\366\335\330\342\330 \323\325\340\336\357" }, + { 248, "\302\320\337 \324\333\357 \333\366\322\336\323\336 \332\333\320\346\320\335\335\357, \337\336\324\322\366\331\335\330\331 \342\320\337 \324\333\357 \337\340\320\322\336\323\336 \332\333\320\346\320\335\335\357" }, + { 249, "\302\325\332\341\342 \366 \336\327\322\343\347\325\335\335\357:" }, + { 250, "\275\325 \334\336\326\343 \337\330\341\320\342\330 \343 \322\330\321\340\320\335\343 \337\320\337\332\343. \261\343\324\354 \333\320\341\332\320, \322\332\320\326\366\342\354 \366\335\350\343." }, + { 251, "\310\333\357\345 \324\336 \342\325\334:" }, + { 252, "\302\325\334\320:" }, + { 253, "\306\325\331 ID \323\340\330 \322\326\325 \322\330\332\336\340\330\341\342\336\322\343\364\342\354\341\357. \261\343\324\354 \333\320\341\332\320, \322\330\321\325\340\366\342\354 \366\335\350\330\331." }, + { 254, "\306\357 \323\340\320 \335\325 \337\366\324\342\340\330\334\343\364 \327\320\322\320\335\342\320\326\325\335\335\357 \327\321\325\340\325\326\325\335\354 \347\325\340\325\327 \323\336\333\336\322\335\325 \334\325\335\356." }, + { 255, "\307\320\341: " }, + { 256, "\307\320\341 \337\366\324\332\333\356\347\325\335\335\357 \324\336 \334\325\340\325\326\366 \322\330\342\366\332" }, + { 257, "\267\334\366\351\325\335\335\357 \342\336\340\332\320\335\354 \337\336 \336\341\366 X" }, + { 258, "\267\334\366\351\325\335\335\357 \342\336\340\332\320\335\354 \337\336 \336\341\366 Y" }, + { 259, "\300\325\326\330\334 \342\320\347\337\320\324\343 \322\330\334\332\335\325\335\330\331." }, + { 260, "\300\325\326\330\334 \342\320\347\337\320\324\343 \343\322\366\334\332\335\325\335\330\331." }, + { 261, "\301\337\340\320\322\326\335\366\331 Roland MT-32 (\322\330\334\332\335\343\342\330 \325\334\343\333\357\346\330\356 GM)" }, + { 262, "\262\330\334\330\332\320\364 \334\320\337\337\366\335\323 General MIDI \324\333\357 \366\323\336\340 \366\327 \327\322\343\332\336\322\336\356 \324\336\340\366\326\332\336\356 \324\333\357 Roland MT-32" }, + { 263, "\275\325\322\366\324\336\334\336" }, + { 264, "\275\325\322\366\324\336\334\320 \337\336\334\330\333\332\320" }, + { 265, "\262\366\324\332\333\356\347\330\342\330 DVD" }, + { 266, "\262\366\324\332\333\356\347\342\330 SMB" }, + { 267, "\261\325\327 \334\320\341\350\342\320\321\343\322\320\335\335\357 (\342\340\325\321\320 \321\343\324\325 \337\340\336\332\340\343\347\343\322\320\342\330 \335\320\333\366\322\336 \366 \335\320\337\340\320\322\336)" }, + { 268, "\300\325\326\330\334 \272\336\333\354\336\340\343 \335\325 \337\366\324\342\340\330\334\343\364\342\354\341\357" }, + { 269, "\267\321\325\340\325\326\325\335\335\357 \321\325\327 \366\334\325\335\366" }, + { 270, "\262\322\325\340\345" }, + { 271, "\262\330\332\336\340\330\341\342\336\322\343\322\320\342\330 \366 MIDI \366 AdLib \324\333\357 \323\325\335\325\340\320\346\366\367 \327\322\343\332\343" }, + { 272, "\262\330\332\336\340\330\341\342\336\322\343\322\320\342\330 \343\337\340\320\322\333\366\335\335\357 \332\343\340\341\336\340\336\334 \357\332 \335\320 \342\340\325\332\337\320\324\366 \333\320\337\342\336\337\366\322" }, + { 273, "\272\336\340\330\341\342\343\322\320\347:" }, + { 274, "\262\330\332\336\340\330\341\342\336\322\343\356 \324\340\320\331\322\325\340 SDL " }, + { 275, "\262\325\340\342\330\332\320\333\354\335\330\331 underscan:" }, + { 276, "\262\366\324\325\336" }, + { 277, "\262\366\340\342\343\320\333\354\335\320 \332\333\320\322\366\320\342\343\340\320" }, + { 278, "\263\343\347\335\366\341\342\354" }, + { 279, "Windows MIDI" }, + { 280, "\275\325\324\336\341\342\320\342\335\354\336 \337\340\320\322 \324\333\357 \327\320\337\330\341\343" }, + { 281, "\277\336\334\330\333\332\320 \327\320\337\330\341\343 \324\320\335\330\345" }, + { 282, "\302\320\332" }, + { 283, "\262\330 \337\336\322\330\335\335\366 \337\325\340\325\327\320\337\343\341\342\330\342\330 ScummVM \351\336\321 \327\320\341\342\336\341\343\322\320\342\330 \327\334\366\335\330." }, + { 284, "\267\336\335\320" }, + { 285, "\267\334\335\350. \334\320\350\342\320\321" }, + { 286, "\267\321\366\333. \334\320\350\342\320\321" }, + { 287, "\332\336\326\335\366 10 \345\322" }, + { 288, "\332\336\326\335\366 15 \345\322" }, + { 289, "\332\336\326\335\366 30 \345\322" }, + { 290, "\332\336\326\335\366 5 \345\322" }, + { 291, "\277\340\336 \337\340\336~\323~\340\320\334\343" }, + { 292, "~\264~\336\324. \323\340\343..." }, + { 293, "\262\366~\324~\334\366\335\320" }, + { 294, "~\267~\320\332\340\330\342\330" }, + { 295, "\300\325\324\320~\323~. \323\340\343..." }, + { 296, "~\264~\336\337\336\334\336\323\320" }, + { 297, "\272\325\340\343\322\320\335\335\357 \321\336\357\334\330 \322 Indy" }, + { 298, "~\272~\333\320\322\366\350\366" }, + { 299, "\273\366\322\336\340\343\332\330\331 \340\325\326\330\334" }, + { 300, "~\267~\320\322\320\335\342\320\326\330\342\330" }, + { 301, "~\267~\320\322\320\335..." }, + { 302, "~\275~\320\341\342" }, + { 303, "~O~K" }, + { 304, "~\276~\337\346\366\367" }, + { 305, "~\276~\337\346\366\367..." }, + { 306, "~\277~\336\337\325\340" }, + { 307, "~\262~\330\345\366\324" }, + { 308, "~\262~\330\324\320\333\330\342\330 \323\340\343" }, + { 309, "\277\340\336\324\336\322~\326~\330\342\330" }, + { 310, "~\277~\336\322\325\340\335\343\342\330\341\354 \322 \323\336\333\336\322\335\325 \334\325\335\356" }, + { 311, "~\267~\320\337\330\341\320\342\330" }, + { 312, "\267~\320~\337\343\341\332" }, + { 313, "\277\325\340\325\345\336\324\330 \320\332\342\330\322\336\322\320\335\366" }, + { 314, "\265\344\325\332\342\330 \322\336\324\330 \322\332\333\356\347\325\335\366" }, + { 315, "\300\325\326\330\334 \350\322\330\324\332\336\323\336 \337\325\340\325\345\336\324\343 \320\332\342\330\322\336\322\320\335\330\331" }, { -1, NULL } }; static const PoMessageEntry _translation_ca_ES[] = { - { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-12 17:44+0200\nPO-Revision-Date: 2010-06-26 16:45+0100\nLast-Translator: Jordi Vilalta Prat <jvprat@gmail.com>\nLanguage-Team: Catalan <scummvm-devel@lists.sf.net>\nLanguage: Catalan\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\n" }, + { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-30 22:14+0100\nPO-Revision-Date: 2010-06-26 16:45+0100\nLast-Translator: Jordi Vilalta Prat <jvprat@gmail.com>\nLanguage-Team: Catalan <scummvm-devel@lists.sf.net>\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\nLanguage: Catalan\n" }, { 2, " (Actiu)" }, { 3, " (Joc)" }, { 4, " (Global)" }, @@ -1402,254 +1788,516 @@ static const PoMessageEntry _translation_ca_ES[] = { { 124, "Emulador OPL de MAME" }, { 125, "MIDI" }, { 126, "Guany MIDI:" }, - { 127, "Dispositiu MT32:" }, - { 128, "Emulador de MT-32" }, - { 129, "Escalat de la pantalla principal:" }, - { 130, "Mapeja" }, - { 131, "Addici\363 Massiva..." }, - { 132, "Men\372" }, - { 133, "Misc" }, - { 134, "Mode combinat AdLib/MIDI" }, - { 135, "Munta el DVD" }, - { 136, "Munta SMB" }, - { 137, "Clic del ratol\355" }, - { 138, "Funci\363 M\372ltiple" }, - { 139, "Dispositiu GM:" }, - { 140, "Volum de la m\372sica:" }, - { 141, "Silenciar tot" }, - { 142, "Nom:" }, - { 143, "Xarxa inactiva" }, - { 144, "Xarxa no iniciada (%d)" }, - { 145, "Xarxa activa" }, - { 146, "Xarxa activa, compartici\363 muntada" }, - { 147, "Mai" }, - { 148, "No" }, - { 149, "No hi ha data desada" }, - { 150, "Sense m\372sica" }, - { 151, "No hi ha temps de joc desat" }, - { 152, "No hi ha hora desada" }, - { 153, "Cap" }, - { 154, "Normal (sense escalar)" }, - { 155, "D'acord" }, - { 156, "Freq\374\350ncia de sortida:" }, - { 157, "Fer canvis sobre les opcions globals de MIDI" }, - { 158, "Fer canvis sobre les opcions globals d'\340udio" }, - { 159, "Fer canvis sobre les opcions globals de gr\340fics" }, - { 160, "Fer canvis sobre les opcions globals de volum" }, - { 161, "Emulador d'Altaveu de PC" }, - { 162, "Contrasenya:" }, - { 163, "El cam\355 no \351s un directori" }, - { 164, "El cam\355 no \351s un fitxer" }, - { 165, "El cam\355 no existeix" }, - { 166, "Camins" }, - { 167, "Pausa" }, - { 168, "Seleccioneu el joc:" }, - { 169, "Plataforma per la que el joc es va dissenyar originalment" }, - { 170, "Plataforma:" }, - { 171, "Temps de joc: " }, - { 172, "Seleccioneu una acci\363" }, - { 173, "Cam\355 dels connectors:" }, - { 174, "Dispositiu Preferit:" }, - { 175, "Premeu la tecla a associar" }, - { 176, "Surt" }, - { 177, "Surt de ScummVM" }, - { 178, "S'ha denegat el perm\355s de lectura" }, - { 179, "Ha fallat la lectura" }, - { 180, "Remapeja les tecles" }, - { 181, "Elimina un joc de la llista. Els fitxers de dades del joc es mantenen intactes" }, - { 182, "Mode de pintat:" }, - { 183, "Dreta" }, - { 184, "Clic dret" }, - { 185, "Clic dret" }, - { 186, "Rotar" }, - { 187, "Volum dels efectes:" }, - { 188, "SMB" }, - { 189, "Desa" }, - { 190, "Cam\355 de les Partides:" }, - { 191, "Cam\355 de les Partides: " }, - { 192, "Desa la partida:" }, - { 193, "S'ha acabat la cerca!" }, - { 194, "S'han cercat %d directoris ..." }, - { 195, "Men\372 Principal de ScummVM" }, - { 196, "ScummVM no ha pogut trobar cap motor capa\347 d'executar el joc seleccionat!" }, - { 197, "ScummVM no ha pogut trobar cap joc al directori especificat!" }, - { 198, "ScummVM no ha pogut obrir el directori especificat!" }, - { 199, "Cerca a la llista de jocs" }, - { 200, "Cerca:" }, - { 201, "Seleccioneu el fitxer SoundFont" }, - { 202, "Seleccioneu un Tema" }, - { 203, "Seleccioneu el directori addicional del joc" }, - { 204, "Seleccioneu una acci\363 i cliqueu 'Mapeja'" }, - { 205, "Seleccioneu el directori dels temes de la Interf\355cie d'Usuari" }, - { 206, "Seleccioneu el directori dels fitxers extra" }, - { 207, "Seleccioneu el directori dels connectors" }, - { 208, "Seleccioneu el directori de les partides desades" }, - { 209, "Seleccioneu el directori de les partides desades" }, - { 210, "Seleccioneu el directori amb les dades del joc" }, - { 211, "Sensibilitat" }, - { 212, "Servidor:" }, - { 213, "Compartici\363:" }, - { 214, "Identificador de joc curt utilitzat per referir-se a les partides i per executar el joc des de la l\355nia de comandes" }, - { 215, "Mostra el teclat" }, - { 216, "Mostra el cursor del ratol\355" }, - { 217, "Mostra els subt\355tols i reprodueix la veu" }, - { 218, "Mostra/Oculta el cursor" }, - { 219, "Salta" }, - { 220, "Salta la l\355nia" }, - { 221, "Salta el text" }, - { 223, "Escalat per software (bona qualitat, per\362 m\351s lent)" }, - { 224, "So engegat/parat" }, - { 225, "Algunes targes de so, Fluidsynth i Timidity suporten SoundFont" }, - { 226, "Fitxer SoundFont:" }, - { 227, "Veus" }, - { 228, "Modes de dispersi\363 especials suportats per alguns jocs" }, - { 229, "Volum dels sons d'efectes especials" }, - { 230, "Especifica el dispositiu de so per defecte per a la sortida General MIDI" }, - { 231, "Especifica el dispositiu de so per defecte per a la sortida de Roland MT-32/LAPC1/CM32l/CM64" }, - { 232, "Especifica el dispositiu de so o l'emulador de tarja de so de sortida" }, - { 233, "Especifica el cam\355 de les dades addicionals utilitzades per tots els jocs o pel ScummVM" }, - { 234, "Especifica el cam\355 de dades addicionals utilitzades pel joc" }, - { 235, "Especifica el dispositiu de so o l'emulador de tarja de so preferit" }, - { 236, "Especifica on es desaran les partides" }, - { 237, "Veus" }, - { 238, "Volum de la veu:" }, - { 239, "Pintat est\340ndard (16bpp)" }, - { 240, "Iniciant el joc seleccionat" }, - { 241, "Estat:" }, - { 242, "Subt" }, - { 243, "Velocitat dels subt\355tols:" }, - { 244, "Subt\355tols" }, - { 245, "Commuta el personatge" }, - { 246, "Toc per a clic esquerre, doble toc per a clic dret" }, - { 247, "Text i Veus:" }, - { 248, "No es pot escriure al directori seleccionat. Si us plau, escolliu-ne un altre." }, - { 249, "Cam\355 dels Temes:" }, - { 250, "Tema:" }, - { 251, "Aquest identificador de joc ja est\340 usat. Si us plau, trieu-ne un altre." }, - { 252, "Aquest joc no suporta la c\340rrega de partides des del llan\347ador." }, - { 253, "Hora: " }, - { 255, "Despla\347ament X del toc" }, - { 256, "Despla\347ament Y del toc" }, - { 257, "Mode Touchpad desactivat." }, - { 258, "Mode Touchpad activat." }, - { 259, "Roland MT-32 real (desactiva l'emulaci\363 GM)" }, - { 260, "Desactiva la conversi\363 General MIDI pels jocs que tenen banda sonora per a Roland MT-32" }, - { 261, "Desconegut" }, - { 262, "Error desconegut" }, - { 263, "Desmunta el DVD" }, - { 264, "Desmunta SMB" }, - { 265, "Sense escalar (haureu de despla\347ar-vos a esquerra i dreta)" }, - { 266, "Mode de color no suportat" }, - { 267, "Partida sense t\355tol" }, - { 268, "Amunt" }, - { 269, "Utilitza MIDI i la generaci\363 de so AdLib alhora" }, - { 270, "Utilitza el control del cursor a l'estil del trackpad dels port\340tils" }, - { 271, "Nom d'usuari:" }, - { 272, "Utilitzant el controlador SDL " }, - { 274, "V\355deo" }, - { 275, "Teclat virtual" }, - { 276, "Volum" }, - { 277, "MIDI de Windows" }, - { 278, "S'ha denegat el perm\355s d'escriptura" }, - { 279, "Ha fallat l'escriptura de dades" }, - { 280, "S\355" }, - { 281, "Heu de reiniciar ScummVM perqu\350 tots els canvis tingui efecte." }, - { 282, "Zona" }, - { 283, "Redueix" }, - { 284, "Amplia" }, - { 285, "cada 10 minuts" }, - { 286, "cada 15 minuts" }, - { 287, "cada 30 minuts" }, - { 288, "cada 5 minuts" }, - { 289, "~Q~uant a" }, - { 290, "~A~fegeix Joc..." }, - { 291, "~C~ancel\267la" }, - { 292, "~T~anca" }, - { 293, "~E~dita Joc..." }, - { 294, "~A~juda" }, - { 295, "Controls de lluita de l'~I~ndy" }, - { 296, "~T~ecles" }, - { 297, "Mode ~e~squerr\340" }, - { 298, "C~a~rrega" }, - { 299, "~C~arrega..." }, - { 300, "~S~eg\374ent" }, - { 301, "~D~'acord" }, - { 302, "~O~pcions" }, - { 303, "~O~pcions..." }, - { 304, "~A~nterior" }, - { 305, "~T~anca" }, - { 306, "~S~uprimeix Joc" }, - { 307, "~C~ontinua" }, - { 308, "~R~etorna al Llan\347ador" }, - { 309, "~D~esa" }, - { 310, "~I~nicia" }, - { 311, "~T~ransicions activades" }, - { 312, "~E~fecte de l'aigua activat" }, - { 313, "Mode ~Z~ip activat" }, + { 128, "Dispositiu MT32:" }, + { 129, "Emulador de MT-32" }, + { 130, "Escalat de la pantalla principal:" }, + { 131, "Mapeja" }, + { 132, "Addici\363 Massiva..." }, + { 133, "Men\372" }, + { 134, "Misc" }, + { 135, "Mode combinat AdLib/MIDI" }, + { 136, "Munta el DVD" }, + { 137, "Munta SMB" }, + { 138, "Clic del ratol\355" }, + { 139, "Funci\363 M\372ltiple" }, + { 140, "Dispositiu GM:" }, + { 141, "Volum de la m\372sica:" }, + { 142, "Silenciar tot" }, + { 143, "Nom:" }, + { 144, "Xarxa inactiva" }, + { 145, "Xarxa no iniciada (%d)" }, + { 146, "Xarxa activa" }, + { 147, "Xarxa activa, compartici\363 muntada" }, + { 148, "Mai" }, + { 149, "No" }, + { 150, "No hi ha data desada" }, + { 151, "Sense m\372sica" }, + { 152, "No hi ha temps de joc desat" }, + { 153, "No hi ha hora desada" }, + { 154, "Cap" }, + { 155, "Normal (sense escalar)" }, + { 156, "D'acord" }, + { 157, "Freq\374\350ncia de sortida:" }, + { 158, "Fer canvis sobre les opcions globals de MIDI" }, + { 159, "Fer canvis sobre les opcions globals de MIDI" }, + { 160, "Fer canvis sobre les opcions globals d'\340udio" }, + { 161, "Fer canvis sobre les opcions globals de gr\340fics" }, + { 162, "Fer canvis sobre les opcions globals de volum" }, + { 163, "Emulador d'Altaveu de PC" }, + { 164, "Contrasenya:" }, + { 165, "El cam\355 no \351s un directori" }, + { 166, "El cam\355 no \351s un fitxer" }, + { 167, "El cam\355 no existeix" }, + { 168, "Camins" }, + { 169, "Pausa" }, + { 170, "Seleccioneu el joc:" }, + { 171, "Plataforma per la que el joc es va dissenyar originalment" }, + { 172, "Plataforma:" }, + { 173, "Temps de joc: " }, + { 174, "Seleccioneu una acci\363" }, + { 175, "Cam\355 dels connectors:" }, + { 176, "Dispositiu Preferit:" }, + { 177, "Premeu la tecla a associar" }, + { 178, "Surt" }, + { 179, "Surt de ScummVM" }, + { 180, "S'ha denegat el perm\355s de lectura" }, + { 181, "Ha fallat la lectura" }, + { 182, "Remapeja les tecles" }, + { 183, "Elimina un joc de la llista. Els fitxers de dades del joc es mantenen intactes" }, + { 184, "Mode de pintat:" }, + { 185, "Dreta" }, + { 186, "Clic dret" }, + { 187, "Clic dret" }, + { 188, "Rotar" }, + { 189, "Volum dels efectes:" }, + { 190, "SMB" }, + { 191, "Desa" }, + { 192, "Cam\355 de les Partides:" }, + { 193, "Cam\355 de les Partides: " }, + { 194, "Desa la partida:" }, + { 195, "S'ha acabat la cerca!" }, + { 196, "S'han cercat %d directoris ..." }, + { 197, "Men\372 Principal de ScummVM" }, + { 198, "ScummVM no ha pogut trobar cap motor capa\347 d'executar el joc seleccionat!" }, + { 199, "ScummVM no ha pogut trobar cap joc al directori especificat!" }, + { 200, "ScummVM no ha pogut obrir el directori especificat!" }, + { 201, "Cerca a la llista de jocs" }, + { 202, "Cerca:" }, + { 203, "Seleccioneu el fitxer SoundFont" }, + { 204, "Seleccioneu un Tema" }, + { 205, "Seleccioneu el directori addicional del joc" }, + { 206, "Seleccioneu una acci\363 i cliqueu 'Mapeja'" }, + { 207, "Seleccioneu el directori dels temes de la Interf\355cie d'Usuari" }, + { 208, "Seleccioneu el directori dels fitxers extra" }, + { 209, "Seleccioneu el directori dels connectors" }, + { 210, "Seleccioneu el directori de les partides desades" }, + { 211, "Seleccioneu el directori de les partides desades" }, + { 212, "Seleccioneu el directori amb les dades del joc" }, + { 213, "Sensibilitat" }, + { 214, "Servidor:" }, + { 215, "Compartici\363:" }, + { 216, "Identificador de joc curt utilitzat per referir-se a les partides i per executar el joc des de la l\355nia de comandes" }, + { 217, "Mostra el teclat" }, + { 218, "Mostra el cursor del ratol\355" }, + { 219, "Mostra els subt\355tols i reprodueix la veu" }, + { 220, "Mostra/Oculta el cursor" }, + { 221, "Salta" }, + { 222, "Salta la l\355nia" }, + { 223, "Salta el text" }, + { 225, "Escalat per software (bona qualitat, per\362 m\351s lent)" }, + { 226, "So engegat/parat" }, + { 227, "Algunes targes de so, Fluidsynth i Timidity suporten SoundFont" }, + { 228, "Fitxer SoundFont:" }, + { 229, "Veus" }, + { 230, "Modes de dispersi\363 especials suportats per alguns jocs" }, + { 231, "Volum dels sons d'efectes especials" }, + { 232, "Especifica el dispositiu de so per defecte per a la sortida General MIDI" }, + { 233, "Especifica el dispositiu de so per defecte per a la sortida de Roland MT-32/LAPC1/CM32l/CM64" }, + { 234, "Especifica el dispositiu de so o l'emulador de tarja de so de sortida" }, + { 235, "Especifica el cam\355 de les dades addicionals utilitzades per tots els jocs o pel ScummVM" }, + { 236, "Especifica el cam\355 de dades addicionals utilitzades pel joc" }, + { 237, "Especifica el dispositiu de so o l'emulador de tarja de so preferit" }, + { 238, "Especifica on es desaran les partides" }, + { 239, "Veus" }, + { 240, "Volum de la veu:" }, + { 241, "Pintat est\340ndard (16bpp)" }, + { 242, "Iniciant el joc seleccionat" }, + { 243, "Estat:" }, + { 244, "Subt" }, + { 245, "Velocitat dels subt\355tols:" }, + { 246, "Subt\355tols" }, + { 247, "Commuta el personatge" }, + { 248, "Toc per a clic esquerre, doble toc per a clic dret" }, + { 249, "Text i Veus:" }, + { 250, "No es pot escriure al directori seleccionat. Si us plau, escolliu-ne un altre." }, + { 251, "Cam\355 dels Temes:" }, + { 252, "Tema:" }, + { 253, "Aquest identificador de joc ja est\340 usat. Si us plau, trieu-ne un altre." }, + { 254, "Aquest joc no suporta la c\340rrega de partides des del llan\347ador." }, + { 255, "Hora: " }, + { 257, "Despla\347ament X del toc" }, + { 258, "Despla\347ament Y del toc" }, + { 259, "Mode Touchpad desactivat." }, + { 260, "Mode Touchpad activat." }, + { 261, "Roland MT-32 real (desactiva l'emulaci\363 GM)" }, + { 262, "Desactiva la conversi\363 General MIDI pels jocs que tenen banda sonora per a Roland MT-32" }, + { 263, "Desconegut" }, + { 264, "Error desconegut" }, + { 265, "Desmunta el DVD" }, + { 266, "Desmunta SMB" }, + { 267, "Sense escalar (haureu de despla\347ar-vos a esquerra i dreta)" }, + { 268, "Mode de color no suportat" }, + { 269, "Partida sense t\355tol" }, + { 270, "Amunt" }, + { 271, "Utilitza MIDI i la generaci\363 de so AdLib alhora" }, + { 272, "Utilitza el control del cursor a l'estil del trackpad dels port\340tils" }, + { 273, "Nom d'usuari:" }, + { 274, "Utilitzant el controlador SDL " }, + { 276, "V\355deo" }, + { 277, "Teclat virtual" }, + { 278, "Volum" }, + { 279, "MIDI de Windows" }, + { 280, "S'ha denegat el perm\355s d'escriptura" }, + { 281, "Ha fallat l'escriptura de dades" }, + { 282, "S\355" }, + { 283, "Heu de reiniciar ScummVM perqu\350 tots els canvis tingui efecte." }, + { 284, "Zona" }, + { 285, "Redueix" }, + { 286, "Amplia" }, + { 287, "cada 10 minuts" }, + { 288, "cada 15 minuts" }, + { 289, "cada 30 minuts" }, + { 290, "cada 5 minuts" }, + { 291, "~Q~uant a" }, + { 292, "~A~fegeix Joc..." }, + { 293, "~C~ancel\267la" }, + { 294, "~T~anca" }, + { 295, "~E~dita Joc..." }, + { 296, "~A~juda" }, + { 297, "Controls de lluita de l'~I~ndy" }, + { 298, "~T~ecles" }, + { 299, "Mode ~e~squerr\340" }, + { 300, "C~a~rrega" }, + { 301, "~C~arrega..." }, + { 302, "~S~eg\374ent" }, + { 303, "~D~'acord" }, + { 304, "~O~pcions" }, + { 305, "~O~pcions..." }, + { 306, "~A~nterior" }, + { 307, "~T~anca" }, + { 308, "~S~uprimeix Joc" }, + { 309, "~C~ontinua" }, + { 310, "~R~etorna al Llan\347ador" }, + { 311, "~D~esa" }, + { 312, "~I~nicia" }, + { 313, "~T~ransicions activades" }, + { 314, "~E~fecte de l'aigua activat" }, + { 315, "Mode ~Z~ip activat" }, { -1, NULL } }; -static const PoMessageEntry _translation_hu_HU[] = { - { 0, "Project-Id-Version: ScummVM VERSION\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-12 17:44+0200\nPO-Revision-Date: 2009-11-25 07:42-0500\nLast-Translator: Alex Bevilacqua <alexbevi@gmail.com>\nLanguage-Team: Hungarian\nLanguage: \nMIME-Version: 1.0\nContent-Type: text/plain; charset=cp1250\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=(n != 1);\n" }, - { 14, "<alap\351rtelmezett>" }, - { 16, "AdLib vezet :" }, - { 17, "AdLib vezet :" }, - { 21, "Aspect adag korrekci\363" }, - { 24, "Hang" }, - { 25, "Automatikus ment\351s:" }, - { 28, "Kulcsok" }, - { 42, "Renderel\351si m\363d:" }, - { 53, "<alap\351rtelmezett>" }, - { 69, "K\351pess\351 Roland GS Mode" }, - { 74, "Extra \332tvonal:" }, - { 76, "Grafikus m\363d:" }, - { 80, "Teljes k\351perny s m\363d:" }, - { 86, "Lek\351pez eszk\366z GUI:" }, - { 90, "Extra \332tvonal:" }, - { 94, "Grafik\341val" }, - { 95, "Grafikus m\363d:" }, - { 115, "Kulcsok" }, - { 124, "AdLib vezet :" }, - { 126, "MIDI nyeres\351g:" }, - { 127, "Zene mennyis\351g:" }, - { 134, "Vegyes AdLib/MIDI m\363d" }, - { 139, "Zene mennyis\351g:" }, - { 140, "Zene mennyis\351g:" }, - { 141, "Muta \326sszes" }, - { 147, "Soha" }, - { 148, "Semmi" }, - { 153, "Semmi" }, - { 155, "Igen" }, - { 156, "Kimeneti teljes\355tm\351ny:" }, - { 166, "\326sv\351nyek" }, - { 167, "\326sv\351nyek" }, - { 182, "Renderel\351si m\363d:" }, - { 187, "SFX mennyis\351ge" }, - { 190, "Extra \332tvonal:" }, - { 212, "Soha" }, - { 237, "Csak a besz\351d" }, - { 238, "Besz\351d mennyis\351g:" }, - { 243, "Felirat sebess\351g:" }, - { 244, "Csak feliratok" }, - { 247, "Sz\366veg \351s besz\351d:" }, - { 250, "T\351ma:" }, - { 253, "T\351ma:" }, - { 259, "Igaz Roland MT-32 (megb\351n\355t GM emul\341ci\363)" }, - { 272, "Zenei vezet :" }, - { 276, "Volumene" }, - { 282, "Semmi" }, - { 285, "10 percenk\351nt" }, - { 286, "15 percenk\351nt" }, - { 287, "30 percenk\351nt" }, - { 288, "5 percenk\351nt" }, - { 296, "Kulcsok" }, - { 297, "Renderel\351si m\363d:" }, - { 301, "Igen" }, +static const PoMessageEntry _translation_es_ES[] = { + { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-30 22:14+0100\nPO-Revision-Date: 2010-07-30 22:17+0100\nLast-Translator: Tom\341s Maidagan\nLanguage-Team: \nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\nLanguage: Espanol\n" }, + { 1, "\277Seguro que quieres salir?" }, + { 2, "(Activa)" }, + { 3, "(Juego)" }, + { 4, "(General)" }, + { 5, "(compilado el %s)" }, + { 6, ", error al montar el disco compartido" }, + { 7, ", disco compartido no montado" }, + { 8, "... progreso..." }, + { 9, "11kHz" }, + { 10, "22 kHz" }, + { 11, "44 kHz" }, + { 12, "48 kHz" }, + { 13, "8 kHz" }, + { 14, "<por defecto>" }, + { 15, "Acerca de ScummVM" }, + { 16, "Emulador de AdLib" }, + { 17, "Emulador de AdLib:" }, + { 18, "AdLib se usa para la m\372sica en muchos juegos" }, + { 19, "A\361adir juego..." }, + { 20, "Antialiasing (16bpp)" }, + { 21, "Correcci\363n de aspecto" }, + { 22, "Tecla asociada: %s" }, + { 23, "Tecla asociada: ninguna" }, + { 24, "Sonido" }, + { 25, "Autoguardado:" }, + { 26, "Motores disponibles:" }, + { 27, "Acerca ~d~e" }, + { 28, "Asignar teclas" }, + { 29, "Ambos" }, + { 30, "Brillo:" }, + { 31, "Cancelar" }, + { 32, "Imposible crear el archivo" }, + { 33, "Cambiar opciones de juego" }, + { 34, "Cambiar opciones generales de ScummVM" }, + { 35, "Marcar si se quiere usar un dispositivo de sonido real conectado al ordenador y compatible con Roland" }, + { 36, "Elegir" }, + { 37, "Elige la acci\363n a asociar" }, + { 38, "Eliminar valor" }, + { 39, "Cerrar" }, + { 40, "Corregir relaci\363n de aspecto en juegos 320x200" }, + { 41, "No se ha podido encontrar ning\372n motor capaz de ejecutar el juego" }, + { 42, "Modo de v\355deo actual:" }, + { 43, "Abajo" }, + { 44, "Izquierda" }, + { 45, "Derecha" }, + { 46, "Arriba" }, + { 47, "Emulador de DOSBox OPL" }, + { 48, "DVD" }, + { 49, "DVD montado con \351xito" }, + { 50, "DVD no montado" }, + { 51, "Fecha:" }, + { 52, "Debugger" }, + { 53, "Por defecto" }, + { 54, "Borrar" }, + { 55, "Desactivar apagado" }, + { 56, "GFX desactivados" }, + { 57, "Se han encontrado %d juegos nuevos..." }, + { 58, "Se han encontrado %d juegos nuevos." }, + { 59, "Pantalla" }, + { 60, "Mostrar el teclado" }, + { 61, "\277Seguro que quieres borrar esta partida?" }, + { 62, "\277Seguro que quieres eliminar la configuraci\363n de este juego?" }, + { 63, "\277Seguro que quieres ejecutar la detecci\363n masiva? Puede que se a\361ada un gran n\372mero de juegos." }, + { 64, "\277Quieres cargar o guardar el juego?" }, + { 65, "\277Quieres realizar una b\372squeda autom\341tica?" }, + { 66, "\277Quieres salir?" }, + { 67, "Doble golpe" }, + { 68, "Abajo" }, + { 69, "Activar modo Roland GS" }, + { 70, "El motor no soporta el nivel de debug '%s'" }, + { 71, "Ingl\351s" }, + { 72, "Error al ejecutar el juego:" }, + { 73, "Error al montar el DVD" }, + { 74, "Adicional:" }, + { 75, "Emulador de FM Towns" }, + { 76, "Modo r\341pido" }, + { 77, "Caracter\355sticas compiladas:" }, + { 78, "Vista libre" }, + { 79, "T\355tulo completo del juego" }, + { 80, "Pantalla completa" }, + { 81, "Aceleraci\363n del pad GC:" }, + { 82, "Sensibilidad del pad GC:" }, + { 83, "GFX" }, + { 84, "Dispositivo GM:" }, + { 85, "Idioma de la interfaz:" }, + { 86, "Render de la interfaz" }, + { 87, "Juego" }, + { 88, "No se han encontrado datos de juego" }, + { 89, "ID del juego no soportada" }, + { 90, "Juego:" }, + { 91, "Men\372 general" }, + { 92, "Ir al directorio anterior" }, + { 93, "Arriba" }, + { 94, "Gr\341ficos" }, + { 95, "Modo gr\341fico:" }, + { 96, "Escalado por hardware (r\341pido, pero de baja calidad)" }, + { 97, "Hercules \341mbar" }, + { 98, "Hercules verde" }, + { 99, "Ocultar barra de tareas" }, + { 100, "Sonido de alta calidad (m\341s lento) (reinicio)" }, + { 101, "Los valores m\341s altos ofrecen mayor calidad, pero puede que tu tarjeta de sonido no sea compatible" }, + { 102, "Mant\351n pulsado May\372s para a\361adir varios" }, + { 103, "Underscan horizontal" }, + { 104, "Emulador de IBM PCjr" }, + { 105, "ID:" }, + { 106, "Inicializar red" }, + { 107, "Escalado de la pantalla inicial superior:" }, + { 108, "Iniciando emulador de MT-32" }, + { 109, "Inicializando red" }, + { 110, "Entrada" }, + { 111, "Ruta no v\341lida" }, + { 112, "Asignaci\363n de teclas" }, + { 113, "Teclado" }, + { 114, "Asignaci\363n de teclas:" }, + { 115, "Teclas" }, + { 116, "Idioma de la interfaz de ScummVM" }, + { 117, "Idioma del juego. No sirve para pasar al ingl\351s la versi\363n espa\361ola de un juego" }, + { 118, "Idioma:" }, + { 119, "Izquierda" }, + { 120, "Clic izquierdo" }, + { 121, "Cargar" }, + { 122, "Cargar juego:" }, + { 123, "Cargar partida del juego seleccionado" }, + { 124, "Emulador de MAME OPL" }, + { 125, "MIDI" }, + { 126, "Ganancia MIDI:" }, + { 127, "MT-32" }, + { 128, "Dispositivo MT-32:" }, + { 129, "Emulador de MT-32" }, + { 130, "Escalado de la pantalla principal:" }, + { 131, "Asignar" }, + { 132, "A\361adir varios..." }, + { 133, "Men\372" }, + { 134, "Otros" }, + { 135, "Modo AdLib/MIDI" }, + { 136, "Montar DVD" }, + { 137, "Montar SMB" }, + { 138, "Clic de rat\363n" }, + { 139, "Multifunci\363n" }, + { 140, "Dispositivo de m\372sica:" }, + { 141, "Volumen de la m\372sica:" }, + { 142, "Silenciar" }, + { 143, "Nombre:" }, + { 144, "Red desconectada" }, + { 145, "Red no inicializada (%d)" }, + { 146, "Red conectada" }, + { 147, "Red conectada, disco compartido montado" }, + { 148, "Nunca" }, + { 149, "No" }, + { 150, "No hay fecha guardada" }, + { 151, "Sin m\372sica" }, + { 152, "No hay tiempo de juego guardado" }, + { 153, "No hay hora guardada" }, + { 154, "Ninguno" }, + { 155, "Normal (sin escalado)" }, + { 156, "De acuerdo" }, + { 157, "Frecuencia de salida:" }, + { 158, "Ignorar opciones MIDI generales" }, + { 159, "Ignorar opciones MT-32 generales" }, + { 160, "Ignorar opciones de sonido generales" }, + { 161, "Ignorar opciones gr\341ficas generales" }, + { 162, "Ignorar opciones de volumen generales" }, + { 163, "Emulador del altavoz de PC" }, + { 164, "Contrase\361a:" }, + { 165, "La ruta no es un directorio" }, + { 166, "La ruta no es un archivo" }, + { 167, "La ruta no existe" }, + { 168, "Rutas" }, + { 169, "Pausar" }, + { 170, "Elige el juego:" }, + { 171, "Plataforma para la que se dise\361\363 el juego" }, + { 172, "Plataforma:" }, + { 173, "Tiempo de juego:" }, + { 174, "Por favor, selecciona una acci\363n" }, + { 175, "Plugins:" }, + { 176, "Dispositivo preferido:" }, + { 177, "Pulsa la tecla a asignar" }, + { 178, "Salir" }, + { 179, "Cerrar ScummVM" }, + { 180, "Permiso de lectura denegado" }, + { 181, "Lectura fallida" }, + { 182, "Asignar teclas" }, + { 183, "Elimina el juego de la lista. Los archivos no se borran" }, + { 184, "Modo de renderizado:" }, + { 185, "Derecha" }, + { 186, "Clic derecho" }, + { 187, "Clic derecho" }, + { 188, "Rotar" }, + { 189, "Volumen de los efectos" }, + { 190, "SMB" }, + { 191, "Guardar" }, + { 192, "Partidas:" }, + { 193, "Partidas:" }, + { 194, "Guardar partida" }, + { 195, "\241B\372squeda completada!" }, + { 196, "Se ha buscado en %d directorios..." }, + { 197, "Men\372 principal de ScummVM" }, + { 198, "\241ScummVM no ha podido encontrar ning\372n motor capaz de ejecutar el juego!" }, + { 199, "\241ScummVM no ha encontrado ning\372n juego en el directorio!" }, + { 200, "\241ScummVM no ha podido abrir el directorio!" }, + { 201, "Buscar en la lista de juegos" }, + { 202, "Buscar:" }, + { 203, "Seleccionar SoundFont" }, + { 204, "Selecciona un tema" }, + { 205, "Seleccionar directorio de juego adicional" }, + { 206, "Selecciona una acci\363n y pulsa \"Asignar\"" }, + { 207, "Selecciona el directorio para temas de interfaz" }, + { 208, "Selecciona el directorio para archivos adicionales" }, + { 209, "Selecciona el directorio para plugins" }, + { 210, "Seleccionar directorio para partidas guardadas" }, + { 211, "Selecciona el directorio para partidas guardadas." }, + { 212, "Seleccionar directorio con los archivos del juego" }, + { 213, "Sensibilidad" }, + { 214, "Servidor:" }, + { 215, "Disco compartido:" }, + { 216, "Identificador usado para las partidas guardadas y para ejecutar el juego desde la l\355nea de comando" }, + { 217, "Mostrar teclado" }, + { 218, "Mostrar el cursor" }, + { 219, "Reproducir voces y subt\355tulos" }, + { 220, "Mostrar/ocultar cursor" }, + { 221, "Saltar" }, + { 222, "Saltar frase" }, + { 223, "Saltar texto" }, + { 224, "Pegar a los bordes" }, + { 225, "Escalado por software (buena calidad, pero m\341s lento)" }, + { 226, "Sonido activado/desactivado" }, + { 227, "Algunas tarjetas de sonido, Fluidsynth y Timidity soportan SoundFont" }, + { 228, "SoundFont:" }, + { 229, "Voces" }, + { 230, "Modos especiales de expansi\363n soportados por algunos juegos" }, + { 231, "Volumen de los efectos de sonido" }, + { 232, "Especifica el dispositivo de salida General MIDI por defecto" }, + { 233, "Especifica el dispositivo de sonido para la salida Roland MT-32/LAPC1/CM32l/CM64 por defecto" }, + { 234, "Especifica el dispositivo de sonido o emulador de tarjeta de sonido de salida" }, + { 235, "Especifica el directorio adicional usado por los juegos y ScummVM" }, + { 236, "Especifica un directorio para datos adicionales del juego" }, + { 237, "Especifica qu\351 dispositivo de sonido o emulador de tarjeta de sonido prefieres" }, + { 238, "Especifica d\363nde guardar tus partidas" }, + { 239, "Voces" }, + { 240, "Volumen de las voces" }, + { 241, "Est\341ndar (16bpp)" }, + { 242, "Jugar al juego seleccionado" }, + { 243, "Estado:" }, + { 244, "Subt." }, + { 245, "Velocidad de los subt\355tulos:" }, + { 246, "Subt\355tulos" }, + { 247, "Cambiar personaje" }, + { 248, "Un toque para clic izquierdo, dos para clic derecho" }, + { 249, "Texto y voces:" }, + { 250, "No se puede escribir en el directorio elegido. Por favor, selecciona otro." }, + { 251, "Temas:" }, + { 252, "Tema:" }, + { 253, "Esta ID ya est\341 siendo usada. Por favor, elige otra." }, + { 254, "Este juego no permite cargar partidas desde el lanzador." }, + { 255, "Hora:" }, + { 256, "Se ha excedido el tiempo de inicializaci\363n de red" }, + { 257, "Compensaci\363n X del toque" }, + { 258, "Compensaci\363n Y del toque" }, + { 259, "Modo Touchpad desactivado." }, + { 260, "Modo Touchpad activado." }, + { 261, "Roland MT-32 aut\351ntica (desactivar emulaci\363n GM)" }, + { 262, "Desactiva la conversi\363n General MIDI en juegos con sonido Roland MT-32" }, + { 263, "Desconocido" }, + { 264, "Error desconocido" }, + { 265, "Desmontar DVD" }, + { 266, "Desmontar SMB" }, + { 267, "Sin escalado (debes desplazar la pantalla a los lados)" }, + { 268, "Modo de color no soportado" }, + { 269, "Partida sin nombre" }, + { 270, "Arriba" }, + { 271, "Usar tanto MIDI como AdLib en la generaci\363n de sonido" }, + { 272, "Activar el sistema de control tipo trackpad de los port\341tiles" }, + { 273, "Usuario:" }, + { 274, "Usando driver SDL" }, + { 275, "Underscan vertical:" }, + { 276, "V\355deo" }, + { 277, "Teclado virtual" }, + { 278, "Volumen" }, + { 279, "Windows MIDI" }, + { 280, "Permiso de escritura denegado" }, + { 281, "Escritura de datos fallida" }, + { 282, "S\355" }, + { 283, "Tienes que reiniciar ScummVM para aplicar los cambios." }, + { 284, "Zona" }, + { 285, "Disminuir zoom" }, + { 286, "Aumentar zoom" }, + { 287, "cada 10 minutos" }, + { 288, "cada 15 minutos" }, + { 289, "cada 30 minutos" }, + { 290, "cada 5 minutos" }, + { 291, "Acerca ~d~e" }, + { 292, "~A~\361adir juego..." }, + { 293, "~C~ancelar" }, + { 294, "Cerra~r~" }, + { 295, "~E~ditar juego..." }, + { 296, "~A~yuda" }, + { 297, "Controles para pelear de ~I~ndy" }, + { 298, "~T~eclas" }, + { 299, "Modo para ~z~urdos" }, + { 300, "~C~argar" }, + { 301, "~C~argar..." }, + { 302, "Si~g~uiente" }, + { 303, "~S~\355" }, + { 304, "~O~opciones" }, + { 305, "~O~opciones..." }, + { 306, "~A~nterior" }, + { 307, "~S~alir" }, + { 308, "E~l~iminar juego" }, + { 309, "~R~eanudar" }, + { 310, "~V~olver al lanzador" }, + { 311, "~G~uardar" }, + { 312, "~J~ugar" }, + { 313, "Tra~n~siciones activadas" }, + { 314, "Efecto ag~u~a activado" }, + { 315, "Modo ~Z~ip activado" }, { -1, NULL } }; static const PoMessageEntry _translation_de_DE[] = { - { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-12 17:44+0200\nPO-Revision-Date: 2010-07-09 20:37+0100\nLast-Translator: Simon Sawatzki\nLanguage-Team: Lothar Serra Mari <Lothar@Windowsbase.de> & Simon Sawatzki <SimSaw@gmx.de>\nLanguage: Deutsch\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=n != 1;\n" }, + { 0, "Project-Id-Version: ScummVM 1.2.0svn\nReport-Msgid-Bugs-To: scummvm-devel@lists.sf.net\nPOT-Creation-Date: 2010-07-30 22:14+0100\nPO-Revision-Date: 2010-07-09 20:37+0100\nLast-Translator: Simon Sawatzki\nLanguage-Team: Lothar Serra Mari <Lothar@Windowsbase.de> & Simon Sawatzki <SimSaw@gmx.de>\nMIME-Version: 1.0\nContent-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: 8bit\nLanguage: Deutsch\nPlural-Forms: nplurals=2; plural=n != 1;\n" }, { 1, " M\366chten Sie wirklich beenden? " }, { 2, " (Aktiv)" }, { 3, " (Spiel)" }, @@ -1776,210 +2424,214 @@ static const PoMessageEntry _translation_de_DE[] = { { 124, "MAME-OPL-Emulator" }, { 125, "MIDI" }, { 126, "MIDI-Lautst\344rke:" }, - { 127, "MT32-Ger\344t:" }, - { 128, "MT-32-Emulation" }, - { 129, "Hauptbildschirm-Skalierung:" }, - { 130, "Zuweisen" }, - { 131, "Durchsuchen" }, - { 132, "Men\374" }, - { 133, "Sonstiges" }, - { 134, "AdLib-/MIDI-Modus" }, - { 135, "DVD einbinden" }, - { 136, "SMB einbinden" }, - { 137, "Mausklick" }, - { 138, "Multifunktion" }, - { 139, "Musikger\344t:" }, - { 140, "Musiklautst\344rke:" }, - { 141, "Alles aus" }, - { 142, "Name:" }, - { 143, "Netzwerk ist aus." }, - { 144, "Netzwerk nicht gestartet (%d)" }, - { 145, "Netzwerk gestartet" }, - { 146, "Netzwerk gestartet, \366ffentliches Verzeichnis eingebunden" }, - { 147, "Niemals" }, - { 148, "Nein" }, - { 149, "Kein Datum gespeichert" }, - { 150, "Keine Musik" }, - { 151, "Keine Spielzeit gespeichert" }, - { 152, "Keine Zeit gespeichert" }, - { 153, "-" }, - { 154, "Normal (keine Skalierung)" }, - { 155, "OK" }, - { 156, "Ausgabefrequenz:" }, - { 157, "Globale MIDI-Einstellungen \374bergehen" }, - { 158, "Globale Audioeinstellungen \374bergehen" }, - { 159, "Globale Grafikeinstellungen \374bergehen" }, - { 160, "Globale Lautst\344rke-Einstellungen \374bergehen" }, - { 161, "PC-Lautsprecher-Emulator" }, - { 162, "Passwort:" }, - { 163, "Ung\374ltiges Verzeichnis" }, - { 164, "Pfad ist keine Datei." }, - { 165, "Verzeichnis existiert nicht." }, - { 166, "Pfade" }, - { 167, "Pause" }, - { 168, "Spiel ausw\344hlen:" }, - { 169, "Plattform, f\374r die das Spiel urspr\374nglich erstellt wurde" }, - { 170, "Plattform:" }, - { 171, "Spieldauer: " }, - { 172, "Bitte eine Aktion ausw\344hlen" }, - { 173, "Plugin-Pfad:" }, - { 174, "Standard-Ger\344t:" }, - { 175, "Taste dr\374cken, um sie zuzuweisen" }, - { 176, "Beenden" }, - { 177, "ScummVM beenden" }, - { 178, "Lese-Berechtigung nicht vorhanden" }, - { 179, "Lesefehler aufgetreten" }, - { 180, "Tasten neu zuweisen" }, - { 181, "Spiel aus der Liste entfernen. Die Spieldateien bleiben erhalten." }, - { 182, "Render-Modus:" }, - { 183, "Rechts" }, - { 184, "Rechtsklick" }, - { 185, "Rechtsklick" }, - { 186, "Drehen" }, - { 187, "Effektlautst\344rke:" }, - { 188, "SMB" }, - { 189, "Speichern" }, - { 190, "Spielst\344nde:" }, - { 191, "Spielst\344nde: " }, - { 192, "Speichern:" }, - { 193, "Suchlauf abgeschlossen!" }, - { 194, "%d Ordner durchsucht..." }, - { 195, "ScummVM-Hauptmen\374" }, - { 196, "ScummVM konnte keine Engine finden, um das Spiel zu starten!" }, - { 197, "ScummVM kann in dem gew\344hlten Verzeichnis kein Spiel finden!" }, - { 198, "ScummVM kann das gew\344hlte Verzeichnis nicht \366ffnen!" }, - { 199, "In Spieleliste suchen" }, - { 200, "Suchen:" }, - { 201, "SoundFont ausw\344hlen" }, - { 202, "Thema ausw\344hlen" }, - { 203, "Verzeichnis mit zus\344tzlichen Dateien ausw\344hlen" }, - { 204, "Aktion ausw\344hlen und \"Zuweisen\" klicken" }, - { 205, "Verzeichnis f\374r Oberfl\344chen-Themen" }, - { 206, "Verzeichnis f\374r zus\344tzliche Dateien ausw\344hlen" }, - { 207, "Verzeichnis f\374r Erweiterungen ausw\344hlen" }, - { 208, "Verzeichnis f\374r Spielst\344nde ausw\344hlen" }, - { 209, "Verzeichnis f\374r Spielst\344nde ausw\344hlen" }, - { 210, "Verzeichnis mit Spieldateien ausw\344hlen" }, - { 211, "Empfindlichkeit" }, - { 212, "Server:" }, - { 213, "\326ffentliches Verzeichnis:" }, - { 214, "Kurzer Spielname, um die Spielst\344nde zuzuordnen und das Spiel von der Kommandozeile aus starten zu k\366nnen" }, - { 215, "Tastatur zeigen" }, - { 216, "Mauszeiger anzeigen" }, - { 217, "Untertitel anzeigen und Sprachausgabe aktivieren" }, - { 218, "Cursor zeigen/verbergen" }, - { 219, "\334berspringen" }, - { 220, "Zeile \374berspringen" }, - { 221, "Text \374berspringen" }, - { 222, "An Ecken anheften" }, - { 223, "Software-Skalierung (gute Qualit\344t, aber langsamer)" }, - { 224, "Ton ein/aus" }, - { 225, "SoundFont wird von einigen Soundkarten, Fluidsynth und Timidity unterst\374tzt." }, - { 226, "SoundFont:" }, - { 227, "Spr." }, - { 228, "Spezielle Farbmischungsmethoden werden von manchen Spielen unterst\374tzt." }, - { 229, "Lautst\344rke spezieller Soundeffekte" }, - { 230, "Legt das standardm\344\337ige Musikwiedergabe-Ger\344t f\374r General-MIDI-Ausgabe fest." }, - { 231, "Legt das standardm\344\337ige Tonwiedergabe-Ger\344t f\374r die Ausgabe von Roland MT-32/LAPC1/CM32l/CM64 fest." }, - { 232, "Legt das Musikwiedergabe-Ger\344t oder den Soundkarten-Emulator fest." }, - { 233, "Legt das Verzeichnis f\374r zus\344tzliche Spieldateien f\374r alle Spiele in ScummVM fest." }, - { 234, "Legt das Verzeichnis f\374r zus\344tzliche Spieldateien fest." }, - { 235, "Legt das bevorzugte Tonwiedergabe-Ger\344t oder den Soundkarten-Emulator fest." }, - { 236, "Legt fest, wo die Spielst\344nde abgelegt werden." }, - { 237, "Sprache" }, - { 238, "Sprachlautst\344rke:" }, - { 239, "Standard-Renderer (16bpp)" }, - { 240, "Ausgew\344hltes Spiel starten" }, - { 241, "Status:" }, - { 242, "Untert." }, - { 243, "Untertitel-Tempo:" }, - { 244, "Untertitel" }, - { 245, "Figur wechseln" }, - { 246, "Tippen f\374r Linksklick, Doppeltippen f\374r Rechtsklick" }, - { 247, "Text und Sprache:" }, - { 248, "In das gew\344hlte Verzeichnis kann nicht geschrieben werden. Bitte ein anderes ausw\344hlen." }, - { 249, "Themenpfad:" }, - { 250, "Thema:" }, - { 251, "Diese Spielkennung ist schon vergeben. Bitte eine andere w\344hlen." }, - { 252, "F\374r dieses Spiel wird das Laden aus der Spieleliste heraus nicht unterst\374tzt." }, - { 253, "Zeit: " }, - { 254, "Zeit\374berschreitung beim Starten des Netzwerks" }, - { 255, "Zu X-Position gehen" }, - { 256, "Zu Y-Position gehen" }, - { 257, "Touchpad-Modus ausgeschaltet." }, - { 258, "Touchpad-Modus aktiviert." }, - { 259, "Echte Roland-MT-32-Emulation (GM-Emulation deaktiviert)" }, - { 260, "Schaltet die General-MIDI-Zuweisung f\374r Spiele mit Roland-MT-32-Audiospur aus." }, - { 261, "Unbekannt" }, - { 262, "Unbekannter Fehler" }, - { 263, "DVD aush\344ngen" }, - { 264, "SMB aush\344ngen" }, - { 265, "Nicht skalieren (Sie m\374ssen nach links und nach rechts scrollen)" }, - { 266, "Farbmodus nicht unterst\374tzt" }, - { 267, "Unbenannt" }, - { 268, "Hoch" }, - { 269, "Benutzt MIDI und AdLib zur Sounderzeugung." }, - { 270, "Den Trackpad-Style f\374r Maussteuerung benutzen" }, - { 271, "Benutzername:" }, - { 272, "SDL-Treiber verwenden" }, - { 273, "Vertikale Bildverkleinerung:" }, - { 274, "Video" }, - { 275, "Virtuelle Tastatur" }, - { 276, "Lautst\344rke" }, - { 277, "Windows MIDI" }, - { 278, "Schreib-Berechtigung nicht vorhanden" }, - { 279, "Daten konnten nicht geschrieben werden." }, - { 280, "Ja" }, - { 281, "Sie m\374ssen ScummVM neustarten, um die Einstellungen zu \374bernehmen." }, - { 282, "Zone" }, - { 283, "Hineinzoomen" }, - { 284, "Herauszoomen" }, - { 285, "alle 10 Minuten" }, - { 286, "alle 15 Minuten" }, - { 287, "alle 30 Minuten" }, - { 288, "alle 5 Minuten" }, - { 289, "\334be~r~" }, - { 290, "Spiel ~h~inzuf\374gen" }, - { 291, "~A~bbrechen" }, - { 292, "~S~chlie\337en" }, - { 293, "Spielo~p~tionen" }, - { 294, "~H~ilfe" }, - { 295, "~K~ampfsteuerung f\374r Indiana Jones" }, - { 296, "~T~asten" }, - { 297, "~L~inke-Hand-Modus" }, - { 298, "~L~aden" }, - { 299, "~L~aden..." }, - { 300, "~W~eiter" }, - { 301, "~O~K" }, - { 302, "~O~ptionen" }, - { 303, "~O~ptionen" }, - { 304, "~Z~ur\374ck" }, - { 305, "~B~eenden" }, - { 306, "Spiel ~e~ntfernen" }, - { 307, "~F~ortsetzen" }, - { 308, "Zur Spiele~l~iste zur\374ck" }, - { 309, "~S~peichern" }, - { 310, "~S~tarten" }, - { 311, "\334ber~g~\344nge aktiviert" }, - { 312, "~W~assereffekt aktiviert" }, - { 313, "~Z~ip-Modus aktiviert" }, + { 128, "MT32-Ger\344t:" }, + { 129, "MT-32-Emulation" }, + { 130, "Hauptbildschirm-Skalierung:" }, + { 131, "Zuweisen" }, + { 132, "Durchsuchen" }, + { 133, "Men\374" }, + { 134, "Sonstiges" }, + { 135, "AdLib-/MIDI-Modus" }, + { 136, "DVD einbinden" }, + { 137, "SMB einbinden" }, + { 138, "Mausklick" }, + { 139, "Multifunktion" }, + { 140, "Musikger\344t:" }, + { 141, "Musiklautst\344rke:" }, + { 142, "Alles aus" }, + { 143, "Name:" }, + { 144, "Netzwerk ist aus." }, + { 145, "Netzwerk nicht gestartet (%d)" }, + { 146, "Netzwerk gestartet" }, + { 147, "Netzwerk gestartet, \366ffentliches Verzeichnis eingebunden" }, + { 148, "Niemals" }, + { 149, "Nein" }, + { 150, "Kein Datum gespeichert" }, + { 151, "Keine Musik" }, + { 152, "Keine Spielzeit gespeichert" }, + { 153, "Keine Zeit gespeichert" }, + { 154, "-" }, + { 155, "Normal (keine Skalierung)" }, + { 156, "OK" }, + { 157, "Ausgabefrequenz:" }, + { 158, "Globale MIDI-Einstellungen \374bergehen" }, + { 159, "Globale MIDI-Einstellungen \374bergehen" }, + { 160, "Globale Audioeinstellungen \374bergehen" }, + { 161, "Globale Grafikeinstellungen \374bergehen" }, + { 162, "Globale Lautst\344rke-Einstellungen \374bergehen" }, + { 163, "PC-Lautsprecher-Emulator" }, + { 164, "Passwort:" }, + { 165, "Ung\374ltiges Verzeichnis" }, + { 166, "Pfad ist keine Datei." }, + { 167, "Verzeichnis existiert nicht." }, + { 168, "Pfade" }, + { 169, "Pause" }, + { 170, "Spiel ausw\344hlen:" }, + { 171, "Plattform, f\374r die das Spiel urspr\374nglich erstellt wurde" }, + { 172, "Plattform:" }, + { 173, "Spieldauer: " }, + { 174, "Bitte eine Aktion ausw\344hlen" }, + { 175, "Plugin-Pfad:" }, + { 176, "Standard-Ger\344t:" }, + { 177, "Taste dr\374cken, um sie zuzuweisen" }, + { 178, "Beenden" }, + { 179, "ScummVM beenden" }, + { 180, "Lese-Berechtigung nicht vorhanden" }, + { 181, "Lesefehler aufgetreten" }, + { 182, "Tasten neu zuweisen" }, + { 183, "Spiel aus der Liste entfernen. Die Spieldateien bleiben erhalten." }, + { 184, "Render-Modus:" }, + { 185, "Rechts" }, + { 186, "Rechtsklick" }, + { 187, "Rechtsklick" }, + { 188, "Drehen" }, + { 189, "Effektlautst\344rke:" }, + { 190, "SMB" }, + { 191, "Speichern" }, + { 192, "Spielst\344nde:" }, + { 193, "Spielst\344nde: " }, + { 194, "Speichern:" }, + { 195, "Suchlauf abgeschlossen!" }, + { 196, "%d Ordner durchsucht..." }, + { 197, "ScummVM-Hauptmen\374" }, + { 198, "ScummVM konnte keine Engine finden, um das Spiel zu starten!" }, + { 199, "ScummVM kann in dem gew\344hlten Verzeichnis kein Spiel finden!" }, + { 200, "ScummVM kann das gew\344hlte Verzeichnis nicht \366ffnen!" }, + { 201, "In Spieleliste suchen" }, + { 202, "Suchen:" }, + { 203, "SoundFont ausw\344hlen" }, + { 204, "Thema ausw\344hlen" }, + { 205, "Verzeichnis mit zus\344tzlichen Dateien ausw\344hlen" }, + { 206, "Aktion ausw\344hlen und \"Zuweisen\" klicken" }, + { 207, "Verzeichnis f\374r Oberfl\344chen-Themen" }, + { 208, "Verzeichnis f\374r zus\344tzliche Dateien ausw\344hlen" }, + { 209, "Verzeichnis f\374r Erweiterungen ausw\344hlen" }, + { 210, "Verzeichnis f\374r Spielst\344nde ausw\344hlen" }, + { 211, "Verzeichnis f\374r Spielst\344nde ausw\344hlen" }, + { 212, "Verzeichnis mit Spieldateien ausw\344hlen" }, + { 213, "Empfindlichkeit" }, + { 214, "Server:" }, + { 215, "\326ffentliches Verzeichnis:" }, + { 216, "Kurzer Spielname, um die Spielst\344nde zuzuordnen und das Spiel von der Kommandozeile aus starten zu k\366nnen" }, + { 217, "Tastatur zeigen" }, + { 218, "Mauszeiger anzeigen" }, + { 219, "Untertitel anzeigen und Sprachausgabe aktivieren" }, + { 220, "Cursor zeigen/verbergen" }, + { 221, "\334berspringen" }, + { 222, "Zeile \374berspringen" }, + { 223, "Text \374berspringen" }, + { 224, "An Ecken anheften" }, + { 225, "Software-Skalierung (gute Qualit\344t, aber langsamer)" }, + { 226, "Ton ein/aus" }, + { 227, "SoundFont wird von einigen Soundkarten, Fluidsynth und Timidity unterst\374tzt." }, + { 228, "SoundFont:" }, + { 229, "Spr." }, + { 230, "Spezielle Farbmischungsmethoden werden von manchen Spielen unterst\374tzt." }, + { 231, "Lautst\344rke spezieller Soundeffekte" }, + { 232, "Legt das standardm\344\337ige Musikwiedergabe-Ger\344t f\374r General-MIDI-Ausgabe fest." }, + { 233, "Legt das standardm\344\337ige Tonwiedergabe-Ger\344t f\374r die Ausgabe von Roland MT-32/LAPC1/CM32l/CM64 fest." }, + { 234, "Legt das Musikwiedergabe-Ger\344t oder den Soundkarten-Emulator fest." }, + { 235, "Legt das Verzeichnis f\374r zus\344tzliche Spieldateien f\374r alle Spiele in ScummVM fest." }, + { 236, "Legt das Verzeichnis f\374r zus\344tzliche Spieldateien fest." }, + { 237, "Legt das bevorzugte Tonwiedergabe-Ger\344t oder den Soundkarten-Emulator fest." }, + { 238, "Legt fest, wo die Spielst\344nde abgelegt werden." }, + { 239, "Sprache" }, + { 240, "Sprachlautst\344rke:" }, + { 241, "Standard-Renderer (16bpp)" }, + { 242, "Ausgew\344hltes Spiel starten" }, + { 243, "Status:" }, + { 244, "Untert." }, + { 245, "Untertitel-Tempo:" }, + { 246, "Untertitel" }, + { 247, "Figur wechseln" }, + { 248, "Tippen f\374r Linksklick, Doppeltippen f\374r Rechtsklick" }, + { 249, "Text und Sprache:" }, + { 250, "In das gew\344hlte Verzeichnis kann nicht geschrieben werden. Bitte ein anderes ausw\344hlen." }, + { 251, "Themenpfad:" }, + { 252, "Thema:" }, + { 253, "Diese Spielkennung ist schon vergeben. Bitte eine andere w\344hlen." }, + { 254, "F\374r dieses Spiel wird das Laden aus der Spieleliste heraus nicht unterst\374tzt." }, + { 255, "Zeit: " }, + { 256, "Zeit\374berschreitung beim Starten des Netzwerks" }, + { 257, "Zu X-Position gehen" }, + { 258, "Zu Y-Position gehen" }, + { 259, "Touchpad-Modus ausgeschaltet." }, + { 260, "Touchpad-Modus aktiviert." }, + { 261, "Echte Roland-MT-32-Emulation (GM-Emulation deaktiviert)" }, + { 262, "Schaltet die General-MIDI-Zuweisung f\374r Spiele mit Roland-MT-32-Audiospur aus." }, + { 263, "Unbekannt" }, + { 264, "Unbekannter Fehler" }, + { 265, "DVD aush\344ngen" }, + { 266, "SMB aush\344ngen" }, + { 267, "Nicht skalieren (Sie m\374ssen nach links und nach rechts scrollen)" }, + { 268, "Farbmodus nicht unterst\374tzt" }, + { 269, "Unbenannt" }, + { 270, "Hoch" }, + { 271, "Benutzt MIDI und AdLib zur Sounderzeugung." }, + { 272, "Den Trackpad-Style f\374r Maussteuerung benutzen" }, + { 273, "Benutzername:" }, + { 274, "SDL-Treiber verwenden" }, + { 275, "Vertikale Bildverkleinerung:" }, + { 276, "Video" }, + { 277, "Virtuelle Tastatur" }, + { 278, "Lautst\344rke" }, + { 279, "Windows MIDI" }, + { 280, "Schreib-Berechtigung nicht vorhanden" }, + { 281, "Daten konnten nicht geschrieben werden." }, + { 282, "Ja" }, + { 283, "Sie m\374ssen ScummVM neustarten, um die Einstellungen zu \374bernehmen." }, + { 284, "Zone" }, + { 285, "Hineinzoomen" }, + { 286, "Herauszoomen" }, + { 287, "alle 10 Minuten" }, + { 288, "alle 15 Minuten" }, + { 289, "alle 30 Minuten" }, + { 290, "alle 5 Minuten" }, + { 291, "\334be~r~" }, + { 292, "Spiel ~h~inzuf\374gen" }, + { 293, "~A~bbrechen" }, + { 294, "~S~chlie\337en" }, + { 295, "Spielo~p~tionen" }, + { 296, "~H~ilfe" }, + { 297, "~K~ampfsteuerung f\374r Indiana Jones" }, + { 298, "~T~asten" }, + { 299, "~L~inke-Hand-Modus" }, + { 300, "~L~aden" }, + { 301, "~L~aden..." }, + { 302, "~W~eiter" }, + { 303, "~O~K" }, + { 304, "~O~ptionen" }, + { 305, "~O~ptionen" }, + { 306, "~Z~ur\374ck" }, + { 307, "~B~eenden" }, + { 308, "Spiel ~e~ntfernen" }, + { 309, "~F~ortsetzen" }, + { 310, "Zur Spiele~l~iste zur\374ck" }, + { 311, "~S~peichern" }, + { 312, "~S~tarten" }, + { 313, "\334ber~g~\344nge aktiviert" }, + { 314, "~W~assereffekt aktiviert" }, + { 315, "~Z~ip-Modus aktiviert" }, { -1, NULL } }; struct PoLangEntry { const char *lang; const char *charset; + const char *langname; const PoMessageEntry *msgs; }; const PoLangEntry _translations[] = { - { "ru_RU", "iso-8859-5", _translation_ru_RU }, - { "fr_FR", "iso-8859-1", _translation_fr_FR }, - { "it_IT", "iso-8859-1", _translation_it_IT }, - { "ca_ES", "iso-8859-1", _translation_ca_ES }, - { "hu_HU", "cp1250", _translation_hu_HU }, - { "de_DE", "iso-8859-1", _translation_de_DE }, - { NULL, NULL, NULL } + { "ru_RU", "iso-8859-5", "Russian", _translation_ru_RU }, + { "it_IT", "iso-8859-1", "Italiano", _translation_it_IT }, + { "hu_HU", "cp1250", NULL, _translation_hu_HU }, + { "fr_FR", "iso-8859-1", "Francais", _translation_fr_FR }, + { "uk_UA", "iso-8859-5", "Ukrainian", _translation_uk_UA }, + { "ca_ES", "iso-8859-1", "Catalan", _translation_ca_ES }, + { "es_ES", "iso-8859-1", "Espanol", _translation_es_ES }, + { "de_DE", "iso-8859-1", "Deutsch", _translation_de_DE }, + { NULL, NULL, NULL, NULL } }; // code @@ -2061,3 +2713,10 @@ const char *po2c_getlang(const int num) { assert(num < ARRAYSIZE(_translations)); return _translations[num].lang; } + +const char *po2c_getlangname(const int num) { + assert(num < ARRAYSIZE(_translations)); + if (_translations[num].langname != NULL) + return _translations[num].langname; + return _translations[num].lang; +} diff --git a/common/translation.cpp b/common/translation.cpp index ab6a922c6e..b52aad0d1f 100644 --- a/common/translation.cpp +++ b/common/translation.cpp @@ -138,12 +138,12 @@ String TranslationManager::getTranslation(const String &message) { return po2c_gettext(message.c_str()); } -const TLangArray TranslationManager::getSupportedLanguages() const { +const TLangArray TranslationManager::getSupportedLanguageNames() const { TLangArray languages; int total = po2c_getnumlangs(); for (int i = 0; i < total; i++) { - TLanguage lng(po2c_getlang(i), i + 1); + TLanguage lng(po2c_getlangname(i), i + 1); languages.push_back(lng); } @@ -208,7 +208,7 @@ String TranslationManager::getTranslation(const String &message) { return message; } -const TLangArray TranslationManager::getSupportedLanguages() const { +const TLangArray TranslationManager::getSupportedLanguageNames() const { return TLangArray(); } diff --git a/common/translation.h b/common/translation.h index 277ac6f5c4..ccdd0f3500 100644 --- a/common/translation.h +++ b/common/translation.h @@ -117,9 +117,9 @@ public: /** * Returns a list of supported languages. * - * @return The list of supported languages. + * @return The list of supported languages in a user readable form. */ - const TLangArray getSupportedLanguages() const; + const TLangArray getSupportedLanguageNames() const; /** * Returns charset specified by selected translation language @@ -363,7 +363,7 @@ get_system_exe_extension() { arm-riscos) _exeext=",ff8" ;; - dreamcast | gamecube | ds | ps2 | psp | wii) + dreamcast | ds | gamecube | n64 | ps2 | psp | wii) _exeext=".elf" ;; gp2x-linux) @@ -933,6 +933,11 @@ get_system_exe_extension $guessed_host NATIVEEXEEXT=$_exeext case $_host in +android) + _host_os=android + _host_cpu=arm + _host_alias=arm-oe-linux-androideabi + ;; arm-riscos) _host_os=riscos _host_cpu=arm @@ -944,6 +949,11 @@ dreamcast) CXXFLAGS="$CXXFLAGS -ml -m4-single-only" LDFLAGS="$LDFLAGS -ml -m4-single-only" ;; +ds) + _host_os=ds + _host_cpu=arm + _host_alias=arm-eabi + ;; gamecube) _host_os=gamecube _host_cpu=ppc @@ -982,10 +992,10 @@ motomagx) _host_cpu=arm _host_alias=arm-linux-gnueabi ;; -ds) - _host_os=ds - _host_cpu=arm - _host_alias=arm-eabi +n64) + _host_os=n64 + _host_cpu=mips + _host_alias=mips64 ;; neuros) _host_os=linux @@ -1037,11 +1047,6 @@ wince) _host_cpu=arm _host_alias=arm-wince-mingw32ce ;; -android) - _host_os=android - _host_cpu=arm - _host_alias=arm-oe-linux-androideabi - ;; *) if test -n "$_host"; then guessed_host=`$_srcdir/config.sub $_host` @@ -1103,12 +1108,24 @@ esac # Platform specific sanity checks # case $_host_os in -gamecube | ds | wii) +android) + if test -z "$ANDROID_SDK"; then + echo "Please set ANDROID_SDK in your environment. export ANDROID_SDK=<path to Android SDK>" + exit 1 + fi + ;; +ds | gamecube | wii) if test -z "$DEVKITPRO"; then echo "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to devkitPRO>" exit 1 fi ;; +n64) + if test -z "$N64SDK"; then + echo "Please set N64SDK in your environment. export N64SDK=<path to n64 sdk>" + exit 1 + fi + ;; ps2) if test -z "$PS2SDK"; then echo "Please set PS2SDK in your environment. export PS2SDK=<path to ps2 sdk>" @@ -1122,12 +1139,6 @@ psp) exit 1 fi ;; -android) - if test -z "$ANDROID_SDK"; then - echo "Please set ANDROID_SDK in your environment. export ANDROID_SDK=<path to Android SDK>" - exit 1 - fi - ;; *) ;; esac @@ -1361,6 +1372,12 @@ case $_host_os in # as (unsigned) long, and consequently we'd get a compiler error otherwise. type_4_byte='long' ;; + android) + CXXFLAGS="$CXXFLAGS -Os -msoft-float -mtune=xscale -march=armv5te -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5TE__" + add_line_to_config_mk "ANDROID_SDK = $ANDROID_SDK" + _unix=yes + _seq_midi=no + ;; beos*) DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" # Needs -lbind -lsocket for the timidity MIDI driver @@ -1388,6 +1405,16 @@ case $_host_os in dreamcast) DEFINES="$DEFINES -D__DC__ -DNONSTANDARD_PORT" ;; + 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 -mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer -mthumb-interwork" + CXXFLAGS="$CXXFLAGS -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" + ;; freebsd*) LDFLAGS="$LDFLAGS -L/usr/local/lib" CXXFLAGS="$CXXFLAGS -I/usr/local/include" @@ -1432,14 +1459,10 @@ case $_host_os in DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" _unix=yes ;; - 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" + n64) + DEFINES="$DEFINES -D__N64__ -DLIMIT_FPS -DNONSTANDARD_PORT" + DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER -DDISABLE_COMMAND_LINE" + DEFINES="$DEFINES -DDISABLE_FANCY_THEMES -DDISABLE_DOSBOX_OPL -DDISABLE_SID -DDISABLE_NES_APU" ;; os2-emx*) _unix=yes # FIXME??? Why?? @@ -1470,12 +1493,6 @@ case $_host_os in DEFINES="$DEFINES -D_WIN32_WCE=300 -D__ARM__ -D_ARM_ -DUNICODE -DFPM_DEFAULT -DNONSTANDARD_PORT" DEFINES="$DEFINES -DWIN32 -Dcdecl= -D__cdecl__=" ;; - android) - CXXFLAGS="$CXXFLAGS -Os -msoft-float -mtune=xscale -march=armv5te -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5TE__" - add_line_to_config_mk "ANDROID_SDK = $ANDROID_SDK" - _unix=yes - _seq_midi=no - ;; # given this is a shell script assume some type of unix *) echo "WARNING: could not establish system type, assuming unix like" @@ -1487,6 +1504,19 @@ if test -n "$_host"; then # Cross-compiling mode - add your target here if needed echo "Cross-compiling to $_host" case "$_host" in + android) + DEFINES="$DEFINES -DANDROID -DUSE_ARM_SMUSH_ASM" + _unix=yes + _need_memalign=yes + 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' + add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' + add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' + _backend="android" + _port_mk="backends/platform/android/android.mk" + _seq_midi=no + ;; arm-linux|arm*-linux-gnueabi|arm-*-linux) _unix=yes _need_memalign=yes @@ -1513,18 +1543,36 @@ if test -n "$_host"; then CXXFLAGS="$CXXFLAGS -O3 -funroll-loops -fschedule-insns2 -fomit-frame-pointer -fdelete-null-pointer-checks" _need_memalign=yes _backend="dc" - _build_scalers="no" - _mad="yes" - _zlib="yes" + _build_scalers=no + _mad=yes + _zlib=yes add_line_to_config_mk 'ronindir = /usr/local/ronin' _port_mk="backends/platform/dc/dreamcast.mk" ;; + ds) + # TODO: complete this + DEFINES="$DEFINES -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555" + DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER" + DEFINES="$DEFINES -DREDUCE_MEMORY_USAGE -DSTREAM_AUDIO_FROM_DISK" + DEFINES="$DEFINES -DDISABLE_DOSBOX_OPL -DDISABLE_SID -DDISABLE_NES_APU" + DEFINES="$DEFINES -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE" + _need_memalign=yes + 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' + add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' + add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' + _backend="ds" + _build_scalers=no + _mt32emu=no + _port_mk="backends/platform/ds/ds.mk" + ;; gamecube) _endian=big _need_memalign=yes _backend="wii" - _build_scalers="no" - _mt32emu="no" + _build_scalers=no + _mt32emu=no _port_mk="backends/platform/wii/wii.mk" add_line_to_config_mk 'GAMECUBE = 1' add_line_to_config_h '#define GAMECUBE' @@ -1545,9 +1593,9 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' _backend="gp2x" - _build_hq_scalers="no" - _mt32emu="no" - _vkeybd="yes" + _build_hq_scalers=no + _mt32emu=no + _vkeybd=yes _seq_midi=no _port_mk="backends/platform/gp2x/gp2x-bundle.mk" ;; @@ -1563,9 +1611,9 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' _backend="gp2xwiz" - _build_hq_scalers="no" - _mt32emu="no" - _vkeybd="yes" + _build_hq_scalers=no + _mt32emu=no + _vkeybd=yes _seq_midi=no _port_mk="backends/platform/gp2xwiz/gp2xwiz-bundle.mk" ;; @@ -1576,7 +1624,7 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' _backend="iphone" - _build_hq_scalers="no" + _build_hq_scalers=no _seq_midi=no ;; m68k-atari-mint) @@ -1609,9 +1657,9 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' _backend="linuxmoto" - _build_hq_scalers="no" - _mt32emu="no" - _vkeybd="yes" + _build_hq_scalers=no + _mt32emu=no + _vkeybd=yes _seq_midi=no _port_mk="backends/platform/linuxmoto/linuxmoto.mk" ;; @@ -1626,37 +1674,42 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' _backend="linuxmoto" - _build_hq_scalers="no" - _mt32emu="no" - _vkeybd="yes" + _build_hq_scalers=no + _mt32emu=no + _vkeybd=yes _seq_midi=no _port_mk="backends/platform/linuxmoto/linuxmoto.mk" ;; - ds) - # TODO: complete this - DEFINES="$DEFINES -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555" - DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER" - DEFINES="$DEFINES -DREDUCE_MEMORY_USAGE -DSTREAM_AUDIO_FROM_DISK" - DEFINES="$DEFINES -DDISABLE_DOSBOX_OPL" - DEFINES="$DEFINES -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE" + n64) + CXXFLAGS="$CXXFLAGS -mno-extern-sdata --param max-inline-insns-auto=20 -fomit-frame-pointer" + CXXFLAGS="$CXXFLAGS -march=vr4300 -mtune=vr4300 -mhard-float" + LDFLAGS="$LDFLAGS -march=vr4300 -mtune=vr4300 -nodefaultlibs -nostartfiles -mno-crt0" + LDFLAGS="$LDFLAGS -L$N64SDK/hkz-libn64 -L$N64SDK/lib" + LDFLAGS="$LDFLAGS -T n64ld_cpp.x -Xlinker -Map -Xlinker scummvm.map" + _backend="n64" _need_memalign=yes - 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' - add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' - add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' - _backend="ds" - _build_hq_scalers="no" - _mt32emu="no" - _port_mk="backends/platform/ds/ds.mk" + _mt32emu=no + _vkeybd=yes + _build_scalers=no + _indeo3=no + _translation=no + _keymapper=no + _text_console=no + _vkeybd=yes + _dynamic_modules=no + _plugins_default=static + # Force use of libmad, libtremor and zlib + _mad=yes + _tremor=yes + _zlib=yes ;; neuros) DEFINES="$DEFINES -DNEUROS" _unix=yes _need_memalign=yes _backend='null' - _build_hq_scalers="no" - _mt32emu="no" + _build_hq_scalers=no + _mt32emu=no ;; ppc-amigaos) _endian=big @@ -1665,16 +1718,17 @@ if test -n "$_host"; then ps2) # TODO: complete this DEFINES="$DEFINES -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DDISABLE_DOSBOX_OPL" + DEFINES="$DEFINES -DDISABLE_SID -DDISABLE_NES_APU" _need_memalign=yes _backend="ps2" - _build_scalers="no" - _mt32emu="no" + _build_scalers=no + _mt32emu=no # HACK to enable mad & zlib (they are not properly detected due to linker issues). # This trick doesn't work for tremor right now, as the PS2 port the resulting library # libtremor, while our code later on expects it to be called libvorbisidec. # TODO: Enable tremor, e.g. by adding -ltremor or by renaming the lib. - _mad="yes" - _zlib="yes" + _mad=yes + _zlib=yes # HACK to fix compilation of C source files for now. add_line_to_config_mk 'CC = ee-gcc' # HACK to fix linking for now. It seems ee-g++ does not handle linking correctly. @@ -1694,8 +1748,8 @@ if test -n "$_host"; then psp) _need_memalign=yes _backend="psp" - _build_scalers="no" - _mt32emu="no" + _build_scalers=no + _mt32emu=no _port_mk="backends/platform/psp/psp.mk" ;; samsungtv) @@ -1710,14 +1764,14 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' _backend="samsungtv" - _mt32emu="no" - _vkeybd="yes" + _mt32emu=no + _vkeybd=yes ;; wii) _endian=big _need_memalign=yes _backend="wii" - _build_scalers="no" + _build_scalers=no _port_mk="backends/platform/wii/wii.mk" add_line_to_config_mk 'GAMECUBE = 0' add_line_to_config_h "#define DEBUG_WII_USBGECKO" @@ -1737,22 +1791,9 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' _backend="wince" - _mt32emu="no" + _mt32emu=no _port_mk="backends/platform/wince/wince.mk" ;; - android) - DEFINES="$DEFINES -DANDROID -DUSE_ARM_SMUSH_ASM" - _unix=yes - _need_memalign=yes - 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' - add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' - add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' - _backend="android" - _port_mk="backends/platform/android/android.mk" - _seq_midi=no - ;; *) echo "WARNING: Unknown target, continuing with auto-detected values" ;; @@ -2022,9 +2063,9 @@ define_in_config_if_yes "$_build_hq_scalers" 'USE_HQ_SCALERS' if test "$_indeo3" = auto ; then # Autodetect. Build if either the gob engine or plugins are enabled if test `get_engine_build gob` = yes || test "$_dynamic_modules" = yes ; then - _indeo3="yes" + _indeo3=yes else - _indeo3="no" + _indeo3=no fi fi define_in_config_if_yes "$_indeo3" 'USE_INDEO3' @@ -2493,11 +2534,49 @@ fi # Backend related stuff # case $_backend in + 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="-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' + ;; dc) INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/dc -isystem $(ronindir)/include' LDFLAGS="$LDFLAGS -Wl,-Ttext,0x8c010000 -nostartfiles "'$(ronindir)/lib/crt0.o -L$(ronindir)/lib' LIBS="$LIBS -lronin -lm" ;; + 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' + ;; gp2x) find_sdlconfig INCLUDES="$INCLUDES `$_sdlconfig --prefix="$_sdlpath" --cflags`" @@ -2522,11 +2601,12 @@ case $_backend in LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`" DEFINES="$DEFINES -DSDL_BACKEND -DLINUXMOTO" ;; - 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' + n64) + INCLUDES="$INCLUDES "'-I$(N64SDK)/include' + INCLUDES="$INCLUDES "'-I$(N64SDK)/mips64/include' + INCLUDES="$INCLUDES "'-I$(N64SDK)/hkz-libn64' + INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/n64' + LIBS="$LIBS -lpakfs -lframfs -ln64 -ln64utils -lromfs -lm -lstdc++ -lc -lgcc -lz -lnosys" ;; null) DEFINES="$DEFINES -DUSE_NULL_DRIVER" @@ -2573,38 +2653,6 @@ case $_backend in INCLUDES="$INCLUDES "'-I$(srcdir) -I$(srcdir)/backends/platform/wince -I$(srcdir)/engines -I$(srcdir)/backends/platform/wince/missing/gcc -I$(srcdir)/backends/platform/wince/CEgui -I$(srcdir)/backends/platform/wince/CEkeys' 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="-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" exit 1 @@ -2620,7 +2668,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 | ds | psp | wince | amigaos* | android) + amigaos* | android | ds | dreamcast | gamecube | mingw* | n64 | psp | wii | wince ) CXXFLAGS="$CXXFLAGS -W -Wno-unused-parameter" ;; *) @@ -2641,7 +2689,7 @@ fi; # Some platforms use certain GNU extensions in header files case $_host_os in -gamecube | psp | wii | android) +android | gamecube | psp | wii) ;; *) CXXFLAGS="$CXXFLAGS -pedantic" diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex 3fba5780f4..ff21159362 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index 315763a6da..f4af4a8500 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -209,6 +209,9 @@ static void updateGameDescriptor(GameDescriptor &desc, const ADGameDescription * desc.setGUIOptions(realDesc->guioptions | params.guioptions); desc.appendGUIOptions(getGameGUIOptionsDescriptionLanguage(realDesc->language)); + + if (realDesc->flags & ADGF_ADDENGLISH) + desc.appendGUIOptions(getGameGUIOptionsDescriptionLanguage(Common::EN_ANY)); } GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const { @@ -306,7 +309,12 @@ 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, getGameGUIOptionsDescriptionLanguage(agdDesc->language)); + Common::String lang = getGameGUIOptionsDescriptionLanguage(agdDesc->language); + if (agdDesc->flags & ADGF_ADDENGLISH) + lang += " " + getGameGUIOptionsDescriptionLanguage(Common::EN_ANY); + + Common::updateGameGUIOptions(agdDesc->guioptions | params.guioptions, lang); + debug(2, "Running %s", toGameDescriptor(*agdDesc, params.list).description().c_str()); if (!createInstance(syst, engine, agdDesc)) @@ -455,7 +463,8 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p // Do not even bother to look at entries which do not have matching // language and platform (if specified). - if ((language != Common::UNK_LANG && g->language != Common::UNK_LANG && g->language != language) || + if ((language != Common::UNK_LANG && g->language != Common::UNK_LANG && g->language != language + && !(language == Common::EN_ANY && (g->flags & ADGF_ADDENGLISH))) || (platform != Common::kPlatformUnknown && g->platform != Common::kPlatformUnknown && g->platform != platform)) { continue; } diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h index de4fc3bbf8..1e59df04bf 100644 --- a/engines/advancedDetector.h +++ b/engines/advancedDetector.h @@ -38,11 +38,14 @@ struct ADGameFileDescription { int32 fileSize; // Optional. Set to -1 to ignore. }; -#define AD_ENTRY1(f, x) {{ f, 0, x, -1}, {NULL, 0, NULL, 0}} -#define AD_ENTRY1s(f, x, s) {{ f, 0, x, s}, {NULL, 0, NULL, 0}} +#define AD_LISTEND {NULL, 0, NULL, 0} + +#define AD_ENTRY1(f, x) {{ f, 0, x, -1}, AD_LISTEND} +#define AD_ENTRY1s(f, x, s) {{ f, 0, x, s}, AD_LISTEND} enum ADGameFlags { ADGF_NO_FLAGS = 0, + ADGF_ADDENGLISH = (1 << 24), // always add English as language option ADGF_MACRESFORK = (1 << 25), // the md5 for this entry will be calculated from the resource fork ADGF_USEEXTRAASTITLE = (1 << 26), // Extra field value will be used as main game title, not gameid ADGF_KEEPMATCH = (1 << 27), // this entry is kept even when there are matched entries with more files diff --git a/engines/draci/detection.cpp b/engines/draci/detection.cpp index e1025e698a..07a9928cfa 100644 --- a/engines/draci/detection.cpp +++ b/engines/draci/detection.cpp @@ -71,6 +71,16 @@ const ADGameDescription gameDescriptions[] = { GUIO_NONE }, + { + "draci", + 0, + AD_ENTRY1s("INIT.DFW", "9a7115b91cdea361bcaff3e046ac7ded", 906), + Common::DE_DEU, + Common::kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NONE + }, + AD_TABLE_END_MARKER }; diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 125edd4307..51bc1b88a5 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -73,7 +73,7 @@ bool VideoPlayer::Video::open(const char *fileName, Type which, int16 width, int return false; } - if (!_video->load(*_stream)) { + if (!_video->load(_stream)) { warning("While loading video \"%s\"", fileName); close(); return false; diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index f3e6c7c8cc..135a9ae7b2 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -105,7 +105,8 @@ bool Kyra::KyraEngine_v1::hasFeature(EngineFeature f) const { return (f == kSupportsRTL) || (f == kSupportsLoadingDuringRuntime) || - (f == kSupportsSavingDuringRuntime); + (f == kSupportsSavingDuringRuntime) || + (f == kSupportsSubtitleOptions); } bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp index 2716f0b285..0fafaa15ce 100644 --- a/engines/kyra/kyra_hof.cpp +++ b/engines/kyra/kyra_hof.cpp @@ -679,7 +679,7 @@ void KyraEngine_HoF::updateWithText() { restorePage3(); drawAnimObjects(); - if (textEnabled() && _chatText) { + if (_chatTextEnabled && _chatText) { int pageBackUp = _screen->_curPage; _screen->_curPage = 2; objectChatPrintText(_chatText, _chatObject); @@ -1996,9 +1996,10 @@ void KyraEngine_HoF::writeSettings() { } void KyraEngine_HoF::readSettings() { + KyraEngine_v2::readSettings(); + int talkspeed = ConfMan.getInt("talkspeed"); _configTextspeed = (talkspeed*95)/255 + 2; - KyraEngine_v1::readSettings(); } } // End of namespace Kyra diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h index b37a14bad4..50f36d7b71 100644 --- a/engines/kyra/kyra_lok.h +++ b/engines/kyra/kyra_lok.h @@ -319,7 +319,7 @@ protected: // chat // -> process void characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration); - void waitForChatToFinish(int vocFile, int16 chatDuration, const char *str, uint8 charNum); + void waitForChatToFinish(int vocFile, int16 chatDuration, const char *str, uint8 charNum, const bool printText); // -> initialization int initCharacterChat(int8 charNum); diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp index 61bc3708c3..2169e5283f 100644 --- a/engines/kyra/kyra_mr.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -1127,7 +1127,7 @@ void KyraEngine_MR::updateWithText() { restorePage3(); drawAnimObjects(); - if (textEnabled() && _chatText) { + if (_chatTextEnabled && _chatText) { int curPage = _screen->_curPage; _screen->_curPage = 2; objectChatPrintText(_chatText, _chatObject); @@ -1490,7 +1490,7 @@ void KyraEngine_MR::writeSettings() { } void KyraEngine_MR::readSettings() { - KyraEngine_v1::readSettings(); + KyraEngine_v2::readSettings(); _configStudio = ConfMan.getBool("studio_audience"); _configSkip = ConfMan.getBool("skip_support"); diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index 5db2c360d6..1c27716a67 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -625,6 +625,10 @@ uint8 KyraEngine_v1::getVolume(kVolumeEntry vol) { void KyraEngine_v1::syncSoundSettings() { Engine::syncSoundSettings(); + // We need to use this here to allow the subtitle options to be changed + // through the GMM's options dialog. + readSettings(); + if (_sound) _sound->updateVolumeSettings(); } diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index 34284a8e20..53c57c21cd 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -63,6 +63,7 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const Engi _chatVocLow = -1; _chatText = 0; _chatObject = -1; + _chatTextEnabled = false; memset(_hiddenItems, -1, sizeof(_hiddenItems)); diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index 6aaa8c3687..6414040344 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -350,6 +350,7 @@ protected: int _chatObject; uint32 _chatEndTime; int _chatVocHigh, _chatVocLow; + bool _chatTextEnabled; EMCData _chatScriptData; EMCState _chatScriptState; diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 5a066e5d0c..98f0e31b69 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -810,8 +810,8 @@ void LoLEngine::startup() { pal.fill(0, 1, 0x3F); pal.fill(2, 126, 0x3F); pal.fill(192, 4, 0x3F); - _screen->generateOverlay(pal, _screen->_paletteOverlay1, 1, 96); - _screen->generateOverlay(pal, _screen->_paletteOverlay2, 144, 65); + _screen->generateOverlay(pal, _screen->_paletteOverlay1, 1, 96, 254); + _screen->generateOverlay(pal, _screen->_paletteOverlay2, 144, 65, 254); _screen->copyPalette(0, 1); } diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 7983be9a68..d572c1ac54 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -209,6 +209,7 @@ enum KyraResources { k1CreditsStrings, + k1TownsMusicFadeTable, k1TownsSFXwdTable, k1TownsSFXbtTable, k1TownsCDATable, diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp index 959d89f0ad..56e1c73d0a 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -122,7 +122,7 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab header.thumbnail = 0; } } else { - Graphics::skipThumbnailHeader(*in); + Graphics::skipThumbnail(*in); } } diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp index ddc6e41bec..bf3320486a 100644 --- a/engines/kyra/scene_lol.cpp +++ b/engines/kyra/scene_lol.cpp @@ -468,7 +468,7 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight for (int i = 0; i < 7; i++) { weight = 100 - (i * _lastSpecialColorWeight); weight = (weight > 0) ? (weight * 255) / 100 : 0; - _screen->generateLevelOverlay(tpal, _screen->getLevelOverlay(i), _lastSpecialColor, weight); + _screen->generateOverlay(tpal, _screen->getLevelOverlay(i), _lastSpecialColor, weight); int l = _flags.use16ColorMode ? 256 : 128; uint8 *levelOverlay = _screen->getLevelOverlay(i); diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp index e350d2c977..be3dbe5b21 100644 --- a/engines/kyra/screen_lol.cpp +++ b/engines/kyra/screen_lol.cpp @@ -183,68 +183,6 @@ void Screen_LoL::generateGrayOverlay(const Palette &srcPal, uint8 *grayOverlay, grayOverlay[i] = findLeastDifferentColor(tmpPal.getData() + 3 * i, srcPal, 0, lastColor, skipSpecialColors); } -uint8 *Screen_LoL::generateLevelOverlay(const Palette &srcPal, uint8 *ovl, int opColor, int weight) { - if (!ovl) - return ovl; - - if (weight > 255) - weight = 255; - - const uint8 *srt = srcPal.getData(); - - uint16 r = srt[opColor * 3]; - uint16 g = srt[opColor * 3 + 1]; - uint16 b = srt[opColor * 3 + 2]; - - uint8 *d = ovl; - *d++ = 0; - - for (int i = 1; i != 256; i++) { - uint16 a = srt[i * 3]; - uint8 dr = a - ((((a - r) * (weight >> 1)) << 1) >> 8); - a = srt[i * 3 + 1]; - uint8 dg = a - ((((a - g) * (weight >> 1)) << 1) >> 8); - a = srt[i * 3 + 2]; - uint8 db = a - ((((a - b) * (weight >> 1)) << 1) >> 8); - - int l = opColor; - int m = _use16ColorMode ? 0xffff : 0x7fff; - int ii = _use16ColorMode ? 255 : 127; - int x = 1; - const uint8 *s = srt + 3; - - do { - if (!_use16ColorMode && i == x) { - s += 3; - } else { - int t = *s++ - dr; - int c = t * t; - t = *s++ - dg; - c += (t * t); - t = *s++ - db; - c += (t * t); - - if (!c) { - l = x; - break; - } - - if (c <= m) { - if (!_use16ColorMode || (x == opColor || i != x)) { - m = c; - l = x; - } - } - } - x++; - } while (--ii); - - *d++ = l & 0xff; - } - - return ovl; -} - void Screen_LoL::createTransparencyTablesIntern(const uint8 *ovl, int a, const uint8 *fxPal1, const uint8 *fxPal2, uint8 *outTable1, uint8 *outTable2, int b) { Palette screenPal(256); screenPal.copy(fxPal2, 0, 256); diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h index cdd18f98f6..52e66df1ec 100644 --- a/engines/kyra/screen_lol.h +++ b/engines/kyra/screen_lol.h @@ -79,7 +79,6 @@ public: Palette **generateFadeTable(Palette **dst, Palette *src1, Palette *src2, int numTabs); void generateGrayOverlay(const Palette &Pal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColors); - uint8 *generateLevelOverlay(const Palette &Pal, uint8 *ovl, int opColor, int weight); uint8 *getLevelOverlay(int index) { return _levelOverlays[index]; } void createTransparencyTablesIntern(const uint8 *ovl, int a, const uint8 *fxPal1, const uint8 *fxPal2, uint8 *outTable1, uint8 *outTable2, int b); diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp index 919b9086f3..3907f844cb 100644 --- a/engines/kyra/screen_v2.cpp +++ b/engines/kyra/screen_v2.cpp @@ -38,38 +38,67 @@ Screen_v2::~Screen_v2() { delete[] _wsaFrameAnimBuffer; } -uint8 *Screen_v2::generateOverlay(const Palette &pal, uint8 *buffer, int startColor, uint16 factor) { +uint8 *Screen_v2::generateOverlay(const Palette &pal, uint8 *buffer, int opColor, uint weight, int maxColor) { if (!buffer) return buffer; - factor = MIN<uint16>(255, factor); - factor >>= 1; - factor &= 0xFF; + weight = MIN<uint>(weight, 255) >> 1; - const byte col1 = pal[startColor * 3 + 0]; - const byte col2 = pal[startColor * 3 + 1]; - const byte col3 = pal[startColor * 3 + 2]; + const byte opR = pal[opColor * 3 + 0]; + const byte opG = pal[opColor * 3 + 1]; + const byte opB = pal[opColor * 3 + 2]; uint8 *dst = buffer; *dst++ = 0; - for (int i = 1; i != 255; ++i) { - uint8 processedPalette[3]; - byte col; + int maxIndex = maxColor; + if (maxIndex == -1) { + if (_vm->gameFlags().gameID == GI_LOL) { + if (_use16ColorMode) + maxIndex = 255; + else + maxIndex = 127; + } else { + maxIndex = 255; + } + } + + for (int i = 1; i != 256; ++i) { + const byte curR = pal[i * 3 + 0] - ((((pal[i * 3 + 0] - opR) * weight) >> 7) & 0x7F); + const byte curG = pal[i * 3 + 1] - ((((pal[i * 3 + 1] - opG) * weight) >> 7) & 0x7F); + const byte curB = pal[i * 3 + 2] - ((((pal[i * 3 + 2] - opB) * weight) >> 7) & 0x7F); + + uint16 idxSum = _use16ColorMode ? 0xFFFF : 0x7FFF; + byte index = opColor; + + for (int curIdx = 1; curIdx <= maxIndex; ++curIdx) { + if (!_use16ColorMode && i == curIdx) + continue; - col = pal[i * 3 + 0]; - col -= ((((col - col1) * factor) << 1) >> 8) & 0xFF; - processedPalette[0] = col; + int diff = 0; + uint16 sum = 0; - col = pal[i * 3 + 1]; - col -= ((((col - col2) * factor) << 1) >> 8) & 0xFF; - processedPalette[1] = col; + diff = pal[curIdx * 3 + 0] - curR; + sum += diff * diff; + diff = pal[curIdx * 3 + 1] - curG; + sum += diff * diff; + diff = pal[curIdx * 3 + 2] - curB; + sum += diff * diff; - col = pal[i * 3 + 2]; - col -= ((((col - col3) * factor) << 1) >> 8) & 0xFF; - processedPalette[2] = col; + if (!sum) { + index = curIdx; + break; + } + + if (sum <= idxSum) { + if (!_use16ColorMode || (curIdx == opColor || curIdx != i)) { + idxSum = sum; + index = curIdx; + } + } + } - *dst++ = findLeastDifferentColor(processedPalette, pal, 1, 255) + 1; + *dst++ = index; } return buffer; diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h index 7be68e7b6d..92aeb3525d 100644 --- a/engines/kyra/screen_v2.h +++ b/engines/kyra/screen_v2.h @@ -40,7 +40,7 @@ public: void checkedPageUpdate(int srcPage, int dstPage); // palette handling - uint8 *generateOverlay(const Palette &pal, uint8 *buffer, int color, uint16 factor); + uint8 *generateOverlay(const Palette &pal, uint8 *buffer, int color, uint weight, int maxColor = -1); void applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay); int findLeastDifferentColor(const uint8 *paletteEntry, const Palette &pal, uint8 firstColor, uint16 numColors, bool skipSpecialColors = false); diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h index a229dc310d..f8738bc791 100644 --- a/engines/kyra/sound_intern.h +++ b/engines/kyra/sound_intern.h @@ -31,7 +31,9 @@ #include "common/mutex.h" -#include "sound/softsynth/ym2612.h" +#include "sound/softsynth/fmtowns_pc98/towns_pc98_driver.h" +#include "sound/softsynth/fmtowns_pc98/towns_euphony.h" + #include "sound/softsynth/emumidi.h" #include "sound/midiparser.h" @@ -99,10 +101,7 @@ private: Common::Mutex _mutex; }; -class Towns_EuphonyDriver; -class TownsPC98_OpnDriver; - -class SoundTowns : public MidiDriver, public Sound { +class SoundTowns : public Sound { public: SoundTowns(KyraEngine_v1 *vm, Audio::Mixer *mixer); ~SoundTowns(); @@ -119,43 +118,35 @@ public: void haltTrack(); void playSoundEffect(uint8); + void stopAllSoundEffects(); void beginFadeOut(); - //MidiDriver interface implementation - int open(); - void close(); - void send(uint32 b); - void metaEvent(byte type, byte *data, uint16 length) {} - - void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { } - uint32 getBaseTempo(); - - //Channel allocation functions - MidiChannel *allocateChannel() { return 0; } - MidiChannel *getPercussionChannel() { return 0; } - - static float calculatePhaseStep(int8 semiTone, int8 semiToneRootkey, - uint32 sampleRate, uint32 outputRate, int32 pitchWheel); + void updateVolumeSettings(); private: bool loadInstruments(); void playEuphonyTrack(uint32 offset, int loop); - static void onTimer(void *data); + void fadeOutSoundEffects(); int _lastTrack; Audio::AudioStream *_currentSFX; Audio::SoundHandle _sfxHandle; + uint8 *_musicTrackData; + uint _sfxFileIndex; uint8 *_sfxFileData; + uint8 _sfxChannel; - Towns_EuphonyDriver * _driver; - MidiParser * _parser; - + TownsEuphonyDriver *_driver; + Common::Mutex _mutex; + bool _cdaPlaying; + + const uint8 *_musicFadeTable; const uint8 *_sfxBTTable; const uint8 *_sfxWDTable; }; @@ -186,7 +177,7 @@ protected: int _lastTrack; uint8 *_musicTrackData; uint8 *_sfxTrackData; - TownsPC98_OpnDriver *_driver; + TownsPC98_AudioDriver *_driver; }; class SoundTownsPC98_v2 : public Sound { @@ -218,7 +209,7 @@ protected: uint8 *_musicTrackData; uint8 *_sfxTrackData; - TownsPC98_OpnDriver *_driver; + TownsPC98_AudioDriver *_driver; }; // PC Speaker MIDI driver diff --git a/engines/kyra/sound_lok.cpp b/engines/kyra/sound_lok.cpp index 1d0b334a09..40daa0b5bd 100644 --- a/engines/kyra/sound_lok.cpp +++ b/engines/kyra/sound_lok.cpp @@ -49,16 +49,14 @@ void KyraEngine_LoK::snd_playWanderScoreViaMap(int command, int restart) { _lastMusicCommand = -1; if (_flags.platform == Common::kPlatformFMTowns) { - if (command == 1) { - _sound->beginFadeOut(); - } else if (command >= 35 && command <= 38) { + if (command >= 35 && command <= 38) { snd_playSoundEffect(command - 20); } else if (command >= 2) { if (_lastMusicCommand != command) // the original does -2 here we handle this inside _sound->playTrack() _sound->playTrack(command); } else { - _sound->haltTrack(); + _sound->beginFadeOut(); } _lastMusicCommand = command; } else if (_flags.platform == Common::kPlatformPC98) { diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp index 1bcb77c89d..c233987120 100644 --- a/engines/kyra/sound_lol.cpp +++ b/engines/kyra/sound_lol.cpp @@ -225,7 +225,7 @@ void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) { for (int i = 3; i > 0; i--) { int dir = calcMonsterDirection(cbl & 0x1f, cbl >> 5, block & 0x1f, block >> 5); - cbl += blockShiftTable[dir]; + cbl = (cbl + blockShiftTable[dir]) & 0x3ff; if (cbl != block) { if (testWallFlag(cbl, 0, 1)) _environmentSfxVol >>= 1; diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index 32fbbdf1e7..8d01d47262 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -35,3889 +35,39 @@ #include "common/util.h" -#define EUPHONY_FADEOUT_TICKS 600 - namespace Kyra { -enum EnvelopeState { s_ready, s_attacking, s_decaying, s_sustaining, s_releasing }; - -class Towns_EuphonyChannel : public MidiChannel { -public: - Towns_EuphonyChannel() {} - virtual ~Towns_EuphonyChannel() {} - - virtual void nextTick(int32 *outbuf, int buflen) = 0; - virtual void rate(uint16 r) = 0; - -protected: - uint16 _rate; -}; - -class Towns_EuphonyFmChannel : public Towns_EuphonyChannel { -public: - Towns_EuphonyFmChannel(); - virtual ~Towns_EuphonyFmChannel(); - - void nextTick(int32 *outbuf, int buflen); - void rate(uint16 r); - - // MidiChannel interface - MidiDriver *device() { return 0; } - byte getNumber() { return 0; } - void release() { } - void send(uint32) { } - void noteOff(byte note); - void noteOn(byte note, byte onVelo); - void programChange(byte) {} - void pitchBend(int16 value); - void controlChange(byte control, byte value); - void pitchBendFactor(byte) { } - void sysEx_customInstrument(uint32 unused, const byte *instr); - -protected: - Voice2612 *_voice; -}; - -class Towns_EuphonyPcmChannel : public Towns_EuphonyChannel { -public: - void nextTick(int32 *outbuf, int buflen); - void rate(uint16 r); - - Towns_EuphonyPcmChannel(); - virtual ~Towns_EuphonyPcmChannel(); - - // MidiChannel interface - MidiDriver *device() { return 0; } - byte getNumber() { return 0; } - void release() { } - void send(uint32 b) { } - void noteOff(byte note); - void noteOn(byte note, byte onVelo); - void programChange(byte program) {} - void pitchBend(int16 value); - void controlChange(byte control, byte value); - void pitchBendFactor(byte value) { } - void sysEx_customInstrument(uint32 type, const byte *instr); - -protected: - void velocity(int velo); - void panPosition(int8 pan); - void evpNextTick(); - - int _ctrl7_volume; - int16 _velocity; - int16 _note; - int32 _frequencyOffs; - float _phase; - int8 _current; - - struct Voice { - char name[9]; - uint16 split[8]; - uint32 id[8]; - struct Snd { - char name[9]; - int32 id; - int32 numSamples; - int32 loopStart; - int32 loopLength; - int32 samplingRate; - int32 keyOffset; - int32 keyNote; - const int8 *_samples; - } *_snd[8]; - struct Env { - EnvelopeState state; - int32 currentLevel; - int32 rate; - int32 tickCount; - int32 totalLevel; - int32 attackRate; - int32 decayRate; - int32 sustainLevel; - int32 sustainRate; - int32 releaseLevel; - int32 releaseRate; - int32 rootKeyOffset; - int32 size; - } *_env[8]; - } *_voice; -}; - -class Towns_EuphonyTrackQueue { -public: - Towns_EuphonyTrackQueue(Towns_EuphonyDriver *driver, Towns_EuphonyTrackQueue *last); - ~Towns_EuphonyTrackQueue() {} - - Towns_EuphonyTrackQueue *release(); - void initDriver(); - void loadDataToCurrentPosition(uint8 *trackdata, uint32 size, bool loop = 0); - void loadDataToEndOfQueue(uint8 *trackdata, uint32 size, bool loop = 0); - void setPlayBackStatus(bool playing); - bool isPlaying() const {return _playing; } - uint8 *trackData() {return _trackData; } - - bool _loop; - Towns_EuphonyTrackQueue *_next; - -private: - uint8 *_trackData; - uint8 *_used; - uint8 *_fchan; - uint8 *_wchan; - bool _playing; - Towns_EuphonyDriver *_driver; - Towns_EuphonyTrackQueue *_last; -}; - -class Towns_EuphonyParser : public MidiParser { -public: - Towns_EuphonyParser(Towns_EuphonyTrackQueue * queue); - bool loadMusic (byte *data, uint32 size); - int32 calculateTempo(int16 val); - -protected: - void parseNextEvent (EventInfo &info); - void resetTracking(); - void setup(); - - byte *_enable; - byte *_mode; - byte *_channel; - byte *_adjVelo; - int8 *_adjNote; - - uint8 _firstBaseTickStep; - uint8 _nextBaseTickStep; - uint32 _initialTempo; - uint32 _baseTick; - - byte _tempo[3]; - Towns_EuphonyTrackQueue *_queue; -}; - -class Towns_EuphonyDriver : public MidiDriver_Emulated { -public: - Towns_EuphonyDriver(Audio::Mixer *mixer); - virtual ~Towns_EuphonyDriver(); - - int open(); - void close(); - void send(uint32 b); - void send(byte channel, uint32 b); - uint32 property(int prop, uint32 param) { return 0; } - - void setPitchBendRange(byte channel, uint range) { } - void loadFmInstruments(const byte *instr); - void loadWaveInstruments(const byte *instr); - - Towns_EuphonyTrackQueue *queue() { return _queue; } - - MidiChannel *allocateChannel() { return 0; } - MidiChannel *getPercussionChannel() { return 0; } - - void assignFmChannel(uint8 midiChannelNumber, uint8 fmChannelNumber); - void assignWaveChannel(uint8 midiChannelNumber, uint8 waveChannelNumber); - void removeChannel(uint8 midiChannelNumber); - - void setVolume(int val = -1) { if (val >= 0) _volume = val; } - int getVolume(int val = -1) { return _volume; } - - // AudioStream API - bool isStereo() const { return true; } - int getRate() const { return _mixer->getOutputRate(); } - - void fading(bool status = true); - -protected: - void nextTick(int16 *buf1, int buflen); - void rate(uint16 r); - - void generateSamples(int16 *buf, int len); - - Towns_EuphonyFmChannel *_fChannel[6]; - Towns_EuphonyPcmChannel *_wChannel[8]; - Towns_EuphonyChannel *_channel[16]; - Towns_EuphonyTrackQueue *_queue; - - int _volume; - bool _fading; - int16 _fadestate; - - uint8 *_fmInstruments; - uint8 *_waveInstruments; - int8 * _waveSounds[10]; -}; - -Towns_EuphonyFmChannel::Towns_EuphonyFmChannel() { - _voice = new Voice2612; -} - -Towns_EuphonyFmChannel::~Towns_EuphonyFmChannel() { - delete _voice; -} - -void Towns_EuphonyFmChannel::noteOn(byte note, byte onVelo) { - _voice->noteOn(note, onVelo); -} - -void Towns_EuphonyFmChannel::noteOff(byte note) { - _voice->noteOff(note); -} - -void Towns_EuphonyFmChannel::controlChange(byte control, byte value) { - if (control == 121) { - // Reset controller - delete _voice; - _voice = new Voice2612; - } else if (control == 10) { - // pan position - } else { - _voice->setControlParameter(control, value); - } -} - -void Towns_EuphonyFmChannel::sysEx_customInstrument(uint32, const byte *fmInst) { - _voice->_rate = _rate; - _voice->setInstrument(fmInst); -} - -void Towns_EuphonyFmChannel::pitchBend(int16 value) { - _voice->pitchBend(value); -} - -void Towns_EuphonyFmChannel::nextTick(int32 *outbuf, int buflen) { - _voice->nextTick((int *)outbuf, buflen); -} - -void Towns_EuphonyFmChannel::rate(uint16 r) { - _rate = r; - _voice->_rate = r; -} - -Towns_EuphonyPcmChannel::Towns_EuphonyPcmChannel() { - _voice = new Voice; - for (uint8 i = 0; i < 8; i++) { - _voice->_env[i] = new Voice::Env; - _voice->_snd[i] = 0; - } - - _ctrl7_volume = 127; - velocity(0); - _frequencyOffs = 0x2000; - _current = -1; -} - -Towns_EuphonyPcmChannel::~Towns_EuphonyPcmChannel() { - for (uint8 i = 0; i < 8; i++) { - if (_voice->_snd[i]) - delete _voice->_snd[i]; - delete _voice->_env[i]; - } - delete _voice; -} - -void Towns_EuphonyPcmChannel::noteOn(byte note, byte onVelo) { - _note = note; - velocity(onVelo); - _phase = 0; - - for (_current = 0; _current < 7; _current++) { - if (note <= _voice->split[_current]) - break; - } - - _voice->_env[_current]->state = s_attacking; - _voice->_env[_current]->currentLevel = 0; - _voice->_env[_current]->rate = _rate; - _voice->_env[_current]->tickCount = 0; -} - -void Towns_EuphonyPcmChannel::noteOff(byte note) { - if (_current == -1) - return; - if (_voice->_env[_current]->state == s_ready) - return; - - _voice->_env[_current]->state = s_releasing; - _voice->_env[_current]->releaseLevel = _voice->_env[_current]->currentLevel; - _voice->_env[_current]->tickCount = 0; -} - -void Towns_EuphonyPcmChannel::controlChange(byte control, byte value) { - switch (control) { - case 0x07: - // volume - _ctrl7_volume = value; - break; - case 0x0A: - // pan position - break; - case 0x79: - // Reset controller - for (uint8 i = 0; i < 8; i++) { - if (_voice->_snd[i]) - delete _voice->_snd[i]; - delete _voice->_env[i]; - } - delete _voice; - _voice = new Voice; - for (uint8 i = 0; i < 8; i++) { - _voice->_env[i] = new Voice::Env; - _voice->_snd[i] = 0; - } - break; - case 0x7B: - noteOff(_note); - break; - default: - break; - } -} - -void Towns_EuphonyPcmChannel::sysEx_customInstrument(uint32 type, const byte *fmInst) { - if (type == 0x80) { - for (uint8 i = 0; i < 8; i++) { - const byte * const *pos = (const byte * const *)fmInst; - for (uint8 ii = 0; ii < 10; ii++) { - if (_voice->id[i] == *(pos[ii] + 8)) { - if (!_voice->_snd[i]) - _voice->_snd[i] = new Voice::Snd; - memset(_voice->_snd[i]->name, 0, 9); - memcpy(_voice->_snd[i]->name, (const char *)pos[ii], 8); - _voice->_snd[i]->id = READ_LE_UINT32(pos[ii] + 8); - _voice->_snd[i]->numSamples = READ_LE_UINT32(pos[ii] + 12); - _voice->_snd[i]->loopStart = READ_LE_UINT32(pos[ii] + 16); - _voice->_snd[i]->loopLength = READ_LE_UINT32(pos[ii] + 20); - _voice->_snd[i]->samplingRate = READ_LE_UINT16(pos[ii] + 24); - _voice->_snd[i]->keyOffset = READ_LE_UINT16(pos[ii] + 26); - _voice->_snd[i]->keyNote = *(const uint8 *)(pos[ii] + 28); - _voice->_snd[i]->_samples = (const int8 *)(pos[ii] + 32); - } - } - } - } else { - memset(_voice->name, 0, 9); - memcpy(_voice->name, (const char *)fmInst, 8); - - for (uint8 i = 0; i < 8; i++) { - _voice->split[i] = READ_LE_UINT16(fmInst + 16 + 2 * i); - _voice->id[i] = READ_LE_UINT32(fmInst + 32 + 4 * i); - _voice->_snd[i] = 0; - _voice->_env[i]->state = s_ready; - _voice->_env[i]->currentLevel = 0; - _voice->_env[i]->totalLevel = *(fmInst + 64 + 8 * i); - _voice->_env[i]->attackRate = *(fmInst + 65 + 8 * i) * 10; - _voice->_env[i]->decayRate = *(fmInst + 66 + 8 * i) * 10; - _voice->_env[i]->sustainLevel = *(fmInst + 67 + 8 * i); - _voice->_env[i]->sustainRate = *(fmInst + 68 + 8 * i) * 20; - _voice->_env[i]->releaseRate = *(fmInst + 69 + 8 * i) * 10; - _voice->_env[i]->rootKeyOffset = *(fmInst + 70 + 8 * i); - } - } -} - -void Towns_EuphonyPcmChannel::pitchBend(int16 value) { - _frequencyOffs = value; -} - -void Towns_EuphonyPcmChannel::nextTick(int32 *outbuf, int buflen) { - if (_current == -1 || !_voice->_snd[_current] || !_voice->_env[_current]->state || !_velocity) { - velocity(0); - _current = -1; - return; - } - - float phaseStep = SoundTowns::calculatePhaseStep(_note, _voice->_snd[_current]->keyNote - - _voice->_env[_current]->rootKeyOffset, _voice->_snd[_current]->samplingRate, _rate, _frequencyOffs); - - int32 looplength = _voice->_snd[_current]->loopLength; - int32 numsamples = _voice->_snd[_current]->numSamples; - const int8 * samples = _voice->_snd[_current]->_samples; - - for (int i = 0; i < buflen; i++) { - if (looplength > 0) { - while (_phase >= numsamples) - _phase -= looplength; - } else { - if (_phase >= numsamples) { - velocity(0); - _current = -1; - break; - } - } - - int32 output; - - int32 phase0 = int32(_phase); - int32 phase1 = int32(_phase + 1); - if (phase1 >= numsamples) - phase1 -= looplength; - float weight0 = _phase - phase0; - float weight1 = phase1 - _phase; - output = int32(samples[phase0] * weight0 + samples[phase1] * weight1); - - output *= _velocity; - output <<= 1; - - evpNextTick(); - output *= _voice->_env[_current]->currentLevel; - output >>= 7; - output *= _ctrl7_volume; - output >>= 7; - - output *= 185; - output >>= 8; - outbuf[i] += output; - _phase += phaseStep; - } -} - -void Towns_EuphonyPcmChannel::evpNextTick() { - switch (_voice->_env[_current]->state) { - case s_ready: - _voice->_env[_current]->currentLevel = 0; - return; - - case s_attacking: - if (_voice->_env[_current]->attackRate == 0) - _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel; - else if (_voice->_env[_current]->attackRate >= 1270) - _voice->_env[_current]->currentLevel = 0; - else - _voice->_env[_current]->currentLevel = (_voice->_env[_current]->totalLevel * - _voice->_env[_current]->tickCount++ * 1000) / - (_voice->_env[_current]->attackRate * _voice->_env[_current]->rate); - - if (_voice->_env[_current]->currentLevel >= _voice->_env[_current]->totalLevel) { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel; - _voice->_env[_current]->state = s_decaying; - _voice->_env[_current]->tickCount = 0; - } - break; - - case s_decaying: - if (_voice->_env[_current]->decayRate == 0) { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel; - } else if (_voice->_env[_current]->decayRate >= 1270) { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel; - } else { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel; - _voice->_env[_current]->currentLevel -= ((_voice->_env[_current]->totalLevel - - _voice->_env[_current]->sustainLevel) * _voice->_env[_current]->tickCount++ * 1000) / - (_voice->_env[_current]->decayRate * _voice->_env[_current]->rate); - } - - if (_voice->_env[_current]->currentLevel <= _voice->_env[_current]->sustainLevel) { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel; - _voice->_env[_current]->state = s_sustaining; - _voice->_env[_current]->tickCount = 0; - } - break; - - case s_sustaining: - if (_voice->_env[_current]->sustainRate == 0) { - _voice->_env[_current]->currentLevel = 0; - } else if (_voice->_env[_current]->sustainRate >= 2540) { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel; - } else { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel; - _voice->_env[_current]->currentLevel -= (_voice->_env[_current]->sustainLevel * - _voice->_env[_current]->tickCount++ * 1000) / (_voice->_env[_current]->sustainRate * - _voice->_env[_current]->rate); - } - - if (_voice->_env[_current]->currentLevel <= 0) { - _voice->_env[_current]->currentLevel = 0; - _voice->_env[_current]->state = s_ready; - _voice->_env[_current]->tickCount = 0; - } - break; - - case s_releasing: - if (_voice->_env[_current]->releaseRate == 0) { - _voice->_env[_current]->currentLevel = 0; - } else if (_voice->_env[_current]->releaseRate >= 1270) { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->releaseLevel; - } else { - _voice->_env[_current]->currentLevel = _voice->_env[_current]->releaseLevel; - _voice->_env[_current]->currentLevel -= (_voice->_env[_current]->releaseLevel * - _voice->_env[_current]->tickCount++ * 1000) / (_voice->_env[_current]->releaseRate * - _voice->_env[_current]->rate); - } - - if (_voice->_env[_current]->currentLevel <= 0) { - _voice->_env[_current]->currentLevel = 0; - _voice->_env[_current]->state = s_ready; - } - break; - - default: - break; - } -} - -void Towns_EuphonyPcmChannel::rate(uint16 r) { - _rate = r; -} - -void Towns_EuphonyPcmChannel::velocity(int velo) { - _velocity = velo; -} - -Towns_EuphonyDriver::Towns_EuphonyDriver(Audio::Mixer *mixer) - : MidiDriver_Emulated(mixer) { - _volume = 255; - _fadestate = EUPHONY_FADEOUT_TICKS; - _queue = 0; - - MidiDriver_YM2612::createLookupTables(); - - for (uint8 i = 0; i < 6; i++) - _channel[i] = _fChannel[i] = new Towns_EuphonyFmChannel; - for (uint8 i = 0; i < 8; i++) - _channel[i + 6] = _wChannel[i] = new Towns_EuphonyPcmChannel; - _channel[14] = _channel[15] = 0; - - _fmInstruments = _waveInstruments = 0; - memset(_waveSounds, 0, sizeof(uint8 *)* 10); - - rate(getRate()); - fading(0); - - _queue = new Towns_EuphonyTrackQueue(this, 0); -} - -Towns_EuphonyDriver::~Towns_EuphonyDriver() { - for (int i = 0; i < 6; i++) - delete _fChannel[i]; - for (int i = 0; i < 8; i++) - delete _wChannel[i]; - - MidiDriver_YM2612::removeLookupTables(); - - delete[] _fmInstruments; - _fmInstruments = 0; - - delete[] _waveInstruments; - _waveInstruments = 0; - - for (int i = 0; i < 10; i++) { - delete[] _waveSounds[i]; - _waveSounds[i] = 0; - } - - if (_queue) { - _queue->release(); - delete _queue; - _queue = 0; - } -} - -int Towns_EuphonyDriver::open() { - if (_isOpen) - return MERR_ALREADY_OPEN; - MidiDriver_Emulated::open(); - - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, - this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); - - return 0; -} - -void Towns_EuphonyDriver::close() { - if (!_isOpen) - return; - _isOpen = false; - _mixer->stopHandle(_mixerSoundHandle); -} - -void Towns_EuphonyDriver::send(uint32 b) { - send(b & 0xF, b & 0xFFFFFFF0); -} - -void Towns_EuphonyDriver::send(byte chan, uint32 b) { - byte param2 = (byte) ((b >> 16) & 0xFF); - byte param1 = (byte) ((b >> 8) & 0xFF); - byte cmd = (byte) (b & 0xF0); - if (chan > ARRAYSIZE(_channel)) - return; - - switch (cmd) { - case 0x80:// Note Off - if (_channel[chan]) - _channel[chan]->noteOff(param1); - break; - case 0x90: // Note On - if (_channel[chan]) - _channel[chan]->noteOn(param1, param2); - break; - case 0xA0: // Aftertouch - break; // Not supported. - case 0xB0: // Control Change - if (param1 == 0x79) { - fading(0); - for (int i = 0; i < 15; i++) { - if (_channel[i]) { - _channel[i]->controlChange(param1, param2); - _channel[i]->programChange(0); - } - } - } else if (param1 == 0x7B) { - for (int i = 0; i < 15; i++) { - if (_channel[i]) - _channel[i]->controlChange(param1, param2); - } - } else { - if (_channel[chan]) - _channel[chan]->controlChange(param1, param2); - } - break; - case 0xC0: // Program Change - for (int i = 0; i < 6; i++) { - if (_channel[chan] == _fChannel[i]) { - _channel[chan]->sysEx_customInstrument(0, _fmInstruments + param1 * 0x30); - break; - } - } - for (int i = 0; i < 8; i++) { - if (_channel[chan] == _wChannel[i]) { - _channel[chan]->sysEx_customInstrument(0, _waveInstruments + param1 * 0x80); - _channel[chan]->sysEx_customInstrument(0x80, (const byte *)_waveSounds); - break; - } - } - break; - case 0xD0: // Channel Pressure - break; // Not supported. - case 0xE0: // Pitch Bend - if (_channel[chan]) - _channel[chan]->pitchBend((param1 | (param2 << 7)) - 0x2000); - break; - default: - warning("Towns_EuphonyDriver: Unknown send() command 0x%02X", cmd); - } -} - -void Towns_EuphonyDriver::loadFmInstruments(const byte *instr) { - delete[] _fmInstruments; - _fmInstruments = new uint8[0x1800]; - memcpy(_fmInstruments, instr, 0x1800); -} - -void Towns_EuphonyDriver::loadWaveInstruments(const byte *instr) { - delete[] _waveInstruments; - _waveInstruments = new uint8[0x1000]; - memcpy(_waveInstruments, instr, 0x1000); - - const uint8 *pos = (const uint8 *)(instr + 0x1000); - - for (uint8 i = 0; i < 10; i++) { - delete[] _waveSounds[i]; - uint32 numsamples = READ_LE_UINT32(pos + 0x0C); - _waveSounds[i] = new int8[numsamples + 0x20]; - memcpy(_waveSounds[i], pos, 0x20); - pos += 0x20; - for (uint32 ii = 0; ii < numsamples; ii++) { - uint8 s = *(pos + ii); - s = (s < 0x80) ? 0x80 - s : s; - _waveSounds[i][ii + 0x20] = s ^ 0x80; - } - pos += numsamples; - } -} - - -void Towns_EuphonyDriver::assignFmChannel(uint8 midiChannelNumber, uint8 fmChannelNumber) { - _channel[midiChannelNumber] = _fChannel[fmChannelNumber]; -} - -void Towns_EuphonyDriver::assignWaveChannel(uint8 midiChannelNumber, uint8 waveChannelNumber) { - _channel[midiChannelNumber] = _wChannel[waveChannelNumber]; -} - -void Towns_EuphonyDriver::removeChannel(uint8 midiChannelNumber) { - _channel[midiChannelNumber] = 0; -} - -void Towns_EuphonyDriver::generateSamples(int16 *data, int len) { - memset(data, 0, 2 * sizeof(int16) * len); - nextTick(data, len); -} - -void Towns_EuphonyDriver::nextTick(int16 *buf1, int buflen) { - int32 *buf0 = (int32 *)buf1; - - for (int i = 0; i < ARRAYSIZE(_channel); i++) { - if (_channel[i]) - _channel[i]->nextTick(buf0, buflen); - } - - for (int i = 0; i < buflen; ++i) { - int s = int( float(buf0[i] * _volume) * float((float)_fadestate / EUPHONY_FADEOUT_TICKS) ); - buf1[i*2] = buf1[i*2+1] = (s >> 9) & 0xffff; - } - - if (_fading) { - if (_fadestate) { - _fadestate--; - } else { - _fading = false; - _queue->setPlayBackStatus(false); - } - } -} - -void Towns_EuphonyDriver::rate(uint16 r) { - for (uint8 i = 0; i < 16; i++) { - if (_channel[i]) - _channel[i]->rate(r); - } -} - -void Towns_EuphonyDriver::fading(bool status) { - _fading = status; - if (!_fading) - _fadestate = EUPHONY_FADEOUT_TICKS; -} - -Towns_EuphonyParser::Towns_EuphonyParser(Towns_EuphonyTrackQueue * queue) : MidiParser(), - _firstBaseTickStep(0x33), _nextBaseTickStep(0x33) { - _initialTempo = calculateTempo(0x5a); - _queue = queue; -} - -void Towns_EuphonyParser::parseNextEvent(EventInfo &info) { - byte *pos = _position._play_pos; - - if (_queue->_next) { - if (info.ext.type == 0x2F) { - unloadMusic(); - memset(&info, 0, sizeof(EventInfo)); - pos = _position._play_pos = _tracks[0] = _queue->trackData() + 0x806; - } else if (_active_track == 255) { - _queue = _queue->_next; - setup(); - setTrack(0); - _queue->setPlayBackStatus(true); - return; - } else if (!_queue->isPlaying()) { - unloadMusic(); - _queue = _queue->_next; - setup(); - setTrack(0); - _queue->setPlayBackStatus(true); - return; - } - } - - bool loop = true; - while (loop) { - byte cmd = *pos; - byte evt = (cmd & 0xF0); - - if (evt == 0x90) { - byte chan = pos[1]; - - if (_enable[chan]) { - uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick; - info.start = pos + 6; - uint32 last = _position._last_event_tick; - info.delta = (tick < last) ? 0 : (tick - last); - - info.event = 0x90 | _channel[chan]; - info.length = pos[7] | (pos[8] << 4) | (pos[9] << 8) | (pos[10] << 12); - - int8 note = (int8) pos[4]; - if (_adjNote[chan]) { - note = (note & 0x7f) & _adjNote[chan]; - if (note > 0x7c) - note -= 0x0c; - else if (note < 0) - note += 0x0c; - } - info.basic.param1 = (byte) note; - - uint8 onVelo = (pos[5] & 0x7f) + _adjVelo[chan]; - if (onVelo > 0x7f) - onVelo = 0x7f; - if (onVelo < 1) - onVelo = 1; - info.basic.param2 = onVelo; - - pos += 12; - loop = false; - } else { - pos += 6; - } - } else if (evt == 0xB0 || evt == 0xC0 || evt == 0xe0) { - byte chan = pos[1]; - - if (_enable[chan]) { - info.start = pos; - uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick; - uint32 last = _position._last_event_tick; - info.delta = (tick < last) ? 0 : (tick - last); - info.event = evt | _channel[chan]; - info.length = 0; - info.basic.param1 = pos[4]; - info.basic.param2 = pos[5]; - pos += 6; - loop = false; - } else { - pos += 6; - } - } else if (cmd == 0xF2) { - static const uint16 tickTable[] = { 0x180, 0xC0, 0x80, 0x60, 0x40, 0x30, 0x20, 0x18 }; - _baseTick += tickTable[_nextBaseTickStep >> 4] * ((_nextBaseTickStep & 0x0f) + 1); - _nextBaseTickStep = pos[1]; - pos += 6; - } else if (cmd == 0xF8) { - int32 tempo = calculateTempo(pos[4] | (pos[5] << 7)); - info.event = 0xff; - info.length = 3; - info.ext.type = 0x51; - _tempo[0] = (tempo >> 16) & 0xff; - _tempo[1] = (tempo >> 8) & 0xff; - _tempo[2] = tempo & 0xff; - info.ext.data = (byte *)_tempo; - pos += 6; - loop = false; - } else if (cmd == 0xFD || cmd == 0xFE) { - // End of track. - if (_autoLoop) { - unloadMusic(); - _queue->setPlayBackStatus(true); - pos = info.start = _tracks[0]; - } else { - info.start = pos; - } - - uint32 last = _position._last_event_tick; - uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick; - info.delta = (tick < last) ? 0 : (tick - last); - info.event = 0xFF; - info.ext.type = 0x2F; - info.ext.data = pos; - loop = false; - } else { - warning("Unknown Euphony music event 0x%02X", (int)cmd); - memset(&info, 0, sizeof(info)); - pos = 0; - loop = false; - } - } - _position._play_pos = pos; -} - -bool Towns_EuphonyParser::loadMusic(byte *data, uint32 size) { - bool loop = _autoLoop; - - if (_queue->isPlaying() && !_queue->_loop) { - _queue->loadDataToEndOfQueue(data, size, loop); - } else { - unloadMusic(); - _queue = _queue->release(); - _queue->loadDataToCurrentPosition(data, size, loop); - setup(); - setTrack(0); - _queue->setPlayBackStatus(true); - } - return true; -} - -int32 Towns_EuphonyParser::calculateTempo(int16 val) { - int32 tempo = val; - - if (tempo < 0) - tempo = 0; - if (tempo > 0x1F4) - tempo = 0x1F4; - - tempo = 0x4C4B4 / (tempo + 0x1E); - while (tempo < 0x451) - tempo <<= 1; - tempo <<= 8; - - return tempo; -} - -void Towns_EuphonyParser::resetTracking() { - MidiParser::resetTracking(); - - _nextBaseTickStep = _firstBaseTickStep; - _baseTick = 0; - setTempo(_initialTempo); - _queue->setPlayBackStatus(false); -} - -void Towns_EuphonyParser::setup() { - uint8 *data = _queue->trackData(); - if (!data) - return; - _queue->initDriver(); - - _enable = data + 0x354; - _mode = data + 0x374; - _channel = data + 0x394; - _adjVelo = data + 0x3B4; - _adjNote = (int8 *)data + 0x3D4; - - _nextBaseTickStep = _firstBaseTickStep = data[0x804]; - _initialTempo = calculateTempo((data[0x805] > 0xfc) ? 0x5a : data[0x805]); - - property(MidiParser::mpAutoLoop, _queue->_loop); - - _num_tracks = 1; - _ppqn = 120; - _tracks[0] = data + 0x806; -} - -Towns_EuphonyTrackQueue::Towns_EuphonyTrackQueue(Towns_EuphonyDriver * driver, Towns_EuphonyTrackQueue * last) { - _trackData = 0; - _next = 0; - _driver = driver; - _last = last; - _used = _fchan = _wchan = 0; - _playing = _loop = false; -} - -void Towns_EuphonyTrackQueue::setPlayBackStatus(bool playing) { - Towns_EuphonyTrackQueue *i = this; - do { - i->_playing = playing; - i = i->_next; - } while (i); -} - -void Towns_EuphonyTrackQueue::loadDataToCurrentPosition(uint8 * trackdata, uint32 size, bool loop) { - delete[] _trackData; - _trackData = new uint8[0xC58A]; - memset(_trackData, 0, 0xC58A); - Screen::decodeFrame4(trackdata, _trackData, size); - - _used = _trackData + 0x374; - _fchan = _trackData + 0x6d4; - _wchan = _trackData + 0x6dA; - _loop = loop; - _playing = false; -} - -void Towns_EuphonyTrackQueue::loadDataToEndOfQueue(uint8 * trackdata, uint32 size, bool loop) { - if (!_trackData) { - loadDataToCurrentPosition(trackdata, size, loop); - return; - } - - Towns_EuphonyTrackQueue *i = this; - while (i->_next) - i = i->_next; - - i = i->_next = new Towns_EuphonyTrackQueue(_driver, i); - i->_trackData = new uint8[0xC58A]; - memset(i->_trackData, 0, 0xC58A); - Screen::decodeFrame4(trackdata, i->_trackData, size); - - i->_used = i->_trackData + 0x374; - i->_fchan = i->_trackData + 0x6d4; - i->_wchan = i->_trackData + 0x6dA; - i->_loop = loop; - i->_playing = _playing; -} - -Towns_EuphonyTrackQueue *Towns_EuphonyTrackQueue::release() { - Towns_EuphonyTrackQueue *i = this; - while (i->_next) - i = i->_next; - - Towns_EuphonyTrackQueue *res = i; - - while (i) { - i->_playing = false; - i->_used = i->_fchan = i->_wchan = 0; - delete[] i->_trackData; - i->_trackData = 0; - i = i->_last; - if (i) { - res = i; - delete i->_next; - i->_next = 0; - } - } - - delete[] res->_trackData; - res->_trackData = 0; - - return res; -} - -void Towns_EuphonyTrackQueue::initDriver() { - for (uint8 i = 0; i < 6; i++) { - if (_used[_fchan[i]]) - _driver->assignFmChannel(_fchan[i], i); - } - - for (uint8 i = 0; i < 8; i++) { - if (_used[_wchan[i]]) - _driver->assignWaveChannel(_wchan[i], i); - } - - for (uint8 i = 0; i < 16; i++) { - if (!_used[i]) - _driver->removeChannel(i); - } - _driver->send(0x79B0); -} - -class TownsPC98_OpnOperator { -public: - TownsPC98_OpnOperator(const uint32 timerbase, const uint8 *rateTable, - const uint8 *shiftTable, const uint8 *attackDecayTable, const uint32 *frqTable, - const uint32 *sineTable, const int32 *tlevelOut, const int32 *detuneTable); - ~TownsPC98_OpnOperator() {} - - void keyOn(); - void keyOff(); - void frequency(int freq); - void updatePhaseIncrement(); - void recalculateRates(); - void generateOutput(int32 phasebuf, int32 *feedbuf, int32 &out); - - void feedbackLevel(int32 level) {_feedbackLevel = level ? level + 6 : 0; } - void detune(int value) { _detn = &_detnTbl[value << 5]; } - void multiple(uint32 value) { _multiple = value ? (value << 1) : 1; } - void attackRate(uint32 value) { _specifiedAttackRate = value; } - bool scaleRate(uint8 value); - void decayRate(uint32 value) { _specifiedDecayRate = value; recalculateRates(); } - void sustainRate(uint32 value) { _specifiedSustainRate = value; recalculateRates(); } - void sustainLevel(uint32 value) { _sustainLevel = (value == 0x0f) ? 0x3e0 : value << 5; } - void releaseRate(uint32 value) { _specifiedReleaseRate = value; recalculateRates(); } - void totalLevel(uint32 value) { _totalLevel = value << 3; } - void reset(); - -protected: - EnvelopeState _state; - bool _playing; - uint32 _feedbackLevel; - uint32 _multiple; - uint32 _totalLevel; - uint8 _keyScale1; - uint8 _keyScale2; - uint32 _specifiedAttackRate; - uint32 _specifiedDecayRate; - uint32 _specifiedSustainRate; - uint32 _specifiedReleaseRate; - uint32 _tickCount; - uint32 _sustainLevel; - - uint32 _frequency; - uint8 _kcode; - uint32 _phase; - uint32 _phaseIncrement; - const int32 *_detn; - - const uint8 *_rateTbl; - const uint8 *_rshiftTbl; - const uint8 *_adTbl; - const uint32 *_fTbl; - const uint32 *_sinTbl; - const int32 *_tLvlTbl; - const int32 *_detnTbl; - - const uint32 _tickLength; - uint32 _timer; - int32 _currentLevel; - - struct EvpState { - uint8 rate; - uint8 shift; - } fs_a, fs_d, fs_s, fs_r; -}; - -TownsPC98_OpnOperator::TownsPC98_OpnOperator(const uint32 timerbase, const uint8 *rateTable, - const uint8 *shiftTable, const uint8 *attackDecayTable, const uint32 *frqTable, - const uint32 *sineTable, const int32 *tlevelOut, const int32 *detuneTable) : - _rateTbl(rateTable), _rshiftTbl(shiftTable), _adTbl(attackDecayTable), _fTbl(frqTable), - _sinTbl(sineTable), _tLvlTbl(tlevelOut), _detnTbl(detuneTable), _tickLength(timerbase * 2), - _specifiedAttackRate(0), _specifiedDecayRate(0), _specifiedReleaseRate(0), _specifiedSustainRate(0), - _phase(0), _state(s_ready), _playing(false), _timer(0), _keyScale1(0), _keyScale2(0), _currentLevel(1023), - _tickCount(0) { - - fs_a.rate = fs_a.shift = fs_d.rate = fs_d.shift = fs_s.rate = fs_s.shift = fs_r.rate = fs_r.shift = 0; - - reset(); -} - -void TownsPC98_OpnOperator::keyOn() { - if (_playing) - return; - - _playing = true; - _state = s_attacking; - _phase = 0; -} - -void TownsPC98_OpnOperator::keyOff() { - if (!_playing) - return; - - _playing = false; - if (_state != s_ready) - _state = s_releasing; -} - -void TownsPC98_OpnOperator::frequency(int freq) { - uint8 block = (freq >> 11); - uint16 pos = (freq & 0x7ff); - uint8 c = pos >> 7; - - _kcode = (block << 2) | ((c < 7) ? 0 : ((c > 8) ? 3 : c - 6 )); - _frequency = _fTbl[pos << 1] >> (7 - block); -} - -void TownsPC98_OpnOperator::updatePhaseIncrement() { - _phaseIncrement = ((_frequency + _detn[_kcode]) * _multiple) >> 1; - uint8 keyscale = _kcode >> _keyScale1; - if (_keyScale2 != keyscale) { - _keyScale2 = keyscale; - recalculateRates(); - } -} - -void TownsPC98_OpnOperator::recalculateRates() { - int k = _keyScale2; - int r = _specifiedAttackRate ? (_specifiedAttackRate << 1) + 0x20 : 0; - fs_a.rate = ((r + k) < 94) ? _rateTbl[r + k] : 136; - fs_a.shift = ((r + k) < 94) ? _rshiftTbl[r + k] : 0; - - r = _specifiedDecayRate ? (_specifiedDecayRate << 1) + 0x20 : 0; - fs_d.rate = _rateTbl[r + k]; - fs_d.shift = _rshiftTbl[r + k]; - - r = _specifiedSustainRate ? (_specifiedSustainRate << 1) + 0x20 : 0; - fs_s.rate = _rateTbl[r + k]; - fs_s.shift = _rshiftTbl[r + k]; - - r = (_specifiedReleaseRate << 2) + 0x22; - fs_r.rate = _rateTbl[r + k]; - fs_r.shift = _rshiftTbl[r + k]; -} - -void TownsPC98_OpnOperator::generateOutput(int32 phasebuf, int32 *feed, int32 &out) { - if (_state == s_ready) - return; - - _timer += _tickLength; - while (_timer > 0x5B8D80) { - _timer -= 0x5B8D80; - ++_tickCount; - - int32 levelIncrement = 0; - uint32 targetTime = 0; - int32 targetLevel = 0; - EnvelopeState nextState = s_ready; - - switch (_state) { - case s_ready: - return; - case s_attacking: - targetLevel = 0; - nextState = s_decaying; - if ((_specifiedAttackRate << 1) + _keyScale2 < 64) { - targetTime = (1 << fs_a.shift) - 1; - levelIncrement = (~_currentLevel * _adTbl[fs_a.rate + ((_tickCount >> fs_a.shift) & 7)]) >> 4; - break; - } else { - _currentLevel = targetLevel; - _state = nextState; - } - // Fall through - case s_decaying: - targetTime = (1 << fs_d.shift) - 1; - nextState = s_sustaining; - targetLevel = _sustainLevel; - levelIncrement = _adTbl[fs_d.rate + ((_tickCount >> fs_d.shift) & 7)]; - break; - case s_sustaining: - targetTime = (1 << fs_s.shift) - 1; - nextState = s_sustaining; - targetLevel = 1023; - levelIncrement = _adTbl[fs_s.rate + ((_tickCount >> fs_s.shift) & 7)]; - break; - case s_releasing: - targetTime = (1 << fs_r.shift) - 1; - nextState = s_ready; - targetLevel = 1023; - levelIncrement = _adTbl[fs_r.rate + ((_tickCount >> fs_r.shift) & 7)]; - break; - } - - if (!(_tickCount & targetTime)) { - _currentLevel += levelIncrement; - if ((_state == s_attacking && _currentLevel <= targetLevel) || (_state != s_attacking && _currentLevel >= targetLevel)) { - if (_state != s_decaying) - _currentLevel = targetLevel; - _state = nextState; - } - } - } - - uint32 lvlout = _totalLevel + (uint32) _currentLevel; - - - int32 outp = 0; - int32 *i = &outp, *o = &outp; - int phaseShift = 0; - - if (feed) { - o = &feed[0]; - i = &feed[1]; - phaseShift = _feedbackLevel ? ((*o + *i) << _feedbackLevel) : 0; - *o = *i; - } else { - phaseShift = phasebuf << 15; - } - - if (lvlout < 832) { - uint32 index = (lvlout << 3) + _sinTbl[(((int32)((_phase & 0xffff0000) - + phaseShift)) >> 16) & 0x3ff]; - *i = ((index < 6656) ? _tLvlTbl[index] : 0); - } else { - *i = 0; - } - - _phase += _phaseIncrement; - out += *o; -} - -void TownsPC98_OpnOperator::reset(){ - keyOff(); - _timer = 0; - _keyScale2 = 0; - _currentLevel = 1023; - - frequency(0); - detune(0); - scaleRate(0); - multiple(0); - updatePhaseIncrement(); - attackRate(0); - decayRate(0); - releaseRate(0); - sustainRate(0); - feedbackLevel(0); - totalLevel(127); -} - -bool TownsPC98_OpnOperator::scaleRate(uint8 value) { - value = 3 - value; - if (_keyScale1 != value) { - _keyScale1 = value; - return true; - } - - int k = _keyScale2; - int r = _specifiedAttackRate ? (_specifiedAttackRate << 1) + 0x20 : 0; - fs_a.rate = ((r + k) < 94) ? _rateTbl[r + k] : 136; - fs_a.shift = ((r + k) < 94) ? _rshiftTbl[r + k] : 0; - return false; -} - -class TownsPC98_OpnDriver; -class TownsPC98_OpnChannel { -public: - TownsPC98_OpnChannel(TownsPC98_OpnDriver *driver, uint8 regOffs, uint8 flgs, uint8 num, - uint8 key, uint8 prt, uint8 id); - virtual ~TownsPC98_OpnChannel(); - virtual void init(); - - typedef enum channelState { - CHS_RECALCFREQ = 0x01, - CHS_KEYOFF = 0x02, - CHS_SSGOFF = 0x04, - CHS_VBROFF = 0x08, - CHS_ALLOFF = 0x0f, - CHS_PROTECT = 0x40, - CHS_EOT = 0x80 - } ChannelState; - - virtual void loadData(uint8 *data); - virtual void processEvents(); - virtual void processFrequency(); - virtual bool processControlEvent(uint8 cmd); - - virtual void keyOn(); - void keyOff(); - - void setOutputLevel(); - virtual void fadeStep(); - virtual void reset(); - - const uint8 _idFlag; - -protected: - void setupVibrato(); - bool processVibrato(); - - bool control_dummy(uint8 para); - bool control_f0_setPatch(uint8 para); - bool control_f1_presetOutputLevel(uint8 para); - bool control_f2_setKeyOffTime(uint8 para); - bool control_f3_setFreqLSB(uint8 para); - bool control_f4_setOutputLevel(uint8 para); - bool control_f5_setTempo(uint8 para); - bool control_f6_repeatSection(uint8 para); - bool control_f7_setupVibrato(uint8 para); - bool control_f8_toggleVibrato(uint8 para); - bool control_fa_writeReg(uint8 para); - virtual bool control_fb_incOutLevel(uint8 para); - virtual bool control_fc_decOutLevel(uint8 para); - bool control_fd_jump(uint8 para); - virtual bool control_ff_endOfTrack(uint8 para); - - uint8 _ticksLeft; - uint8 _algorithm; - uint8 _instr; - uint8 _totalLevel; - uint8 _frqBlockMSB; - int8 _frqLSB; - uint8 _keyOffTime; - bool _hold; - uint8 *_dataPtr; - uint8 _vbrInitDelayHi; - uint8 _vbrInitDelayLo; - int16 _vbrModInitVal; - uint8 _vbrDuration; - uint8 _vbrCurDelay; - int16 _vbrModCurVal; - uint8 _vbrDurLeft; - uint16 _frequency; - uint8 _block; - uint8 _regOffset; - uint8 _flags; - uint8 _ssgTl; - uint8 _ssgStep; - uint8 _ssgTicksLeft; - uint8 _ssgTargetLvl; - uint8 _ssgStartLvl; - - const uint8 _chanNum; - const uint8 _keyNum; - const uint8 _part; - - TownsPC98_OpnDriver *_drv; - - typedef bool (TownsPC98_OpnChannel::*ControlEventFunc)(uint8 para); - const ControlEventFunc *controlEvents; -}; - -class TownsPC98_OpnChannelSSG : public TownsPC98_OpnChannel { -public: - TownsPC98_OpnChannelSSG(TownsPC98_OpnDriver *driver, uint8 regOffs, - uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id); - virtual ~TownsPC98_OpnChannelSSG() {} - void init(); - - virtual void loadData(uint8 *data); - void processEvents(); - void processFrequency(); - bool processControlEvent(uint8 cmd); - - void keyOn(); - void nextShape(); - - void protect(); - void restore(); - virtual void reset(); - - void fadeStep(); - -protected: - void setOutputLevel(uint8 lvl); - - bool control_f0_setPatch(uint8 para); - bool control_f1_setTotalLevel(uint8 para); - bool control_f4_setAlgorithm(uint8 para); - bool control_f9_loadCustomPatch(uint8 para); - bool control_fb_incOutLevel(uint8 para); - bool control_fc_decOutLevel(uint8 para); - bool control_ff_endOfTrack(uint8 para); - - typedef bool (TownsPC98_OpnChannelSSG::*ControlEventFunc)(uint8 para); - const ControlEventFunc *controlEvents; -}; - -class TownsPC98_OpnSfxChannel : public TownsPC98_OpnChannelSSG { -public: - TownsPC98_OpnSfxChannel(TownsPC98_OpnDriver *driver, uint8 regOffs, - uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id) : - TownsPC98_OpnChannelSSG(driver, regOffs, flgs, num, key, prt, id) {} - ~TownsPC98_OpnSfxChannel() {} - - void loadData(uint8 *data); - void reset(); -}; - -class TownsPC98_OpnChannelPCM : public TownsPC98_OpnChannel { -public: - TownsPC98_OpnChannelPCM(TownsPC98_OpnDriver *driver, uint8 regOffs, - uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id); - ~TownsPC98_OpnChannelPCM() {} - void init(); - - void loadData(uint8 *data); - void processEvents(); - bool processControlEvent(uint8 cmd); - -private: - bool control_f1_prcStart(uint8 para); - bool control_ff_endOfTrack(uint8 para); - - typedef bool (TownsPC98_OpnChannelPCM::*ControlEventFunc)(uint8 para); - const ControlEventFunc *controlEvents; -}; - -class TownsPC98_OpnSquareSineSource { -public: - TownsPC98_OpnSquareSineSource(const uint32 timerbase); - ~TownsPC98_OpnSquareSineSource(); - - void init(const int *rsTable, const int *rseTable); - void reset(); - void writeReg(uint8 address, uint8 value, bool force = false); - - void nextTick(int32 *buffer, uint32 bufferSize); - - void setVolumeIntern(int volA, int volB) { _volumeA = volA; _volumeB = volB; } - void setVolumeChannelMasks(int channelMaskA, int channelMaskB) { _volMaskA = channelMaskA; _volMaskB = channelMaskB; } - - uint8 chanEnable() const { return _chanEnable; } -private: - void updateRegs(); - - uint8 _updateRequestBuf[64]; - int _updateRequest; - int _rand; - - int8 _evpTimer; - uint32 _pReslt; - uint8 _attack; - - bool _evpUpdate, _cont; - - int _evpUpdateCnt; - uint8 _outN; - int _nTick; - - int32 *_tlTable; - int32 *_tleTable; - - const uint32 _tickLength; - uint32 _timer; - - struct Channel { - int tick; - uint8 smp; - uint8 out; - - uint8 frqL; - uint8 frqH; - uint8 vol; - } _channels[3]; - - uint8 _noiseGenerator; - uint8 _chanEnable; - - uint8 **_reg; - - uint16 _volumeA; - uint16 _volumeB; - int _volMaskA; - int _volMaskB; - - bool _ready; -}; - -class TownsPC98_OpnPercussionSource { -public: - TownsPC98_OpnPercussionSource(const uint32 timerbase); - ~TownsPC98_OpnPercussionSource() { delete[] _reg; } - - void init(const uint8 *instrData = 0); - void reset(); - void writeReg(uint8 address, uint8 value); - - void nextTick(int32 *buffer, uint32 bufferSize); - - void setVolumeIntern(int volA, int volB) { _volumeA = volA; _volumeB = volB; } - void setVolumeChannelMasks(int channelMaskA, int channelMaskB) { _volMaskA = channelMaskA; _volMaskB = channelMaskB; } - -private: - struct RhtChannel { - const uint8 *data; - - const uint8 *start; - const uint8 *end; - const uint8 *pos; - uint32 size; - bool active; - uint8 level; - - int8 decState; - uint8 decStep; - - int16 samples[2]; - int out; - - uint8 startPosH; - uint8 startPosL; - uint8 endPosH; - uint8 endPosL; - }; - - void recalcOuput(RhtChannel *ins); - void advanceInput(RhtChannel *ins); - - RhtChannel _rhChan[6]; - - uint8 _totalLevel; - - const uint32 _tickLength; - uint32 _timer; - - uint8 **_reg; - - uint16 _volumeA; - uint16 _volumeB; - int _volMaskA; - int _volMaskB; - - bool _ready; -}; - -class TownsPC98_OpnCore : public Audio::AudioStream { -public: - enum OpnType { - OD_TOWNS, - OD_TYPE26, - OD_TYPE86 - }; - - TownsPC98_OpnCore(Audio::Mixer *mixer, OpnType type); - virtual ~TownsPC98_OpnCore(); - - virtual bool init(); - virtual void reset(); - - void writeReg(uint8 part, uint8 regAddress, uint8 value); - - // AudioStream interface - int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const { return true; } - bool endOfData() const { return false; } - int getRate() const { return _mixer->getOutputRate(); } - -protected: - void toggleRegProtection(bool prot) { _regProtectionFlag = prot; } - uint8 readSSGStatus() { return _ssg->chanEnable(); } - - virtual void timerCallbackA() = 0; - virtual void timerCallbackB() = 0; - - // The audio driver can store and apply two different audio settings - // (usually for music and sound effects). The channel mask will determine - // which channels get effected by the setting. The first bits will be - // the normal opn channels, the next bits the ssg channels and the final - // bit the rhythm channel. - void setVolumeIntern(int volA, int volB); - void setVolumeChannelMasks(int channelMaskA, int channelMaskB); - - const int _numChan; - const int _numSSG; - const bool _hasPercussion; - - Common::Mutex _mutex; -private: - void generateTables(); - void nextTick(int32 *buffer, uint32 bufferSize); - void generateOutput(int32 &leftSample, int32 &rightSample, int32 *del, int32 *feed); - - struct ChanInternal { - ChanInternal() { - memset(this, 0, sizeof(ChanInternal)); - } - - ~ChanInternal() { - for (uint i = 0; i < ARRAYSIZE(opr); ++i) - delete opr[i]; - } - - uint16 frqTemp; - bool enableLeft; - bool enableRight; - bool updateEnvelopeParameters; - int32 feedbuf[3]; - uint8 algorithm; - TownsPC98_OpnOperator *opr[4]; - }; - - TownsPC98_OpnSquareSineSource *_ssg; - TownsPC98_OpnPercussionSource *_prc; - ChanInternal *_chanInternal; - - uint8 *_oprRates; - uint8 *_oprRateshift; - uint8 *_oprAttackDecay; - uint32 *_oprFrq; - uint32 *_oprSinTbl; - int32 *_oprLevelOut; - int32 *_oprDetune; - - bool _regProtectionFlag; - - typedef void (TownsPC98_OpnCore::*OpnTimerProc)(); - - struct OpnTimer { - bool enabled; - uint16 value; - - int32 smpTillCb; - uint32 smpTillCbRem; - int32 smpPerCb; - uint32 smpPerCbRem; - - OpnTimerProc cb; - }; - - OpnTimer _timers[2]; - - int _volMaskA, _volMaskB; - uint16 _volumeA, _volumeB; - - const float _baserate; - uint32 _timerbase; - - Audio::Mixer *_mixer; - Audio::SoundHandle _soundHandle; - - static const uint8 _percussionData[]; - static const uint32 _adtStat[]; - static const uint8 _detSrc[]; - static const int _ssgTables[]; - - bool _ready; -}; - -class TownsPC98_OpnDriver : public TownsPC98_OpnCore { -friend class TownsPC98_OpnChannel; -friend class TownsPC98_OpnChannelSSG; -friend class TownsPC98_OpnSfxChannel; -friend class TownsPC98_OpnChannelPCM; -public: - TownsPC98_OpnDriver(Audio::Mixer *mixer, OpnType type); - ~TownsPC98_OpnDriver(); - - void loadMusicData(uint8 *data, bool loadPaused = false); - void loadSoundEffectData(uint8 *data, uint8 trackNum); - bool init(); - void reset(); - - void fadeStep(); - - void pause() { _musicPlaying = false; } - void cont() { _musicPlaying = true; } - - void timerCallbackB(); - void timerCallbackA(); - - bool looping() { return _looping == _updateChannelsFlag ? true : false; } - bool musicPlaying() { return _musicPlaying; } - - void setMusicVolume(int volume) { _musicVolume = volume; setVolumeIntern(_musicVolume, _sfxVolume); } - void setSoundEffectVolume(int volume) { _sfxVolume = volume; setVolumeIntern(_musicVolume, _sfxVolume); } - -protected: - void startSoundEffect(); - - void setMusicTempo(uint8 tempo); - void setSfxTempo(uint16 tempo); - - TownsPC98_OpnChannel **_channels; - TownsPC98_OpnChannelSSG **_ssgChannels; - TownsPC98_OpnSfxChannel **_sfxChannels; - TownsPC98_OpnChannelPCM *_rhythmChannel; - - const uint8 *_opnCarrier; - const uint8 *_opnFreqTable; - const uint8 *_opnFreqTableSSG; - const uint8 *_opnFxCmdLen; - const uint8 *_opnLvlPresets; - - uint8 *_musicBuffer; - uint8 *_sfxBuffer; - uint8 *_trackPtr; - uint8 *_patches; - uint8 *_ssgPatches; - - uint8 _updateChannelsFlag; - uint8 _updateSSGFlag; - uint8 _updateRhythmFlag; - uint8 _updateSfxFlag; - uint8 _finishedChannelsFlag; - uint8 _finishedSSGFlag; - uint8 _finishedRhythmFlag; - uint8 _finishedSfxFlag; - - bool _musicPlaying; - bool _sfxPlaying; - uint8 _fading; - uint8 _looping; - uint32 _musicTickCounter; - - int _sfxOffs; - uint8 *_sfxData; - uint16 _sfxOffsets[2]; - - uint16 _musicVolume; - uint16 _sfxVolume; - - static const uint8 _drvTables[]; - - bool _ready; -}; - -TownsPC98_OpnChannel::TownsPC98_OpnChannel(TownsPC98_OpnDriver *driver, uint8 regOffs, uint8 flgs, uint8 num, - uint8 key, uint8 prt, uint8 id) : _drv(driver), _regOffset(regOffs), _flags(flgs), _chanNum(num), _keyNum(key), - _part(prt), _idFlag(id), controlEvents(0) { - - _ticksLeft = _algorithm = _instr = _totalLevel = _frqBlockMSB = _keyOffTime = 0; - _ssgStartLvl = _ssgTl = _ssgStep = _ssgTicksLeft = _ssgTargetLvl = _block = 0; - _vbrInitDelayHi = _vbrInitDelayLo = _vbrDuration = _vbrCurDelay = _vbrDurLeft = 0; - _frqLSB = 0; - _hold = false; - _dataPtr = 0; - _vbrModInitVal = _vbrModCurVal = 0; - _frequency = 0; -} - -TownsPC98_OpnChannel::~TownsPC98_OpnChannel() { -} - -void TownsPC98_OpnChannel::init() { - #define Control(x) &TownsPC98_OpnChannel::control_##x - static const ControlEventFunc ctrlEvents[] = { - Control(f0_setPatch), - Control(f1_presetOutputLevel), - Control(f2_setKeyOffTime), - Control(f3_setFreqLSB), - Control(f4_setOutputLevel), - Control(f5_setTempo), - Control(f6_repeatSection), - Control(f7_setupVibrato), - Control(f8_toggleVibrato), - Control(dummy), - Control(fa_writeReg), - Control(fb_incOutLevel), - Control(fc_decOutLevel), - Control(fd_jump), - Control(dummy), - Control(ff_endOfTrack) - }; - #undef Control - - controlEvents = ctrlEvents; -} - -void TownsPC98_OpnChannel::keyOff() { - // all operators off - uint8 value = _keyNum & 0x0f; - if (_part) - value |= 4; - uint8 regAddress = 0x28; - _drv->writeReg(0, regAddress, value); - _flags |= CHS_KEYOFF; -} - -void TownsPC98_OpnChannel::keyOn() { - // all operators on - uint8 value = _keyNum | 0xf0; - if (_part) - value |= 4; - uint8 regAddress = 0x28; - _drv->writeReg(0, regAddress, value); -} - -void TownsPC98_OpnChannel::loadData(uint8 *data) { - _flags = (_flags & ~CHS_EOT) | CHS_ALLOFF; - _ticksLeft = 1; - _dataPtr = data; - _totalLevel = 0x7F; - - uint8 *tmp = _dataPtr; - for (bool loop = true; loop; ) { - uint8 cmd = *tmp++; - if (cmd < 0xf0) { - tmp++; - } else if (cmd == 0xff) { - if (READ_LE_UINT16(tmp)) { - _drv->_looping |= _idFlag; - tmp += _drv->_opnFxCmdLen[cmd - 240]; - } else - loop = false; - } else if (cmd == 0xf6) { - // reset repeat section countdown - tmp[0] = tmp[1]; - tmp += 4; - } else { - tmp += _drv->_opnFxCmdLen[cmd - 240]; - } - } -} - -void TownsPC98_OpnChannel::processEvents() { - if (_flags & CHS_EOT) - return; - - if (!_hold && _ticksLeft == _keyOffTime) - keyOff(); - - if (--_ticksLeft) - return; - - if (!_hold) - keyOff(); - - uint8 cmd = 0; - bool loop = true; - - while (loop) { - cmd = *_dataPtr++; - if (cmd < 0xf0) - loop = false; - else if (!processControlEvent(cmd)) - return; - } - - uint8 para = *_dataPtr++; - - if (cmd == 0x80) { - keyOff(); - _hold = false; - } else { - keyOn(); - - if (_hold == false || cmd != _frqBlockMSB) - _flags |= CHS_RECALCFREQ; - - _hold = (para & 0x80) ? true : false; - _frqBlockMSB = cmd; - } - - _ticksLeft = para & 0x7f; -} - -void TownsPC98_OpnChannel::processFrequency() { - if (_flags & CHS_RECALCFREQ) { - - _frequency = (((const uint16 *)_drv->_opnFreqTable)[_frqBlockMSB & 0x0f] + _frqLSB) | (((_frqBlockMSB & 0x70) >> 1) << 8); - - _drv->writeReg(_part, _regOffset + 0xa4, (_frequency >> 8)); - _drv->writeReg(_part, _regOffset + 0xa0, (_frequency & 0xff)); - - setupVibrato(); - } - - if (!(_flags & CHS_VBROFF)) { - if (!processVibrato()) - return; - - _drv->writeReg(_part, _regOffset + 0xa4, (_frequency >> 8)); - _drv->writeReg(_part, _regOffset + 0xa0, (_frequency & 0xff)); - } -} - -void TownsPC98_OpnChannel::setupVibrato() { - _vbrCurDelay = _vbrInitDelayHi; - if (_flags & CHS_KEYOFF) { - _vbrModCurVal = _vbrModInitVal; - _vbrCurDelay += _vbrInitDelayLo; - } - _vbrDurLeft = (_vbrDuration >> 1); - _flags &= ~(CHS_KEYOFF | CHS_RECALCFREQ); -} - -bool TownsPC98_OpnChannel::processVibrato() { - if (--_vbrCurDelay) - return false; - - _vbrCurDelay = _vbrInitDelayHi; - _frequency += _vbrModCurVal; - - if (!--_vbrDurLeft) { - _vbrDurLeft = _vbrDuration; - _vbrModCurVal = -_vbrModCurVal; - } - - return true; -} - -bool TownsPC98_OpnChannel::processControlEvent(uint8 cmd) { - uint8 para = *_dataPtr++; - return (this->*controlEvents[cmd & 0x0f])(para); -} - -void TownsPC98_OpnChannel::setOutputLevel() { - uint8 outopr = _drv->_opnCarrier[_algorithm]; - uint8 reg = 0x40 + _regOffset; - - for (int i = 0; i < 4; i++) { - if (outopr & 1) - _drv->writeReg(_part, reg, _totalLevel); - outopr >>= 1; - reg += 4; - } -} - -void TownsPC98_OpnChannel::fadeStep() { - _totalLevel += 3; - if (_totalLevel > 0x7f) - _totalLevel = 0x7f; - setOutputLevel(); -} - -void TownsPC98_OpnChannel::reset() { - _hold = false; - _keyOffTime = 0; - _ticksLeft = 1; - - _flags = (_flags & ~CHS_EOT) | CHS_ALLOFF; - - _totalLevel = 0; - _algorithm = 0; - _flags = CHS_EOT; - _algorithm = 0; - - _block = 0; - _frequency = 0; - _frqBlockMSB = 0; - _frqLSB = 0; - - _ssgTl = 0; - _ssgStartLvl = 0; - _ssgTargetLvl = 0; - _ssgStep = 0; - _ssgTicksLeft = 0; - - _vbrInitDelayHi = 0; - _vbrInitDelayLo = 0; - _vbrModInitVal = 0; - _vbrDuration = 0; - _vbrCurDelay = 0; - _vbrModCurVal = 0; - _vbrDurLeft = 0; -} - -bool TownsPC98_OpnChannel::control_f0_setPatch(uint8 para) { - _instr = para; - uint8 reg = _regOffset + 0x80; - - for (int i = 0; i < 4; i++) { - // set release rate for each operator - _drv->writeReg(_part, reg, 0x0f); - reg += 4; - } - - const uint8 *tptr = _drv->_patches + ((uint32)_instr << 5); - reg = _regOffset + 0x30; - - // write registers 0x30 to 0x8f - for (int i = 0; i < 6; i++) { - _drv->writeReg(_part, reg, tptr[0]); - reg += 4; - _drv->writeReg(_part, reg, tptr[2]); - reg += 4; - _drv->writeReg(_part, reg, tptr[1]); - reg += 4; - _drv->writeReg(_part, reg, tptr[3]); - reg += 4; - tptr += 4; - } - - reg = _regOffset + 0xB0; - _algorithm = tptr[0] & 7; - // set feedback and algorithm - _drv->writeReg(_part, reg, tptr[0]); - - setOutputLevel(); - return true; -} - -bool TownsPC98_OpnChannel::control_f1_presetOutputLevel(uint8 para) { - if (_drv->_fading) - return true; - - _totalLevel = _drv->_opnLvlPresets[para]; - setOutputLevel(); - return true; -} - -bool TownsPC98_OpnChannel::control_f2_setKeyOffTime(uint8 para) { - _keyOffTime = para; - return true; -} - -bool TownsPC98_OpnChannel::control_f3_setFreqLSB(uint8 para) { - _frqLSB = (int8) para; - return true; -} - -bool TownsPC98_OpnChannel::control_f4_setOutputLevel(uint8 para) { - if (_drv->_fading) - return true; - - _totalLevel = para; - setOutputLevel(); - return true; -} - -bool TownsPC98_OpnChannel::control_f5_setTempo(uint8 para) { - _drv->setMusicTempo(para); - return true; -} - -bool TownsPC98_OpnChannel::control_f6_repeatSection(uint8 para) { - _dataPtr--; - _dataPtr[0]--; - - if (*_dataPtr) { - // repeat section until counter has reached zero - _dataPtr = _drv->_trackPtr + READ_LE_UINT16(_dataPtr + 2); - } else { - // reset counter, advance to next section - _dataPtr[0] = _dataPtr[1]; - _dataPtr += 4; - } - return true; -} - -bool TownsPC98_OpnChannel::control_f7_setupVibrato(uint8 para) { - _vbrInitDelayHi = _dataPtr[0]; - _vbrInitDelayLo = para; - _vbrModInitVal = (int16) READ_LE_UINT16(_dataPtr + 1); - _vbrDuration = _dataPtr[3]; - _dataPtr += 4; - _flags = (_flags & ~CHS_VBROFF) | CHS_KEYOFF | CHS_RECALCFREQ; - return true; -} - -bool TownsPC98_OpnChannel::control_f8_toggleVibrato(uint8 para) { - if (para == 0x10) { - if (*_dataPtr++) { - _flags = (_flags & ~CHS_VBROFF) | CHS_KEYOFF; - } else { - _flags |= CHS_VBROFF; - } - } else { - /* NOT IMPLEMENTED - uint8 skipChannels = para / 36; - uint8 entry = para % 36; - TownsPC98_OpnDriver::TownsPC98_OpnChannel *t = &chan[skipChannels]; - - t->unnamedEntries[entry] = *_dataPtr++;*/ - } - return true; -} - -bool TownsPC98_OpnChannel::control_fa_writeReg(uint8 para) { - _drv->writeReg(_part, para, *_dataPtr++); - return true; -} - -bool TownsPC98_OpnChannel::control_fb_incOutLevel(uint8 para) { - _dataPtr--; - if (_drv->_fading) - return true; - - uint8 val = (_totalLevel + 3); - if (val > 0x7f) - val = 0x7f; - - _totalLevel = val; - setOutputLevel(); - return true; -} - -bool TownsPC98_OpnChannel::control_fc_decOutLevel(uint8 para) { - _dataPtr--; - if (_drv->_fading) - return true; - - int8 val = (int8) (_totalLevel - 3); - if (val < 0) - val = 0; - - _totalLevel = (uint8) val; - setOutputLevel(); - return true; -} - -bool TownsPC98_OpnChannel::control_fd_jump(uint8 para) { - uint8 *tmp = _drv->_trackPtr + READ_LE_UINT16(_dataPtr - 1); - _dataPtr = (tmp[1] == 1) ? tmp : (_dataPtr + 1); - return true; -} - -bool TownsPC98_OpnChannel::control_dummy(uint8 para) { - _dataPtr--; - return true; -} - -bool TownsPC98_OpnChannel::control_ff_endOfTrack(uint8 para) { - uint16 val = READ_LE_UINT16(--_dataPtr); - if (val) { - // loop - _dataPtr = _drv->_trackPtr + val; - return true; - } else { - // quit parsing for active channel - --_dataPtr; - _flags |= CHS_EOT; - _drv->_finishedChannelsFlag |= _idFlag; - keyOff(); - return false; - } -} - -TownsPC98_OpnChannelSSG::TownsPC98_OpnChannelSSG(TownsPC98_OpnDriver *driver, uint8 regOffs, - uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id) : - TownsPC98_OpnChannel(driver, regOffs, flgs, num, key, prt, id), controlEvents(0) { -} - -void TownsPC98_OpnChannelSSG::init() { - _algorithm = 0x80; - - #define Control(x) &TownsPC98_OpnChannelSSG::control_##x - static const ControlEventFunc ctrlEventsSSG[] = { - Control(f0_setPatch), - Control(f1_setTotalLevel), - Control(f2_setKeyOffTime), - Control(f3_setFreqLSB), - Control(f4_setAlgorithm), - Control(f5_setTempo), - Control(f6_repeatSection), - Control(f7_setupVibrato), - Control(f8_toggleVibrato), - Control(f9_loadCustomPatch), - Control(fa_writeReg), - Control(fb_incOutLevel), - Control(fc_decOutLevel), - Control(fd_jump), - Control(dummy), - Control(ff_endOfTrack) - }; - #undef Control - - controlEvents = ctrlEventsSSG; -} - -void TownsPC98_OpnChannelSSG::processEvents() { - if (_flags & CHS_EOT) - return; - - _drv->toggleRegProtection(_flags & CHS_PROTECT ? true : false); - - if (!_hold && _ticksLeft == _keyOffTime) - nextShape(); - - if (!--_ticksLeft) { - - uint8 cmd = 0; - bool loop = true; - - while (loop) { - cmd = *_dataPtr++; - if (cmd < 0xf0) - loop = false; - else if (!processControlEvent(cmd)) - return; - } - - uint8 para = *_dataPtr++; - - if (cmd == 0x80) { - nextShape(); - _hold = false; - } else { - if (!_hold) { - _instr &= 0xf0; - _ssgStep = _drv->_ssgPatches[_instr]; - _ssgTicksLeft = _drv->_ssgPatches[_instr + 1] & 0x7f; - _ssgTargetLvl = _drv->_ssgPatches[_instr + 2]; - _ssgStartLvl = _drv->_ssgPatches[_instr + 3]; - _flags = (_flags & ~CHS_SSGOFF) | CHS_KEYOFF; - } - - keyOn(); - - if (_hold == false || cmd != _frqBlockMSB) - _flags |= CHS_RECALCFREQ; - - _hold = (para & 0x80) ? true : false; - _frqBlockMSB = cmd; - } - - _ticksLeft = para & 0x7f; - } - - if (!(_flags & CHS_SSGOFF)) { - if (--_ssgTicksLeft) { - if (!_drv->_fading) - setOutputLevel(_ssgStartLvl); - return; - } - - _ssgTicksLeft = _drv->_ssgPatches[_instr + 1] & 0x7f; - - if (_drv->_ssgPatches[_instr + 1] & 0x80) { - uint8 t = _ssgStartLvl - _ssgStep; - - if (_ssgStep <= _ssgStartLvl && _ssgTargetLvl < t) { - if (!_drv->_fading) - setOutputLevel(t); - return; - } - } else { - int t = _ssgStartLvl + _ssgStep; - uint8 p = (uint8) (t & 0xff); - - if (t < 256 && _ssgTargetLvl > p) { - if (!_drv->_fading) - setOutputLevel(p); - return; - } - } - - setOutputLevel(_ssgTargetLvl); - if (_ssgStartLvl && !(_instr & 8)){ - _instr += 4; - _ssgStep = _drv->_ssgPatches[_instr]; - _ssgTicksLeft = _drv->_ssgPatches[_instr + 1] & 0x7f; - _ssgTargetLvl = _drv->_ssgPatches[_instr + 2]; - } else { - _flags |= CHS_SSGOFF; - setOutputLevel(0); - } - } -} - -void TownsPC98_OpnChannelSSG::processFrequency() { - if (_algorithm & 0x40) - return; - - if (_flags & CHS_RECALCFREQ) { - _block = _frqBlockMSB >> 4; - _frequency = ((const uint16 *)_drv->_opnFreqTableSSG)[_frqBlockMSB & 0x0f] + _frqLSB; - - uint16 f = _frequency >> _block; - _drv->writeReg(_part, _regOffset << 1, f & 0xff); - _drv->writeReg(_part, (_regOffset << 1) + 1, f >> 8); - - setupVibrato(); - } - - if (!(_flags & (CHS_EOT | CHS_VBROFF | CHS_SSGOFF))) { - if (!processVibrato()) - return; - - uint16 f = _frequency >> _block; - _drv->writeReg(_part, _regOffset << 1, f & 0xff); - _drv->writeReg(_part, (_regOffset << 1) + 1, f >> 8); - } -} - -bool TownsPC98_OpnChannelSSG::processControlEvent(uint8 cmd) { - uint8 para = *_dataPtr++; - return (this->*controlEvents[cmd & 0x0f])(para); -} - -void TownsPC98_OpnChannelSSG::nextShape() { - _instr = (_instr & 0xf0) + 0x0c; - _ssgStep = _drv->_ssgPatches[_instr]; - _ssgTicksLeft = _drv->_ssgPatches[_instr + 1] & 0x7f; - _ssgTargetLvl = _drv->_ssgPatches[_instr + 2]; -} - -void TownsPC98_OpnChannelSSG::keyOn() { - uint8 c = 0x7b; - uint8 t = (_algorithm & 0xC0) << 1; - if (_algorithm & 0x80) - t |= 4; - - c = (c << (_regOffset + 1)) | (c >> (7 - _regOffset)); - t = (t << (_regOffset + 1)) | (t >> (7 - _regOffset)); - - if (!(_algorithm & 0x80)) - _drv->writeReg(_part, 6, _algorithm & 0x7f); - - uint8 e = (_drv->readSSGStatus() & c) | t; - _drv->writeReg(_part, 7, e); -} - -void TownsPC98_OpnChannelSSG::protect() { - _flags |= CHS_PROTECT; -} - -void TownsPC98_OpnChannelSSG::restore() { - _flags &= ~CHS_PROTECT; - keyOn(); - _drv->writeReg(_part, 8 + _regOffset, _ssgTl); - uint16 f = _frequency >> _block; - _drv->writeReg(_part, _regOffset << 1, f & 0xff); - _drv->writeReg(_part, (_regOffset << 1) + 1, f >> 8); -} - -void TownsPC98_OpnChannelSSG::loadData(uint8 *data) { - _drv->toggleRegProtection(_flags & CHS_PROTECT ? true : false); - TownsPC98_OpnChannel::loadData(data); - setOutputLevel(0); - _algorithm = 0x80; -} - -void TownsPC98_OpnChannelSSG::setOutputLevel(uint8 lvl) { - _ssgStartLvl = lvl; - uint16 newTl = (((uint16)_totalLevel + 1) * (uint16)lvl) >> 8; - if (newTl == _ssgTl) - return; - _ssgTl = newTl; - _drv->writeReg(_part, 8 + _regOffset, _ssgTl); -} - -void TownsPC98_OpnChannelSSG::reset() { - TownsPC98_OpnChannel::reset(); - - // Unlike the original we restore the default patch data. This fixes a bug - // where certain sound effects would bring each other out of tune (e.g. the - // dragon's fire in Darm's house in Kyra 1 would sound different each time - // you triggered another sfx by dropping an item etc.) - uint8 i = (10 + _regOffset) << 4; - const uint8 *src = &_drv->_drvTables[156]; - _drv->_ssgPatches[i] = src[i]; - _drv->_ssgPatches[i + 3] = src[i + 3]; - _drv->_ssgPatches[i + 4] = src[i + 4]; - _drv->_ssgPatches[i + 6] = src[i + 6]; - _drv->_ssgPatches[i + 8] = src[i + 8]; - _drv->_ssgPatches[i + 12] = src[i + 12]; -} - -void TownsPC98_OpnChannelSSG::fadeStep() { - _totalLevel--; - if ((int8)_totalLevel < 0) - _totalLevel = 0; - setOutputLevel(_ssgStartLvl); -} - -bool TownsPC98_OpnChannelSSG::control_f0_setPatch(uint8 para) { - _instr = para << 4; - para = (para >> 3) & 0x1e; - if (para) - return control_f4_setAlgorithm(para | 0x40); - return true; -} - -bool TownsPC98_OpnChannelSSG::control_f1_setTotalLevel(uint8 para) { - if (!_drv->_fading) - _totalLevel = para; - return true; -} - -bool TownsPC98_OpnChannelSSG::control_f4_setAlgorithm(uint8 para) { - _algorithm = para; - return true; -} - -bool TownsPC98_OpnChannelSSG::control_f9_loadCustomPatch(uint8 para) { - _instr = (_drv->_sfxOffs + 10 + _regOffset) << 4; - _drv->_ssgPatches[_instr] = *_dataPtr++; - _drv->_ssgPatches[_instr + 3] = para; - _drv->_ssgPatches[_instr + 4] = *_dataPtr++; - _drv->_ssgPatches[_instr + 6] = *_dataPtr++; - _drv->_ssgPatches[_instr + 8] = *_dataPtr++; - _drv->_ssgPatches[_instr + 12] = *_dataPtr++; - return true; -} - -bool TownsPC98_OpnChannelSSG::control_fb_incOutLevel(uint8 para) { - _dataPtr--; - if (_drv->_fading) - return true; - - _totalLevel--; - if ((int8)_totalLevel < 0) - _totalLevel = 0; - - return true; -} - -bool TownsPC98_OpnChannelSSG::control_fc_decOutLevel(uint8 para) { - _dataPtr--; - if (_drv->_fading) - return true; - - if (_totalLevel + 1 < 0x10) - _totalLevel++; - - return true; -} - -bool TownsPC98_OpnChannelSSG::control_ff_endOfTrack(uint8 para) { - if (!_drv->_sfxOffs) { - uint16 val = READ_LE_UINT16(--_dataPtr); - if (val) { - // loop - _dataPtr = _drv->_trackPtr + val; - return true; - } else { - // stop parsing - if (!_drv->_fading) - setOutputLevel(0); - --_dataPtr; - _flags |= CHS_EOT; - _drv->_finishedSSGFlag |= _idFlag; - } - } else { - // end of sfx track - restore ssg music channel - _flags |= CHS_EOT; - _drv->_finishedSfxFlag |= _idFlag; - _drv->_ssgChannels[_chanNum]->restore(); - } - - return false; -} - -void TownsPC98_OpnSfxChannel::loadData(uint8 *data) { - _flags = CHS_ALLOFF; - _ticksLeft = 1; - _dataPtr = data; - _ssgTl = 0xff; - _algorithm = 0x80; - - uint8 *tmp = _dataPtr; - for (bool loop = true; loop; ) { - uint8 cmd = *tmp++; - if (cmd < 0xf0) { - tmp++; - } else if (cmd == 0xff) { - loop = false; - } else if (cmd == 0xf6) { - // reset repeat section countdown - tmp[0] = tmp[1]; - tmp += 4; - } else { - tmp += _drv->_opnFxCmdLen[cmd - 240]; - } - } -} - -void TownsPC98_OpnSfxChannel::reset() { - TownsPC98_OpnChannel::reset(); - - // Unlike the original we restore the default patch data. This fixes a bug - // where certain sound effects would bring each other out of tune (e.g. the - // dragon's fire in Darm's house in Kyra 1 would sound different each time - // you triggered another sfx by dropping an item etc.) - uint8 i = (13 + _regOffset) << 4; - const uint8 *src = &_drv->_drvTables[156]; - _drv->_ssgPatches[i] = src[i]; - _drv->_ssgPatches[i + 3] = src[i + 3]; - _drv->_ssgPatches[i + 4] = src[i + 4]; - _drv->_ssgPatches[i + 6] = src[i + 6]; - _drv->_ssgPatches[i + 8] = src[i + 8]; - _drv->_ssgPatches[i + 12] = src[i + 12]; -} - -TownsPC98_OpnChannelPCM::TownsPC98_OpnChannelPCM(TownsPC98_OpnDriver *driver, uint8 regOffs, - uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id) : - TownsPC98_OpnChannel(driver, regOffs, flgs, num, key, prt, id), controlEvents(0) { -} - -void TownsPC98_OpnChannelPCM::init() { - _algorithm = 0x80; - - #define Control(x) &TownsPC98_OpnChannelPCM::control_##x - static const ControlEventFunc ctrlEventsPCM[] = { - Control(dummy), - Control(f1_prcStart), - Control(dummy), - Control(dummy), - Control(dummy), - Control(dummy), - Control(f6_repeatSection), - Control(dummy), - Control(dummy), - Control(dummy), - Control(fa_writeReg), - Control(dummy), - Control(dummy), - Control(dummy), - Control(dummy), - Control(ff_endOfTrack) - }; - #undef Control - - controlEvents = ctrlEventsPCM; -} - -void TownsPC98_OpnChannelPCM::loadData(uint8 *data) { - _flags = (_flags & ~CHS_EOT) | CHS_ALLOFF; - _ticksLeft = 1; - _dataPtr = data; - _totalLevel = 0x7F; -} - -void TownsPC98_OpnChannelPCM::processEvents() { - if (_flags & CHS_EOT) - return; - - if (--_ticksLeft) - return; - - uint8 cmd = 0; - bool loop = true; - - while (loop) { - cmd = *_dataPtr++; - if (cmd == 0x80) { - loop = false; - } else if (cmd < 0xf0) { - _drv->writeReg(_part, 0x10, cmd); - } else if (!processControlEvent(cmd)) { - return; - } - } - - _ticksLeft = *_dataPtr++; -} - -bool TownsPC98_OpnChannelPCM::processControlEvent(uint8 cmd) { - uint8 para = *_dataPtr++; - return (this->*controlEvents[cmd & 0x0f])(para); -} - -bool TownsPC98_OpnChannelPCM::control_f1_prcStart(uint8 para) { - _totalLevel = para; - _drv->writeReg(_part, 0x11, para); - return true; -} - -bool TownsPC98_OpnChannelPCM::control_ff_endOfTrack(uint8 para) { - uint16 val = READ_LE_UINT16(--_dataPtr); - if (val) { - // loop - _dataPtr = _drv->_trackPtr + val; - return true; - } else { - // quit parsing for active channel - --_dataPtr; - _flags |= CHS_EOT; - _drv->_finishedRhythmFlag |= _idFlag; - return false; - } -} - -TownsPC98_OpnSquareSineSource::TownsPC98_OpnSquareSineSource(const uint32 timerbase) : _tlTable(0), - _tleTable(0), _updateRequest(-1), _tickLength(timerbase * 27), _ready(0), _reg(0), _rand(1), _outN(1), - _nTick(0), _evpUpdateCnt(0), _evpTimer(0x1f), _pReslt(0x1f), _attack(0), _cont(false), _evpUpdate(true), - _timer(0), _noiseGenerator(0), _chanEnable(0), - _volMaskA(0), _volMaskB(0), _volumeA(Audio::Mixer::kMaxMixerVolume), _volumeB(Audio::Mixer::kMaxMixerVolume) { - - memset(_channels, 0, sizeof(_channels)); - memset(_updateRequestBuf, 0, sizeof(_updateRequestBuf)); - _reg = new uint8 *[11]; - - _reg[0] = &_channels[0].frqL; - _reg[1] = &_channels[0].frqH; - _reg[2] = &_channels[1].frqL; - _reg[3] = &_channels[1].frqH; - _reg[4] = &_channels[2].frqL; - _reg[5] = &_channels[2].frqH; - _reg[6] = &_noiseGenerator; - _reg[7] = &_chanEnable; - _reg[8] = &_channels[0].vol; - _reg[9] = &_channels[1].vol; - _reg[10] = &_channels[2].vol; - - reset(); -} - -TownsPC98_OpnSquareSineSource::~TownsPC98_OpnSquareSineSource() { - delete[] _tlTable; - delete[] _tleTable; - delete[] _reg; -} - -void TownsPC98_OpnSquareSineSource::init(const int *rsTable, const int *rseTable) { - if (_ready) { - reset(); - return; - } - - delete[] _tlTable; - delete[] _tleTable; - _tlTable = new int32[16]; - _tleTable = new int32[32]; - float a, b, d; - d = 801.0f; - - for (int i = 0; i < 16; i++) { - b = 1.0f / rsTable[i]; - a = 1.0f / d + b + 1.0f / 1000.0f; - float v = (b / a) * 32767.0f; - _tlTable[i] = (int32) v; - - b = 1.0f / rseTable[i]; - a = 1.0f / d + b + 1.0f / 1000.0f; - v = (b / a) * 32767.0f; - _tleTable[i] = (int32) v; - } - - for (int i = 16; i < 32; i++) { - b = 1.0f / rseTable[i]; - a = 1.0f / d + b + 1.0f / 1000.0f; - float v = (b / a) * 32767.0f; - _tleTable[i] = (int32) v; - } - - _ready = true; -} - -void TownsPC98_OpnSquareSineSource::reset() { - _rand = 1; - _outN = 1; - _updateRequest = -1; - _nTick = _evpUpdateCnt = 0; - _evpTimer = 0x1f; - _pReslt = 0x1f; - _attack = 0; - _cont = false; - _evpUpdate = true; - _timer = 0; - - for (int i = 0; i < 3; i++) { - _channels[i].tick = 0; - _channels[i].smp = _channels[i].out = 0; - } - - for (int i = 0; i < 14; i++) - writeReg(i, 0, true); - - writeReg(7, 0xbf, true); -} - -void TownsPC98_OpnSquareSineSource::writeReg(uint8 address, uint8 value, bool force) { - if (!_ready) - return; - - if (address > 10 || *_reg[address] == value) { - if ((address == 11 || address == 12 || address == 13) && value) - warning("TownsPC98_OpnSquareSineSource: unsupported reg address: %d", address); - return; - } - - if (!force) { - if (_updateRequest >= 63) { - warning("TownsPC98_OpnSquareSineSource: event buffer overflow"); - _updateRequest = -1; - } - _updateRequestBuf[++_updateRequest] = value; - _updateRequestBuf[++_updateRequest] = address; - return; - } - - *_reg[address] = value; -} - -void TownsPC98_OpnSquareSineSource::nextTick(int32 *buffer, uint32 bufferSize) { - if (!_ready) - return; - - for (uint32 i = 0; i < bufferSize; i++) { - _timer += _tickLength; - while (_timer > 0x5B8D80) { - _timer -= 0x5B8D80; - - if (++_nTick >= (_noiseGenerator & 0x1f)) { - if ((_rand + 1) & 2) - _outN ^= 1; - - _rand = (((_rand & 1) ^ ((_rand >> 3) & 1)) << 16) | (_rand >> 1); - _nTick = 0; - } - - for (int ii = 0; ii < 3; ii++) { - if (++_channels[ii].tick >= (((_channels[ii].frqH & 0x0f) << 8) | _channels[ii].frqL)) { - _channels[ii].tick = 0; - _channels[ii].smp ^= 1; - } - _channels[ii].out = (_channels[ii].smp | ((_chanEnable >> ii) & 1)) & (_outN | ((_chanEnable >> (ii + 3)) & 1)); - } - - if (_evpUpdate) { - if (++_evpUpdateCnt >= 0) { - _evpUpdateCnt = 0; - - if (--_evpTimer < 0) { - if (_cont) { - _evpTimer &= 0x1f; - } else { - _evpUpdate = false; - _evpTimer = 0; - } - } - } - } - _pReslt = _evpTimer ^ _attack; - updateRegs(); - } - - int32 finOut = 0; - for (int ii = 0; ii < 3; ii++) { - int32 finOutTemp = ((_channels[ii].vol >> 4) & 1) ? _tleTable[_channels[ii].out ? _pReslt : 0] : _tlTable[_channels[ii].out ? (_channels[ii].vol & 0x0f) : 0]; - - if ((1 << ii) & _volMaskA) - finOutTemp = (finOutTemp * _volumeA) / Audio::Mixer::kMaxMixerVolume; - - if ((1 << ii) & _volMaskB) - finOutTemp = (finOutTemp * _volumeB) / Audio::Mixer::kMaxMixerVolume; - - finOut += finOutTemp; - } - - finOut /= 3; - - buffer[i << 1] += finOut; - buffer[(i << 1) + 1] += finOut; - } -} - -void TownsPC98_OpnSquareSineSource::updateRegs() { - for (int i = 0; i < _updateRequest;) { - uint8 b = _updateRequestBuf[i++]; - uint8 a = _updateRequestBuf[i++]; - writeReg(a, b, true); - } - _updateRequest = -1; -} - -TownsPC98_OpnPercussionSource::TownsPC98_OpnPercussionSource(const uint32 timerbase) : - _tickLength(timerbase * 2), _timer(0), _ready(false), _volMaskA(0), _volMaskB(0), _volumeA(Audio::Mixer::kMaxMixerVolume), _volumeB(Audio::Mixer::kMaxMixerVolume) { - - memset(_rhChan, 0, sizeof(RhtChannel) * 6); - _reg = new uint8 *[40]; - - _reg[0] = _reg[1] = _reg[2] = _reg[3] = _reg[4] = _reg[5] = _reg[6] = _reg[7] = _reg[8] = _reg[9] = _reg[10] = _reg[11] = _reg[12] = _reg[13] = _reg[14] = _reg[15] = 0; - _reg[16] = &_rhChan[0].startPosL; - _reg[17] = &_rhChan[1].startPosL; - _reg[18] = &_rhChan[2].startPosL; - _reg[19] = &_rhChan[3].startPosL; - _reg[20] = &_rhChan[4].startPosL; - _reg[21] = &_rhChan[5].startPosL; - _reg[22] = &_rhChan[0].startPosH; - _reg[23] = &_rhChan[1].startPosH; - _reg[24] = &_rhChan[2].startPosH; - _reg[25] = &_rhChan[3].startPosH; - _reg[26] = &_rhChan[4].startPosH; - _reg[27] = &_rhChan[5].startPosH; - _reg[28] = &_rhChan[0].endPosL; - _reg[29] = &_rhChan[1].endPosL; - _reg[30] = &_rhChan[2].endPosL; - _reg[31] = &_rhChan[3].endPosL; - _reg[32] = &_rhChan[4].endPosL; - _reg[33] = &_rhChan[5].endPosL; - _reg[34] = &_rhChan[0].endPosH; - _reg[35] = &_rhChan[1].endPosH; - _reg[36] = &_rhChan[2].endPosH; - _reg[37] = &_rhChan[3].endPosH; - _reg[38] = &_rhChan[4].endPosH; - _reg[39] = &_rhChan[5].endPosH; -} - -void TownsPC98_OpnPercussionSource::init(const uint8 *instrData) { - if (_ready) { - reset(); - return; - } - - const uint8 *start = instrData; - const uint8 *pos = start; - - if (instrData) { - for (int i = 0; i < 6; i++) { - _rhChan[i].data = start + READ_BE_UINT16(pos); - pos += 2; - _rhChan[i].size = READ_BE_UINT16(pos); - pos += 2; - } - reset(); - _ready = true; - } else { - memset(_rhChan, 0, sizeof(RhtChannel) * 6); - _ready = false; - } -} - -void TownsPC98_OpnPercussionSource::reset() { - _timer = 0; - _totalLevel = 63; - - for (int i = 0; i < 6; i++) { - RhtChannel *s = &_rhChan[i]; - s->pos = s->start = s->data; - s->end = s->data + s->size; - s->active = false; - s->level = 0; - s->out = 0; - s->decStep = 1; - s->decState = 0; - s->samples[0] = s->samples[1] = 0; - s->startPosH = s->startPosL = s->endPosH = s->endPosL = 0; - } -} - -void TownsPC98_OpnPercussionSource::writeReg(uint8 address, uint8 value) { - if (!_ready) - return; - - uint8 h = address >> 4; - uint8 l = address & 15; - - if (address > 15) - *_reg[address] = value; - - if (address == 0) { - if (value & 0x80) { - //key off - for (int i = 0; i < 6; i++) { - if ((value >> i) & 1) - _rhChan[i].active = false; - } - } else { - //key on - for (int i = 0; i < 6; i++) { - if ((value >> i) & 1) { - RhtChannel *s = &_rhChan[i]; - s->pos = s->start; - s->active = true; - s->out = 0; - s->samples[0] = s->samples[1] = 0; - s->decStep = 1; - s->decState = 0; - } - } - } - } else if (address == 1) { - // total level - _totalLevel = (value & 63) ^ 63; - for (int i = 0; i < 6; i++) - recalcOuput(&_rhChan[i]); - } else if (!h && l & 8) { - // instrument level - l &= 7; - _rhChan[l].level = (value & 0x1f) ^ 0x1f; - recalcOuput(&_rhChan[l]); - } else if (h & 3) { - l &= 7; - if (h == 1) { - // set start offset - _rhChan[l].start = _rhChan[l].data + ((_rhChan[l].startPosH << 8 | _rhChan[l].startPosL) << 8); - } else if (h == 2) { - // set end offset - _rhChan[l].end = _rhChan[l].data + ((_rhChan[l].endPosH << 8 | _rhChan[l].endPosL) << 8) + 255; - } - } -} - -void TownsPC98_OpnPercussionSource::nextTick(int32 *buffer, uint32 bufferSize) { - if (!_ready) - return; - - for (uint32 i = 0; i < bufferSize; i++) { - _timer += _tickLength; - while (_timer > 0x5B8D80) { - _timer -= 0x5B8D80; - - for (int ii = 0; ii < 6; ii++) { - RhtChannel *s = &_rhChan[ii]; - if (s->active) { - recalcOuput(s); - if (s->decStep) { - advanceInput(s); - if (s->pos == s->end) - s->active = false; - } - s->decStep ^= 1; - } - } - } - - int32 finOut = 0; - - for (int ii = 0; ii < 6; ii++) { - if (_rhChan[ii].active) - finOut += _rhChan[ii].out; - } - - finOut <<= 1; - - if (1 & _volMaskA) - finOut = (finOut * _volumeA) / Audio::Mixer::kMaxMixerVolume; - - if (1 & _volMaskB) - finOut = (finOut * _volumeB) / Audio::Mixer::kMaxMixerVolume; - - buffer[i << 1] += finOut; - buffer[(i << 1) + 1] += finOut; - } -} - -void TownsPC98_OpnPercussionSource::recalcOuput(RhtChannel *ins) { - uint32 s = _totalLevel + ins->level; - uint32 x = s > 62 ? 0 : (1 + (s >> 3)); - int32 y = s > 62 ? 0 : (15 - (s & 7)); - ins->out = ((ins->samples[ins->decStep] * y) >> x) & ~3; -} - -void TownsPC98_OpnPercussionSource::advanceInput(RhtChannel *ins) { - static const int8 adjustIndex[] = {-1, -1, -1, -1, 2, 5, 7, 9 }; - - static const int16 stepTable[] = { 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, - 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, - 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552 - }; - - uint8 cur = (int8) *ins->pos++; - - for (int i = 0; i < 2; i++) { - int b = (2 * (cur & 7) + 1) * stepTable[ins->decState] / 8; - ins->samples[i] = CLIP<int16>(ins->samples[i ^ 1] + (cur & 8 ? b : -b), -2048, 2047); - ins->decState = CLIP<int8>(ins->decState + adjustIndex[cur & 7], 0, 48); - cur >>= 4; - } -} - -TownsPC98_OpnCore::TownsPC98_OpnCore(Audio::Mixer *mixer, OpnType type) : - _mixer(mixer), - _chanInternal(0), _ssg(0), _prc(0), - _numChan(type == OD_TYPE26 ? 3 : 6), _numSSG(type == OD_TOWNS ? 0 : 3), _hasPercussion(type == OD_TYPE86 ? true : false), - _oprRates(0), _oprRateshift(0), _oprAttackDecay(0), _oprFrq(0), _oprSinTbl(0), _oprLevelOut(0), _oprDetune(0), - _baserate(55125.0f / (float)mixer->getOutputRate()), - _volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), - _regProtectionFlag(false), _ready(false) { - - memset(&_timers[0], 0, sizeof(OpnTimer)); - memset(&_timers[1], 0, sizeof(OpnTimer)); - _timers[0].cb = &TownsPC98_OpnCore::timerCallbackA; - _timers[1].cb = &TownsPC98_OpnCore::timerCallbackB; - _timerbase = (uint32)(_baserate * 1000000.0f); -} - -TownsPC98_OpnCore::~TownsPC98_OpnCore() { - Common::StackLock lock(_mutex); - _mixer->stopHandle(_soundHandle); - delete _ssg; - delete _prc; - delete[] _chanInternal; - - delete[] _oprRates; - delete[] _oprRateshift; - delete[] _oprFrq; - delete[] _oprAttackDecay; - delete[] _oprSinTbl; - delete[] _oprLevelOut; - delete[] _oprDetune; -} - -bool TownsPC98_OpnCore::init() { - if (_ready) { - reset(); - return true; - } - - generateTables(); - - _chanInternal = new ChanInternal[_numChan]; - for (int i = 0; i < _numChan; i++) { - memset(&_chanInternal[i], 0, sizeof(ChanInternal)); - for (int j = 0; j < 4; ++j) - _chanInternal[i].opr[j] = new TownsPC98_OpnOperator(_timerbase, _oprRates, _oprRateshift, _oprAttackDecay, _oprFrq, _oprSinTbl, _oprLevelOut, _oprDetune); - } - - if (_numSSG) { - _ssg = new TownsPC98_OpnSquareSineSource(_timerbase); - _ssg->init(&_ssgTables[0], &_ssgTables[16]); - } - - if (_hasPercussion) { - _prc = new TownsPC98_OpnPercussionSource(_timerbase); - _prc->init(_percussionData); - } - - _mixer->playStream(Audio::Mixer::kPlainSoundType, - &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); - - _ready = true; - - return true; -} - -void TownsPC98_OpnCore::reset() { - for (int i = 0; i < _numChan; i++) { - for (int ii = 0; ii < 4; ii++) - _chanInternal[i].opr[ii]->reset(); - memset(_chanInternal[i].feedbuf, 0, 3); - _chanInternal[i].algorithm = 0; - _chanInternal[i].frqTemp = 0; - _chanInternal[i].enableLeft = _chanInternal[i].enableRight = true; - _chanInternal[i].updateEnvelopeParameters = false; - } - - writeReg(0, 0x27, 0x33); - - if (_ssg) - _ssg->reset(); - - if (_prc) - _prc->reset(); -} - -void TownsPC98_OpnCore::writeReg(uint8 part, uint8 regAddress, uint8 value) { - if (_regProtectionFlag || !_ready) - return; - - static const uint8 oprOrdr[] = { 0, 2, 1, 3 }; - - uint8 h = regAddress & 0xf0; - uint8 l = (regAddress & 0x0f); - - ChanInternal *c = 0; - TownsPC98_OpnOperator **co = 0; - TownsPC98_OpnOperator *o = 0; - - if (regAddress > 0x2F) { - c = &_chanInternal[(l & 3) + 3 * part]; - co = c->opr; - o = c->opr[oprOrdr[(l - (l & 3)) >> 2]]; - } else if (regAddress == 0x28) { - c = &_chanInternal[(value & 3) + ((value & 4) ? 3 : 0)]; - co = c->opr; - } - - switch (h) { - case 0x00: - // ssg - if (_ssg) - _ssg->writeReg(l, value); - break; - case 0x10: - // pcm rhythm channel - if (_prc) - _prc->writeReg(l, value); - break; - case 0x20: - if (l == 8) { - // Key on/off - for (int i = 0; i < 4; i++) { - if ((value >> (4 + i)) & 1) - co[oprOrdr[i]]->keyOn(); - else - co[oprOrdr[i]]->keyOff(); - } - } else if (l == 4) { - // Timer A - _timers[0].value = (_timers[0].value & 0xff00) | value; - } else if (l == 5) { - // Timer A - _timers[0].value = (_timers[0].value & 0xff) | (value << 8); - } else if (l == 6) { - // Timer B - _timers[1].value = value & 0xff; - } else if (l == 7) { - _timers[0].enabled = (value & 1) ? 1 : 0; - _timers[1].enabled = (value & 2) ? 1 : 0; - - float spc = (float)(0x400 - _timers[0].value) / _baserate; - _timers[0].smpPerCb = (int32) spc; - _timers[0].smpPerCbRem = (uint32) ((spc - (float)_timers[0].smpPerCb) * 1000000.0f); - - spc = (float)(0x100 - _timers[1].value) * 16.0f / _baserate; - _timers[1].smpPerCb = (int32) spc; - _timers[1].smpPerCbRem = (uint32) ((spc - (float)_timers[1].smpPerCb) * 1000000.0f); - - if (value & 10) { - _timers[0].smpTillCb = _timers[0].smpPerCb; - _timers[0].smpTillCbRem = _timers[0].smpTillCbRem; - } - - if (value & 20) { - _timers[1].smpTillCb = _timers[1].smpPerCb; - _timers[1].smpTillCbRem = _timers[1].smpTillCbRem; - } - } else if (l == 2) { - // LFO - warning("TownsPC98_OpnDriver: TRYING TO USE LFO (NOT SUPPORTED)"); - } else if (l == 10 || l == 11) { - // DAC - warning("TownsPC98_OpnDriver: TRYING TO USE DAC (NOT SUPPORTED)"); - } - break; - - case 0x30: - // detune, multiple - o->detune((value >> 4) & 7); - o->multiple(value & 0x0f); - c->updateEnvelopeParameters = true; - break; - - case 0x40: - // total level - o->totalLevel(value & 0x7f); - break; - - case 0x50: - // rate scaling, attack rate - o->attackRate(value & 0x1f); - if (o->scaleRate(value >> 6)) - c->updateEnvelopeParameters = true; - break; - - case 0x60: - // first decay rate, amplitude modulation - o->decayRate(value & 0x1f); - if (value & 0x80) - warning("TownsPC98_OpnDriver: TRYING TO USE AMP MODULATION (NOT SUPPORTED)"); - break; - - case 0x70: - // secondary decay rate - o->sustainRate(value & 0x1f); - break; - - case 0x80: - // secondary amplitude, release rate; - o->sustainLevel(value >> 4); - o->releaseRate(value & 0x0f); - break; - - case 0x90: - warning("TownsPC98_OpnDriver: TRYING TO SSG ENVELOPE SHAPES (NOT SUPPORTED)"); - break; - - case 0xa0: - // frequency - l &= ~3; - if (l == 0) { - c->frqTemp = (c->frqTemp & 0xff00) | value; - c->updateEnvelopeParameters = true; - for (int i = 0; i < 4; i++) - co[i]->frequency(c->frqTemp); - } else if (l == 4) { - c->frqTemp = (c->frqTemp & 0xff) | (value << 8); - } else if (l == 8) { - // Ch 3/6 special mode frq - warning("TownsPC98_OpnDriver: TRYING TO USE CH 3/6 SPECIAL MODE FREQ (NOT SUPPORTED)"); - } else if (l == 12) { - // Ch 3/6 special mode frq - warning("TownsPC98_OpnDriver: TRYING TO USE CH 3/6 SPECIAL MODE FREQ (NOT SUPPORTED)"); - } - break; - - case 0xb0: - l &= ~3; - if (l == 0) { - // feedback, _algorithm - co[0]->feedbackLevel((value >> 3) & 7); - c->algorithm = value & 7; - } else if (l == 4) { - // stereo, LFO sensitivity - c->enableLeft = value & 0x80 ? true : false; - c->enableRight = value & 0x40 ? true : false; - uint8 ams = (value & 0x3F) >> 3; - if (ams) - warning("TownsPC98_OpnDriver: TRYING TO USE AMP MODULATION SENSITIVITY (NOT SUPPORTED)"); - uint8 fms = value & 3; - if (fms) - warning("TownsPC98_OpnDriver: TRYING TO USE FREQ MODULATION SENSITIVITY (NOT SUPPORTED)"); - } - break; - - default: - warning("TownsPC98_OpnDriver: UNKNOWN ADDRESS %d", regAddress); - } -} - -int TownsPC98_OpnCore::readBuffer(int16 *buffer, const int numSamples) { - Common::StackLock lock(_mutex); - - memset(buffer, 0, sizeof(int16) * numSamples); - int32 *tmp = new int32[numSamples]; - int32 *tmpStart = tmp; - memset(tmp, 0, sizeof(int32) * numSamples); - int32 samplesLeft = numSamples >> 1; - - while (samplesLeft) { - int32 render = samplesLeft; - - for (int i = 0; i < 2; i++) { - if (_timers[i].enabled && _timers[i].cb) { - if (!_timers[i].smpTillCb) { - (this->*_timers[i].cb)(); - _timers[i].smpTillCb = _timers[i].smpPerCb; - - _timers[i].smpTillCbRem += _timers[i].smpPerCbRem; - if (_timers[i].smpTillCbRem >= _timerbase) { - _timers[i].smpTillCb++; - _timers[i].smpTillCbRem -= _timerbase; - } - } - render = MIN(render, _timers[i].smpTillCb); - } - } - - samplesLeft -= render; - - for (int i = 0; i < 2; i++) { - if (_timers[i].enabled && _timers[i].cb) { - _timers[i].smpTillCb -= render; - } - } - - nextTick(tmp, render); - - if (_ssg) - _ssg->nextTick(tmp, render); - if (_prc) - _prc->nextTick(tmp, render); - - for (int i = 0; i < render; ++i) { - int32 l = CLIP<int32>(tmp[i << 1], -32767, 32767); - buffer[i << 1] = (int16) l; - int32 r = CLIP<int32>(tmp[(i << 1) + 1], -32767, 32767); - buffer[(i << 1) + 1] = (int16) r; - } - - buffer += (render << 1); - tmp += (render << 1); - } - - delete[] tmpStart; - return numSamples; -} - -void TownsPC98_OpnCore::setVolumeIntern(int volA, int volB) { - Common::StackLock lock(_mutex); - _volumeA = volA; - _volumeB = volB; - if (_ssg) - _ssg->setVolumeIntern(volA, volB); - if (_prc) - _prc->setVolumeIntern(volA, volB); -} - -void TownsPC98_OpnCore::setVolumeChannelMasks(int channelMaskA, int channelMaskB) { - Common::StackLock lock(_mutex); - _volMaskA = channelMaskA; - _volMaskB = channelMaskB; - if (_ssg) - _ssg->setVolumeChannelMasks(_volMaskA >> _numChan, _volMaskB >> _numChan); - if (_prc) - _prc->setVolumeChannelMasks(_volMaskA >> (_numChan + _numSSG), _volMaskB >> (_numChan + _numSSG)); -} - -void TownsPC98_OpnCore::generateTables() { - delete[] _oprRates; - _oprRates = new uint8[128]; - - WRITE_BE_UINT32(_oprRates + 32, _numChan == 6 ? 0x90900000 : 0x00081018); - WRITE_BE_UINT32(_oprRates + 36, _numChan == 6 ? 0x00001010 : 0x00081018); - memset(_oprRates, 0x90, 32); - memset(_oprRates + 96, 0x80, 32); - uint8 *dst = (uint8 *)_oprRates + 40; - for (int i = 0; i < 40; i += 4) - WRITE_BE_UINT32(dst + i, 0x00081018); - for (int i = 0; i < 48; i += 4) - WRITE_BE_UINT32(dst + i, 0x00081018); - dst += 40; - for (uint8 i = 0; i < 16; i ++) { - uint8 v = (i < 12) ? i : 12; - *dst++ = ((4 + v) << 3); - } - - delete[] _oprRateshift; - _oprRateshift = new uint8[128]; - memset(_oprRateshift, 0, 128); - dst = (uint8 *)_oprRateshift + 32; - for (int i = 11; i; i--) { - memset(dst, i, 4); - dst += 4; - } - - delete[] _oprFrq; - _oprFrq = new uint32[0x1000]; - for (uint32 i = 0; i < 0x1000; i++) - _oprFrq[i] = (uint32)(_baserate * (float)(i << 11)); - - delete[] _oprAttackDecay; - _oprAttackDecay = new uint8[152]; - memset(_oprAttackDecay, 0, 152); - for (int i = 0; i < 36; i++) - WRITE_BE_UINT32(_oprAttackDecay + (i << 2), _adtStat[i]); - - delete[] _oprSinTbl; - _oprSinTbl = new uint32[1024]; - for (int i = 0; i < 1024; i++) { - double val = sin((double) (((i << 1) + 1) * PI / 1024.0)); - double d_dcb = log(1.0 / (double)ABS(val)) / log(2.0) * 256.0; - int32 i_dcb = (int32)(2.0 * d_dcb); - i_dcb = (i_dcb & 1) ? (i_dcb >> 1) + 1 : (i_dcb >> 1); - _oprSinTbl[i] = (i_dcb << 1) + (val >= 0.0 ? 0 : 1); - } - - delete[] _oprLevelOut; - _oprLevelOut = new int32[0x1a00]; - for (int i = 0; i < 256; i++) { - double val = floor(65536.0 / pow(2.0, 0.00390625 * (double)(1 + i))); - int32 val_int = ((int32) val) >> 4; - _oprLevelOut[i << 1] = (val_int & 1) ? ((val_int >> 1) + 1) << 2 : (val_int >> 1) << 2; - _oprLevelOut[(i << 1) + 1] = -_oprLevelOut[i << 1]; - for (int ii = 1; ii < 13; ii++) { - _oprLevelOut[(i << 1) + (ii << 9)] = _oprLevelOut[i << 1] >> ii; - _oprLevelOut[(i << 1) + (ii << 9) + 1] = -_oprLevelOut[(i << 1) + (ii << 9)]; - } - } - - uint8 *dtt = new uint8[128]; - memset(dtt, 0, 36); - memset(dtt + 36, 1, 8); - memcpy(dtt + 44, _detSrc, 84); - - delete[] _oprDetune; - _oprDetune = new int32[256]; - for (int i = 0; i < 128; i++) { - _oprDetune[i] = (int32) ((float)dtt[i] * _baserate * 64.0); - _oprDetune[i + 128] = -_oprDetune[i]; - } - - delete[] dtt; -} - -void TownsPC98_OpnCore::nextTick(int32 *buffer, uint32 bufferSize) { - if (!_ready) - return; - - for (int i = 0; i < _numChan; i++) { - TownsPC98_OpnOperator **o = _chanInternal[i].opr; - - if (_chanInternal[i].updateEnvelopeParameters) { - _chanInternal[i].updateEnvelopeParameters = false; - for (int ii = 0; ii < 4 ; ii++) - o[ii]->updatePhaseIncrement(); - } - - for (uint32 ii = 0; ii < bufferSize ; ii++) { - int32 phbuf1, phbuf2, output; - phbuf1 = phbuf2 = output = 0; - - int32 *leftSample = &buffer[ii * 2]; - int32 *rightSample = &buffer[ii * 2 + 1]; - int32 *del = &_chanInternal[i].feedbuf[2]; - int32 *feed = _chanInternal[i].feedbuf; - - switch (_chanInternal[i].algorithm) { - case 0: - o[0]->generateOutput(0, feed, phbuf1); - o[2]->generateOutput(*del, 0, phbuf2); - *del = 0; - o[1]->generateOutput(phbuf1, 0, *del); - o[3]->generateOutput(phbuf2, 0, output); - break; - case 1: - o[0]->generateOutput(0, feed, phbuf1); - o[2]->generateOutput(*del, 0, phbuf2); - o[1]->generateOutput(0, 0, phbuf1); - o[3]->generateOutput(phbuf2, 0, output); - *del = phbuf1; - break; - case 2: - o[0]->generateOutput(0, feed, phbuf2); - o[2]->generateOutput(*del, 0, phbuf2); - o[1]->generateOutput(0, 0, phbuf1); - o[3]->generateOutput(phbuf2, 0, output); - *del = phbuf1; - break; - case 3: - o[0]->generateOutput(0, feed, phbuf2); - o[2]->generateOutput(0, 0, *del); - o[1]->generateOutput(phbuf2, 0, phbuf1); - o[3]->generateOutput(*del, 0, output); - *del = phbuf1; - break; - case 4: - o[0]->generateOutput(0, feed, phbuf1); - o[2]->generateOutput(0, 0, phbuf2); - o[1]->generateOutput(phbuf1, 0, output); - o[3]->generateOutput(phbuf2, 0, output); - *del = 0; - break; - case 5: - o[0]->generateOutput(0, feed, phbuf1); - o[2]->generateOutput(*del, 0, output); - o[1]->generateOutput(phbuf1, 0, output); - o[3]->generateOutput(phbuf1, 0, output); - *del = phbuf1; - break; - case 6: - o[0]->generateOutput(0, feed, phbuf1); - o[2]->generateOutput(0, 0, output); - o[1]->generateOutput(phbuf1, 0, output); - o[3]->generateOutput(0, 0, output); - *del = 0; - break; - case 7: - o[0]->generateOutput(0, feed, output); - o[2]->generateOutput(0, 0, output); - o[1]->generateOutput(0, 0, output); - o[3]->generateOutput(0, 0, output); - *del = 0; - break; - }; - - int32 finOut = (output << 2) / ((_numChan + _numSSG - 3) / 3); - - if ((1 << i) & _volMaskA) - finOut = (finOut * _volumeA) / Audio::Mixer::kMaxMixerVolume; - - if ((1 << i) & _volMaskB) - finOut = (finOut * _volumeB) / Audio::Mixer::kMaxMixerVolume; - - if (_chanInternal[i].enableLeft) - *leftSample += finOut; - - if (_chanInternal[i].enableRight) - *rightSample += finOut; - } - } -} - -TownsPC98_OpnDriver::TownsPC98_OpnDriver(Audio::Mixer *mixer, OpnType type) : TownsPC98_OpnCore(mixer, type), - _channels(0), _ssgChannels(0), _sfxChannels(0), _rhythmChannel(0), - _trackPtr(0), _sfxData(0), _sfxOffs(0), _ssgPatches(0), - _patches(0), _sfxBuffer(0), _musicBuffer(0), - - _opnCarrier(_drvTables + 76), _opnFreqTable(_drvTables + 108), _opnFreqTableSSG(_drvTables + 132), - _opnFxCmdLen(_drvTables + 36), _opnLvlPresets(_drvTables + (type == OD_TOWNS ? 52 : 84)), - - _updateChannelsFlag(type == OD_TYPE26 ? 0x07 : 0x3F), _finishedChannelsFlag(0), - _updateSSGFlag(type == OD_TOWNS ? 0x00 : 0x07), _finishedSSGFlag(0), - _updateRhythmFlag(type == OD_TYPE86 ? 0x01 : 0x00), _finishedRhythmFlag(0), - _updateSfxFlag(0), _finishedSfxFlag(0), - - _musicTickCounter(0), - - _musicVolume(255), _sfxVolume(255), - - _musicPlaying(false), _sfxPlaying(false), _fading(false), _looping(0), _ready(false) { - - _sfxOffsets[0] = _sfxOffsets[1] = 0; -} - -TownsPC98_OpnDriver::~TownsPC98_OpnDriver() { - reset(); - - if (_channels) { - for (int i = 0; i < _numChan; i++) - delete _channels[i]; - delete[] _channels; - } - - if (_ssgChannels) { - for (int i = 0; i < _numSSG; i++) - delete _ssgChannels[i]; - delete[] _ssgChannels; - } - - if (_sfxChannels) { - for (int i = 0; i < 2; i++) - delete _sfxChannels[i]; - delete[] _sfxChannels; - } - - delete _rhythmChannel; - - delete[] _ssgPatches; -} - -bool TownsPC98_OpnDriver::init() { - if (_ready) { - reset(); - return true; - } - - TownsPC98_OpnCore::init(); - - setVolumeChannelMasks(-1, 0); - - _channels = new TownsPC98_OpnChannel *[_numChan]; - for (int i = 0; i < _numChan; i++) { - int ii = i * 6; - _channels[i] = new TownsPC98_OpnChannel(this, _drvTables[ii], _drvTables[ii + 1], - _drvTables[ii + 2], _drvTables[ii + 3], _drvTables[ii + 4], _drvTables[ii + 5]); - _channels[i]->init(); - } - - if (_numSSG) { - _ssgPatches = new uint8[256]; - memcpy(_ssgPatches, _drvTables + 156, 256); - - _ssgChannels = new TownsPC98_OpnChannelSSG *[_numSSG]; - for (int i = 0; i < _numSSG; i++) { - int ii = i * 6; - _ssgChannels[i] = new TownsPC98_OpnChannelSSG(this, _drvTables[ii], _drvTables[ii + 1], - _drvTables[ii + 2], _drvTables[ii + 3], _drvTables[ii + 4], _drvTables[ii + 5]); - _ssgChannels[i]->init(); - } - - _sfxChannels = new TownsPC98_OpnSfxChannel *[2]; - for (int i = 0; i < 2; i++) { - int ii = (i + 1) * 6; - _sfxChannels[i] = new TownsPC98_OpnSfxChannel(this, _drvTables[ii], _drvTables[ii + 1], - _drvTables[ii + 2], _drvTables[ii + 3], _drvTables[ii + 4], _drvTables[ii + 5]); - _sfxChannels[i]->init(); - } - } - - if (_hasPercussion) { - _rhythmChannel = new TownsPC98_OpnChannelPCM(this, 0, 0, 0, 0, 0, 1); - _rhythmChannel->init(); - } - - setMusicTempo(84); - setSfxTempo(654); - - _ready = true; - - return true; -} - -void TownsPC98_OpnDriver::loadMusicData(uint8 *data, bool loadPaused) { - if (!_ready) { - warning("TownsPC98_OpnDriver: Driver must be initialized before loading data"); - return; - } - - if (!data) { - warning("TownsPC98_OpnDriver: Invalid music file data"); - return; - } - - reset(); - - Common::StackLock lock(_mutex); - uint8 *src_a = _trackPtr = _musicBuffer = data; - - for (uint8 i = 0; i < 3; i++) { - _channels[i]->loadData(data + READ_LE_UINT16(src_a)); - src_a += 2; - } - - for (int i = 0; i < _numSSG; i++) { - _ssgChannels[i]->loadData(data + READ_LE_UINT16(src_a)); - src_a += 2; - } - - for (uint8 i = 3; i < _numChan; i++) { - _channels[i]->loadData(data + READ_LE_UINT16(src_a)); - src_a += 2; - } - - if (_hasPercussion) { - _rhythmChannel->loadData(data + READ_LE_UINT16(src_a)); - src_a += 2; - } - - toggleRegProtection(false); - - _patches = src_a + 4; - _finishedChannelsFlag = _finishedSSGFlag = _finishedRhythmFlag = 0; - - _musicPlaying = (loadPaused ? false : true); -} - -void TownsPC98_OpnDriver::loadSoundEffectData(uint8 *data, uint8 trackNum) { - if (!_ready) { - warning("TownsPC98_OpnDriver: Driver must be initialized before loading data"); - return; - } - - if (!_sfxChannels) { - warning("TownsPC98_OpnDriver: Sound effects not supported by this configuration"); - return; - } - - if (!data) { - warning("TownsPC98_OpnDriver: Invalid sound effects file data"); - return; - } - - Common::StackLock lock(_mutex); - _sfxData = _sfxBuffer = data; - _sfxOffsets[0] = READ_LE_UINT16(&_sfxData[(trackNum << 2)]); - _sfxOffsets[1] = READ_LE_UINT16(&_sfxData[(trackNum << 2) + 2]); - _sfxPlaying = true; - _finishedSfxFlag = 0; -} - -void TownsPC98_OpnDriver::reset() { - Common::StackLock lock(_mutex); - - _musicPlaying = false; - _sfxPlaying = false; - _fading = false; - _looping = 0; - _musicTickCounter = 0; - _sfxData = 0; - - TownsPC98_OpnCore::reset(); - - for (int i = 0; i < _numChan; i++) - _channels[i]->reset(); - for (int i = 0; i < _numSSG; i++) - _ssgChannels[i]->reset(); - - if (_numSSG) { - for (int i = 0; i < 2; i++) - _sfxChannels[i]->reset(); - - memcpy(_ssgPatches, _drvTables + 156, 256); - } - - if (_rhythmChannel) - _rhythmChannel->reset(); -} - -void TownsPC98_OpnDriver::fadeStep() { - if (!_musicPlaying) - return; - - Common::StackLock lock(_mutex); - for (int j = 0; j < _numChan; j++) { - if (_updateChannelsFlag & _channels[j]->_idFlag) - _channels[j]->fadeStep(); - } - - for (int j = 0; j < _numSSG; j++) { - if (_updateSSGFlag & _ssgChannels[j]->_idFlag) - _ssgChannels[j]->fadeStep(); - } - - if (!_fading) { - _fading = 19; - if (_hasPercussion) { - if (_updateRhythmFlag & _rhythmChannel->_idFlag) - _rhythmChannel->reset(); - } - } else { - if (!--_fading) - reset(); - } -} - -void TownsPC98_OpnDriver::timerCallbackB() { - _sfxOffs = 0; - - if (_musicPlaying) { - _musicTickCounter++; - - for (int i = 0; i < _numChan; i++) { - if (_updateChannelsFlag & _channels[i]->_idFlag) { - _channels[i]->processEvents(); - _channels[i]->processFrequency(); - } - } - - for (int i = 0; i < _numSSG; i++) { - if (_updateSSGFlag & _ssgChannels[i]->_idFlag) { - _ssgChannels[i]->processEvents(); - _ssgChannels[i]->processFrequency(); - } - } - - if (_hasPercussion) - if (_updateRhythmFlag & _rhythmChannel->_idFlag) - _rhythmChannel->processEvents(); - } - - toggleRegProtection(false); - - if (_finishedChannelsFlag == _updateChannelsFlag && _finishedSSGFlag == _updateSSGFlag && _finishedRhythmFlag == _updateRhythmFlag) - _musicPlaying = false; -} - -void TownsPC98_OpnDriver::timerCallbackA() { - if (_sfxChannels && _sfxPlaying) { - if (_sfxData) - startSoundEffect(); - - _sfxOffs = 3; - _trackPtr = _sfxBuffer; - - for (int i = 0; i < 2; i++) { - if (_updateSfxFlag & _sfxChannels[i]->_idFlag) { - _sfxChannels[i]->processEvents(); - _sfxChannels[i]->processFrequency(); - } - } - - _trackPtr = _musicBuffer; - } - - if (_updateSfxFlag && _finishedSfxFlag == _updateSfxFlag) { - _sfxPlaying = false; - _updateSfxFlag = 0; - setVolumeChannelMasks(-1, 0); - } -} - -void TownsPC98_OpnDriver::setMusicTempo(uint8 tempo) { - writeReg(0, 0x26, tempo); - writeReg(0, 0x27, 0x33); -} - -void TownsPC98_OpnDriver::setSfxTempo(uint16 tempo) { - writeReg(0, 0x24, tempo & 0xff); - writeReg(0, 0x25, tempo >> 8); - writeReg(0, 0x27, 0x33); -} - -void TownsPC98_OpnDriver::startSoundEffect() { - int volFlags = 0; - - for (int i = 0; i < 2; i++) { - if (_sfxOffsets[i]) { - _ssgChannels[i + 1]->protect(); - _sfxChannels[i]->reset(); - _sfxChannels[i]->loadData(_sfxData + _sfxOffsets[i]); - _updateSfxFlag |= _sfxChannels[i]->_idFlag; - volFlags |= (_sfxChannels[i]->_idFlag << _numChan); - } else { - _ssgChannels[i + 1]->restore(); - _updateSfxFlag &= ~_sfxChannels[i]->_idFlag; - } - } - - setVolumeChannelMasks(~volFlags, volFlags); - _sfxData = 0; -} - -const uint8 TownsPC98_OpnDriver::_drvTables[] = { - // channel presets - 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x80, 0x01, 0x01, 0x00, 0x02, - 0x02, 0x80, 0x02, 0x02, 0x00, 0x04, - 0x00, 0x80, 0x03, 0x04, 0x01, 0x08, - 0x01, 0x80, 0x04, 0x05, 0x01, 0x10, - 0x02, 0x80, 0x05, 0x06, 0x01, 0x20, - - // control event size - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x05, - 0x02, 0x06, 0x02, 0x00, 0x00, 0x02, 0x00, 0x02, - - // fmt level presets - 0x54, 0x50, 0x4C, 0x48, 0x44, 0x40, 0x3C, 0x38, - 0x34, 0x30, 0x2C, 0x28, 0x24, 0x20, 0x1C, 0x18, - 0x14, 0x10, 0x0C, 0x08, 0x04, 0x90, 0x90, 0x90, - - // carriers - 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0E, 0x0E, 0x0F, - - // pc98 level presets - 0x40, 0x3B, 0x38, 0x34, 0x30, 0x2A, 0x28, 0x25, - 0x22, 0x20, 0x1D, 0x1A, 0x18, 0x15, 0x12, 0x10, - 0x0D, 0x0A, 0x08, 0x05, 0x02, 0x90, 0x90, 0x90, - - // frequencies - 0x6A, 0x02, 0x8F, 0x02, 0xB6, 0x02, 0xDF, 0x02, - 0x0B, 0x03, 0x39, 0x03, 0x6A, 0x03, 0x9E, 0x03, - 0xD5, 0x03, 0x10, 0x04, 0x4E, 0x04, 0x8F, 0x04, - - // ssg frequencies - 0xE8, 0x0E, 0x12, 0x0E, 0x48, 0x0D, 0x89, 0x0C, - 0xD5, 0x0B, 0x2B, 0x0B, 0x8A, 0x0A, 0xF3, 0x09, - 0x64, 0x09, 0xDD, 0x08, 0x5E, 0x08, 0xE6, 0x07, - - // ssg patch data - 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00, - 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0x37, 0x81, 0xC8, 0x00, - 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0x37, 0x81, 0xC8, 0x00, - 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00, - 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00, - 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00, - 0x04, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00, - 0x0A, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0x01, 0x00, - 0xFF, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, - 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0x00, - 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - 0x64, 0x01, 0xFF, 0x64, 0xFF, 0x81, 0xFF, 0x00, - 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - - 0x02, 0x01, 0xFF, 0x28, 0xFF, 0x81, 0xF0, 0x00, - 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xC8, 0x00, - 0x01, 0x81, 0x00, 0x00, 0x28, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0x78, 0x5F, 0x81, 0xA0, 0x00, - 0x05, 0x81, 0x00, 0x00, 0x28, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00, - 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00, - 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, - 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00, - 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00 -}; - SoundTowns::SoundTowns(KyraEngine_v1 *vm, Audio::Mixer *mixer) - : Sound(vm, mixer), _lastTrack(-1), _currentSFX(0), _sfxFileData(0), - _sfxFileIndex((uint)-1), _sfxWDTable(0), _sfxBTTable(0), _parser(0) { + : Sound(vm, mixer), _lastTrack(-1), _currentSFX(0), _musicTrackData(0), _sfxFileData(0), _cdaPlaying(0), + _sfxFileIndex((uint)-1), _musicFadeTable(0), _sfxWDTable(0), _sfxBTTable(0), _sfxChannel(0x46) { - _driver = new Towns_EuphonyDriver(_mixer); - int ret = open(); - if (ret != MERR_ALREADY_OPEN && ret != 0) - error("couldn't open midi driver"); + _driver = new TownsEuphonyDriver(_mixer); } SoundTowns::~SoundTowns() { g_system->getAudioCDManager()->stop(); haltTrack(); + delete[] _musicTrackData; delete[] _sfxFileData; - - Common::StackLock lock(_mutex); - _driver->setTimerCallback(0, 0); - close(); - - _driver = 0; } bool SoundTowns::init() { _vm->checkCD(); int unused = 0; + _musicFadeTable = _vm->staticres()->loadRawData(k1TownsMusicFadeTable, unused); _sfxWDTable = _vm->staticres()->loadRawData(k1TownsSFXwdTable, unused); _sfxBTTable = _vm->staticres()->loadRawData(k1TownsSFXbtTable, unused); + _musicTrackData = new uint8[50570]; + + if (!_driver->init()) + return false; + + if (!loadInstruments()) + return false; + + _driver->cdaSetVolume(1, 118, 118); - return loadInstruments(); + return true; } void SoundTowns::process() { @@ -3941,10 +91,13 @@ void SoundTowns::playTrack(uint8 track) { beginFadeOut(); if (_musicEnabled == 2 && trackNum != -1) { - g_system->getAudioCDManager()->play(trackNum+1, loop ? -1 : 1, 0, 0); + _driver->cdaSetVolume(1, 118, 118); + g_system->getAudioCDManager()->play(trackNum + 1, loop ? -1 : 1, 0, 0); g_system->getAudioCDManager()->updateCD(); + _cdaPlaying = true; } else if (_musicEnabled) { playEuphonyTrack(READ_LE_UINT32(&tTable[tTableIndex]), loop); + _cdaPlaying = false; } _lastTrack = track; @@ -3954,15 +107,15 @@ void SoundTowns::haltTrack() { _lastTrack = -1; g_system->getAudioCDManager()->stop(); g_system->getAudioCDManager()->updateCD(); - if (_parser) { - Common::StackLock lock(_mutex); - _parser->setTrack(0); - _parser->jumpToTick(0); - _parser->unloadMusic(); - delete _parser; - _parser = 0; - } - _driver->queue()->release(); + _cdaPlaying = false; + + for (int i = 0; i < 6; i++) + _driver->chanVolume(i, 0); + for (int i = 0x40; i < 0x46; i++) + _driver->chanVolume(i, 0); + for (int i = 0; i < 32; i++) + _driver->chanEnable(i, 0); + _driver->stopParser(); } void SoundTowns::loadSoundFile(uint file) { @@ -3976,27 +129,26 @@ void SoundTowns::loadSoundFile(uint file) { void SoundTowns::playSoundEffect(uint8 track) { if (!_sfxEnabled || !_sfxFileData) return; - + if (track == 0 || track == 10) { - _mixer->stopHandle(_sfxHandle); + stopAllSoundEffects(); return; } else if (track == 1) { - // sfx fadeout - _mixer->stopHandle(_sfxHandle); + fadeOutSoundEffects(); return; } - uint8 note = 0x3c; + uint8 note = 60; if (_sfxFileIndex == 5) { - if (track == 0x10) { - note = 0x3e; - track = 0x0f; - } else if (track == 0x11) { - note = 0x40; - track = 0x0f; - } else if (track == 0x12) { - note = 0x41; - track = 0x0f; + if (track == 16) { + note = 62; + track = 15; + } else if (track == 17) { + note = 64; + track = 15; + } else if (track == 18) { + note = 65; + track = 15; } } @@ -4005,32 +157,37 @@ void SoundTowns::playSoundEffect(uint8 track) { if (offset == -1) return; - uint32 *sfxHeader = (uint32 *)(fileBody + offset); + if (!_driver->soundEffectIsPlaying(_sfxChannel ^ 1)) { + _sfxChannel ^= 1; + } else if (_driver->soundEffectIsPlaying(_sfxChannel)) { + _sfxChannel ^= 1; + _driver->stopSoundEffect(_sfxChannel); + } + uint32 *sfxHeader = (uint32 *)(fileBody + offset); uint32 sfxHeaderID = READ_LE_UINT32(sfxHeader); - uint32 sfxHeaderInBufferSize = READ_LE_UINT32(&sfxHeader[1]); - uint32 sfxHeaderOutBufferSize = READ_LE_UINT32(&sfxHeader[3]); - uint32 sfxRootNoteOffs = READ_LE_UINT32(&sfxHeader[7]); - uint32 sfxRate = READ_LE_UINT32(&sfxHeader[6]); + uint32 playbackBufferSize = sfxHeaderID == 1 ? 30704 : READ_LE_UINT32(&sfxHeader[3]); - uint32 playbackBufferSize = (sfxHeaderID == 1) ? sfxHeaderInBufferSize : sfxHeaderOutBufferSize; + uint8 *sfxPlaybackBuffer = new uint8[playbackBufferSize + 32]; + memcpy(sfxPlaybackBuffer, fileBody + offset, 32); - uint8 *sfxPlaybackBuffer = (uint8 *)malloc(playbackBufferSize); - memset(sfxPlaybackBuffer, 0x80, playbackBufferSize); + uint8 *dst = sfxPlaybackBuffer + 32; + memset(dst, 0x80, playbackBufferSize); uint8 *sfxBody = ((uint8 *)sfxHeader) + 0x20; if (!sfxHeaderID) { - memcpy(sfxPlaybackBuffer, sfxBody, playbackBufferSize); + memcpy(dst, sfxBody, playbackBufferSize); } else if (sfxHeaderID == 1) { - Screen::decodeFrame4(sfxBody, sfxPlaybackBuffer, playbackBufferSize); + Screen::decodeFrame4(sfxBody, dst, playbackBufferSize); } else if (_sfxWDTable) { - uint8 *tgt = sfxPlaybackBuffer; + uint8 *tgt = dst; uint32 sfx_BtTable_Offset = 0; uint32 sfx_WdTable_Offset = 0; uint32 sfx_WdTable_Number = 5; + uint32 inSize = READ_LE_UINT32(&sfxHeader[1]); - for (uint32 i = 0; i < sfxHeaderInBufferSize; i++) { + for (uint32 i = 0; i < inSize; i++) { sfx_WdTable_Offset = (sfx_WdTable_Number * 3 << 9) + sfxBody[i] * 6; sfx_WdTable_Number = READ_LE_UINT16(_sfxWDTable + sfx_WdTable_Offset); @@ -4042,124 +199,174 @@ void SoundTowns::playSoundEffect(uint8 track) { } } - for (uint32 i = 0; i < playbackBufferSize; i++) { - if (sfxPlaybackBuffer[i] < 0x80) - sfxPlaybackBuffer[i] = 0x80 - sfxPlaybackBuffer[i]; - } + _driver->chanVolume(_sfxChannel, 127); + _driver->chanPanPos(_sfxChannel, 0x40); + _driver->chanPitch(_sfxChannel, 0); + _driver->playSoundEffect(_sfxChannel, note, 127, sfxPlaybackBuffer); +} - playbackBufferSize -= 0x20; +void SoundTowns::updateVolumeSettings() { + if (!_driver) + return; - uint32 outputRate = uint32(11025 * calculatePhaseStep(note, sfxRootNoteOffs, sfxRate, 11025, 0x2000)); + bool mute = false; + _driver->setSoundEffectVolume(ConfMan.getInt("sfx_volume")); + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); - _currentSFX = Audio::makeRawStream(sfxPlaybackBuffer, playbackBufferSize, - outputRate, Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN); - _mixer->playStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, _currentSFX); + _driver->setMusicVolume((mute ? 0 : ConfMan.getInt("music_volume"))); + _driver->setSoundEffectVolume((mute ? 0 : ConfMan.getInt("sfx_volume"))); +} + +void SoundTowns::stopAllSoundEffects() { + _driver->chanVolume(0x46, 0); + _driver->chanVolume(0x47, 0); + _driver->stopSoundEffect(0x46); + _driver->stopSoundEffect(0x47); + _sfxChannel = 0x46; } void SoundTowns::beginFadeOut() { - _lastTrack = -1; - _driver->fading(); + if (_cdaPlaying) { + for (int i = 118; i > 103; i--) { + _driver->cdaSetVolume(1, i, i); + _vm->delay(2 * _vm->tickLength()); + } - // TODO: this should fade out too - g_system->getAudioCDManager()->stop(); - g_system->getAudioCDManager()->updateCD(); -} + for (int i = 103; i > 83; i -= 2) { + _driver->cdaSetVolume(1, i, i); + _vm->delay(2 * _vm->tickLength()); + } -int SoundTowns::open() { - if (!_driver) - return 255; + for (int i = 83; i > 58; i -= 2) { + _driver->cdaSetVolume(1, i, i); + _vm->delay(_vm->tickLength()); + } - int ret = _driver->open(); - if (ret) - return ret; + for (int i = 58; i > 0; i--) + _driver->cdaSetVolume(1, i, i); - _driver->setTimerCallback(this, &onTimer); - return 0; -} + _driver->cdaSetVolume(1, 0, 0); -void SoundTowns::close() { - if (_driver) - _driver->close(); -} + } else { + if (_lastTrack == -1) + return; -void SoundTowns::send(uint32 b) { - _driver->send(b); -} + uint32 ticks = 2; + int tickAdv = 0; + + uint16 fadeVolCur[12]; + uint16 fadeVolStep[12]; + + for (int i = 0; i < 6; i++) { + fadeVolCur[i] = READ_LE_UINT16(&_musicFadeTable[(_lastTrack * 12 + i) * 2]); + fadeVolStep[i] = fadeVolCur[i] / 50; + fadeVolCur[i + 6] = READ_LE_UINT16(&_musicFadeTable[(_lastTrack * 12 + 6 + i) * 2]); + fadeVolStep[i + 6] = fadeVolCur[i + 6] / 30; + } + + for (int i = 0; i < 12; i++) { + for (int ii = 0; ii < 6; ii++) + _driver->chanVolume(ii, fadeVolCur[ii]); + for (int ii = 0x40; ii < 0x46; ii++) + _driver->chanVolume(ii, fadeVolCur[ii - 0x3a]); + + for (int ii = 0; ii < 6; ii++) { + fadeVolCur[ii] -= fadeVolStep[ii]; + if (fadeVolCur[ii] < 10) + fadeVolCur[ii] = 0; + fadeVolCur[ii + 6] -= fadeVolStep[ii + 6]; + if (fadeVolCur[ii + 6] < 10) + fadeVolCur[ii + 6] = 0; + } + + if (++tickAdv == 3) { + tickAdv = 0; + ticks += 2; + } + _vm->delay(ticks * _vm->tickLength()); + } + } -uint32 SoundTowns::getBaseTempo() { - return _driver ? _driver->getBaseTempo() : 0; + haltTrack(); } bool SoundTowns::loadInstruments() { uint8 *twm = _vm->resource()->fileData("twmusic.pak", 0); if (!twm) return false; - _driver->queue()->loadDataToCurrentPosition(twm, 0x8BF0); - _driver->loadFmInstruments(_driver->queue()->trackData() + 8); - _driver->queue()->loadDataToCurrentPosition(twm + 0x0CA0, 0xC58A); - _driver->loadWaveInstruments(_driver->queue()->trackData() + 8); + Common::StackLock lock(_mutex); + + Screen::decodeFrame4(twm, _musicTrackData, 50570); + for (int i = 0; i < 128; i++) + _driver->loadInstrument(0, i, &_musicTrackData[i * 48 + 8]); + + Screen::decodeFrame4(twm + 3232, _musicTrackData, 50570); + for (int i = 0; i < 32; i++) + _driver->loadInstrument(0x40, i, &_musicTrackData[i * 128 + 8]); + + _driver->unloadWaveTable(-1); + uint8 *src = &_musicTrackData[32 * 128 + 8]; + for (int i = 0; i < 10; i++) { + _driver->loadWaveTable(src); + src = src + READ_LE_UINT16(&src[12]) + 32; + } + + _driver->reserveSoundEffectChannels(2); + delete[] twm; - _driver->queue()->release(); return true; } void SoundTowns::playEuphonyTrack(uint32 offset, int loop) { - uint8 *twm = _vm->resource()->fileData("twmusic.pak", 0); Common::StackLock lock(_mutex); - if (!_parser) { - _parser = new Towns_EuphonyParser(_driver->queue()); - _parser->setMidiDriver(this); - _parser->setTimerRate(getBaseTempo()); - } + uint8 *twm = _vm->resource()->fileData("twmusic.pak", 0); + Screen::decodeFrame4(twm + 19312 + offset, _musicTrackData, 50570); + delete[] twm; - _parser->property(MidiParser::mpAutoLoop, loop); - _parser->loadMusic(twm + 0x4b70 + offset, 0xC58A); + const uint8 *src = _musicTrackData + 852; + for (int i = 0; i < 32; i++) + _driver->chanEnable(i, *src++); + for (int i = 0; i < 32; i++) + _driver->chanMode(i, *src++); + for (int i = 0; i < 32; i++) + _driver->chanOrdr(i, *src++); + for (int i = 0; i < 32; i++) + _driver->chanLevel(i, *src++); + for (int i = 0; i < 32; i++) + _driver->chanTranspose(i, *src++); + + src = _musicTrackData + 1748; + for (int i = 0; i < 6; i++) + _driver->assignChannel(i, *src++); + for (int i = 0x40; i < 0x46; i++) + _driver->assignChannel(i, *src++); - delete[] twm; -} + uint32 trackSize = READ_LE_UINT32(_musicTrackData + 2048); + uint8 startTick = _musicTrackData[2052]; + + _driver->setMusicTempo(_musicTrackData[2053]); + + src = _musicTrackData + 2054; + uint32 l = READ_LE_UINT32(src + trackSize); + trackSize += (l + 4); + l = READ_LE_UINT32(src + trackSize); + trackSize += (l + 4); -void SoundTowns::onTimer(void *data) { - SoundTowns *music = (SoundTowns *)data; - Common::StackLock lock(music->_mutex); - if (music->_parser) - music->_parser->onTimer(); + _driver->setMusicLoop(loop); + _driver->startMusicTrack(src, trackSize, startTick); } -float SoundTowns::calculatePhaseStep(int8 semiTone, int8 semiToneRootkey, - uint32 sampleRate, uint32 outputRate, int32 pitchWheel) { - if (semiTone < 0) - semiTone = 0; - if (semiTone > 119) - semiTone = 119; - if (semiTone < 0) - semiTone = 0; - if (semiTone > 119) - semiTone = 119; - - static const float noteFrq[] = { - 0004.13f, 0004.40f, 0004.64f, 0004.95f, 0005.16f, 0005.50f, 0005.80f, 0006.19f, 0006.60f, 0006.86f, - 0007.43f, 0007.73f, 0008.25f, 0008.80f, 0009.28f, 0009.90f, 0010.31f, 0011.00f, 0011.60f, 0012.38f, - 0013.20f, 0013.75f, 0014.85f, 0015.47f, 0016.50f, 0017.60f, 0018.56f, 0019.80f, 0020.63f, 0022.00f, - 0023.21f, 0024.75f, 0026.40f, 0027.50f, 0029.70f, 0030.94f, 0033.00f, 0035.20f, 0037.16f, 0039.60f, - 0041.25f, 0044.00f, 0046.41f, 0049.50f, 0052.80f, 0055.00f, 0059.40f, 0061.88f, 0066.00f, 0070.40f, - 0074.25f, 0079.20f, 0082.50f, 0088.00f, 0092.83f, 0099.00f, 0105.60f, 0110.00f, 0118.80f, 0123.75f, - 0132.00f, 0140.80f, 0148.50f, 0158.40f, 0165.00f, 0176.00f, 0185.65f, 0198.00f, 0211.20f, 0220.00f, - 0237.60f, 0247.50f, 0264.00f, 0281.60f, 0297.00f, 0316.80f, 0330.00f, 0352.00f, 0371.30f, 0396.00f, - 0422.40f, 0440.00f, 0475.20f, 0495.00f, 0528.00f, 0563.20f, 0594.00f, 0633.60f, 0660.00f, 0704.00f, - 0742.60f, 0792.00f, 0844.80f, 0880.00f, 0950.40f, 0990.00f, 1056.00f, 1126.40f, 1188.00f, 1267.20f, - 1320.00f, 1408.00f, 1485.20f, 1584.00f, 1689.60f, 1760.00f, 1900.80f, 1980.00f, 2112.00f, 2252.80f, - 2376.00f, 2534.40f, 2640.00f, 2816.00f, 2970.40f, 3168.00f, 3379.20f, 3520.00f, 3801.60f, 3960.00f - }; - - float pwModifier = (pitchWheel - 0x2000) / 0x2000; - int8 d = pwModifier ? (pwModifier < 0 ? -1 : 1) : 0; - float rateshift = (noteFrq[semiTone] - ((noteFrq[semiTone] - - noteFrq[semiTone + d]) * pwModifier * d)) / noteFrq[semiToneRootkey]; - - return (float)sampleRate * 10.0f * rateshift / outputRate; +void SoundTowns::fadeOutSoundEffects() { + for (int i = 127; i > 0; i-= 12) { + _driver->chanVolume(0x46, i); + _driver->chanVolume(0x47, i); + _vm->delay(_vm->tickLength()); + } + stopAllSoundEffects(); } SoundPC98::SoundPC98(KyraEngine_v1 *vm, Audio::Mixer *mixer) : @@ -4173,7 +380,7 @@ SoundPC98::~SoundPC98() { } bool SoundPC98::init() { - _driver = new TownsPC98_OpnDriver(_mixer, TownsPC98_OpnDriver::OD_TYPE26); + _driver = new TownsPC98_AudioDriver(_mixer, TownsPC98_AudioDriver::kType26); bool reslt = _driver->init(); updateVolumeSettings(); return reslt; @@ -4254,6 +461,7 @@ void SoundPC98::updateVolumeSettings() { return; bool mute = false; + _driver->setSoundEffectVolume(ConfMan.getInt("sfx_volume")); if (ConfMan.hasKey("mute")) mute = ConfMan.getBool("mute"); @@ -4274,8 +482,8 @@ SoundTownsPC98_v2::~SoundTownsPC98_v2() { } bool SoundTownsPC98_v2::init() { - _driver = new TownsPC98_OpnDriver(_mixer, _vm->gameFlags().platform == Common::kPlatformPC98 ? - TownsPC98_OpnDriver::OD_TYPE86 : TownsPC98_OpnDriver::OD_TOWNS); + _driver = new TownsPC98_AudioDriver(_mixer, _vm->gameFlags().platform == Common::kPlatformPC98 ? + TownsPC98_AudioDriver::kType86 : TownsPC98_AudioDriver::kTypeTowns); if (_vm->gameFlags().platform == Common::kPlatformFMTowns) { _vm->checkCD(); @@ -4375,7 +583,7 @@ void SoundTownsPC98_v2::beginFadeOut() { } int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle, uint8, bool) { - static const uint16 rates[] = { 0x10E1, 0x0CA9, 0x0870, 0x0654, 0x0438, 0x032A, 0x021C, 0x0194 }; + //static const uint16 rates[] = { 0x10E1, 0x0CA9, 0x0870, 0x0654, 0x0438, 0x032A, 0x021C, 0x0194 }; static const char patternHOF[] = "%s.PCM"; static const char patternLOL[] = "%s.VOC"; @@ -4396,7 +604,7 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle, if (!src) return 0; - uint16 sfxRate = rates[READ_LE_UINT16(src)]; + //uint16 sfxRate = rates[READ_LE_UINT16(src)]; src += 2; bool compressed = (READ_LE_UINT16(src) & 1) ? true : false; src += 2; @@ -4436,9 +644,7 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle, sfx[i] = cmd; } - uint32 outputRate = uint32(11025 * SoundTowns::calculatePhaseStep(0x3c, 0x3c, sfxRate, 11025, 0x2000)); - - _currentSFX = Audio::makeRawStream(sfx, outsize, outputRate, + _currentSFX = Audio::makeRawStream(sfx, outsize, 11025, Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN); _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundChannels[h], _currentSFX); if (handle) @@ -4460,6 +666,7 @@ void SoundTownsPC98_v2::updateVolumeSettings() { return; bool mute = false; + _driver->setSoundEffectVolume(ConfMan.getInt("sfx_volume")); if (ConfMan.hasKey("mute")) mute = ConfMan.getBool("mute"); @@ -4467,158 +674,6 @@ void SoundTownsPC98_v2::updateVolumeSettings() { _driver->setSoundEffectVolume((mute ? 0 : ConfMan.getInt("sfx_volume"))); } -// static resources - -const uint32 TownsPC98_OpnCore::_adtStat[] = { - 0x00010001, 0x00010001, 0x00010001, 0x01010001, - 0x00010101, 0x00010101, 0x00010101, 0x01010101, - 0x01010101, 0x01010101, 0x01010102, 0x01010102, - 0x01020102, 0x01020102, 0x01020202, 0x01020202, - 0x02020202, 0x02020202, 0x02020204, 0x02020204, - 0x02040204, 0x02040204, 0x02040404, 0x02040404, - 0x04040404, 0x04040404, 0x04040408, 0x04040408, - 0x04080408, 0x04080408, 0x04080808, 0x04080808, - 0x08080808, 0x08080808, 0x10101010, 0x10101010 -}; - -const uint8 TownsPC98_OpnCore::_detSrc[] = { - 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, - 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x10, 0x10, 0x10, 0x10, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, - 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, - 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x13, 0x14, - 0x16, 0x16, 0x16, 0x16 -}; - -const int TownsPC98_OpnCore::_ssgTables[] = { - 0x01202A, 0x0092D2, 0x006B42, 0x0053CB, 0x003DF8, 0x003053, 0x0022DA, 0x001A8C, - 0x00129B, 0x000DC1, 0x000963, 0x0006C9, 0x000463, 0x0002FA, 0x0001B6, 0x0000FB, - 0x0193B6, 0x01202A, 0x00CDB1, 0x0092D2, 0x007D7D, 0x006B42, 0x005ECD, 0x0053CB, - 0x00480F, 0x003DF8, 0x0036B9, 0x003053, 0x00290A, 0x0022DA, 0x001E6B, 0x001A8C, - 0x001639, 0x00129B, 0x000FFF, 0x000DC1, 0x000B5D, 0x000963, 0x0007FB, 0x0006C9, - 0x000575, 0x000463, 0x00039D, 0x0002FA, 0x000242, 0x0001B6, 0x00014C, 0x0000FB -}; - -const uint8 TownsPC98_OpnCore::_percussionData[] = { - 0,24,1,192,1,216,2,128,4,88,23,64,27,152,1,128,29,24,2,128,31,152,0,128,136,128,128,128,0,136,97,103,153,139,34,163,72,195,27,69,1,154,137,35,8,51,169,122,164,75,133,203,81,146,168,121,185,68,202,8,33,237,49,177,12,133,140,17,160,42,161,10,0,137,176, 57, - 233,41,160,136,235,65,177,137,128,26,164,28,3,157,51,137,1,152,113,161,40,146,115,192,56,5,169,66,161,56,1,50,145,59,39,168,97,1,160,57,7,153,50,153,32,2,25,129,32,20,186,66,129,24,153,164,142,130,169,153,26,242,138,217,9,128,204,58,209,172,40, 176, 141, - 128,155,144,203,139,0,235,9,177,172,0,185,168,138,25,240,59,211,139,19,176,90,160,17,26,132,41,1,5,25,3,50,144,115,147,42,39,152,41,3,56,193,105,130,155,66,200,26,19,218,154,49,201,171,138,176,251,139,185,172,136,189,139,145,207,41,160,171,152, 186, 139, - 186,141,128,218,171,51,217,170,56,163,12,4,155,81,147,42,37,152,32,54,136,49,50,48,37,32,69,0,17,50,50,83,2,16,68,20,8,66,4,154,84,145,24,33,24,32,17,18,145,32,22,168,49,163,1,33,50,184,115,129,25,66,1,24,67,2,80,35,40,53,2,65,51,19,67,37,0,52,35,49, 37, - 34,49,37,17,52,17,35,35,35,34,32,49,33,152,34,145,24,24,128,138,128,184,9,177,171,168,185,155,152,172,155,186,172,185,172,155,186,173,153,202,187,185,202,170,171,202,186,169,170,170,171,139,154,171,153,154,169,10,168,154,128,168,154,0,153, 152, 136, 137, - 128,153,0,152,8,128,137,0,136,136,8,9,8,9,8,24,153,128,136,153,144,0,161,138,1,169,136,128,160,168,152,153,138,137,154,153,153,154,153,170,168,170,185,168,169,154,169,171,153,169,170,153,152,154,153,137,169,137,136,144,152,144,128,128,144,129,129, 0, 33, - 0,17,17,17,33,33,18,18,34,34,34,34,34,34,35,19,35,19,35,35,18,19,18,35,18,33,0,8,8,8,8,8,8,8,160,205,65,176,171,203,16,240,95,242,120,145,156,66,177,26,19,153,9,35,35,239,56,132,138,154,50,145,203,25,32,20,237,24,130,138,160,27,39,173,50,203,64,145, 139, - 18,168,48,146,171,65,18,176,12,52,128,25,5,57,240,104,161,25,129,18,188,114,160,26,36,200,154,18,1,128,186,73,162,173,32,184,25,144,137,234,8,154,32,160,158,18,187,81,2,235,41,36,144,154,17,67,128,33,160,114,146,26,37,33,232,41,130,41,178,29,50, 251, 24, - 1,153,138,160,76,179,155,11,0,38,252,41,146,41,178,27,193,43,39,170,136,17,129,8,49,233,48,129,11,6,26,130,136,128,64,1,248,105,145,9,16,144,140,5,25,168,16,186,48,5,171,217,57,134,171,8,34,188,20,203,41,6,155,161,89,164,140,2,136,51,202,41,131, 56, 144, - 8,97,144,146,13,69,200,42,130,25,152,57,6,220,88,177,26,148,9,168,8,67,192,156,65,145,137,10,4,154,18,157,67,160,154,1,50,188,82,170,82,185,49,220,97,144,10,8,16,145,9,136,18,202,51,184,141,114,179,139,24,19,8,250,121,160,40,160,10,18,152,168,42,35, 216, - 187,120,145,18,156,203,84,144,9,144,26,66,161,13,1,128,17,154,18,142,6,154,65,192,29,35,186,64,192,24,9,146,56,185,16,248,121,176,40,129,136,171,96,147,140,50,203,64,144,41,128,161,187,71,200,24,129,24,217,56,20,220,24,4,169,9,1,33,201,26,134,141,51,201, - 25,16,33,235,32,144,33,153,169,99,160,11,3,136,58,210,33,203,48,163,17,219,128,140,38,8,184,141,50,131,159,33,128,153,25,18,153,88,242,43,3,9,136,157,53,202,40,145,25,2,204,105,146,156,66,152,8,153,33,128,129,136,153,50,186,55,188,51,249,64,178, 27, 128, - 48,177,156,18,35,175,51,189,32,51,234,155,69,184,26,2,152,9,17,136,144,137,50,235,115,216,24,2,170,67,187,49,129,155,4,27,129,56,232,43,39,203,40,3,154,169,66,184,114,224,25,2,9,128,11,35,155,18,11,202,84,169,26,5,154,8,160,98,185,17,187,50, 23, 188, 33, - 1,139,4,154,90,147,12,3,43,2,170,171,103,193,28,132,137,8,129,24,170,50,201,42,35,202,169,52,201,33,218,40,39,203,0,40,147,29,163,139,83,185,1,4,159,34,160,12,21,155,40,129,137,58,151,13,2,136,144,16,153,40,17,131,207,51,144,140,4,154,17,146,170,73, 163, - 44,164,12,152,37,203,17,128,144,139,23,154,128,138,38,216,41,1,0,233,73,131,171,49,136,9,164,46,3,171,32,0,145,157,38,187,64,176,58,134,155,18,136,217,64,1,200,140,38,153,170,66,161,8,169,65,185,98,200,41,3,155,144,58,23,187,1,145,40,147,189,32, 68, 249, - 1,112,255,199,195,19,108,76,187,247,247,183,40,168,212,245,199,227,68,45,59,10,145,177,198,24,130,76,26,193,180,129,0,162,42,160,199,162,0,16,152,137,132,168,195,130,162,181,227,163,161,179,211,180,179,164,128,162,161,194,164,179,40,153,195,213,146, 178, - 147,176,50,186,161,196,151,58,16,28,162,160,131,122,155,33,241,146,128,40,26,128,154,36,170,89,59,9,24,144,77,161,8,177,112,139,33,232,148,24,41,61,9,26,162,32,30,58,153,32,59,73,59,11,79,137,57,9,49,30,24,153,131,25,106,61,153,73,28,56,27, 41, 137, 148, - 76,43,74,58,13,161,3,171,149,32,77,10,74,42,168,16,0,123,138,129,162,178,225,50,140,161,0,147,10,129,41,244,210,165,1,152,24,162,184,166,32,144,59,216,132,177,8,145,67,143,146,160,183,162,130,24,192,32,225,146,144,33,44,73,30,129,137,32,76, 152, 25, 161, - 2,154,32,177,132,232,2,136,210,128,149,177,32,58,27,168,225,133,8,44,107,136,25,136,17,26,58,46,16,11,145,17,144,79,136,144,136,145,152,33,31,162,130,200,82,153,74,137,147,26,0,13,133,170,149,16,192,0,178,0,128,152,182,150,9,16,9,137,33,59,63,10,152, 32, - 179,192,5,154,228,182,145,130,144,42,128,242,2,136,41,168,17,76,57,31,129,136,17,47,8,41,138,32,138,123,59,58,10,136,161,4,46,25,145,136,129,25,56,28,91,41,154,108,9,16,44,24,137,48,15,0,194,162,41,194,56,241,163,146,0,139,7,186,150,129,152,1,208,33,176, - 136,164,163,185,7,138,130,242,162,163,177,88,136,184,166,146,0,25,25,177,199,146,16,136,9,145,178,178,0,147,138,229,18,152,25,144,163,246,162,129,129,184,5,152,178,145,148,136,146,95,152,128,144,33,170,81,11,40,202,131,0,243,24,1,11,148,42, 24, 163, 140, - 120,9,76,58,153,145,56,30,72,46,42,9,8,57,91,76,59,26,160,129,41,76,10,57,192,163,129,16,225,2,27,40,200,48,91,226,40,145,43,177,177,182,196,145,33,184,165,17,192,163,194,129,211,128,162,197,129,0,136,211,146,8,162,144,0,167,160,1,176,150,137,1, 24, 243, - 0,129,145,25,123,169,130,168,132,41,63,42,136,137,120,26,136,8,24,89,29,58,177,193,147,1,26,162,176,167,180,8,49,28,29,178,162,88,43,42,57,43,61,8,29,129,128,128,123,137,24,243,16,136,16,46,0,169,149,128,1,60,153,72,154,90,25,25,25,8,91,73,12,16,137,144, - 72,11,8,167,128,129,9,138,166,193,147,162,123,137,145,1,162,26,1,219,147,129,210,147,243,1,243,16,144,145,160,131,200,4,59,75,57,218,2,178,77,24,60,11,147,10,50,141,64,27,185,122,161,41,128,90,136,24,46,16,139,16,24,28,124,9,41,8,26,121,10,42,40,139,129, - 0,201,135,137,56,176,176,35,215,145,1,26,145,144,160,135,138,1,177,146,146,161,65,242,136,164,177,1,1,186,151,208,148,129,10,32,241,145,163,178,17,168,136,151,168,2,148,185,133,176,130,129,154,163,215,0,146,136,40,211,161,131,171,81,144,170, 21, 184, 56, - 195,168,133,177,91,16,187,5,145,153,66,172,18,177,42,120,138,27,134,26,106,42,138,146,184,66,75,46,41,168,0,145,57,91,75,27,24,27,48,169,40,122,9,109,10,8,177,146,16,74,30,129,160,162,146,41,124,138,24,145,152,3,1,14,3,139,1,192,161,151,177,122,8, 10, 0, - 176,130,129,27,88,225,0,2,154,129,129,193,49,203,81,153,226,33,0,30,0,176,179,18,9,96,156,162,148,160,129,2,29,195,128,0,56,156,20,232,129,128,32,10,144,74,183,9,145,162,1,162,138,23,171,1,164,224,34,43,43,177,200,135,161,91,57,154,177,148, 145, 146, 58, - 108,136,170,35,208,177,34,128,44,129,155,151,243,16,1,154,72,193,144,18,11,122,160,153,5,192,24,130,184,132,226,0,128,153,131,181,136,65,154,128,17,170,39,28,59,144,168,80,25,47,24,26,144,32,47,41,153,161,148,8,92,9,9,129,144,33,26,47,24,137,108, 25, 10, - 17,10,73,75,47,24,184,48,8,45,57,138,136,150,10,48,139,136,35,203,121,8,27,179,161,106,0,29,16,176,179,3,185,19,227,41,145,168,61,197,177,20,10,57,42,250,147,196,16,41,138,24,195,208,135,137,0,145,160,2,210,146,195,177,132,136,153,167,210,146,162, 40, 8, - 138,148,227,145,17,137,40,169,179,130,242,2,196,9,146,145,169,167,146,130,137,136,51,220,17,163,28,74,10,76,40,140,5,137,43,18,12,107,137,40,8,201,50,0,143,3,138,161,134,138,104,169,16,162,160,121,25,28,129,152,32,56,14,16,184,146,3,46,25, 176, 129, 179, - 193,17,130,202,135,8,57,25,154,148,184,120,9,153,211,165,24,128,26,17,242,161,18,185,81,42,11,17,12,25,181,137,66,42,47,41,184,166,129,24,91,27,136,196,0,0,74,28,178,161,149,160,32,8,225,32,128,59,8,169,50,139,47,72,186,16,132,9,122,9,160,146,144,89,153, - 10,149,178,0,121,11,146,152,162,48,13,123,177,24,0,106,27,9,144,132,12,17,0,168,0,181,56,169,129,242,195,129,17,154,64,161,244,16,137,24,144,144,164,129,75,42,176,149,9,179,148,203,4,166,136,163,128,227,163,8,57,11,30,165,0,74,59,62,9,208,131,144,40, 76, - 26,27,196,129,1,25,43,49,174,67,153,136,106,152,41,25,28,2,43,44,104,45,59,8,43,128,144,120,25,12,17,152,9,130,155,151,145,74,40,13,48,192,58,90,43,43,177,146,49,31,75,24,217,131,0,76,26,152,149,161,24,74,154,193,166,145,32,27,161,164,176,135,152,24,193, - 162,146,164,58,227,193,148,161,128,18,234,130,180,145,2,200,1,163,186,98,184,129,149,153,49,42,186,151,242,129,1,43,8,177,212,165,8,40,137,24,8,144,90,9,25,48,44,46,24,138,40,144,108,58,27,128,181,128,80,29,42,152,162,130,25,106,136,11,148,8,144,128,136, - 112,139,80,153,24,136,129,46,0,60,129,208,1,3,13,57,168,144,1,242,17,9,26,2,185,27,55,140,73,137,179,16,192,3,145,143,33,9,171,135,160,17,137,10,151,168,3,178,44,17,208,144,167,0,40,155,16,167,152,18,144,26,160,199,1,136,91,136,160,178,150,161,1,10, 181, - 145,161,1,145,161,198,2,9,90,137,177,160,150,40,29,129,144,145,162,57,77,169,16,148,42,42,40,141,34,170,121,154,210,131,162,107,8,9,160,195,40,73,139,18,224,162,34,139,0,244,178,163,24,26,146,194,166,49,29,42,137,130,192,16,93,128,154,19,59, 11, 122, 11, - 146,177,120,42,26,43,164,152,17,60,63,137,128,48,10,58,92,9,59,91,75,139,32,25,25,61,74,28,177,40,130,74,29,73,168,130,128,48,14,8,77,9,25,26,179,211,32,78,26,41,152,161,180,89,59,9,153,166,160,3,26,57,106,154,88,184,40,1,27,58,73,143,131,169,3,161, 184, - 122,152,16,181,145,129,17,15,129,193,147,145,192,33,193,162,183,163,136,178,129,178,197,2,41,216,131,168,163,181,226,163,178,1,33,187,166,212,129,1,27,24,162,184,151,8,16,160,144,181,210,72,168,128,32,42,25,40,142,5,185,88,58,11,58,177,32,129,63,42, 136, - 186,53,29,75,58,144,144,129,77,128,11,144,133,29,40,152,24,161,129,80,155,60,3,12,89,8,60,152,152,49,136,47,57,224,129,16,41,90,139,162,147,170,51,169,27,17,95,26,26,160,5,139,48,76,10,228,146,1,136,44,161,147,209,130,137,73,224,1,162,195,32,210,177,180, - 179,148,145,154,132,242,146,1,152,32,192,1,144,155,7,177,168,5,138,178,148,152,150,136,89,152,9,41,196,145,40,28,16,8,10,178,167,24,1,44,123,137,136,145,194,48,27,74,26,192,179,135,136,88,27,10,177,163,164,128,73,24,31,8,0,192,149,144,129,9,106, 41, 200, - 161,151,41,138,0,24,226,162,49,42,11,90,136,136,152,17,145,10,63,40,11,56,245,162,16,26,73,11,144,135,137,58,106,10,25,8,57,137,28,33,129,156,113,10,10,161,18,8,153,77,3,217,0,1,242,128,193,18,128,75,60,178,154,37,45,58,29,144,1,184,66,41,29, 8, 145, 10, - 194,33,148,170,107,89,139,128,163,178,16,63,59,176,144,151,129,42,74,10,129,192,2,128,154,97,192,0,177,128,178,183,16,16,155,149,145,184,84,138,8,192,161,20,225,0,130,138,165,0,28,148,153,18,209,128,88,153,89,152,9,17,9,29,130,43,122,153,24, 32, 202, 49, - 24,43,106,154,130,193,27,51,29,28,133,138,65,11,123,25,10,40,152,44,130,26,43,148,45,73,140,33,8,153,88,128,61,144,42,59,225,128,18,155,50,75,186,20,202,120,144,42,92,176,162,165,25,2,169,152,135,185,19,152,8,146,160,123,195,137,132,209,0,16, 11, 2, 242, - 146,164,152,73,193,136,130,178,1,136,169,23,169,128,164,242,129,178,129,32,138,180,167,153,132,8,138,2,209,4,138,1,128,138,92,136,44,129,136,162,33,63,40,141,2,160,144,106,137,64,155,17,129,60,30,146,26,17,28,48,46,169,51,154,91,137,41,26,32,143,18, 138, - 1,32,28,123,177,9,181,195,56,57,14,145,161,17,17,31,41,152,145,194,194,20,153,41,9,243,129,180,0,128,45,16,43,170,135,144,16,25,42,137,242,163,194,16,0,57,14,130,194,178,16,33,30,8,59,211,163,160,5,137,44,10,17,170,3,120,9,44,146,136,131,140, 91, 9, 171, - 7,161,32,73,13,8,161,40,106,11,25,129,59,0,49,31,42,28,40,11,0,81,176,61,32,138,25,178,241,148,136,106,8,136,128,177,90,8,155,96,176,9,18,217,132,129,10,81,156,40,178,161,36,169,76,147,203,150,0,10,146,200,147,149,128,144,148,154,182,24,0,137,11,134,211, - 24,136,129,145,209,33,8,43,163,243,88,41,13,0,160,145,33,31,32,185,145,4,155,17,32,47,161,128,73,160,44,56,176,75,74,12,35,141,104,137,9,89,152,58,56,44,41,30,41,40,157,48,128,154,88,41,42,8,14,3,184,59,120,152,9,56,10,128,41,57,227,186,52,152,62, 8, 56, - 242,0,58,8,156,34,243,128,24,176,51,169,58,183,192,146,164,177,18,170,7,177,208,132,161,24,136,27,147,243,128,133,10,24,161,161,178,214,17,160,25,16,161,137,165,192,48,27,72,58,218,133,162,26,72,27,10,197,178,49,138,89,56,142,1,24,11,0,44,105, 10, 25, 0, - 194,9,3,47,8,138,147,18,28,48,202,147,199,146,25,161,0,145,194,163,57,11,146,248,130,32,57,63,154,16,48,14,128,144,209,133,26,56,154,182,162,195,18,152,44,194,180,168,5,24,137,138,35,192,232,66,176,161,24,41,26,244,129,163,160,75,129,226,147,40, 145, 61, - 13,130,177,17,137,112,170,130,0,136,75,152,177,241,34,0,59,156,51,186,178,91,132,137,137,122,1,45,28,50,172,57,108,8,26,136,32,152,46,144,131,171,4,152,18,141,148,1,216,32,9,60,169,66,152,128,72,90,201,1,17,201,136,3,195,26,73,133,200,176, 150, 146, 169, - 24,33,178,184,151,73,11,28,72,44,153,82,153,17,42,57,78,153,8,160,0,1,123,11,19,171,195,18,59,31,129,10,162,2,58,96,142,130,26,75,128,176,17,180,123,9,90,137,211,145,32,26,76,43,145,130,12,90,41,27,58,160,160,128,178,7,76,59,0,203,180,147,33,62,10,0,243, - 129,146,73,29,145,144,0,26,56,153,185,83,8,76,27,166,161,193,146,131,224,145,165,161,40,168,149,162,226,2,136,138,163,131,211,0,59,146,218,148,1,192,16,16,58,248,88,144,177,136,1,58,45,9,195,197,147,48,29,10,0,162,176,64,122,9,10,17,9,153,56, 75, 27, 31, - 72,136,9,129,129,61,45,59,10,161,18,122,43,59,41,169,34,155,130,131,219,120,162,27,49,208,160,131,156,66,12,145,50,240,16,136,12,162,40,129,130,15,129,162,146,180,83,139,58,217,129,177,4,0,169,197,163,144,242,131,168,179,179,17,197,145,178,164, 128, 160, - 211,2,244,163,145,162,129,212,177,163,17,208,163,195,180,57,24,170,182,164,129,0,60,60,169,149,162,177,122,26,24,136,136,133,43,27,178,56,77,24,128,240,0,2,44,46,8,128,193,146,64,27,42,16,193,25,0,192,148,11,52,47,153,147,243,0,24,73,28,144, 161, 150, 9, - 8,73,170,2,162,25,27,147,167,131,29,1,168,200,165,16,91,137,8,162,176,35,41,31,24,169,50,168,58,123,144,48,128,13,73,169,144,16,57,123,44,200,163,56,153,80,10,176,146,57,94,8,152,131,9,168,125,26,145,177,132,137,41,60,26,144,243,32,192,34,60, 43, 26, 16, - 249,164,16,58,61,11,130,243,146,2,42,44,27,128,165,137,49,45,28,16,43,8,211,48,28,152,105,9,9,163,161,169,35,107,42,232,164,130,168,72,42,168,210,148,144,136,129,3,217,194,50,27,192,41,210,147,40,76,226,1,161,1,155,132,145,147,171,67,173,210,132,161,106, - 137,56,169,209,131,64,13,129,9,194,17,57,61,169,17,128,40,31,16,10,162,57,61,75,139,40,242,17,58,59,138,179,144,50,105,140,179,243,57,40,26,9,243,130,24,29,57,128,210,129,25,59,91,137,162,178,72,27,181,168,19,129,8,184,231,147,178,32,28,184,198,148, 144, - 1,26,128,16,192,2,26,144,244,129,0,16,10,197,177,181,1,41,9,178,165,211,129,25,145,137,210,147,152,210,163,132,194,17,91,169,145,181,130,9,89,137,152,178,4,128,9,63,160,128,106,8,25,43,10,32,47,26,123,152,24,40,25,27,18,186,35,158,64,42,216,33,25,58, 58, - 45,184,147,29,72,46,9,0,178,146,58,77,26,25,209,165,128,145,17,153,128,129,148,240,129,1,40,31,0,152,242,163,16,59,44,24,243,146,128,1,26,26,179,213,145,130,176,131,40,25,145,219,179,167,8,33,59,14,176,166,16,136,74,128,176,128,149,8,8,209,148,152,0, 72, - 153,161,178,35,62,75,154,163,153,19,62,170,133,179,136,89,12,129,164,144,3,47,58,193,177,148,0,61,43,10,129,17,41,61,43,25,8,126,26,25,137,145,34,44,45,129,216,179,1,90,25,137,32,227,8,16,9,170,49,31,32,29,128,145,148,75,25,75,153,162,192,35,12, 80, 136, - 176,8,194,24,1,176,21,154,145,80,251,130,2,30,9,8,130,145,128,98,27,26,129,136,162,15,33,168,59,65,177,77,141,1,128,168,113,10,137,178,163,146,132,74,153,224,164,33,184,19,184,228,161,17,91,152,25,146,152,44,121,9,160,145,17,25,28,93,128,152,2,25,27,161, - 210,129,146,45,179,227,163,162,9,40,193,148,179,57,107,140,196,32,25,57,47,136,210,130,24,40,28,152,210,182,145,40,8,129,184,147,147,140,163,166,160,34,45,144,194,161,134,41,46,152,162,162,3,44,58,75,209,162,144,57,129,47,152,130,59,16,248,129,17,26, 57, - 9,29,167,2,60,42,138,136,209,130,90,42,42,176,146,178,120,28,8,160,145,16,33,31,1,8,160,129,128,242,164,32,152,177,146,213,196,128,40,26,160,163,180,146,108,60,144,144,136,147,137,40,90,161,3,17,219,243,33,184,130,60,136,243,178,179,132,26,8,168,212,147, - 16,57,42,31,145,145,160,32,43,184,66,45,180,33,140,226,1,91,152,16,144,193,162,48,77,25,137,153,17,178,78,0,0,16,14,90,152,153,19,129,13,123,137,129,160,1,73,44,9,129,0,153,120,10,9,162,195,32,139,28,151,161,2,128,26,45,193,146,48,29,146,153, 194, 5, 59, - 29,128,144,195,1,64,43,208,178,149,8,9,16,240,163,129,16,42,185,181,211,24,48,45,137,149,9,24,41,75,184,177,4,43,91,128,180,16,144,29,25,184,167,1,59,60,153,148,161,146,91,42,186,4,24,145,123,11,2,178,77,136,26,25,195,40,115,61,27,168,177,3,59,79,26, 25, - 144,1,48,13,56,154,248,1,16,9,129,8,2,178,31,130,153,162,20,15,33,170,56,40,29,28,128,152,149,144,56,120,11,162,212,129,144,145,59,180,243,147,145,144,16,152,48,241,0,161,176,1,134,10,129,200,166,144,128,121,26,24,177,178,196,48,75,138,41,180,195,26, 24, - 89,138,24,33,187,41,84,155,57,79,136,160,210,130,0,58,58,168,243,132,27,41,75,138,3,8,61,8,29,145,179,76,24,28,146,208,2,49,140,75,196,144,0,40,44,179,208,3,176,33,15,177,2,160,106,8,160,164,164,8,73,27,226,179,161,1,57,1,196,211,128,40,156,145,166, 178, - 131,29,128,145,162,165,40,27,216,146,135,144,40,160,194,177,145,20,139,200,151,178,17,136,40,25,205,130,17,11,17,129,156,38,26,25,137,179,163,11,79,16,12,146,147,143,89,25,136,136,25,48,26,46,129,40,29,42,29,8,145,2,56,27,62,8,25,212,161,48,43, 144, 129, - 29,145,144,41,106,10,107,43,184,131,1,36,61,13,138,2,194,1,16,27,75,186,181,151,8,1,161,138,211,129,2,59,248,129,16,0,144,63,152,150,136,24,25,128,30,161,128,17,24,225,146,10,16,0,9,227,183,129,40,60,26,162,194,181,24,90,9,24,0,176,161,193,194,35,12, 63, - 8,210,162,1,32,78,28,152,164,144,16,48,45,137,162,147,168,152,98,27,43,33,12,160,165,129,137,63,41,153,153,151,16,91,26,8,8,9,56,10,46,24,146,57,168,160,166,241,129,32,140,16,145,179,164,137,113,138,208,131,26,25,1,42,178,196,106,24,171,18,196,8, 18, 29, - 41,194,128,3,249,57,162,152,48,184,120,160,208,33,137,74,57,187,149,129,26,35,158,72,128,168,32,26,25,180,75,2,136,15,163,161,136,120,27,41,160,128,182,56,60,25,12,178,151,128,168,72,10,152,4,177,26,147,137,113,44,42,33,220,2,152,41,82,11, 210, 163, 184, - 133,162,10,196,128,3,234,40,149,152,161,1,44,129,194,4,225,16,58,168,24,194,146,146,154,49,21,218,33,152,248,129,194,147,0,28,1,195,162,20,140,42,25,160,198,1,33,136,142,3,25,24,141,16,177,208,112,0,138,41,160,130,45,60,32,170,73,24,75,59,161,176,49,159, - 97,26,168,149,145,32,28,25,184,211,129,179,74,73,8,153,136,193,151,160,32,48,143,9,147,181,145,32,60,9,187,133,166,144,32,152,25,136,161,150,168,145,81,10,42,0,169,182,148,136,58,41,187,182,211,131,16,137,25,243,144,129,2,9,8,202,7,25,185,21,144,136,153, - 65,184,137,56,151,10,153,49,16,145,14,56,176,11,192,19,89,91,44,168,147,2,8,147,63,27,1,136,229,129,73,26,136,26,137,81,170,147,77,72,12,42,42,192,24,104,91,26,27,65,177,27,32,41,60,14,136,17,170,150,129,24,58,11,16,251,162,19,57,31,0,152,129,145,17, 61, - 14,1,129,27,129,66,169,178,74,12,11,19,198,145,75,33,138,174,133,1,184,57,40,136,169,20,1,60,174,20,154,201,67,26,162,151,42,16,138,59,130,204,20,169,59,180,59,114,184,56,178,242,128,130,43,8,194,3,229,144,33,185,144,34,181,145,168,17,149,153,74,35, 220, - 129,128,1,88,59,75,225,136,130,168,17,144,12,151,8,25,179,8,1,240,16,8,25,145,211,41,130,138,115,169,160,163,168,84,154,74,0,170,144,211,149,2,30,128,137,9,149,1,144,58,60,57,153,178,150,17,29,27,74,25,195,152,56,15,1,25,26,152,149,80,153,57,73,140, 128, - 160,144,113,27,56,28,25,4,42,44,137,60,171,130,50,240,8,5,139,145,1,105,137,200,80,137,145,146,178,179,160,46,16,240,195,131,128,144,24,164,198,128,0,136,137,131,194,165,177,2,161,147,11,144,188,181,148,144,23,0,28,224,128,131,192,32,1,224,1,168,132,145, - 9,41,208,58,137,179,151,145,16,1,30,8,145,178,1,47,32,186,72,169,146,75,8,41,48,136,89,13,48,9,10,124,26,11,42,32,129,91,77,16,12,128,42,57,138,10,60,2,63,9,0,93,128,152,90,8,10,24,40,44,144,29,49,188,48,72,25,30,177,33,128,186,120,129,186,133, 152, 130, - 24,156,51,154,8,226,2,56,155,2,179,233,167,128,24,129,176,136,151,8,184,0,33,224,152,21,177,24,10,163,16,250,17,130,171,83,137,136,37,12,56,242,154,17,160,145,82,13,3,201,128,18,137,24,162,63,162,8,107,178,128,57,158,32,24,200,18,0,106,154,73,16, 248, 8, - 73,137,57,75,0,128,12,65,137,59,75,28,144,129,122,0,58,140,160,195,145,105,56,28,153,145,164,88,8,28,25,153,9,162,113,89,153,136,33,234,147,128,41,72,11,138,151,144,145,16,43,58,248,130,178,42,4,40,10,196,154,147,216,24,7,136,10,161,148,210,161, 98, 138, - 137,128,146,176,33,105,27,43,163,49,185,6,10,136,43,67,174,161,162,151,137,1,64,200,193,24,64,200,56,145,242,24,57,137,1,128,3,162,175,80,128,162,152,25,58,175,17,17,0,200,64,168,162,91,1,154,44,211,177,35,64,160,161,144,4,241,41,209,162,25,1,3,242, 176, - 134,153,42,41,136,135,154,2,130,46,41,161,153,180,145,34,26,46,18,242,137,146,129,25,128,11,151,161,40,179,27,122,168,59,137,181,50,172,36,56,15,9,129,137,128,75,2,58,12,52,141,8,24,58,153,157,122,145,9,1,80,27,184,32,74,219,50,57,168,153,180,48,28, 143, - 131,144,178,65,13,48,168,162,147,155,121,9,170,5,16,153,21,29,144,161,91,0,184,57,128,137,17,159,88,178,128,105,152,9,162,33,164,141,88,178,224,1,0,16,27,185,150,161,9,4,139,16,128,160,194,144,65,180,46,40,136,27,135,160,16,44,57,145,236,2,195,40,75,177, - 2,200,179,146,186,104,50,141,24,169,165,148,11,97,10,11,130,177,49,57,78,42,154,128,165,59,33,28,30,1,136,16,192,41,128,152,123,136,24,1,169,113,10,11,49,153,14,147,19,45,43,8,176,210,148,8,16,11,96,144,192,163,150,10,128,43,26,150,178,165,24,41,171, 18, - 27,215,1,8,128,136,40,35,208,11,161,193,18,73,154,133,155,165,164,10,49,154,8,199,0,2,168,64,192,0,40,162,43,202,180,150,10,106,24,185,145,131,184,113,43,24,162,187,73,146,42,81,171,121,58,155,151,16,43,32,31,9,160,146,17,136,94,10,24,145,25, 9, 130, 59, - 65,13,91,25,169,146,176,112,42,59,16,217,130,20,13,25,9,40,161,138,68,169,154,18,62,154,180,145,135,152,56,58,155,165,211,8,40,42,10,198,1,2,184,57,184,224,51,154,27,134,168,19,202,73,75,184,35,176,75,24,25,209,51,157,19,30,184,179,3,33,148,45, 232, 146, - 129,168,41,32,170,149,193,35,136,16,50,191,56,146,173,149,16,24,41,30,129,168,209,3,57,31,0,16,176,147,41,152,10,17,181,14,40,144,49,170,75,97,141,25,162,146,72,177,92,137,137,19,137,153,113,154,2,41,60,129,217,2,211,152,73,42,193,197,146,147, 10, 59, 0, - 192,196,132,41,160,25,88,169,16,40,241,1,153,81,28,10,147,161,209,88,75,9,161,162,180,16,43,57,235,33,56,156,129,144,2,135,31,128,145,136,163,56,59,154,57,167,160,105,137,0,138,163,3,41,47,185,211,131,41,41,60,139,182,146,16,16,43,242,144,145,129,16,179, - 183,1,26,9,147,240,131,160,91,74,152,184,166,178,33,140,9,4,162,233,34,136,129,144,163,60,142,144,149,128,33,73,13,161,194,131,0,26,56,142,128,163,128,1,233,56,209,41,145,194,147,179,149,64,30,8,128,216,18,24,43,43,32,153,25,74,109,137,153,48,8,137, 122, - 25,144,26,43,59,30,33,41,27,24,96,153,160,50,76,27,47,152,145,163,73,40,14,152,131,176,74,90,8,8,200,67,155,154,50,49,155,28,124,177,152,1,2,17,62,138,180,176,4,25,9,177,245,162,129,40,25,176,164,130,172,4,8,181,194,49,11,168,154,165,133,152,40,136, 226, - 179,19,26,185,16,167,194,16,25,57,243,136,147,1,31,25,184,132,160,33,62,138,129,130,41,121,137,153,145,26,17,107,136,179,1,61,60,26,162,168,148,64,31,25,32,168,152,64,31,137,8,129,33,62,24,137,8,16,59,47,153,33,162,91,59,41,170,145,5,43,60,41,13,178,134, - 57,153,12,194,227,8,2,128,57,208,162,19,216,32,178,25,128,160,48,194,195,37,155,10,33,251,163,146,16,136,12,166,195,160,148,129,176,147,178,150,160,72,162,162,193,162,60,200,145,5,144,25,122,216,129,161,130,0,10,73,1,241,2,9,168,33,13,161,165,24,64, 203, - 50,1,14,9,9,129,161,106,33,27,13,164,128,40,41,107,169,160,33,136,60,92,168,152,2,91,57,176,129,0,144,47,136,162,164,128,80,43,154,179,213,130,74,27,0,145,145,167,58,59,160,9,26,76,8,171,5,49,28,44,169,162,183,130,72,28,144,179,228,2,25,26,129, 186, 151, - 1,75,128,169,17,178,15,57,170,16,166,16,57,8,139,162,181,1,8,152,164,181,41,81,43,10,242,145,57,139,89,8,193,18,154,32,176,10,165,129,137,147,177,134,0,25,25,201,147,227,129,72,59,185,167,128,129,160,91,25,176,130,147,145,9,160,5,202,17,16, 186, 136, 37, - 177,56,76,42,169,186,48,9,145,57,24,128,41,169,134,137,145,147,28,41,168,131,228,32,27,9,60,129,178,64,60,45,25,9,24,152,49,31,136,57,42,0,25,12,181,18,153,57,96,169,177,132,153,123,9,152,129,177,17,74,43,24,169,128,121,137,25,1,139,96,42,10,146,178, 18, - 44,29,1,161,164,146,31,137,146,177,19,1,10,26,209,165,146,43,40,138,240,130,18,144,25,40,212,1,58,11,152,196,147,10,74,26,152,225,130,146,58,60,210,145,16,148,16,185,192,18,44,42,57,199,162,1,9,87,47,186,215,231,197,179,180,195,212,164,32,59,92, 126, 62, - 41,59,76,59,60,168,179,213,197,163,72,44,25,74,126,127,127,79,26,177,148,90,27,225,247,165,0,152,147,123,138,211,164,72,126,127,46,210,196,163,228,215,64,11,210,180,1,8,58,153,1,224,149,57,76,27,24,76,42,43,136,128,243,179,130,106,60,42,42,92,28,243,231, - 147,24,57,44,58,94,45,8,57,139,214,148,40,77,26,9,16,10,144,64,62,43,25,123,59,138,162,48,63,26,41,92,60,43,176,3,59,232,214,164,16,75,75,76,60,153,179,33,62,26,136,40,75,169,197,163,129,57,60,59,75,138,145,64,63,138,179,1,42,136,90,43,176,214,180,1, 25, - 152,195,129,129,106,76,60,137,145,178,2,25,10,228,130,57,59,44,41,154,165,105,76,44,144,16,76,26,41,76,26,152,1,58,26,9,193,165,16,92,26,41,77,59,76,76,60,26,136,161,130,152,195,163,211,146,0,57,11,211,130,8,25,40,62,153,162,17,109,60,153,146,40, 76, 60, - 26,160,179,211,163,32,60,42,153,179,194,199,130,24,58,43,58,27,128,161,195,129,226,196,147,90,59,75,44,136,128,145,160,148,123,59,42,26,41,26,57,27,192,215,147,57,59,27,161,145,213,130,106,76,43,9,144,162,129,177,181,130,136,194,146,40,10,129,25,210,146, - 178,197,196,179,196,130,8,41,9,144,178,130,209,182,17,92,43,176,147,144,212,130,136,0,177,130,73,62,10,161,130,91,75,59,43,57,46,25,41,77,10,177,164,16,26,136,210,197,179,130,128,57,77,43,25,75,10,227,179,180,179,146,128,57,185,183,163,145,0,8,8,10, 119, - 114,120,16,210,244,60,28,41,25,152,149,56,161,35,44,89,27,24,136,24,164,211,17,233,176,136,192,129,179,17,17,25,0,10,46,160,132,49,66,24,132,177,147,193,56,72,26,29,232,168,176,12,137,41,139,147,9,1,41,15,91,136,35,148,21,18,48,40,1,168,167,144,0,42,172, - 177,204,193,155,232,152,152,26,152,41,146,17,6,4,65,34,35,135,4,16,32,9,24,186,176,0,250,153,204,186,173,154,153,177,3,65,41,34,145,134,35,65,98,49,50,50,2,33,169,138,155,175,170,172,204,192,138,234,136,155,136,10,32,18,5,52,48,24,162,17,67,54,66,51, 34, - 131,184,174,234,153,10,9,40,0,152,251,168,142,154,9,16,33,49,33,128,154,170,156,34,54,54,33,68,0,1,136,201,137,26,88,48,35,99,8,152,189,189,187,155,171,16,24,130,145,188,175,203,144,49,115,67,67,50,19,2,1,0,0,130,131,1,136,206,216,188,203, 204, 187, 187, - 156,153,0,0,51,17,34,24,112,20,69,67,67,34,19,0,136,169,185,137,186,232,185,219,201,203,187,173,170,154,153,129,131,6,2,19,49,49,21,65,19,53,51,83,34,16,168,201,154,172,156,138,0,1,24,201,233,186,204,186,171,137,3,37,48,24,128,201,202,202,129,17, 48, 21, - 22,20,19,19,32,16,2,66,52,68,4,3,1,203,235,188,189,186,171,153,137,153,170,219,170,140,9,17,53,115,50,52,67,51,51,51,17,130,0,145,154,169,188,236,187,190,203,187,172,171,138,136,17,33,18,2,34,98,98,50,50,52,66,34,35,2,19,24,169,203,203,188,219, 169, 154, - 9,137,171,204,188,203,184,136,34,83,50,33,153,184,170,170,152,40,57,19,36,50,50,18,35,17,2,49,49,66,66,66,34,17,168,233,202,202,170,171,170,186,219,203,188,188,154,138,25,33,68,52,68,67,67,36,51,36,18,17,17,136,8,170,176,202,188,206,202,171,172,186, 169, - 153,8,25,144,128,1,34,68,52,68,51,52,34,49,18,34,2,144,136,155,140,187,186,186,154,154,185,185,153,9,9,0,24,0,128,144,168,169,170,154,154,153,9,8,16,8,0,144,19,35,68,51,52,67,51,66,34,50,33,1,144,185,186,172,204,187,188,173,172,186,172,186, 154, 138, 41, - 33,52,53,83,50,51,52,52,37,34,34,18,16,144,152,154,187,219,203,188,173,186,186,186,170,154,153,138,144,16,17,67,82,50,51,21,34,19,33,2,18,33,1,8,153,169,153,153,136,128,0,136,154,153,153,8,8,1,16,0,169,170,187,171,171,154,153,153,152,153,153,0,16,51, 83, - 66,50,67,50,51,67,51,52,35,18,136,186,219,187,189,186,171,187,173,187,188,187,203,138,9,16,33,50,52,53,67,67,147,8,128,128,128,128,128,128,128,128,0,240,255,55,232,23,220,0,148,1,9,18,148,10,189,32,163,62,160,5,137,12,149,42,153,144,34,42,8, 1, 138, 181, - 45,136,18,144,105,138,1,160,14,128,132,145,186,37,138,41,192,48,145,46,160,33,44,24,225,16,13,132,136,137,16,148,25,170,194,82,152,136,91,24,42,169,33,233,131,179,24,185,149,16,57,172,164,18,10,211,160,147,211,33,138,243,129,16,41,193,0,43, 132, 155, 73, - 58,145,244,145,43,35,9,171,16,110,25,8,28,74,162,128,26,27,82,45,136,153,18,8,136,8 -}; - } // End of namespace Kyra #undef EUPHONY_FADEOUT_TICKS diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 9ad2f50619..274acae22c 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -42,7 +42,7 @@ namespace Kyra { -#define RESFILE_VERSION 70 +#define RESFILE_VERSION 71 namespace { bool checkKyraDat(Common::SeekableReadStream *file) { diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp index 48eda97f80..9d20cdd51a 100644 --- a/engines/kyra/text_hof.cpp +++ b/engines/kyra/text_hof.cpp @@ -255,7 +255,8 @@ void KyraEngine_HoF::objectChatInit(const char *str, int object, int vocHigh, in _screen->hideMouse(); - if (textEnabled()) { + _chatTextEnabled = textEnabled(); + if (_chatTextEnabled) { objectChatPrintText(str, object); _chatEndTime = _system->getMillis() + chatCalcDuration(str) * _tickLength; } else { diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp index 79b16bc1be..40f2217a2b 100644 --- a/engines/kyra/text_lok.cpp +++ b/engines/kyra/text_lok.cpp @@ -32,10 +32,9 @@ namespace Kyra { -void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const char *chatStr, uint8 charNum) { +void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const char *chatStr, uint8 charNum, const bool printText) { bool hasUpdatedNPCs = false; bool runLoop = true; - bool drawText = textEnabled(); uint8 currPage; uint32 timeToEnd = strlen(chatStr) * 8 * _tickLength + _system->getMillis(); @@ -92,7 +91,7 @@ void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const _animator->preserveAnyChangedBackgrounds(); _animator->prepDrawAllObjects(); - if (drawText) { + if (printText) { currPage = _screen->_curPage; _screen->_curPage = 2; _text->printCharacterText(chatStr, charNum, _characterList[charNum].x1); @@ -102,7 +101,7 @@ void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const _animator->copyChangedObjectsForward(0); updateTextFade(); - if (((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1 && drawText) || (!drawText && !snd_voiceIsPlaying())) + if (((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1 && printText) || (!printText && !snd_voiceIsPlaying())) break; uint32 nextTime = loopStart + _tickLength; @@ -293,7 +292,9 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu _text->_talkMessageY = yPos; _text->_talkMessageH = lineNum * 10; - if (textEnabled()) { + const bool printText = textEnabled(); + + if (printText) { _animator->restoreAllObjectBackgrounds(); _screen->copyRegion(12, _text->_talkMessageY, 12, 136, 296, _text->_talkMessageH, 2, 2); @@ -310,9 +311,9 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu if (!speechEnabled()) vocFile = -1; - waitForChatToFinish(vocFile, chatTicks, chatStr, charNum); + waitForChatToFinish(vocFile, chatTicks, chatStr, charNum, printText); - if (textEnabled()) { + if (printText) { _animator->restoreAllObjectBackgrounds(); _screen->copyRegion(12, 136, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 2); diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp index ea2dc48031..726d9e339f 100644 --- a/engines/kyra/text_mr.cpp +++ b/engines/kyra/text_mr.cpp @@ -265,7 +265,8 @@ void KyraEngine_MR::objectChatInit(const char *str, int object, int vocHigh, int _screen->hideMouse(); - if (textEnabled()) { + _chatTextEnabled = textEnabled(); + if (_chatTextEnabled) { objectChatPrintText(str, object); _chatEndTime = _system->getMillis() + chatCalcDuration(str) * _tickLength; } else { diff --git a/engines/kyra/timer_hof.cpp b/engines/kyra/timer_hof.cpp index 117b84f48a..d8f86e30a2 100644 --- a/engines/kyra/timer_hof.cpp +++ b/engines/kyra/timer_hof.cpp @@ -97,6 +97,9 @@ void KyraEngine_HoF::setTimer1DelaySecs(int secs) { } void KyraEngine_HoF::setWalkspeed(uint8 newSpeed) { + if (!_timer) + return; + if (newSpeed < 5) newSpeed = 3; else diff --git a/engines/kyra/timer_lok.cpp b/engines/kyra/timer_lok.cpp index 40426a3dfe..6f4948c279 100644 --- a/engines/kyra/timer_lok.cpp +++ b/engines/kyra/timer_lok.cpp @@ -188,6 +188,9 @@ void KyraEngine_LoK::timerRedrawAmulet(int timerNum) { } void KyraEngine_LoK::setWalkspeed(uint8 newSpeed) { + if (!_timer) + return; + static const uint8 speeds[] = { 11, 9, 6, 5, 3 }; assert(newSpeed < ARRAYSIZE(speeds)); diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp index a45a4294c8..17456b8ec3 100644 --- a/engines/mohawk/video.cpp +++ b/engines/mohawk/video.cpp @@ -342,7 +342,7 @@ VideoHandle VideoManager::createVideoHandle(uint16 id, uint16 x, uint16 y, bool entry.loop = loop; entry.enabled = true; entry->setChunkBeginOffset(_vm->getResourceOffset(ID_TMOV, id)); - entry->load(*_vm->getRawData(ID_TMOV, id)); + entry->load(_vm->getRawData(ID_TMOV, id)); // Search for any deleted videos so we can take a formerly used slot for (uint32 i = 0; i < _videoStreams.size(); i++) @@ -378,7 +378,7 @@ VideoHandle VideoManager::createVideoHandle(Common::String filename, uint16 x, u return NULL_VID_HANDLE; } - entry->load(*file); + entry->load(file); // Search for any deleted videos so we can take a formerly used slot for (uint32 i = 0; i < _videoStreams.size(); i++) diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp index 5cda4e3208..74bb52f574 100644 --- a/engines/queen/queen.cpp +++ b/engines/queen/queen.cpp @@ -422,7 +422,7 @@ void QueenEngine::makeGameStateName(int slot, char *buf) const { int QueenEngine::getGameStateSlot(const char *filename) const { int i = -1; const char *slot = strrchr(filename, '.'); - if (slot && slot[1] == 's') { + if (slot && (slot[1] == 's' || slot[1] == 'S')) { i = atoi(slot + 2); } return i; diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 20acbed450..2432d84faa 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -67,7 +67,7 @@ bool g_debug_track_mouse_clicks = false; static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeValue); Console::Console(SciEngine *engine) : GUI::Debugger(), - _engine(engine), _debugState(engine->_debugState) { + _engine(engine), _debugState(engine->_debugState), _enterTime(0) { // Variables DVar_Register("sleeptime_factor", &g_debug_sleeptime_factor, DVAR_INT, 0); @@ -176,10 +176,12 @@ Console::Console(SciEngine *engine) : GUI::Debugger(), DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete)); DCmd_Register("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias DCmd_Register("bc", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias - DCmd_Register("bp_exec_method", WRAP_METHOD(Console, cmdBreakpointExecMethod)); - DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointExecMethod)); // alias - DCmd_Register("bp_exec_function", WRAP_METHOD(Console, cmdBreakpointExecFunction)); - DCmd_Register("bpe", WRAP_METHOD(Console, cmdBreakpointExecFunction)); // alias + DCmd_Register("bp_method", WRAP_METHOD(Console, cmdBreakpointMethod)); + DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointMethod)); // alias + DCmd_Register("bp_kernel", WRAP_METHOD(Console, cmdBreakpointKernel)); + DCmd_Register("bpk", WRAP_METHOD(Console, cmdBreakpointKernel)); // alias + DCmd_Register("bp_function", WRAP_METHOD(Console, cmdBreakpointFunction)); + DCmd_Register("bpe", WRAP_METHOD(Console, cmdBreakpointFunction)); // alias // VM DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps)); DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist)); @@ -214,6 +216,7 @@ Console::~Console() { void Console::preEnter() { if (g_sci && g_sci->_soundCmd) g_sci->_soundCmd->pauseAll(true); + _enterTime = g_system->getMillis(); } void Console::postEnter() { @@ -272,6 +275,9 @@ void Console::postEnter() { _videoFile.clear(); _videoFrameDelay = 0; } + + // Subtract the time we were running the debugger from the game running time + _engine->_gamestate->gameStartTime += g_system->getMillis() - _enterTime; } bool Console::cmdHelp(int argc, const char **argv) { @@ -380,8 +386,9 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf("Breakpoints:\n"); DebugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n"); DebugPrintf(" bp_del / bpdel / bc - Deletes a breakpoint with the specified index\n"); - DebugPrintf(" bp_exec_method / bpx - Sets a breakpoint on the execution of the specified method\n"); - DebugPrintf(" bp_exec_function / bpe - Sets a breakpoint on the execution of the specified exported function\n"); + DebugPrintf(" bp_method / bpx - Sets a breakpoint on the execution or access of a specified method/selector\n"); + DebugPrintf(" bp_kernel / bpk - Sets a breakpoint on execution of a kernel function\n"); + DebugPrintf(" bp_function / bpe - Sets a breakpoint on the execution of the specified exported function\n"); DebugPrintf("\n"); DebugPrintf("VM:\n"); DebugPrintf(" script_steps - Shows the number of executed SCI operations\n"); @@ -840,6 +847,7 @@ bool Console::cmdVerifyScripts(int argc, const char **argv) { } DebugPrintf("SCI1.1-SCI2.1 script check finished\n"); + delete resources; return true; } @@ -1002,6 +1010,7 @@ bool Console::cmdShowInstruments(int argc, const char **argv) { DebugPrintf("\n\n"); } + delete resources; return true; } @@ -1047,7 +1056,6 @@ bool Console::cmdList(int argc, const char **argv) { ++itr; } DebugPrintf("\n"); - delete resources; } @@ -2711,7 +2719,7 @@ bool Console::cmdLogKernel(int argc, const char **argv) { return true; } - if (g_sci->getKernel()->debugSetFunctionLogging(argv[1], logging)) + if (g_sci->getKernel()->debugSetFunction(argv[1], logging, -1)) DebugPrintf("Logging %s for k%s\n", logging ? "enabled" : "disabled", argv[1]); else DebugPrintf("Unknown kernel function %s\n", argv[1]); @@ -2789,10 +2797,10 @@ bool Console::cmdBreakpointDelete(int argc, const char **argv) { return true; } -bool Console::cmdBreakpointExecMethod(int argc, const char **argv) { +bool Console::cmdBreakpointMethod(int argc, const char **argv) { if (argc != 2) { - DebugPrintf("Sets a breakpoint on the execution of the specified method.\n"); - DebugPrintf("Usage: %s <method name>\n", argv[0]); + DebugPrintf("Sets a breakpoint on execution/access of a specified method/selector.\n"); + DebugPrintf("Usage: %s <name>\n", argv[0]); DebugPrintf("Example: %s ego::doit\n", argv[0]); DebugPrintf("May also be used to set a breakpoint that applies whenever an object\n"); DebugPrintf("of a specific type is touched: %s foo::\n", argv[0]); @@ -2812,7 +2820,23 @@ bool Console::cmdBreakpointExecMethod(int argc, const char **argv) { return true; } -bool Console::cmdBreakpointExecFunction(int argc, const char **argv) { +bool Console::cmdBreakpointKernel(int argc, const char **argv) { + if (argc != 2) { + DebugPrintf("Sets a breakpoint on execution of a kernel function.\n"); + DebugPrintf("Usage: %s <name>\n", argv[0]); + DebugPrintf("Example: %s DrawPic\n", argv[0]); + return true; + } + + if (g_sci->getKernel()->debugSetFunction(argv[1], -1, true)) + DebugPrintf("Breakpoint enabled for k%s\n", argv[1]); + else + DebugPrintf("Unknown kernel function %s\n", argv[1]); + + return true; +} + +bool Console::cmdBreakpointFunction(int argc, const char **argv) { // TODO/FIXME: Why does this accept 2 parameters (the high and the low part of the address)?" if (argc != 3) { DebugPrintf("Sets a breakpoint on the execution of the specified exported function.\n"); diff --git a/engines/sci/console.h b/engines/sci/console.h index 234272bbab..60599ea783 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -134,8 +134,9 @@ private: // Breakpoints bool cmdBreakpointList(int argc, const char **argv); bool cmdBreakpointDelete(int argc, const char **argv); - bool cmdBreakpointExecMethod(int argc, const char **argv); - bool cmdBreakpointExecFunction(int argc, const char **argv); + bool cmdBreakpointMethod(int argc, const char **argv); + bool cmdBreakpointKernel(int argc, const char **argv); + bool cmdBreakpointFunction(int argc, const char **argv); // VM bool cmdScriptSteps(int argc, const char **argv); bool cmdVMVarlist(int argc, const char **argv); @@ -163,6 +164,7 @@ private: bool _mouseVisible; Common::String _videoFile; int _videoFrameDelay; + uint32 _enterTime; }; } // End of namespace Sci diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 3698964de5..e330bd5f30 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -299,7 +299,7 @@ Common::String convertSierraGameId(Common::String sierraId, uint32 *gameFlags, R if (sierraId == "fp" || sierraId == "gk" || sierraId == "pq4") demoThreshold = 150; - Common::List<ResourceId> *resources = resMan->listResources(kResourceTypeScript, -1); + Common::ScopedPtr<Common::List<ResourceId> > resources(resMan->listResources(kResourceTypeScript, -1)); if (resources->size() < demoThreshold) { *gameFlags |= ADGF_DEMO; @@ -496,8 +496,8 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl filename.contains("patch.005") || filename.contains("bank.001")) s_fallbackDesc.platform = Common::kPlatformAmiga; - // The existence of 7.pat indicates a Mac game - if (filename.contains("7.pat")) + // The existence of 7.pat or patch.200 indicates a Mac game + if (filename.contains("7.pat") || filename.contains("patch.200")) s_fallbackDesc.platform = Common::kPlatformMacintosh; // The data files for Atari ST versions are the same as their DOS counterparts @@ -627,7 +627,7 @@ bool SciMetaEngine::hasFeature(MetaEngineFeature f) const { bool SciEngine::hasFeature(EngineFeature f) const { return - //(f == kSupportsRTL) || + (f == kSupportsRTL) || (f == kSupportsLoadingDuringRuntime); // || //(f == kSupportsSavingDuringRuntime); // We can't allow saving through ScummVM menu, because diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index da3763b236..0614eff6e6 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -32,7 +32,7 @@ namespace Sci { {"sci-fanmade", name, { \ {"resource.map", 0, resMapMd5, resMapSize}, \ {"resource.001", 0, resMd5, resSize}, \ - {NULL, 0, NULL, 0}}, lang, Common::kPlatformPC, 0, GUIO_NOSPEECH \ + AD_LISTEND}, lang, Common::kPlatformPC, 0, GUIO_NOSPEECH \ } #define FANMADE(name, resMapMd5, resMapSize, resMd5, resSize) FANMADE_L(name, resMapMd5, resMapSize, resMd5, resSize, Common::EN_ANY) @@ -47,7 +47,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"astrochicken", "", { {"resource.map", 0, "f3d1be7752d30ba60614533d531e2e98", 474}, {"resource.001", 0, "6fd05926c2199af0af6f72f90d0d7260", 126895}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Castle of Dr. Brain - English Amiga (from www.back2roots.org) @@ -59,10 +59,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "3fb02ce493f6eacdcc3713851024f80e", 559540}, {"resource.002", 0, "d226d7d3b4f77c4a566913fc310487fc", 792380}, {"resource.003", 0, "d226d7d3b4f77c4a566913fc310487fc", 464348}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, - // Castle of Dr. Brain - German Amiga (from www.back2roots.org) + // Castle of Dr. Brain - German Amiga (from www.back2roots.org, also includes english language) // Executable scanning reports "1.005.001" // SCI interpreter version 1.000.510 {"castlebrain", "", { @@ -71,8 +71,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "4e0836fadc324316c1a418125709ba45", 569057}, {"resource.002", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 826309}, {"resource.003", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 493638}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Castle of Dr. Brain - English DOS Non-Interactive Demo // SCI interpreter version 1.000.005 @@ -80,7 +80,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "467bb5e3224bb54640c3280032aebff5", 633}, {"resource.000", 0, "9780f040d58182994e22d2e34fab85b0", 67367}, {"resource.001", 0, "2af49dbd8f2e1db4ab09f9310dc91259", 570553}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Castle of Dr. Brain - English DOS Floppy EGA (from omer_mor, bug report #3035349) @@ -93,7 +93,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "5e7b90949422de005f80285979972e43", 292423}, {"resource.005", 0, "8a5ed3ba96e2eaf18e36fedfaab89419", 297838}, {"resource.006", 0, "dceed92e709cad1bd9582809a235b0a0", 266682}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Castle of Dr. Brain - English DOS Floppy (from jvprat) @@ -104,7 +104,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 346731}, {"resource.001", 0, "d2f5a1be74ed963fa849a76892be5290", 794832}, {"resource.002", 0, "c0c29c51af66d65cb53f49e785a2d978", 1280907}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Castle of Dr. Brain - English DOS Floppy 1.1 @@ -113,24 +113,39 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 347071}, {"resource.001", 0, "13e81e1839cd7b216d2bb5615c1ca160", 796776}, {"resource.002", 0, "930e416bec196b9703a331d81b3d66f2", 1283812}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, - // Castle of Dr. Brain - Spanish DOS + // Castle of Dr. Brain - English DOS Floppy 1.000 + // Reported by graxer in bug report #3037942 + {"castlebrain", "", { + {"resource.map", 0, "453daa935535cef68d19704c2b1b78a2", 2649}, + {"resource.000", 0, "6e125f4ce3f4f5c35f2617c7b66c6e21", 25929}, + {"resource.001", 0, "4891faa2f6594c622e482f0ddce24fb4", 99404}, + {"resource.002", 0, "aebb56d5d005557ca0d122a03aa85386", 322459}, + {"resource.003", 0, "278ec1e6132c7be844d433dd23beb318", 335156}, + {"resource.004", 0, "fca1c3f2be660185206f004bda09f4fb", 333549}, + {"resource.005", 0, "9294e55da1e83708ad3104b2a3963e18", 327537}, + {"resource.006", 0, "1d778a0c65cac9ddbab65495e50a94ee", 335281}, + {"resource.007", 0, "063bb8ce4157c778cf30d1c912c006f1", 335631}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + + // Castle of Dr. Brain - Spanish DOS (also includes english language) // SCI interpreter version 1.000.510 {"castlebrain", "", { {"resource.map", 0, "5738c163e014bbe046474de009020b82", 2727}, {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 1197694}, {"resource.001", 0, "735be4e58957180cfc807d5e18fdffcd", 1433302}, - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Christmas Card 1988 - English DOS // SCI interpreter version 0.000.294 {"christmas1988", "", { {"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426}, {"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Christmas Card 1990: The Seasoned Professional - English DOS (16 Colors) @@ -138,7 +153,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"christmas1990", "16 Colors", { {"resource.map", 0, "8f656714a05b94423ac6eb10ee8797d0", 600}, {"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 272629}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Christmas Card 1990: The Seasoned Professional - English DOS (256 Colors) @@ -146,7 +161,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"christmas1990", "256 Colors", { {"resource.map", 0, "44b8f45b841b9b5e17e939a35e443988", 600}, {"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 335362}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Christmas Card 1992 - English DOS @@ -154,7 +169,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"christmas1992", "", { {"resource.map", 0, "f1f8c8a8443f523422af70b4ec85b71c", 318}, {"resource.000", 0, "62fb9256f8e7e6e65a6875efdb7939ac", 203396}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Codename: Iceman - English Amiga (from www.back2roots.org) @@ -168,7 +183,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 619219}, {"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 713382}, {"resource.005", 0, "605b67a9ef199a9bb015745e7c004cf4", 478384}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Codename: Iceman - English DOS Non-Interactive Demo @@ -176,7 +191,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"iceman", "Demo", { {"resource.map", 0, "782974f29d8a824782d2d4aea39964e3", 1056}, {"resource.001", 0, "d4b75e280d1c3a97cfef1b0bebff387c", 573647}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Codename: Iceman - English DOS (from jvprat) @@ -189,7 +204,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "36670a917550757d57df84c96cf9e6d9", 566549}, {"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 624303}, {"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 670883}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Codename: Iceman - English DOS (from FRG) @@ -201,7 +216,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "250b859381ebf2bf8922bd99683b0cc1", 566464}, {"resource.003", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 622118}, {"resource.004", 0, "64f342463f6f35ba71b3509ef696ae3f", 669188}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Codename: Iceman - English DOS 1.023 (from abevi, bug report #2612718) @@ -215,7 +230,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 330653}, {"resource.006", 0, "08050329aa113a9f14ed99cbfe3536ec", 232942}, {"resource.007", 0, "64f342463f6f35ba71b3509ef696ae3f", 267702}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Conquests of Camelot - English Amiga (from www.back2roots.org) @@ -230,7 +245,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "6821dc97cf643ba521a4e840dda3c58b", 647410}, {"resource.005", 0, "c6e551bdc24f0acc193159038d4ca767", 605882}, {"resource.006", 0, "8f880a536908ab496bbc552f7f5c3738", 585255}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Conquests of Camelot - English DOS Non-Interactive Demo @@ -238,7 +253,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"camelot", "Demo", { {"resource.map", 0, "f4cd75c15be75e04cdca3acda2c0b0ea", 468}, {"resource.001", 0, "4930708722f34bfbaa4945fb08f55f61", 232523}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Conquests of Camelot - English DOS (from jvprat) @@ -250,7 +265,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 722250}, {"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712}, {"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Conquests of Camelot - English DOS @@ -264,7 +279,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "8e1a3a8c588007404b532b8dfacc1460", 345734}, {"resource.006", 0, "8e1a3a8c588007404b532b8dfacc1460", 332446}, {"resource.007", 0, "8e1a3a8c588007404b532b8dfacc1460", 358182}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Conquests of the Longbow - English Amiga (from www.back2roots.org) @@ -279,7 +294,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "d1038c75d85a6650d48e07d174a6a913", 838175}, {"resource.005", 0, "1c3804e56b114028c5873a35c2f06d13", 653002}, {"resource.006", 0, "f9487732289a4f4966b4e34eea413325", 842817}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Conquests of the Longbow - English DOS @@ -293,7 +308,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1064637}, {"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1154950}, {"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1042966}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Conquests of the Longbow - English DOS Floppy (from jvprat) @@ -307,7 +322,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "1867136d01ece57b531032d466910522", 823686}, {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1261462}, {"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284720}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Conquests of the Longbow - English DOS @@ -320,7 +335,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "1867136d01ece57b531032d466910522", 823610}, {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1260237}, {"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284609}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Conquests of the Longbow EGA - English DOS @@ -334,18 +349,17 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631}, {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243}, {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Conquests of the Longbow - English DOS Non-Interactive Demo // SCI interpreter version 1.000.510 {"longbow", "Demo", { {"resource.map", 0, "cbc5cb73341de1bff1b1e20a640af220", 588}, {"resource.001", 0, "f05a20cc07eee85da8e999d0ac0f596b", 869916}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, - // Conquests of the Longbow - German DOS (suplied by markcoolio in bug report #2727681) + // Conquests of the Longbow - German DOS (suplied by markcoolio in bug report #2727681, also includes english language) // SCI interpreter version 1.000.510 {"longbow", "", { {"resource.map", 0, "7376b7a07f8bd3a8ab8d67595d3f5b51", 6285}, @@ -356,8 +370,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1101869}, {"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1176914}, {"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1123585}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Eco Quest - English DOS Non-Interactive Demo (from FRG) // Executable scanning reports "x.yyy.zzz" @@ -365,16 +379,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ecoquest", "Demo", { {"resource.map", 0, "c819e171359b7c95f4c13b846d5c034e", 873}, {"resource.001", 0, "baf9393a9bfa73098adb501e5bc5487b", 657518}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Eco Quest - English DOS CD 1.1 // SCI interpreter version 1.001.064 {"ecoquest", "CD", { {"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804}, {"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Eco Quest - English DOS Floppy @@ -385,7 +398,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "96d4435d24c01f1c1675e46457604c5f", 1413719}, {"resource.002", 0, "28fe9b4f0567e71feb198bc9f3a2c605", 1241816}, {"resource.003", 0, "f3146df0ad4297f5ce35aa8c4753bf6c", 586832}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Eco Quest - English DOS Floppy @@ -396,10 +409,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212161}, {"resource.002", 0, "323b3b12f43d53f27d259beb225f0aa7", 1129316}, {"resource.003", 0, "83ac03e4bddb2c1ac2d36d2a587d0536", 1145616}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, - // Eco Quest - German DOS Floppy (supplied by markcoolio in bug report #2723744) + // Eco Quest - German DOS Floppy (supplied by markcoolio in bug report #2723744, also includes english language) // SCI interpreter version 1.000.510 {"ecoquest", "Floppy", { {"resource.map", 0, "7a9b43bf27dc000ac8559ecbe824b659", 4395}, @@ -407,10 +420,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212060}, {"resource.002", 0, "02d7d0411f7903aacb3bc8b0f8ca8a9a", 1202581}, {"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1175835}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Eco Quest - Spanish DOS Floppy (from jvprat) + // Eco Quest - Spanish DOS Floppy (from jvprat, also includes english language) // Executable scanning reports "1.ECO.013", VERSION file reports "1.000, 11.12.92" // SCI interpreter version 1.000.510 {"ecoquest", "Floppy", { @@ -419,10 +432,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212060}, {"resource.002", 0, "2d21a1d2dcbffa551552e3e0725d2284", 1186033}, {"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1174993}, - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Eco Quest - French DOS Floppy (from Strangerke) + // Eco Quest - French DOS Floppy (from Strangerke, also includes english language) // SCI interpreter version 1.ECO.013 {"ecoquest", "Floppy", { {"resource.map", 0, "67742945cd59b896d9f22a549f605217", 4407}, @@ -430,15 +443,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "fc7fba54b6bb88fd7e9c229636599aa9", 1205841}, {"resource.002", 0, "b836c6ee9de67d814ac5d1b05f5b9858", 1173872}, {"resource.003", 0, "f8f767f9d6351432621c6e54c1b2ba8c", 1141520}, - {NULL, 0, NULL, 0}}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Eco Quest 2 - English DOS Non-Interactive Demo // SCI interpreter version 1.001.055 {"ecoquest2", "Demo", { {"resource.map", 0, "607cfa0d8a03b7d348c06ee727e3d939", 1321}, {"resource.000", 0, "dd6f614c43c029f063e93cd243af90a4", 525992}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Eco Quest 2 - English DOS Floppy (supplied by markcoolio in bug report #2723761) @@ -446,7 +459,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ecoquest2", "Floppy", { {"resource.map", 0, "28fb7b6abb9fc1cb8882d7c2e701b63f", 5658}, {"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4208192}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Eco Quest 2 - French DOS Floppy (from Strangerke) @@ -454,7 +467,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ecoquest2", "Floppy", { {"resource.map", 0, "c22ab8b33c339c138b6b1697b77b9e79", 5588}, {"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4231946}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Freddy Pharkas - English DOS demo (from FRG) @@ -462,7 +475,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"freddypharkas", "Demo", { {"resource.map", 0, "97aa9fcfe84c9993a64debd28c32393a", 1909}, {"resource.000", 0, "5ea8e7a3ea10cce6efd5c106dc62fd8c", 867724}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Freddy Pharkas - English CD (from FRG) @@ -470,7 +483,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"freddypharkas", "CD", { {"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058}, {"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Freddy Pharkas - English DOS Floppy (updated information from markcoolio in bug reports #2723773 and #2724720) @@ -480,7 +493,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "554f65315d851184f6e38211489fdd8f", -1}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Freddy Pharkas - Windows (supplied by abevi in bug report #2612718) @@ -489,7 +502,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"freddypharkas", "Floppy", { {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, {"resource.000", 0, "fed4808fdb72486908ac7ad0044b14d8", 5233230}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, // Freddy Pharkas - German DOS Floppy (from Tobis87, updated information from markcoolio in bug reports #2723772 and #2724720) @@ -499,7 +512,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "304b5a5781800affd2235152a5794fa8", -1}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Freddy Pharkas - Spanish DOS (from jvprat) @@ -512,7 +525,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "419dbd5366f702b4123dedbbb0cffaae", 1456640}, {"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310}, {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE }, // Freddy Pharkas - Spanish DOS (from jvprat) @@ -522,7 +535,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Freddy Pharkas - English DOS CD Demo @@ -530,7 +543,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"freddypharkas", "CD Demo", { {"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918}, {"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE }, // Fun Seeker's Guide - English DOS @@ -538,7 +551,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"funseeker", "", { {"resource.map", 0, "7ee6859ef74314f6d91938c3595348a9", 282}, {"resource.001", 0, "f1e680095424e31f7fae1255d36bacba", 40692}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Gabriel Knight - English DOS CD Demo @@ -546,7 +559,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "CD Demo", { {"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490}, {"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE }, #ifdef ENABLE_SCI32 @@ -555,16 +568,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "", { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10783}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Gabriel Knight - English DOS Floppy (supplied my markcoolio in bug report #2723777) // SCI interpreter version 2.000.000 {"gk1", "", { {"resource.map", 0, "65e8c14092e4c9b3b3538b7602c8c5ec", 10783}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Gabriel Knight - German DOS Floppy (supplied my markcoolio in bug report #2723775) @@ -572,7 +584,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "", { {"resource.map", 0, "ad6508b0296b25c07b1f58828dc33696", 10789}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13077029}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Gabriel Knight - English DOS CD (from jvprat) @@ -580,7 +592,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "CD", { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Gabriel Knight - German DOS CD (from Tobis87) @@ -588,7 +600,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "CD", { {"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE }, // Gabriel Knight - Spanish DOS CD (from jvprat) @@ -596,7 +608,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "CD", { {"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE }, // Gabriel Knight - French DOS CD (from Hkz) @@ -604,7 +616,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "CD", { {"resource.map", 0, "55f909ba93a2515042a08d8a2da8414e", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13325145}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE }, // Gabriel Knight - English Windows CD (from jvprat) @@ -612,7 +624,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "CD", { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE }, // Gabriel Knight - German Windows CD (from Tobis87) @@ -620,7 +632,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "CD", { {"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NONE }, // Gabriel Knight - Spanish Windows CD (from jvprat) @@ -628,7 +640,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk1", "CD", { {"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformWindows, 0, GUIO_NONE }, // Gabriel Knight 2 - English Windows Non-Interactive Demo @@ -636,7 +648,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"gk2", "Demo", { {"resource.map", 0, "e0effce11c4908f4b91838741716c83d", 1351}, {"resource.000", 0, "d04cfc7f04b6f74d13025378be49ec2b", 4640330}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Gabriel Knight 2 - English DOS (from jvprat) @@ -654,7 +666,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.005", 0, "14b62d4a3bddee57a03cb1495a798a0f", 38075705}, {"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977}, {"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Gabriel Knight 2 - French DOS (6-CDs Sierra Originals reedition) @@ -672,7 +684,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.005", 0, "1eb5a72744799f5a5518543f5b4c3c79", 37882126}, {"resmap.006", 0, "11b2e722170b8c93fdaa5428e2c7676f", 3001}, {"ressci.006", 0, "4037d941aec39d2e654e20960429aefc", 60568486}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, @@ -685,7 +697,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 162783}, {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342309}, {"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328912}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Hoyle 1 - English DOS (supplied by merkur in bug report #2719227) @@ -693,7 +705,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"hoyle1", "", { {"resource.map", 0, "1034a218943d12f1f36e753fa10c95b8", 4386}, {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518308}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, #if 0 // TODO: unknown if these files are corrupt @@ -703,7 +715,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "2a72b1aba65fa6e339370eb86d8601d1", 5166}, {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 218755}, {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 439502}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, #endif @@ -713,7 +725,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "4f894d203f64aa23d9ff64d30ae36926", 2100}, {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 98138}, {"resource.002", 0, "8f2dd70abe01112eca464cda818b5eb6", 196631}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Hoyle 2 - English Amiga (from www.back2roots.org) @@ -722,9 +734,16 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"hoyle2", "", { {"resource.map", 0, "62ed48d20c580e5a98f102f7cd93706a", 1356}, {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 222704}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + + // Hoyle 2 - English Macintosh + // Executable scanning reports "x.yyy.zzz" + {"hoyle2", "", { + {"resource.map", 0, "1af1d3aa3cf564f93477c9f87e53f495", 1728}, + {"resource.001", 0, "b73b8131669d69d41a326415e4519138", 482882}, {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH - }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, #if 0 // TODO: unknown if these files are corrupt // Hoyle 3 - English Amiga (from www.back2roots.org) @@ -734,7 +753,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f1f158e428398cb87fc41fb4aa8c2119", 2088}, {"resource.000", 0, "595b6039ea1356e7f96a52c58eedcf22", 355791}, {"resource.001", 0, "143df8aef214a2db34c2d48190742012", 632273}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, #endif @@ -744,7 +763,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"hoyle3", "Demo", { {"resource.map", 0, "0d06cacc87dc21a08cd017e73036f905", 735}, {"resource.001", 0, "24db2bccda0a3c43ac4a7b5edb116c7e", 797678}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Hoyle 3 - English DOS Floppy (from jvprat) @@ -754,7 +773,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7216a2972f9c595c45ab314941628e43", 2247}, {"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 541845}, {"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 845795}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Hoyle 3 - English DOS Floppy 1.0 (supplied by abevi in bug report #2612718) @@ -762,14 +781,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "1728af1f6a85938c3522e64449e76ca1", 2205}, {"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 319905}, {"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 526438}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Hoyle 4 - English DOS Demo {"hoyle4", "Demo", { {"resource.map", 0, "60f764020a6b788bbbe415dbc2ccb9f3", 931}, {"resource.000", 0, "5fe3670e3ddcd4f85c10013b5453141a", 615522}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Hoyle 4 - English DOS Demo @@ -778,16 +797,32 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"hoyle4", "Demo", { {"resource.map", 0, "662087cb383e52e3cc4ae7ecb10e20aa", 938}, {"resource.000", 0, "24c10844792c54d476d272213cbac300", 675252}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + // Hoyle 4 (Hoyle Classic Card Games) - English DOS/Win + // SCI1.1 + // Supplied by abevi in bug report #3039291 + {"hoyle4", "Demo", { + {"resource.map", 0, "2b577c975cc8d8d43f61b6a756129fe3", 4352}, + {"resource.000", 0, "43e2c15ce436aab611a462ad0603e12d", 2000132}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + // Jones in the Fast Lane EGA - English DOS // SCI interpreter version 1.000.172 (not 100% sure FIXME) - {"jones", "", { + {"jones", "EGA", { {"resource.map", 0, "be4cf9e8c1e253623ef35ae3b8a1d998", 1800}, {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 202105}, {"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 341771}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + + // Jones in the Fast Lane EGA - English DOS (supplied by EddyDrama in bug report #3038761) + {"jones", "EGA", { + {"resource.map", 0, "8e92cf319180cc8b5b87b2ce93a4fe22", 1602}, + {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 511528}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Jones in the Fast Lane VGA - English DOS @@ -796,14 +831,22 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "65cbe19b36fffc71c8e7b2686bd49ad7", 1800}, {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 313476}, {"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 719747}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + + // Jones in the Fast Lane VGA - English DOS (supplied by omer_mor in bug report #3037054) + // VERSION file reports "1.000.060" + {"jones", "", { + {"resource.map", 0, "db175ab494ab0666f19ab8f2597a8e49", 1602}, + {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 994487}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Jones in the Fast Lane - English DOS CD {"jones", "CD", { {"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878}, {"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, // King's Quest 1 SCI Remake - English Amiga (from www.back2roots.org) @@ -815,7 +858,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "9ae2a13708d691cd42f9129173c4b39d", 795123}, {"resource.003", 0, "9ae2a13708d691cd42f9129173c4b39d", 763224}, {"resource.004", 0, "9ae2a13708d691cd42f9129173c4b39d", 820443}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // King's Quest 1 SCI Remake - English DOS Non-Interactive Demo @@ -823,7 +866,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq1sci", "SCI Remake Demo", { {"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954}, {"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection) @@ -834,7 +877,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "fed9e0072ffd511d248674e60dee2099", 555439}, {"resource.002", 0, "fed9e0072ffd511d248674e60dee2099", 714062}, {"resource.003", 0, "fed9e0072ffd511d248674e60dee2099", 717478}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 4 - English Amiga (from www.back2roots.org) @@ -847,7 +890,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "fb351106ec865fad9af5d78bd6b8e3cb", 663629}, {"resource.003", 0, "fd16c9c223f7dc5b65f06447615224ff", 683016}, {"resource.004", 0, "3fac034c7d130e055d05bc43a1f8d5f8", 549993}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // King's Quest 4 - English DOS Non-Interactive Demo @@ -855,7 +898,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq4sci", "Demo", { {"resource.map", 0, "992ac7cc31d3717fe53818a9bb6d1dae", 594}, {"resource.001", 0, "143e1c14f15ad0fbfc714f648a65f661", 205330}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // King's Quest 4 - English DOS (from the King's Quest Collection) @@ -867,7 +910,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "77615c595388acf3d1df8e107bfb6b52", 536573}, {"resource.003", 0, "77615c595388acf3d1df8e107bfb6b52", 707591}, {"resource.004", 0, "77615c595388acf3d1df8e107bfb6b52", 479562}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 4 - English DOS @@ -881,7 +924,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "851a62d00972dc4002f472cc0d84e71d", 321593}, {"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777}, {"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 4 - English DOS @@ -895,7 +938,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0c8566848a76eea19a6d6220914030a7", 325102}, {"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288}, {"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 5 - English Amiga (from www.back2roots.org) @@ -911,10 +954,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "31a5487f4d942e6354d5be49d59707c9", 834146}, {"resource.006", 0, "26c0c25399b6715fec03fc3e12544fe3", 823048}, {"resource.007", 0, "b914b5901e786327213e779725d30dd1", 778772}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, - // King's Quest 5 - German Amiga + // King's Quest 5 - German Amiga (also includes english language) // Executable scanning reports "1.004.024" // SCI interpreter version 1.000.060 {"kq5", "", { @@ -927,10 +970,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "5aa3d59968b569cd509dde00d4eb8751", 754201}, {"resource.006", 0, "56546b20db11a4836f900efa6d3a3e74", 672099}, {"resource.007", 0, "56546b20db11a4836f900efa6d3a3e74", 794194}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // King's Quest 5 - Italian Amiga + // King's Quest 5 - Italian Amiga (also includes english language) // Executable scanning reports "1.004.024" // SCI interpreter version 1.000.060 {"kq5", "", { @@ -943,8 +986,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "de3c5c09e350fded36ca354998c2194d", 754784}, {"resource.006", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 672527}, {"resource.007", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 794259}, - {NULL, 0, NULL, 0}}, - Common::IT_ITA, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::IT_ITA, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // King's Quest 5 - English DOS CD (from the King's Quest Collection) // Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052" @@ -953,7 +996,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f68ba690e5920725dcf9328001b90e33", 13122}, {"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368}, {"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // King's Quest 5 - English DOS Floppy @@ -968,7 +1011,22 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "b6c43441cb78a9b484efc8e614aac092", 1287999}, {"resource.006", 0, "672ede1136e9e401658538e51bd5dc22", 1172619}, {"resource.007", 0, "2f48faf27666b58c276dda20f91f4a93", 1240456}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + + // King's Quest 5 - English DOS Floppy (supplied by omer_mor in bug report #3036996) + // VERSION file reports "0.000.051" + {"kq5", "", { + {"resource.map", 0, "8b2158083302568b73b16fa3655360fe", 8184}, + {"resource.000", 0, "a591bd4b879fc832b8095c0b3befe9e2", 276398}, + {"resource.001", 0, "c0f48d4a7ebeaa6aa074fc98d77423e9", 1099506}, + {"resource.002", 0, "e0c40d0e85340357d2404f9b5ae1921c", 1061243}, + {"resource.003", 0, "89c00d788d022c13a9b250fa96290ab0", 1110169}, + {"resource.004", 0, "d68f0d8a52ac990aa5641b7087476253", 1153751}, + {"resource.005", 0, "ef4f1166bc37b6cfab70234ea60ddc3d", 1032675}, + {"resource.006", 0, "06cb3f689836086ebe08b1efc0126592", 921113}, + {"resource.007", 0, "252249753c6e850eacceb8af634986d3", 1133608}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 5 EGA (supplied by markcoolio in bug report #2829470) @@ -984,7 +1042,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "3cca5b2dae8afe94532edfdc98d7edbe", 669919}, {"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666527}, {"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541743}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 5 EGA (supplied by omer_mor in bug report #3035421) @@ -999,10 +1057,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "3cca5b2dae8afe94532edfdc98d7edbe", 669961}, {"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666541}, {"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541762}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, - // King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101) + // King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101, also includes english language) // SCI interpreter version 1.000.060 {"kq5", "", { {"resource.map", 0, "bff44f0c326a71b1757c793a02b502d6", 8283}, @@ -1014,10 +1072,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "9c429782d102739f6bbb81e8b953b0cb", 1267525}, {"resource.006", 0, "d1a75fdc01840664d00366cff6919366", 1208972}, {"resource.007", 0, "c07494f0cce7c05210893938786a955b", 1337361}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // King's Quest 5 - French DOS Floppy (from the King's Quest Collector's Edition 1994) + // King's Quest 5 - French DOS Floppy (from the King's Quest Collector's Edition 1994, also includes english language) // Supplied by aroenai in bug report #2812611 // VERSION file reports "1.000", SCI interpreter version 1.000.784 {"kq5", "", { @@ -1030,10 +1088,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "f4b31cafc5defac75125c5f7b7f9a31a", 1268334}, {"resource.006", 0, "f7dc85307632ef657ceb1651204f6f51", 1210081}, {"resource.007", 0, "7db4d0a1d8d547c0019cb7d2a6acbdd4", 1338473}, - {NULL, 0, NULL, 0}}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // King's Quest 5 - Italian DOS Floppy (from glorifindel) + // King's Quest 5 - Italian DOS Floppy (from glorifindel, includes english language) // SCI interpreter version 1.000.060 {"kq5", "", { {"resource.map", 0, "d55c9e83894a0885e37cd79bacf86384", 8283}, @@ -1045,10 +1103,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "f4e441f284560eaa8022102315656a7d", 1267757}, {"resource.006", 0, "8eeabd92af71e766e323db2100879102", 1209325}, {"resource.007", 0, "dc10c107e0923b902326a040b9c166b9", 1337859}, - {NULL, 0, NULL, 0}}, - Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::IT_ITA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // King's Quest 5 - Polish DOS Floppy (supplied by jacek909 in bug report #2725722) + // King's Quest 5 - Polish DOS Floppy (supplied by jacek909 in bug report #2725722, includes english language?!) // SCI interpreter version 1.000.060 {"kq5", "", { {"resource.map", 0, "70010c20138541f89013bb5e1b30f16a", 7998}, @@ -1060,8 +1118,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "6556ff8e7c4d1acf6a78aea154daa76c", 1287869}, {"resource.006", 0, "da82e4beb744731d0a151f1d4922fafa", 1170456}, {"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176}, - {NULL, 0, NULL, 0}}, - Common::PL_POL, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::PL_POL, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // King's Quest 5 - English Macintosh // VERSION file reports "1.000.055" @@ -1075,9 +1133,17 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "432e2a58e4d496d730697db072437337", 1366732}, {"resource.006", 0, "3d22904a374c192f51e5665b74364133", 1264079}, {"resource.007", 0, "ffe17e23d5833a79f3695addfc149a56", 1361965}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + // King's Quest 5 - FM-Towns (supplied by abevi in bug report #3038720) + {"kq5", "", { + {"resource.map", 0, "20c7cd248ff1a349ed354568eebd972b", 12733}, + {"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094}, + {"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO_NONE }, + // King's Quest 6 - English DOS Non-Interactive Demo // Executable scanning reports "1.001.055", VERSION file reports "1.000.000" // SCI interpreter version 1.001.055 @@ -1085,7 +1151,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f75727c00a6d884234fa2a43c951943a", 706}, {"resource.000", 0, "535b1b920441ec73f42eaa4ccfd47b89", 264116}, {"resource.msg", 0, "54d1fdc936f98c81f9e4c19e04fb1510", 8260}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // King's Quest 6 - English DOS Floppy @@ -1094,7 +1160,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a362063318eebe7d6423b1d9dc6213e1", 8703}, {"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, {"resource.msg", 0, "3cf5de44de36191f109d425b8450efc8", 258590}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 6 - German DOS Floppy (supplied by markcoolio in bug report #2727156) @@ -1103,7 +1169,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a362063318eebe7d6423b1d9dc6213e1", 8703}, {"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, {"resource.msg", 0, "756297b2155db9e43f621c6f6fb763c3", 282822}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 6 - English DOS CD (from the King's Quest Collection) @@ -1112,7 +1178,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq6", "CD", { {"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215}, {"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // King's Quest 6 - English Windows CD (from the King's Quest Collection) @@ -1121,7 +1187,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq6", "CD", { {"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215}, {"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE }, // King's Quest 6 - Spanish DOS CD (from jvprat) @@ -1131,7 +1197,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a73a5ab04b8f60c4b75b946a4dccea5a", 8953}, {"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260}, {"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE }, // King's Quest 6 - English Macintosh Floppy @@ -1139,7 +1205,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq6", "", { {"Data1", 0, "f3c38a33c94293b8ff0337c1090a4973", 3916479}, {"Data2", 0, "b255edf327d7b366dce816b7debf3b94", 15046256}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 @@ -1150,7 +1216,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq7", "", { {"resource.000", 0, "4948e4e1506f1e1c4e1d47abfa06b7f8", 204385195}, {"resource.map", 0, "40ccafb2195301504eba2e4f4f2c7f3d", 18925}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, // King's Quest 7 - English Windows (from the King's Quest Collection) @@ -1158,7 +1224,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq7", "", { {"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697}, {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, // King's Quest 7 - English DOS (from FRG) @@ -1166,7 +1232,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq7", "", { {"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709}, {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 7 - English Windows (from FRG) @@ -1174,7 +1240,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq7", "", { {"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709}, {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, // King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402) @@ -1182,7 +1248,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq7", "", { {"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697}, {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 7 - Spanish DOS (from jvprat) @@ -1190,7 +1256,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq7", "", { {"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709}, {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // King's Quest 7 - English DOS Non-Interactive Demo @@ -1198,7 +1264,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"kq7", "Demo", { {"resource.map", 0, "b44f774108d63faa1d021101221c5a54", 1690}, {"resource.000", 0, "d9659d2cf0c269c6a9dc776707f5bea0", 2433827}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, #endif // ENABLE_SCI32 @@ -1214,7 +1280,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "2ab23f64306b18c28302c8ec2964c5d6", 605134}, {"resource.004", 0, "aa553977f7e5804081de293800d3bcce", 695067}, {"resource.005", 0, "bfd870d51dc97729f0914095f58e6957", 676881}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Laura Bow - English Atari ST (from jvprat) @@ -1226,7 +1292,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 721149}, {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667365}, {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683737}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO_NOSPEECH }, // Laura Bow - English DOS Non-Interactive Demo @@ -1234,7 +1300,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"laurabow", "Demo", { {"resource.map", 0, "e625726268ff4e123ada11f31f0249f3", 768}, {"resource.001", 0, "0c8912290af0890f8d95faeb4ddb2d68", 333031}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Laura Bow - English DOS 3.5" Floppy (from "The Roberta Williams Anthology"/1996) @@ -1245,7 +1311,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 721381}, {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667468}, {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683807}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Laura Bow - English DOS (from FRG) @@ -1259,10 +1325,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465}, {"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, {"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, - // Laura Bow - German DOS (from Tobis87) + // Laura Bow - German DOS (from Tobis87, also includes english language) // SCI interpreter version 0.000.631 (or 0.000.685?) {"laurabow", "", { {"resource.map", 0, "b1905f6aa68ff65a057b080b1eae954c", 12030}, @@ -1273,8 +1339,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465}, {"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, {"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Laura Bow 2 - English DOS Non-Interactive Demo (from FRG) // Executable scanning reports "x.yyy.zzz" @@ -1282,7 +1348,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"laurabow2", "Demo", { {"resource.map", 0, "24dffc5db1d88c7999f13e8767ed7346", 855}, {"resource.000", 0, "2b2b1b4f7584f9b38fd13f6ab95634d1", 781912}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Laura Bow 2 - English DOS Floppy @@ -1291,7 +1357,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"laurabow2", "", { {"resource.map", 0, "610bfd9a852004222f0faaf5fc9e630a", 6489}, {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5035964}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Laura Bow 2 - English DOS CD (from "The Roberta Williams Antology"/1996) @@ -1300,7 +1366,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"laurabow2", "CD", { {"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274}, {"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Laura Bow 2 v1.1 - French DOS Floppy (from Hkz) @@ -1308,7 +1374,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, {"resource.msg", 0, "0fceedfbdd85a4bc7851fdd9dd2d2f19", 278253}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Laura Bow 2 v1.1 - German DOS Floppy (from Tobis87, updated info from markcoolio in bug report #2723787, updated info from #2797962)) @@ -1317,7 +1383,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, {"resource.msg", 0, "795c928cd00dfec9fbc62ebcd12e1f65", 303185}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Laura Bow 2 - Spanish DOS CD (from jvprat) @@ -1326,7 +1392,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, {"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 1 EGA Remake - English DOS (from spookypeanut) @@ -1337,7 +1403,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "38936d3c68b6f79d3ffb13955713fed7", 591352}, {"resource.002", 0, "24c958bc922b07f91e25e8c93aa01fcf", 491230}, {"resource.003", 0, "685cd6c1e05a695ab1e0db826337ee2a", 553279}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 1 VGA Remake - English Amiga (from www.back2roots.org) @@ -1349,7 +1415,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "24ed6dc01b1e7fbc66c3d63a5994549a", 750465}, {"resource.002", 0, "5790ac0505f7ca98d4567132b875eb1e", 681041}, {"resource.003", 0, "4a34c3367c2fe7eb380d741374da1989", 572251}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Larry 1 VGA Remake - English DOS (from spookypeanut) @@ -1359,7 +1425,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 922406}, {"resource.001", 0, "ec20246209d7b19f38989261e5c8f5b8", 1111226}, {"resource.002", 0, "85d6935ef77e6b0e16bc307640a0d913", 1088312}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 1 VGA Remake - English DOS (from FRG) @@ -1369,7 +1435,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 918242}, {"resource.001", 0, "d34cadb11e1aefbb497cf91bc1d3baa7", 1114688}, {"resource.002", 0, "85b030bb66d5342b0a068f1208c431a8", 1078443}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 1 VGA Remake - English DOS Non-Interactive Demo @@ -1377,10 +1443,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl1sci", "VGA Remake, Demo", { {"resource.map", 0, "434e1f6c39d71647b34f0ee57b2bbd68", 444}, {"resource.001", 0, "0c0768215c562d9dace4a5ca53696cf3", 359913}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, - // Larry 1 VGA Remake - Spanish DOS (from the Leisure Suit Larry Collection) + // Larry 1 VGA Remake - Spanish DOS (from the Leisure Suit Larry Collection, also includes english language) // Executable scanning reports "1.SQ4.057", VERSION file reports "1.000" // This version is known to be corrupted // SCI interpreter version 1.000.510 @@ -1390,10 +1456,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "112648995dbc194037f1e4ed2e195910", 1063341}, {"resource.002", 0, "3fe2a3aec0ed53c7d6db1845a67e3aa2", 1095908}, {"resource.003", 0, "ac175df0ea9a2cba57f0248651856d27", 376556}, - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Larry 1 VGA Remake - Russian DOS + // Larry 1 VGA Remake - Russian DOS (also includes english language?!) // Executable scanning reports "1.000.510", VERSION file reports "2.0" // SCI interpreter version 1.000.510 {"lsl1sci", "VGA Remake", { @@ -1401,8 +1467,16 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "0d7b2afa666bd36d9535a15d3a837a66", 928566}, {"resource.001", 0, "bc8ca10c807515d959cbd91f9ba47735", 1123759}, {"resource.002", 0, "b7409ab32bc3bee2d6cce887cd33f2b6", 1092160}, - {NULL, 0, NULL, 0}}, - Common::RU_RUS, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::RU_RUS, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + + // Larry 1 VGA Remake - Polish DOS (from Polish Leisure Suit Larry Collection, official release) + // SCI interpreter version 1.000.577, VERSION file reports "2.1" (this release does NOT include english text) + {"lsl1sci", "VGA Remake", { + {"resource.map", 0, "58330a85767e42a2487129913283ab5b", 3228}, + {"resource.000", 0, "b6097ff35cdc8469f02150fe2f824198", 4781210}, + AD_LISTEND}, + Common::PL_POL, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 2 - English Amiga (from www.back2roots.org) // Executable scanning reports "x.yyy.zzz" @@ -1413,7 +1487,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "a0d4a625311d307257da7fc43d00459d", 630106}, {"resource.003", 0, "a0d4a625311d307257da7fc43d00459d", 570356}, {"resource.004", 0, "a0d4a625311d307257da7fc43d00459d", 717844}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Larry 2 - English DOS Non-Interactive Demo @@ -1422,7 +1496,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl2", "Demo", { {"resource.map", 0, "03dba704bb77da55a91ad27b5a3cac09", 528}, {"resource.001", 0, "9f5520f0297206928df0b0b36493cd33", 127532}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Larry 2 - English DOS @@ -1435,7 +1509,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "4a24443a25e2b1492462a52809605dc2", 204861}, {"resource.005", 0, "4a24443a25e2b1492462a52809605dc2", 277732}, {"resource.006", 0, "4a24443a25e2b1492462a52809605dc2", 345683}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 2 - English DOS @@ -1450,7 +1524,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { // TODO/FIXME: is the version with size 208739 corrupted? //{"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818}, {"resource.006", 0, "96033f57accfca903750413fd09193c8", -1}, // 345818 or 208739 - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 3 - English Amiga (from www.back2roots.org) @@ -1464,7 +1538,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "5c10e462c8cf589610773e4fe8bfd996", 527238}, {"resource.004", 0, "f408e59cbee1457f042e5773b8c53951", 651634}, {"resource.005", 0, "433911eb764089d493aed1f958a5615a", 524259}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Larry 3 - English DOS @@ -1475,7 +1549,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "f18441027154292836b973c655fa3175", 578024}, {"resource.003", 0, "f18441027154292836b973c655fa3175", 506807}, {"resource.004", 0, "f18441027154292836b973c655fa3175", 513651}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 3 - English DOS @@ -1489,7 +1563,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "f18441027154292836b973c655fa3175", 302946}, {"resource.006", 0, "f18441027154292836b973c655fa3175", 282465}, {"resource.007", 0, "f18441027154292836b973c655fa3175", 257174}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 3 - English DOS Non-Interactive Demo @@ -1498,10 +1572,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "33a2384f395470af3d2180e37ad0322a", 1140}, {"resource.001", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 76525}, {"resource.002", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 268299}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, - // Larry 3 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723832) + // Larry 3 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723832, also includes english language) // Executable scanning reports "S.old.123" // SCI interpreter version 0.000.572 (just a guess) {"lsl3", "", { @@ -1510,10 +1584,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "3827a9b17b926e12dcc336860f50612a", 672403}, {"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 587036}, {"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 691932}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Larry 3 - French DOS (provided by richiefs in bug report #2670691) + // Larry 3 - French DOS (provided by richiefs in bug report #2670691, also includes english language) // Executable scanning reports "S.old.123" // SCI interpreter version 0.000.572 (just a guess) {"lsl3", "", { @@ -1522,8 +1596,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "65f1bdaa20f6d0470e9d969f22473873", 671614}, {"resource.003", 0, "65f1bdaa20f6d0470e9d969f22473873", 586921}, {"resource.004", 0, "65f1bdaa20f6d0470e9d969f22473873", 690826}, - {NULL, 0, NULL, 0}}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Larry 5 - English Amiga // Executable scanning reports "1.004.023" @@ -1537,10 +1611,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "3ce5901f1bc171ac0274d99a4eeb9e57", 623022}, {"resource.005", 0, "f8b2d1137bb767e5d232056b99dd69eb", 623621}, {"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 715598}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, - // Larry 5 - German Amiga + // Larry 5 - German Amiga (also includes english language) // Executable scanning reports "1.004.024" // SCI interpreter version 1.000.784 {"lsl5", "", { @@ -1553,15 +1627,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "59eba83ad465b08d763b44f86afa86f6", 664717}, {"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 754966}, {"resource.007", 0, "59eba83ad465b08d763b44f86afa86f6", 683135}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Larry 5 - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.000.181 {"lsl5", "Demo", { {"resource.map", 0, "efe8d3f45ce4f6bd9a6643e0ac8d2a97", 504}, {"resource.001", 0, "8bd8d9c0b5f455ee1269d63ce86c50dd", 531380}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Larry 5 - English DOS (from spookypeanut) @@ -1576,7 +1650,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 1011944}, {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1024810}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 1030656}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 5 - German DOS (from Tobis87) @@ -1591,8 +1665,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 959342}, {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1021774}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 993408}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Larry 5 - French DOS (provided by richiefs in bug report #2670691) // Executable scanning reports "1.lsl5.019" @@ -1607,8 +1681,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 920524}, {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 946540}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 958842}, - {NULL, 0, NULL, 0}}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Larry 5 - Spanish DOS (from the Leisure Suit Larry Collection) // Executable scanning reports "1.ls5.006", VERSION file reports "1.000, 4/21/92" @@ -1623,15 +1697,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 958079}, {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1015136}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 987222}, - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Larry 5 - Italian DOS Floppy (from glorifindel) // SCI interpreter version 1.000.510 (just a guess) {"lsl5", "", { {"resource.map", 0, "a99776df795127f387cb35dae872d4e4", 5919}, {"resource.000", 0, "a8989a5a89e7d4f702b26b378c7a357a", 7001981}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 6 - English DOS (from spookypeanut) @@ -1639,7 +1713,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl6", "", { {"resource.map", 0, "bb8a39d9e2a77ba449a1e591109ad9a8", 6973}, {"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 6 - English/German/French DOS CD - LORES @@ -1647,7 +1721,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl6", "", { {"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263}, {"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 6 - German DOS CD - LORES (provided by richiefs in bug report #2670691) @@ -1655,7 +1729,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl6", "", { {"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268}, {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 6 - French DOS CD - LORES (provided by richiefs in bug report #2670691) @@ -1663,7 +1737,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl6", "", { {"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268}, {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 6 - Spanish DOS - LORES (from the Leisure Suit Larry Collection) @@ -1671,7 +1745,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl6", "", { {"resource.map", 0, "633bf8f42170b6271019917c8009989b", 6943}, {"resource.000", 0, "7884a8db9253e29e6b37a2651fd90ba3", 5733116}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Crazy Nick's Software Picks: Leisure Suit Larry's Casino - English DOS (from the Leisure Suit Larry Collection) @@ -1679,35 +1753,35 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"cnick-lsl", "", { {"resource.map", 0, "194f1578f2624db813c9072359ad1639", 783}, {"resource.001", 0, "3733433b517ec3d14a3331d9ab3842ae", 344830}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Crazy Nick's Software Picks: King Graham's Board Game Challenge {"cnick-kq", "", { {"resource.map", 0, "44bc538a5cd24b39ffccc967c0ebf84d", 1137}, {"resource.001", 0, "470e7a4a3504635e70b623c44461e1ac", 451272}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Crazy Nick's Software Picks: Parlor Games with Laura Bow {"cnick-laurabow", "", { {"resource.map", 0, "3b826bfe64f8ff1ccf30eef93cd2f727", 999}, {"resource.001", 0, "985ac8db6f636f2b4334c04b0fbb44fb", 336698}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Crazy Nick's Software Picks: Robin Hood's Game of Skill and Chance {"cnick-longbow", "", { {"resource.map", 0, "4a5c81f485a2416bde12978506f2fb5f", 897}, {"resource.001", 0, "ef16dc9e867eb8eeb5b13e110b90bd4b", 571466}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Crazy Nick's Software Picks: Roger Wilco's Spaced Out Game Pack {"cnick-sq", "", { {"resource.map", 0, "b4d95b02d84e297441bd999d34eaa6b1", 879}, {"resource.001", 0, "82ff2b64a60117886fbcd6a3a8c977c6", 364921}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 @@ -1716,7 +1790,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl6hires", "", { {"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872}, {"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 6 - German DOS CD - HIRES (provided by richiefs in bug report #2670691) @@ -1724,7 +1798,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl6hires", "", { {"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896}, {"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 6 - French DOS CD - HIRES (provided by richiefs in bug report #2670691) @@ -1732,7 +1806,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl6hires", "", { {"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896}, {"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691) @@ -1740,7 +1814,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl7", "Demo", { {"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878}, {"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, #ifdef ENABLE_SCI3_GAMES @@ -1749,7 +1823,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl7", "", { {"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188}, {"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 7 - German DOS (from Tobis87) @@ -1757,7 +1831,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl7", "", { {"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188}, {"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 7 - French DOS (provided by richiefs in bug report #2670691) @@ -1765,7 +1839,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl7", "", { {"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206}, {"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Larry 7 - Italian DOS CD (from glorifindel) @@ -1773,7 +1847,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl7", "", { {"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212}, {"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NONE }, // Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection) @@ -1781,23 +1855,25 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"lsl7", "", { {"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188}, {"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, +#endif // Lighthouse - English Windows Demo (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.00" {"lighthouse", "Demo", { {"resource.map", 0, "543124606352bfa5e07696ddf2a669be", 64}, {"resource.000", 0, "5d7714416b612463d750fb9c5690c859", 28952}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, +#ifdef ENABLE_SCI3_GAMES // Lighthouse - English Windows Demo // Executable scanning reports "3.000.000", VERSION file reports "1.00" {"lighthouse", "Demo", { {"resmap.000", 0, "3bdee7a16926975a4729f75cf6b80a92", 1525}, {"ressci.000", 0, "3c585827fa4a82f4c04a56a0bc52ccee", 11494351}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Lighthouse - English DOS (from jvprat) @@ -1807,7 +1883,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.001", 0, "14e922c47b92156377cb49e241691792", 99591924}, {"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573}, {"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Lighthouse - Spanish DOS (from jvprat) @@ -1817,7 +1893,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.001", 0, "18553177dbf83fb2cb6c8edcbb174183", 99543093}, {"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630}, {"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, #endif // ENABLE_SCI3_GAMES @@ -1828,7 +1904,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "c2cf672c3f4251e7472d4542af3bf764", 933}, {"resource.000", 0, "8be56a3a88c065ee00c02c0e29199f3a", 14643}, {"resource.001", 0, "9e33566515b18bee7915db448063bba2", 871853}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Mixed-Up Fairy Tales - English DOS Floppy EGA (from omer_mor, bug report #3035350) @@ -1839,7 +1915,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "4db83250f821607b634c99d663cae74a", 663713}, {"resource.003", 0, "509b2467ba779100d5933ed51a9ae32f", 560255}, {"resource.004", 0, "93afc85d5ffa60ea555d6cc336d22c03", 651109}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791) @@ -1851,7 +1927,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "6767f8c8585f617aaa91d442f41ae714", 1032989}, {"resource.003", 0, "b1288e0821ee358d1ffe877e5900c8ec", 1047565}, {"resource.004", 0, "f79daa70390d73746742ffcfc3dc4471", 937580}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Mixed-Up Fairy Tales - English DOS Floppy (from jvprat) @@ -1862,7 +1938,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "49c8f7dcd9989e4491a93554bec325b0", 238019}, {"resource.002", 0, "564f516d991032e781492592a4eaa275", 1414142}, {"resource.003", 0, "dd6cef0c592eadb7e6be9a25307c57a2", 1344719}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Mixed-Up Mother Goose - English Amiga (from www.back2roots.org) @@ -1872,7 +1948,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "4aa28ac93fae03cf854594da13d9229c", 2700}, {"resource.001", 0, "fb552ae550ca1dac19ed8f6a3767612d", 262885}, {"resource.002", 0, "fb552ae550ca1dac19ed8f6a3767612d", 817191}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Mixed-Up Mother Goose - English DOS Floppy EGA (from omer_mor, bug report #3035354) @@ -1880,7 +1956,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "3490f85dab47e504c41b7eb3312e285e", 2598}, {"resource.001", 0, "d893892d62b3f061357291d66775e360", 239906}, {"resource.002", 0, "d893892d62b3f061357291d66775e360", 719398}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795) @@ -1888,7 +1964,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"mothergoose", "", { {"resource.map", 0, "52aae15e493cafd1da7e1c9b657a5bb9", 7026}, {"resource.000", 0, "b7ecd8ae9e254e80310b5a668b276e6e", 2948975}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Mixed-Up Mother Goose - English DOS CD (from jvprat) @@ -1897,7 +1973,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"mothergoose", "CD", { {"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790}, {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Mixed-Up Mother Goose - English Windows Interactive Demo @@ -1905,9 +1981,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"mothergoose", "Demo", { {"resource.map", 0, "87f9dc1cafc4d4fa835fb2f00cf3a6ef", 4560}, {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 2070072}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH }, + + // Mixed-Up Mother Goose - FM-Towns (supplied by abevi in bug report #3038720) + {"mothergoose", "", { + {"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772}, + {"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO_NONE }, #ifdef ENABLE_SCI32 // Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810) @@ -1915,7 +1997,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"mothergoosehires", "", { {"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741}, {"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Mixed-Up Mother Goose Deluxe - Multilingual Windows CD (English/French/German/Spanish) @@ -1923,7 +2005,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"mothergoosehires", "", { {"resmap.000", 0, "ef611af561898dcfea87846919ebf3eb", 4969}, {"ressci.000", 0, "227685bc59d90821978d330713e44a7a", 17205800}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, #endif // ENABLE_SCI32 @@ -1932,7 +2014,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"msastrochicken", "", { {"resource.map", 0, "5b457cbe5042f557e5b610148171f6c0", 1158}, {"resource.001", 0, "453ea81ef66a50cbe33ce06302afe47f", 229737}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 @@ -1953,7 +2035,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.006", 0, "3aae6559aa1df273bc542d5ac6330d75", 77901360}, {"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972}, //{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Phantasmagoria - English DOS Demo @@ -1961,7 +2043,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"phantasmagoria", "Demo", { {"resmap.001", 0, "416138651ea828219ca454cae18341a3", 11518}, {"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, #ifdef ENABLE_SCI3_GAMES @@ -1978,7 +2060,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.004", 0, "53f457cddb0dffc056593905c4cbb989", 42447131}, {"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942}, {"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, #endif // ENABLE_SCI3_GAMES @@ -1989,7 +2071,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"pepper", "", { {"resource.map", 0, "72726dc81c1b4c1110c486be77369bc8", 5179}, {"resource.000", 0, "670d0c53622429f4b11275caf7f8d292", 5459574}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Pepper - English DOS Non-Interactive Demo @@ -1997,7 +2079,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"pepper", "Demo", { {"resource.map", 0, "379bb4fb896630b14f2d91ed21e36ba1", 984}, {"resource.000", 0, "118f6c31a93ec7fd9a231c61125229e3", 645494}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Pepper - English DOS/Windows Interactive Demo @@ -2005,7 +2087,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"pepper", "Demo", { {"resource.map", 0, "975e8df76106a5c13d12ab674f906a02", 2514}, {"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1698164}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Pepper - English DOS Interactive Demo @@ -2013,7 +2095,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"pepper", "Demo", { {"resource.map", 0, "9c9b7b900651a370dd3fb38d478b1798", 2524}, {"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1713544}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Police Quest 1 VGA Remake - English DOS (from the Police Quest Collection) @@ -2021,7 +2103,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"pq1sci", "VGA Remake", { {"resource.map", 0, "35efa814fb994b1cbdac9611e401da67", 5013}, {"resource.000", 0, "e0d5ddf34eda903a38f0837e2aa7145b", 6401433}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Police Quest 2 - English Amiga (from www.back2roots.org) @@ -2032,7 +2114,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "523db0c07f1da2a822c2c39ee0482544", 179334}, {"resource.002", 0, "499737c21a28ac026e11ab817100d610", 511099}, {"resource.003", 0, "e008f5d6e2a7c4d4a0da0173e4fa8f8b", 553970}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Police Quest 2 - English DOS Non-Interactive Demo @@ -2040,7 +2122,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"pq2", "Demo", { {"resource.map", 0, "8b77d0d4650c2052b356cece28294b58", 576}, {"resource.001", 0, "376ef6d6eaaeed66e1424bd219c4b9ab", 215398}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Police Quest 2 - English DOS (provided by richiefs in bug report #2670691) @@ -2053,7 +2135,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "77f02def3094af804fd2371db25b7100", 342149}, {"resource.005", 0, "77f02def3094af804fd2371db25b7100", 349899}, {"resource.006", 0, "77f02def3094af804fd2371db25b7100", 354991}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Police Quest 2 - English DOS (from the Police Quest Collection) @@ -2063,7 +2145,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509525}, {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000}, {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Police Quest 2 - English DOS (from FRG) @@ -2073,19 +2155,27 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509760}, {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 542897}, {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 586857}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + + // Police Quest 2 English DOS 1.001.006 (supplied by merkur-kun in bug report #3028479) + {"pq2", "", { + {"resource.map", 0, "8e1161c684b342742d30f938a4839a4b", 4518}, + {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 506563}, + {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 541261}, + {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 587511}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, - // Police Quest 2 - Japanese PC-98 + // Police Quest 2 - Japanese PC-98 (also includes english language) // SCI interpreter version unknown {"pq2", "", { {"resource.map", 0, "883804c616dca1d82373bf9fda3a71d2", 4656}, {"resource.001", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 669319}, {"resource.002", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 637662}, {"resource.003", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 684395}, - {NULL, 0, NULL, 0}}, - Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH - }, // also includes english language + AD_LISTEND}, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Police Quest 3 - English Amiga // Executable scanning reports "1.004.024" @@ -2097,10 +2187,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "f7044bb08a1fcbe5077791ed8d4996f0", 691207}, {"resource.003", 0, "630bfa65beb05f743552704ac2899dae", 759891}, {"resource.004", 0, "7b229fbdf30d670d0728cede3e984a7e", 838663}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, - // Police Quest 3 - German Amiga + // Police Quest 3 - German Amiga (also includes english language) // Executable scanning reports "1.004.024" // SCI interpreter version 1.000.784 {"pq3", "", { @@ -2111,9 +2201,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "87361c17fd863b58f98828de68770279", 682288}, {"resource.004", 0, "6258d5dd85898d8e218eb8113ebc9059", 722738}, {"resource.005", 0, "6258d5dd85898d8e218eb8113ebc9059", 704485}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Police Quest 3 - English DOS (from the Police Quest Collection) // Executable scanning reports "T.A00.178", VERSION file reports "1.00" @@ -2125,9 +2214,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "c18e0d408e4f4f40365d42aa15931f67", 1153561}, {"resource.003", 0, "8791b9eef53edf77c2dac950142221d3", 1159791}, {"resource.004", 0, "1b91e891a3c60a941dac0eecdf83375b", 1143606}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Police Quest 3 - English DOS Non-Interactive Demo // Executable scanning reports "T.A00.052" @@ -2136,11 +2224,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ec8e58e7663ae5173853abf6c76b52bb", 867}, {"resource.000", 0, "277f97771f7a6d89677141f02da313d6", 65150}, {"resource.001", 0, "5c5a551b6c86cce2ee75becb90e0b586", 624411}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, - // Police Quest 3 - German DOS (supplied by markcoolio in bug report #2723837) + // Police Quest 3 - German DOS (supplied by markcoolio in bug report #2723837, also includes english language) // Executable scanning reports "T.A00.178" // SCI interpreter version 1.000.510 {"pq3", "", { @@ -2150,18 +2237,16 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "cce99b96a578b62ff6cebdae8d122feb", 1179358}, {"resource.003", 0, "4836f460f4cfc8de61e2df4c45775504", 1180956}, {"resource.004", 0, "0c3eb84b9755852d9e795e0d5c9373c7", 1171760}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Police Quest 4 - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.001.096 {"pq4", "Demo", { {"resource.map", 0, "be56f87a1c4a13062a30a362df860c2f", 1472}, {"resource.000", 0, "527d5684016e6816157cd15d9071b11b", 1121310}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 // Police Quest 4 - English DOS (from the Police Quest Collection) @@ -2169,45 +2254,40 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"pq4", "", { {"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374}, {"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Police Quest 4 - English DOS // SCI interpreter version 2.000.000 (a guess?) {"pq4", "", { {"resource.map", 0, "aed9643158ccf01b71f359db33137f82", 9895}, {"resource.000", 0, "da383857b3be1e4514daeba2524359e0", 15141432}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Police Quest 4 - French DOS (supplied by abevi in bug report #2612718) // SCI interpreter version 2.000.000 {"pq4", "", { {"resource.map", 0, "008030846edcc7c5c7a812c7f4ae4ceb", 9256}, {"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730153}, - {NULL, 0, NULL, 0}}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Police Quest 4 - German DOS (supplied by markcoolio in bug report #2723840) // SCI interpreter version 2.000.000 (a guess?) {"pq4", "", { {"resource.map", 0, "2393ee728ab930b2762cb5889f9b5aff", 9256}, {"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730155}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Police Quest: SWAT - English DOS/Windows Demo (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "0.001.200" {"pqswat", "Demo", { {"resource.map", 0, "8c96733ef94c21526792f7ca4e3f2120", 1648}, {"resource.000", 0, "d8892f1b8c56c8f7704325460f49b300", 3676175}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Police Quest: SWAT - English Windows (from the Police Quest Collection) // Executable scanning reports "2.100.002", VERSION file reports "1.0c" @@ -2221,9 +2301,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.003", 0, "00a755e917c442ca8cf1a1bea689e6fb", 45073980}, {"resmap.004", 0, "4228038906f041623e65789500b22285", 6835}, {"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, #endif // ENABLE_SCI32 // Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by merkur in bug report #2718784) @@ -2235,9 +2314,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "439ba9b6dde216e6eb97ef3a9830fbe4", 646869}, {"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203}, {"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by markcoolio in bug report #2723843) // Executable scanning reports "0.000.566" @@ -2251,31 +2329,36 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "7288ed6d5da89b7a80b4af3897a7963a", 271185}, {"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852}, {"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + + // Quest for Glory 1 / Hero's Quest - English DOS Demo + // Executable scanning reports "0.000.685" + {"qfg1", "Demo", { + {"resource.map", 0, "df34c758cbb9026da175793ff686b0e6", 882}, + {"resource.001", 0, "73fbaafdd313b39aeedb80fbf85ecef1", 389884}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, - // Quest for Glory 1 - Japanese PC-98 5.25" Floppy + // Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes english language) // Executable scanning reports "S.old.201" {"qfg1", "8 Colors", { {"resource.map", 0, "5cbeb95dd2a4b7cb242b415cc6ec1c47", 6444}, {"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 859959}, {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968}, {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897}, - {NULL, 0, NULL, 0}}, - Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Quest for Glory 1 - Japanese PC-98 5.25" Floppy + // Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes english language) // Executable scanning reports "S.old.201" {"qfg1", "16 Colors", { {"resource.map", 0, "3ecaba33bf77cb434067a0b8aee15097", 6444}, {"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 864754}, {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121}, {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575}, - {NULL, 0, NULL, 0}}, - Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Quest for Glory 1 - English Amiga // Executable scanning reports "1.002.020" @@ -2288,9 +2371,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 654096}, {"resource.004", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 689124}, {"resource.005", 0, "5f3386ef2f2b1254e4a066f5d9027324", 609529}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Quest for Glory 1 (from abevi, bug report #2612718) {"qfg1", "", { @@ -2300,9 +2382,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "e64004e020fdf1813be52b639b08be89", 635561}, {"resource.003", 0, "f0af87c60ec869946da442833aa5afa8", 640502}, {"resource.004", 0, "f0af87c60ec869946da442833aa5afa8", 644575}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Quest for Glory 1 - English DOS // SCI interpreter version 0.000.629 @@ -2313,36 +2394,32 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "05ddce5f437a516b89ede2438fac09d8", 635734}, {"resource.003", 0, "951299a82a8134ed12c5c18118d45c2f", 640483}, {"resource.004", 0, "951299a82a8134ed12c5c18118d45c2f", 644443}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 1 VGA Remake - English DOS // Executable scanning reports "2.000.411" {"qfg1vga", "VGA Remake", { {"resource.map", 0, "a731fb6c9c0b282443f7027bc8694d4c", 8469}, {"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 1 VGA Remake - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.001.029 {"qfg1vga", "VGA Remake, Demo", { {"resource.map", 0, "ac0257051c95a59c0cdc0be24d9b11fa", 729}, {"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Quest for Glory 1 VGA Remake - English Macintosh Floppy // VERSION file reports "2.0" {"qfg1vga", "VGA Remake", { {"Data1", 0, "14f26bc75f24bb1ecc94532df17b5371", 1768155}, {"Data2", 0, "a7aee8bd46fc9cef7fd3bea93ef173e0", 6586422}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NOSPEECH }, // Quest for Glory 2 - English Amiga // Executable scanning reports "1.003.004" @@ -2357,9 +2434,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "a77d2576c842b2b06da57d4ac8fc51c0", 579975}, {"resource.006", 0, "ccf5dba33e5cab6d5872838c0f8db44c", 500039}, {"resource.007", 0, "4c9fc1587545879295cb9627f56a2cb8", 575056}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Quest for Glory 2 - English (from FRG) // Executable scanning reports "1.000.072" @@ -2370,9 +2446,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "df137dc7869cab07e1149ba2333c815c", 790750}, {"resource.003", 0, "b192607c42f6960ecdf2ad2e4f90e9bc", 972804}, {"resource.004", 0, "cd2de58e27665d5853530de93fae7cd6", 983617}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 2 - English DOS // Executable scanning reports "1.000.072" @@ -2386,54 +2461,48 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "df137dc7869cab07e1149ba2333c815c", 478688}, {"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489}, {"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 2 - English DOS Non-Interactive Demo // Executable scanning reports "1.000.046" {"qfg2", "Demo", { {"resource.map", 0, "e75eb86bdd517b3ef709058249986a87", 906}, {"resource.001", 0, "9b098f9e1008abe30e56c93b896494e6", 362123}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Quest for Glory 3 - English DOS Non-Interactive Demo (from FRG) // Executable scanning reports "1.001.021", VERSION file reports "1.000, 0.001.059, 6.12.92" {"qfg3", "Demo", { {"resource.map", 0, "fd71de9b588a45f085317caacf050e91", 687}, {"resource.000", 0, "b6c69bf6c18bf177492249fe81fc6a6d", 648702}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Quest for Glory 3 - English DOS // SCI interpreter version 1.001.050 {"qfg3", "", { {"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 3 - English DOS (supplied by abevi in bug report #2612718) // SCI interpreter version 1.001.050 {"qfg3", "", { {"resource.map", 0, "62c185d190363d7df06330fa0cc45b36", 5958}, {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5867442}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 3 - German DOS (supplied by markcoolio in bug report #2723846) // Executable scanning reports "L.rry.083" {"qfg3", "", { {"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 3 - Spanish DOS CD (from jvprat) // Executable scanning reports "L.rry.083", VERSION file reports "1.000.000, June 30, 1994" @@ -2441,18 +2510,16 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "10809197c33a5e62819311d8a2f73f85", 5978}, {"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098}, {"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014}, - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE }, // Quest for Glory 4 - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.001.069 (just a guess) {"qfg4", "Demo", { {"resource.map", 0, "1ba7c7ae1efb315326d45cb931569b1b", 922}, {"resource.000", 0, "41ba03f0b188b029132daa3ece0d3e14", 623154}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 // Quest for Glory 4 1.1 Floppy - English DOS (supplied by markcool in bug report #2723852) @@ -2460,36 +2527,32 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"qfg4", "", { {"resource.map", 0, "685bdb1ed47bbbb0e5e25db392da83ce", 9301}, {"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11004993}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 4 1.1 Floppy - English DOS (supplied by abevi in bug report #2612718) // SCI interpreter version 2.000.000 {"qfg4", "", { {"resource.map", 0, "d10a4cc177d2091d744e2ad8c049b0ae", 9295}, {"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11003589}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 4 1.1 Floppy - German DOS (supplied by markcool in bug report #2723850) // Executable scanning reports "2.000.000", VERSION file reports "1.1" {"qfg4", "", { {"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301}, {"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Quest for Glory 4 - English DOS/Windows (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.0" {"qfg4", "", { {"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, {"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, #endif @@ -2498,9 +2561,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "1846b57fe84774be72f7c50ab3c90df0", 2256126}, {"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044}, {"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 // RAMA - English DOS/Windows Demo @@ -2508,9 +2570,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"rama", "Demo", { {"resmap.001", 0, "775304e9b2a545156be4d94209550094", 1393}, {"ressci.001", 0, "259437fd75fdf51e8207fda8c01fa4fd", 2334384}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NONE }, #ifdef ENABLE_SCI3_GAMES // RAMA - English Windows (from jvprat) @@ -2522,9 +2583,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.002", 0, "2a68edd064e5e4937b5e9c74b38f2082", 128562138}, {"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636}, {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE }, // RAMA - English Windows (from Quietust, in bug report #2850645) {"rama", "", { @@ -2534,18 +2594,16 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.002", 0, "2a68edd064e5e4937b5e9c74b38f2082", 128572432}, {"resmap.003", 0, "48841e4b84ef1b98b48d43566fda9e13", 1636}, {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6870356}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE }, // RAMA - Italian Windows CD (from glorifindel) // SCI interpreter version 3.000.000 (a guess?) {"rama", "", { {"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091}, {"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338}, - {NULL, 0, NULL, 0}}, - Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE }, #endif // ENABLE_SCI3_GAMES // Shivers - English Windows (from jvprat) @@ -2553,26 +2611,23 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"shivers", "", { {"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525}, {"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NONE }, // Shivers - German Windows (from Tobis87) {"shivers", "", { {"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537}, {"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NONE }, // Shivers - English Windows Demo // Executable scanning reports "2.100.002" {"shivers", "Demo", { {"resmap.000", 0, "d9e0bc5eddefcbe47f528760085d8927", 1186}, {"ressci.000", 0, "3a93c6340b54e07e65d0e5583354d186", 10505469}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NONE }, #ifdef ENABLE_SCI3_GAMES @@ -2581,16 +2636,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"shivers2", "Demo", { {"resmap.000", 0, "d8659188b84beaef076bd869837cd530", 634}, {"ressci.000", 0, "7fbac0807a044c9543e8ac376d200e59", 4925003}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NONE }, // Shivers 2 - English Windows (from abevi) // VERSION.TXT Version 1.0 (3/25/97) {"shivers2", "", { {"ressci.001", 0, "a79d03d6eb75be0a79324f14e3d2ace4", 95346793}, {"resmap.001", 0, "a4804d436d90c4ec2e46b537f5e954db", 6268}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, #endif //ENABLE_SCI3_GAMES @@ -2603,9 +2657,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "61b4f74039399e5aa1e737b16d0fc023", 1409}, {"resource.msg", 0, "1aeafe2b495de288d002109650b66614", 1364}, {"resource.000", 0, "8e10d4f05c1fd9f883384fa38a898489", 377394}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org) // SCI interpreter version 1.000.510 (just a guess) @@ -2617,9 +2670,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "2588c1c2ca8b9bed0e3411948c0856a9", 839302}, {"resource.004", 0, "b25a1539c71701f7715f738c5037e9a6", 775515}, {"resource.005", 0, "640ffe1a9acde392cc33cc1b1a528328", 806324}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, // Space Quest 1 VGA Remake - English DOS (from the Space Quest Collection) // Executable scanning reports "T.A00.081", VERSION file reports "2.000" @@ -2631,9 +2683,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "a9e847c687529481f3a22b9bf01f45f7", 1169831}, {"resource.003", 0, "c47600e50c6fc591957ae0c5020ee7b8", 1213262}, {"resource.004", 0, "e19ea4ad131472f9238590f2e1d40289", 1203051}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 1 VGA Remake - English Mac (from Fingolfin) {"sq1sci", "VGA Remake", { @@ -2643,18 +2694,16 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "96860704f7a07ecc10bef223b4b2f153", 1273992}, {"resource.003", 0, "ae46e195e66df5a131917f0aa80b5669", 1242794}, {"resource.004", 0, "91d58a9eb2187c38424990afe4c12bc6", 1250949}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, // Space Quest 1 VGA Remake - English Non-Interactive Demo (from FRG) // SCI interpreter version 1.000.181 {"sq1sci", "VGA Remake, Demo", { {"resource.map", 0, "5af709ac5e0e923e0b8174f49978c30e", 636}, {"resource.001", 0, "fd99ea43f57576ded7c86036996346cf", 507642}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Space Quest 1 VGA Remake - Spanish DOS Floppy (from jvprat) // Executable scanning reports "T.A00.081", VERSION file reports "2.000" @@ -2667,9 +2716,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "8c22700a02991b763f512f837636b3ca", 1211307}, {"resource.004", 0, "9b78228ad4f9f335fedf74f1812dcfca", 513325}, {"resource.005", 0, "7d4ebcb745c0bf8fc42e4013f52ecd49", 1101812}, - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 3 - English Amiga (from www.back2roots.org) // SCI interpreter version 0.000.453 (just a guess) @@ -2679,10 +2727,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 754432}, {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 746496}, {"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 761984}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, - // Space Quest 3 - German Amiga + // Space Quest 3 - German Amiga (also includes english language) // Executable scanning reports "1.004.006" // SCI interpreter version 0.000.453 (just a guess) {"sq3", "", { @@ -2692,15 +2740,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 712374}, {"resource.004", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 545053}, {"resource.005", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 687507}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Space Quest 3 - English DOS Non-Interactive Demo // SCI interpreter version 0.000.453 {"sq3", "Demo", { {"resource.map", 0, "ec66ac2b1ce58b2575ba00b65058de1a", 612}, {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 180245}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, // Space Quest 3 - English DOS (provided by richiefs in bug report #2670691) @@ -2710,7 +2758,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 485158}, {"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720244}, {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688367}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 3 - English DOS (from the Space Quest Collection) @@ -2720,7 +2768,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 490247}, {"resource.002", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 715777}, {"resource.003", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 703370}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 3 - English DOS (from abevi, bug report #2612718) @@ -2732,7 +2780,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 321222}, {"resource.005", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 328278}, {"resource.006", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 356702}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 3 - English Mac (from Fingolfin) @@ -2741,10 +2789,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "0d8dfe42683b46f3131823233a91ce6a", 771917}, {"resource.002", 0, "0d8dfe42683b46f3131823233a91ce6a", 794072}, {"resource.003", 0, "0d8dfe42683b46f3131823233a91ce6a", 776536}, - {NULL, 0, NULL, 0}}, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, - // Space Quest 3 - German DOS (from Tobis87) + // Space Quest 3 - German DOS (from Tobis87, also includes english language) // SCI interpreter version 0.000.453 (?) {"sq3", "", { {"resource.map", 0, "4965c78b5eff50d5e4148ce114594ba8", 7584}, @@ -2755,18 +2803,18 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "9107c2aa5398e28b5c5406df13491f85", 322107}, {"resource.006", 0, "9107c2aa5398e28b5c5406df13491f85", 320643}, {"resource.007", 0, "9107c2aa5398e28b5c5406df13491f85", 344287}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Space Quest 3 v1.052 - German DOS (supplied by markcoolio in bug report #2723860) + // Space Quest 3 v1.052 - German DOS (supplied by markcoolio in bug report #2723860, also includes english language) // Executable scanning reports "S.old.114" {"sq3", "", { {"resource.map", 0, "f0dd735098c254f584878649c6f08dbc", 5154}, {"resource.001", 0, "9107c2aa5398e28b5c5406df13491f85", 567245}, {"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 596768}, {"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 693573}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Space Quest 4 - English Amiga // Executable scanning reports "1.004.024" @@ -2780,11 +2828,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "1887ed88bb34ae7238650e8f77f26315", 798226}, {"resource.005", 0, "3540d1cc84d674cf4b2c898b88a3b563", 790296}, {"resource.006", 0, "ade814bc4d56244c156d9e9bcfebbc11", 664085}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, - // Space Quest 4 - German Amiga (from www.back2roots.org) + // Space Quest 4 - German Amiga (from www.back2roots.org, also includes english language) // SCI interpreter version 1.000.200 (just a guess) {"sq4", "", { {"resource.map", 0, "79641c0d43408e33c251a1d494d2575e", 6252}, @@ -2795,19 +2842,19 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "99c6a017da5e769a3b427ca52c8a564f", 824601}, {"resource.005", 0, "10ee1709e6559c724676d058199b75b5", 818745}, {"resource.006", 0, "67fb188b191d88efe8414af6ea297b93", 672675}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Space Quest 4 - English DOS +#if 0 + // Space Quest 4 - English DOS - THIS VERSION IS PIRATED/CRACKED AND REPACKAGED =DO NOT RE-ADD= // Executable scanning reports "1.000.753" // SCI interpreter version 1.000.200 (just a guess) {"sq4", "", { {"resource.map", 0, "a18088c8aceb06025dbc945f29e02935", 5124}, {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 5502009}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, +#endif // Space Quest 4 - English DOS // Executable scanning reports "1.000.753" @@ -2815,9 +2862,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"sq4", "", { {"resource.map", 0, "71ccf4f82ac4efb588731acfb7bf2603", 5646}, {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 933928}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 4 1.052 - English DOS Floppy (supplied by markcoolio in bug report #2723865) // Executable scanning reports "1.000.753" @@ -2830,9 +2876,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "96fa33d89d838bc3f671c5b953e7a896", 1240130}, {"resource.004", 0, "ff9c87da3bc53473fdee8b9d3edbc93c", 1200631}, {"resource.005", 0, "e33019ac19f755ae33fbf49b4fc9066c", 1053294}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 4 1.000 - English DOS Floppy (from abevi, bug report #2612718) {"sq4", "", { @@ -2843,11 +2888,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "47ee647b5b12232d27e63cc627c25899", 1321146}, {"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368}, {"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, - // Space Quest 4 - German DOS (from Tobis87) + // Space Quest 4 - German DOS (from Tobis87, also includes english language) // SCI interpreter version 1.000.200 (just a guess) {"sq4", "", { {"resource.map", 0, "71715e775e3791178d606cfe6c7e1fb9", 6339}, @@ -2858,11 +2902,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "b8d6efbd3235329bfe844c794097b2c9", 1064761}, {"resource.005", 0, "47ee647b5b12232d27e63cc627c25899", 1156765}, {"resource.006", 0, "dfb023e4e2a1e7a00fa18f9ede72a91b", 924059}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Space Quest 4 - Italian DOS Floppy (from glorifindel) + // Space Quest 4 - Italian DOS Floppy (from glorifindel, also includes english language) // SCI interpreter version 1.000.200 (just a guess) {"sq4", "", { {"resource.map", 0, "e753dfa96d68dd95f84f6cd80479a35e", 6135}, @@ -2872,42 +2915,38 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "5289000399d503b59da9e23129256f1a", 1325546}, {"resource.004", 0, "4277c61bed40a50dadc4b5a344520af2", 1251000}, {"resource.005", 0, "5f885abd335978e2fd4e5f886d7676c8", 1102880}, - {NULL, 0, NULL, 0}}, - Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::IT_ITA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Space Quest 4 - Japanese PC-98 5.25" Floppy + // Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language) // SCI interpreter version 1.000.1068 {"sq4", "", { {"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, {"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, - {NULL, 0, NULL, 0}}, - Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Space Quest 4 - Japanese PC-98 5.25" Floppy + // Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language) // SCI interpreter version 1.000.1068 {"sq4", "", { {"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, {"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC98, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Space Quest 4 - English DOS CD (from the Space Quest Collection) // Executable scanning reports "1.001.064", VERSION file reports "1.0" {"sq4", "CD", { {"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054}, {"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, - // Space Quest 4 - Spanish DOS CD (from jvprat) + // Space Quest 4 - Spanish DOS CD (from jvprat, is still text only, not talkie, also includes english language) // Executable scanning reports "1.SQ4.057", VERSION file reports "1.000" // SCI interpreter version 1.000.200 (just a guess) {"sq4", "", { @@ -2918,11 +2957,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1319306}, {"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752}, {"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328}, - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NONE }, - // Space Quest 4 - Spanish DOS Floppy (from jvprat) + // Space Quest 4 - Spanish DOS Floppy (from jvprat, also includes english language) // Executable scanning reports "1.SQ4.056", VERSION file reports "1.000" // SCI interpreter version 1.000.200 (just a guess) {"sq4", "", { @@ -2931,11 +2969,10 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "567608beb69d9dffdb42a8f39cb11a5e", 994323}, {"resource.002", 0, "74c62fa2146ff3b3b2ea2b3fb95b9af9", 1140801}, {"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1088408}, - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, - // Space Quest 4 1.000 - German DOS Floppy (supplied by markcoolio in bug report #2723862) + // Space Quest 4 1.000 - German DOS Floppy (supplied by markcoolio in bug report #2723862, also includes english language) // Executable scanning reports "1.SQ4.030" // SCI interpreter version 1.000.200 (just a guess) {"sq4", "", { @@ -2946,9 +2983,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "47ee647b5b12232d27e63cc627c25899", 1321146}, {"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368}, {"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, // Space Quest 4 - English Macintosh // Executable scanning reports "x.yyy.zzz" @@ -2962,9 +2998,8 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "20fc54556ebfc737506288a1a32f7705", 364217}, {"resource.005", 0, "869d16cab6641c80b06f4dcee18f86bc", 1426228}, {"resource.006", 0, "91d23407bc0447a3722fbeb952d7edee", 1402451}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, // Space Quest 5 - English DOS (from the Space Quest Collection) // Executable scanning reports "1.001.068", VERSION file reports "1.04" @@ -2972,18 +3007,16 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, {"resource.msg", 0, "bb8ad78793c26bdb3f77498b1d6515a9", 125988}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 5 - English DOS // SCI interpreter version 1.001.067 {"sq5", "", { {"resource.map", 0, "8bde0a9adb9a3e9aaa861826874c9834", 6473}, {"resource.000", 0, "f4a48705764544d7cc64a7bb22a610df", 6025184}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 5 v1.04 - German DOS (from Tobis87, updated information by markcool from bug reports #2723935 and #2724762) // SCI interpreter version 1.001.068 @@ -2991,27 +3024,24 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, {"resource.msg", 0, "7c71cfc36153cfe07b450423a51f7e68", 146282}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 5 v1.04 - French DOS (from Hkz, Included in Space Quest Collector's Edition, with chapters I-V) {"sq5", "", { {"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, {"resource.msg", 0, "877c42380320eb1db7dad83ccd261214", 140374}, - {NULL, 0, NULL, 0}}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // Space Quest 5 - Italian DOS Floppy (from glorifindel) // SCI interpreter version 1.001.068 (just a guess) {"sq5", "", { {"resource.000", 0, "5040026519f37199f3616fb1d4704dff", 6047170}, {"resource.map", 0, "5b09168baa2f6e2e22787429b2d72f54", 6492}, - {NULL, 0, NULL, 0}}, - Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 // Space Quest 6 - English DOS/Win3.11 CD (from the Space Quest Collection) @@ -3019,45 +3049,40 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"sq6", "", { {"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528}, {"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Space Quest 6 - English DOS/Win3.11 CD ver 1.11 (from FRG) // SCI interpreter version 2.100.002 (just a guess) {"sq6", "", { {"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528}, {"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // Space Quest 6 - French DOS/Win3.11 CD (from French magazine Joystick - September 1997) // Executable scanning reports "2.100.002", VERSION file reports "1.0" {"sq6", "", { {"resource.map", 0, "3c831625931d5079b73ae8c275f52c95", 10534}, {"resource.000", 0, "4195ca940f759424f62b90e262cc1737", 40932397}, - {NULL, 0, NULL, 0}}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE }, // Space Quest 6 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723884) // SCI interpreter version 2.100.002 (just a guess) {"sq6", "", { {"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534}, {"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE }, // Space Quest 6 - English DOS/Win3.11 Interactive Demo (from FRG) // SCI interpreter version 2.100.002 (just a guess) {"sq6", "Demo", { {"resource.map", 0, "368f07b07433db3f819fa3fa0e5efee5", 2572}, {"resource.000", 0, "ab12724e078dea34b624e0d2a38dcd7c", 2272050}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, #endif // ENABLE_SCI32 // The Island of Dr. Brain - English DOS CD (from jvprat) @@ -3065,27 +3090,24 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"islandbrain", "", { {"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281}, {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, // The Island of Dr. Brain - English DOS (from Quietust) // Executable scanning reports "1.001.053", VERSION file reports "1.1 2.3.93" {"islandbrain", "", { {"resource.map", 0, "3c07da06bdd1689f9d07af78fb94d0ec", 3101}, {"resource.000", 0, "ecc686e0034fb4d41de077ac7167b3cf", 1947866}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, // The Island of Dr. Brain - English DOS Non-Interactive Demo // SCI interpreter version 1.001.053 (just a guess) {"islandbrain", "Demo", { {"resource.map", 0, "a8e5ca8ed1996974afa59f4c45e06195", 986}, {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 586560}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, #ifdef ENABLE_SCI32 // Torin's Passage - English Windows Interactive Demo @@ -3093,18 +3115,16 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"torin", "Demo", { {"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403}, {"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH }, // Torin's Passage - English Windows // SCI interpreter version 2.100.002 (just a guess) {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, // Torin's Passage - Spanish Windows (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.0" @@ -3112,36 +3132,32 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, // TODO: depend on one of the patches? - {NULL, 0, NULL, 0}}, - Common::ES_ESP, Common::kPlatformWindows, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::ES_ESP, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, // Torin's Passage - French Windows // SCI interpreter version 2.100.002 (just a guess) {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, - Common::FR_FRA, Common::kPlatformWindows, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, // Torin's Passage - German Windows // SCI interpreter version 2.100.002 (just a guess) {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, - Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH - }, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, // Torin's Passage - Italian Windows CD (from glorifindel) // SCI interpreter version 2.100.002 (just a guess) {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, - Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE - }, + AD_LISTEND}, + Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE }, #endif // ENABLE_SCI32 // SCI Fanmade Games diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp index 315c86c56c..f99d412c64 100644 --- a/engines/sci/engine/features.cpp +++ b/engines/sci/engine/features.cpp @@ -216,9 +216,9 @@ SciVersion GameFeatures::detectSetCursorType() { return _setCursorType; } -bool GameFeatures::autoDetectLofsType(int methodNum) { +bool GameFeatures::autoDetectLofsType(Common::String gameSuperClassName, int methodNum) { // Look up the script address - reg_t addr = getDetectionAddr("Game", -1, methodNum); + reg_t addr = getDetectionAddr(gameSuperClassName.c_str(), -1, methodNum); if (!addr.segment) return false; @@ -275,20 +275,35 @@ SciVersion GameFeatures::detectLofsType() { return _lofsType; } + // Find the "Game" object, super class of the actual game-object + const reg_t game = g_sci->getGameObject(); + const Object *gameObject = _segMan->getObject(game); + reg_t gameSuperClass = NULL_REG; + if (gameObject) { + gameSuperClass = gameObject->getSuperClassSelector(); + } + // Find a function of the game object which invokes lofsa/lofss - reg_t gameClass = _segMan->findObjectByName("Game"); - const Object *obj = _segMan->getObject(gameClass); bool found = false; + if (!gameSuperClass.isNull()) { + Common::String gameSuperClassName = _segMan->getObjectName(gameSuperClass); + const Object *gameSuperObject = _segMan->getObject(gameSuperClass); - for (uint m = 0; m < obj->getMethodCount(); m++) { - found = autoDetectLofsType(m); - - if (found) - break; + if (gameSuperObject) { + for (uint m = 0; m < gameSuperObject->getMethodCount(); m++) { + found = autoDetectLofsType(gameSuperClassName, m); + if (found) + break; + } + } else { + warning("detectLofsType(): Could not get superclass object"); + } + } else { + warning("detectLofsType(): Could not find superclass of game object"); } if (!found) { - warning("Lofs detection failed, taking an educated guess"); + warning("detectLofsType(): failed, taking an educated guess"); if (getSciVersion() >= SCI_VERSION_1_MIDDLE) _lofsType = SCI_VERSION_1_MIDDLE; @@ -423,6 +438,8 @@ SciVersion GameFeatures::detectMessageFunctionType() { Common::List<ResourceId> *resources = g_sci->getResMan()->listResources(kResourceTypeMessage, -1); if (resources->empty()) { + delete resources; + // No messages found, so this doesn't really matter anyway... _messageFunctionType = SCI_VERSION_1_1; return _messageFunctionType; @@ -430,6 +447,7 @@ SciVersion GameFeatures::detectMessageFunctionType() { Resource *res = g_sci->getResMan()->findResource(*resources->begin(), false); assert(res); + delete resources; // Only v2 Message resources use the kGetMessage kernel function. // v3-v5 use the kMessage kernel function. diff --git a/engines/sci/engine/features.h b/engines/sci/engine/features.h index 167c207437..755054fb25 100644 --- a/engines/sci/engine/features.h +++ b/engines/sci/engine/features.h @@ -103,7 +103,7 @@ public: private: reg_t getDetectionAddr(const Common::String &objName, Selector slc, int methodNum = -1); - bool autoDetectLofsType(int methodNum); + bool autoDetectLofsType(Common::String gameSuperClassName, int methodNum); bool autoDetectGfxFunctionsType(int methodNum = -1); bool autoDetectSoundType(); bool autoDetectMoveCountType(); diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index d76199c794..157884fac3 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -43,8 +43,17 @@ Kernel::Kernel(ResourceManager *resMan, SegManager *segMan) } Kernel::~Kernel() { - for (KernelFunctionArray::iterator i = _kernelFuncs.begin(); i != _kernelFuncs.end(); ++i) - delete[] i->signature; + for (KernelFunctionArray::iterator it = _kernelFuncs.begin(); it != _kernelFuncs.end(); ++it) { + if (it->subFunctionCount) { + uint16 subFunctionNr = 0; + while (subFunctionNr < it->subFunctionCount) { + delete[] it->subFunctions[subFunctionNr].signature; + subFunctionNr++; + } + delete[] it->subFunctions; + } + delete[] it->signature; + } } uint Kernel::getSelectorNamesSize() const { @@ -56,12 +65,14 @@ const Common::String &Kernel::getSelectorName(uint selector) { // This should only occur in games w/o a selector-table // We need this for proper workaround tables // TODO: maybe check, if there is a fixed selector-table and error() out in that case - for (uint loopSelector = _selectorNames.size(); loopSelector <= selector; loopSelector++) { - Common::String newSelectorName; - newSelectorName = newSelectorName.printf("<noname %d>", loopSelector); - _selectorNames.push_back(newSelectorName); - } + for (uint loopSelector = _selectorNames.size(); loopSelector <= selector; ++loopSelector) + _selectorNames.push_back(Common::String::printf("<noname%d>", loopSelector)); } + + // Ensure that the selector has a name + if (_selectorNames[selector].empty()) + _selectorNames[selector] = Common::String::printf("<noname%d>", selector); + return _selectorNames[selector]; } @@ -650,7 +661,7 @@ void Kernel::mapFunctions() { return; } -bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) { +bool Kernel::debugSetFunction(const char *kernelName, int logging, int breakpoint) { if (strcmp(kernelName, "*")) { for (uint id = 0; id < _kernelFuncs.size(); id++) { if (_kernelFuncs[id].name) { @@ -660,14 +671,21 @@ bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) { KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions; uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount; for (uint subId = 0; subId < kernelSubCallCount; subId++) { - if (kernelSubCall->function) - kernelSubCall->debugLogging = logging; + if (kernelSubCall->function) { + if (logging != -1) + kernelSubCall->debugLogging = logging == 1 ? true : false; + if (breakpoint != -1) + kernelSubCall->debugBreakpoint = breakpoint == 1 ? true : false; + } kernelSubCall++; } return true; } // function name matched, set for this one and exit - _kernelFuncs[id].debugLogging = logging; + if (logging != -1) + _kernelFuncs[id].debugLogging = logging == 1 ? true : false; + if (breakpoint != -1) + _kernelFuncs[id].debugBreakpoint = breakpoint == 1 ? true : false; return true; } else { // main name was not matched @@ -679,7 +697,10 @@ bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) { if (kernelSubCall->function) { if (strcmp(kernelName, kernelSubCall->name) == 0) { // sub-function name matched, set for this one and exit - kernelSubCall->debugLogging = logging; + if (logging != -1) + kernelSubCall->debugLogging = logging == 1 ? true : false; + if (breakpoint != -1) + kernelSubCall->debugBreakpoint = breakpoint == 1 ? true : false; return true; } } @@ -696,14 +717,21 @@ bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) { if (_kernelFuncs[id].name) { if (!_kernelFuncs[id].subFunctions) { // No sub-functions, enable actual kernel function - _kernelFuncs[id].debugLogging = logging; + if (logging != -1) + _kernelFuncs[id].debugLogging = logging == 1 ? true : false; + if (breakpoint != -1) + _kernelFuncs[id].debugBreakpoint = breakpoint == 1 ? true : false; } else { // Sub-Functions available, enable those too KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions; uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount; for (uint subId = 0; subId < kernelSubCallCount; subId++) { - if (kernelSubCall->function) - kernelSubCall->debugLogging = logging; + if (kernelSubCall->function) { + if (logging != -1) + kernelSubCall->debugLogging = logging == 1 ? true : false; + if (breakpoint != -1) + kernelSubCall->debugBreakpoint = breakpoint == 1 ? true : false; + } kernelSubCall++; } } diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 285e746349..b6247b46f1 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -127,6 +127,7 @@ struct KernelSubFunction { uint16 *signature; const SciWorkaroundEntry *workarounds; bool debugLogging; + bool debugBreakpoint; }; struct KernelFunction { @@ -137,6 +138,7 @@ struct KernelFunction { KernelSubFunction *subFunctions; uint16 subFunctionCount; bool debugLogging; + bool debugBreakpoint; }; class Kernel { @@ -218,9 +220,9 @@ public: void loadKernelNames(GameFeatures *features); /** - * Sets debugCalls flag for a kernel function + * Sets debug flags for a kernel function */ - bool debugSetFunctionLogging(const char *kernelName, bool debugCalls); + bool debugSetFunction(const char *kernelName, int logging, int breakpoint); private: /** @@ -467,7 +469,7 @@ reg_t kMoveToEnd(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundInit(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundPlay(EngineState *s, int argc, reg_t *argv); -reg_t kDoSoundDummy(EngineState *s, int argc, reg_t *argv); +reg_t kDoSoundRestore(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundDispose(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundMute(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundStop(EngineState *s, int argc, reg_t *argv); @@ -482,6 +484,7 @@ reg_t kDoSoundUpdateCues(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundSendMidi(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundReverb(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundSetHold(EngineState *s, int argc, reg_t *argv); +reg_t kDoSoundDummy(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundGetAudioCapability(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundSuspend(EngineState *s, int argc, reg_t *argv); reg_t kDoSoundSetVolume(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 886e918fd8..b2b8eb593e 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -86,7 +86,7 @@ struct SciKernelMapSubEntry { static const SciKernelMapSubEntry kDoSound_subops[] = { { SIG_SOUNDSCI0, 0, MAP_CALL(DoSoundInit), "o", NULL }, { SIG_SOUNDSCI0, 1, MAP_CALL(DoSoundPlay), "o", NULL }, - { SIG_SOUNDSCI0, 2, MAP_CALL(DoSoundDummy), "(o)", NULL }, + { SIG_SOUNDSCI0, 2, MAP_CALL(DoSoundRestore), "(o)", NULL }, { SIG_SOUNDSCI0, 3, MAP_CALL(DoSoundDispose), "o", NULL }, { SIG_SOUNDSCI0, 4, MAP_CALL(DoSoundMute), "(i)", NULL }, { SIG_SOUNDSCI0, 5, MAP_CALL(DoSoundStop), "o", NULL }, @@ -99,7 +99,7 @@ static const SciKernelMapSubEntry kDoSound_subops[] = { { SIG_SOUNDSCI0, 12, MAP_CALL(DoSoundStopAll), "", NULL }, { SIG_SOUNDSCI1EARLY, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 1, MAP_CALL(DoSoundMute), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 2, MAP_CALL(DoSoundDummy), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 2, MAP_CALL(DoSoundRestore), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 4, MAP_CALL(DoSoundUpdate), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 5, MAP_CALL(DoSoundInit), NULL, NULL }, @@ -111,7 +111,7 @@ static const SciKernelMapSubEntry kDoSound_subops[] = { // it actually does internally { SIG_SOUNDSCI1EARLY, 8, MAP_CALL(DoSoundStop), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 9, MAP_CALL(DoSoundPause), "[o0]i", NULL }, - { SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade), "oiiii", NULL }, + { SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade), "oiiii", kDoSoundFade_workarounds }, { SIG_SOUNDSCI1EARLY, 11, MAP_CALL(DoSoundUpdateCues), "o", NULL }, { SIG_SOUNDSCI1EARLY, 12, MAP_CALL(DoSoundSendMidi), "oiii", NULL }, { SIG_SOUNDSCI1EARLY, 13, MAP_CALL(DoSoundReverb), "i", NULL }, @@ -120,7 +120,7 @@ static const SciKernelMapSubEntry kDoSound_subops[] = { // ^^ Longbow demo { SIG_SOUNDSCI1LATE, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, { SIG_SOUNDSCI1LATE, 1, MAP_CALL(DoSoundMute), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 2, MAP_CALL(DoSoundDummy), "", NULL }, + { SIG_SOUNDSCI1LATE, 2, MAP_CALL(DoSoundRestore), "", NULL }, { SIG_SOUNDSCI1LATE, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, { SIG_SOUNDSCI1LATE, 4, MAP_CALL(DoSoundGetAudioCapability), "", NULL }, { SIG_SOUNDSCI1LATE, 5, MAP_CALL(DoSoundSuspend), "i", NULL }, @@ -142,7 +142,7 @@ static const SciKernelMapSubEntry kDoSound_subops[] = { #ifdef ENABLE_SCI32 { SIG_SOUNDSCI21, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, { SIG_SOUNDSCI21, 1, MAP_CALL(DoSoundMute), NULL, NULL }, - { SIG_SOUNDSCI21, 2, MAP_CALL(DoSoundDummy), NULL, NULL }, + { SIG_SOUNDSCI21, 2, MAP_CALL(DoSoundRestore), NULL, NULL }, { SIG_SOUNDSCI21, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, { SIG_SOUNDSCI21, 4, MAP_CALL(DoSoundGetAudioCapability), NULL, NULL }, { SIG_SOUNDSCI21, 5, MAP_CALL(DoSoundSuspend), NULL, NULL }, @@ -184,8 +184,8 @@ static const SciKernelMapSubEntry kGraph_subops[] = { { SIG_SCIALL, 9, MAP_CALL(GraphFillBoxBackground), "iiii", NULL }, { SIG_SCIALL, 10, MAP_CALL(GraphFillBoxForeground), "iiii", kGraphFillBoxForeground_workarounds }, { SIG_SCIALL, 11, MAP_CALL(GraphFillBoxAny), "iiiiii(i)(i)", kGraphFillBoxAny_workarounds }, - { SIG_SCI11, 12, MAP_CALL(GraphUpdateBox), "iiii(i)(r0)", NULL }, // kq6 hires - { SIG_SCIALL, 12, MAP_CALL(GraphUpdateBox), "iiii(i)", NULL }, + { SIG_SCI11, 12, MAP_CALL(GraphUpdateBox), "iiii(i)(r0)", kGraphUpdateBox_workarounds }, // kq6 hires + { SIG_SCIALL, 12, MAP_CALL(GraphUpdateBox), "iiii(i)", kGraphUpdateBox_workarounds }, { SIG_SCIALL, 13, MAP_CALL(GraphRedrawBox), "iiii", kGraphRedrawBox_workarounds }, { SIG_SCIALL, 14, MAP_CALL(GraphAdjustPriority), "ii", NULL }, { SIG_SCI11, 15, MAP_CALL(GraphSaveUpscaledHiresBox), "iiii", NULL }, // kq6 hires @@ -319,7 +319,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(CoordPri), SIG_EVERYWHERE, "i(i)", NULL, NULL }, { MAP_CALL(CosDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(DeleteKey), SIG_EVERYWHERE, "l.", NULL, NULL }, - { MAP_CALL(DeviceInfo), SIG_EVERYWHERE, "i(r)(r)(i)", NULL, NULL }, // subop + { MAP_CALL(DeviceInfo), SIG_EVERYWHERE, "i(r)(r)(i)", NULL, kDeviceInfo_workarounds }, // subop { MAP_CALL(Display), SIG_EVERYWHERE, "[ir]([ir!]*)", NULL, NULL }, // ^ we allow invalid references here, because kDisplay gets called with those in e.g. pq3 during intro // restoreBits() checks and skips invalid handles, so that's fine. Sierra SCI behaved the same @@ -418,7 +418,8 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(ScriptID), SIG_EVERYWHERE, "[io](i)", NULL, NULL }, { MAP_CALL(SetCursor), SIG_SCI21, SIGFOR_ALL, "i(i)([io])(i*)", NULL, NULL }, // TODO: SCI2.1 may supply an object optionally (mother goose sci21 right on startup) - find out why - { MAP_CALL(SetCursor), SIG_EVERYWHERE, "i(i*)", NULL, NULL }, + { MAP_CALL(SetCursor), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(iiiiii)", NULL, NULL }, + { MAP_CALL(SetCursor), SIG_EVERYWHERE, "i(i)(i)(i)(i)", NULL, kSetCursor_workarounds }, { MAP_CALL(SetDebug), SIG_EVERYWHERE, "(i*)", NULL, NULL }, { MAP_CALL(SetJump), SIG_EVERYWHERE, "oiii", NULL, NULL }, { MAP_CALL(SetMenu), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, @@ -432,7 +433,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(SinDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(Sort), SIG_EVERYWHERE, "ooo", NULL, NULL }, { MAP_CALL(Sqrt), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(StrAt), SIG_EVERYWHERE, "ri(i)", NULL, NULL }, + { MAP_CALL(StrAt), SIG_EVERYWHERE, "ri(i)", NULL, kStrAt_workarounds }, { MAP_CALL(StrCat), SIG_EVERYWHERE, "rr", NULL, NULL }, { MAP_CALL(StrCmp), SIG_EVERYWHERE, "rr(i)", NULL, NULL }, { MAP_CALL(StrCpy), SIG_EVERYWHERE, "r[r0](i)", NULL, NULL }, diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index d4ba467b25..39c32ccc68 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -282,6 +282,14 @@ enum { }; reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) { + if (g_sci->getGameId() == GID_FANMADE && argc == 1) { + // WORKAROUND: The fan game script library calls kDeviceInfo with one parameter. + // According to the scripts, it wants to call CurDevice. However, it fails to + // provide the subop to the function. + s->_segMan->strcpy(argv[0], "/"); + return s->r_acc; + } + int mode = argv[0].toUint16(); switch (mode) { @@ -480,6 +488,10 @@ reg_t kCheckSaveGame(EngineState *s, int argc, reg_t *argv) { Common::Array<SavegameDesc> saves; listSavegames(saves); + // we allow 0 (happens in QfG2 when trying to restore from an empty saved game list) and return false in that case + if (virtualId == 0) + return NULL_REG; + // Find saved-game if ((virtualId < SAVEGAMEID_OFFICIALRANGE_START) || (virtualId > SAVEGAMEID_OFFICIALRANGE_END)) error("kCheckSaveGame: called with invalid savegameId!"); @@ -494,7 +506,7 @@ reg_t kCheckSaveGame(EngineState *s, int argc, reg_t *argv) { return NULL_REG; // Otherwise we assume the savegame is OK - return make_reg(0, 1); + return TRUE_REG; } reg_t kGetSaveFiles(EngineState *s, int argc, reg_t *argv) { diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 56518f10bf..e1e92b1cf9 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -29,6 +29,8 @@ #include "graphics/cursorman.h" #include "graphics/surface.h" +#include "gui/message.h" + #include "sci/sci.h" #include "sci/debug.h" // for g_debug_sleeptime_factor #include "sci/resource.h" @@ -172,8 +174,8 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) { } break; } + case 9: // case for kq5cd, we are getting calling with 4 additional 900d parameters case 5: - case 9: hotspot = new Common::Point(argv[3].toSint16(), argv[4].toSint16()); // Fallthrough case 3: @@ -182,6 +184,18 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) { else g_sci->_gfxCursor->kernelSetView(argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16(), hotspot); break; + case 10: + // Freddy pharkas, when using the whiskey glass to read the prescription (bug #3034973) + // magnifier support, disabled using argc == 1, argv == -1 + warning("kSetCursor: unsupported magnifier"); + // we just set the view cursor currently + g_sci->_gfxCursor->kernelSetView(argv[5].toUint16(), argv[6].toUint16(), argv[7].toUint16(), hotspot); + // argv[0] -> 1, 2, 4 -> maybe magnification multiplier + // argv[1-4] -> rect for magnification + // argv[5, 6, 7] -> view resource for cursor + // argv[8] -> picture resource for mag + // argv[9] -> color for magnifier replacement + break; default : error("kSetCursor: Unhandled case: %d arguments given", argc); break; @@ -739,8 +753,10 @@ reg_t kPortrait(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -// Original top-left must stay on kControl rects, we adjust accordingly because sierra sci actually wont draw rects that -// are upside down (example: jones, when challenging jones - one button is a duplicate and also has lower-right which is 0, 0) +// Original top-left must stay on kControl rects, we adjust accordingly because +// sierra sci actually wont draw rects that are upside down (example: jones, +// when challenging jones - one button is a duplicate and also has lower-right +// which is 0, 0) Common::Rect kControlCreateRect(int16 x, int16 y, int16 x1, int16 y1) { if (x > x1) x1 = x; if (y > y1) y1 = y; @@ -882,7 +898,8 @@ reg_t kDrawControl(EngineState *s, int argc, reg_t *argv) { // Disable the "Change Directory" button, as we don't allow the game engine to // change the directory where saved games are placed - if (objName == "changeDirI") { + // "changeDirItem" is used in the import windows of QFG2&3 + if ((objName == "changeDirI") || (objName == "changeDirItem")) { int state = readSelectorValue(s->_segMan, controlObject, SELECTOR(state)); writeSelectorValue(s->_segMan, controlObject, SELECTOR(state), (state | SCI_CONTROLS_STYLE_DISABLED) & ~SCI_CONTROLS_STYLE_ENABLED); } @@ -898,6 +915,24 @@ reg_t kDrawControl(EngineState *s, int argc, reg_t *argv) { } } } + if (objName == "savedHeros") { + // Import of QfG character files dialog is shown + // display additional popup information before letting user use it + reg_t changeDirButton = s->_segMan->findObjectByName("changeDirItem"); + if (!changeDirButton.isNull()) { + // check if checkDirButton is still enabled, in that case we are called the first time during that room + if (!(readSelectorValue(s->_segMan, changeDirButton, SELECTOR(state)) & SCI_CONTROLS_STYLE_DISABLED)) { + GUI::MessageDialog dialog("Characters saved inside ScummVM are shown " + "automatically. Character files saved in the original " + "interpreter need to be put inside ScummVM's saved games " + "directory and a prefix needs to be added depending on which " + "game it was saved in: 'qfg1-' for Quest for Glory 1, 'qfg2-' " + "for Quest for Glory 2. Example: 'qfg2-thief.sav'.", + "OK"); + dialog.runModal(); + } + } + } _k_GenericDrawControl(s, controlObject, false); return NULL_REG; @@ -1070,7 +1105,7 @@ reg_t kShakeScreen(EngineState *s, int argc, reg_t *argv) { int16 shakeCount = (argc > 0) ? argv[0].toUint16() : 1; int16 directions = (argc > 1) ? argv[1].toUint16() : 1; - g_sci->_gfxPaint->kernelShakeScreen(shakeCount, directions); + g_sci->_gfxScreen->kernelShakeScreen(shakeCount, directions); return s->r_acc; } diff --git a/engines/sci/engine/kmath.cpp b/engines/sci/engine/kmath.cpp index bdc705cae3..f3769b653b 100644 --- a/engines/sci/engine/kmath.cpp +++ b/engines/sci/engine/kmath.cpp @@ -37,8 +37,18 @@ reg_t kRandom(EngineState *s, int argc, reg_t *argv) { case 2: { // get random number int fromNumber = argv[0].toUint16(); int toNumber = argv[1].toUint16(); - double randomNumber = fromNumber + ((toNumber + 1.0 - fromNumber) * (rand() / (RAND_MAX + 1.0))); - return make_reg(0, (int)randomNumber); + + // TODO/CHECKME: It is propbably not required to check whether + // toNumber is greater than fromNumber, at least not when one + // goes by their names, but let us be on the safe side and + // allow toNumber to be smaller than fromNumber too. + if (fromNumber > toNumber) + SWAP(fromNumber, toNumber); + + const uint diff = (uint)(toNumber - fromNumber); + + const int randomNumber = fromNumber + (int)g_sci->getRNG().getRandomNumber(diff); + return make_reg(0, randomNumber); } case 3: // get seed diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 305e202ae9..fbe20410de 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -46,25 +46,37 @@ reg_t kRestartGame(EngineState *s, int argc, reg_t *argv) { ** Returns the restarting_flag in acc */ reg_t kGameIsRestarting(EngineState *s, int argc, reg_t *argv) { - s->r_acc = make_reg(0, s->gameWasRestarted); + s->r_acc = make_reg(0, s->gameIsRestarting); if (argc) { // Only happens during replay if (!argv[0].toUint16()) // Set restarting flag - s->gameWasRestarted = false; + s->gameIsRestarting = GAMEISRESTARTING_NONE; } uint32 neededSleep = 30; - // WORKAROUND: LSL3 calculates a machinespeed variable during game startup - // (right after the filthy questions). This one would go through w/o - // throttling resulting in having to do 1000 pushups or something. Another - // way of handling this would be delaying incrementing of "machineSpeed" - // selector. - if (g_sci->getGameId() == GID_LSL3 && s->currentRoomNumber() == 290) - s->_throttleTrigger = true; - else if (g_sci->getGameId() == GID_ICEMAN && s->currentRoomNumber() == 27) { - s->_throttleTrigger = true; - neededSleep = 60; + // WORKAROUNDS: + switch (g_sci->getGameId()) { + case GID_LSL3: + // LSL3 calculates a machinespeed variable during game startup + // (right after the filthy questions). This one would go through w/o + // throttling resulting in having to do 1000 pushups or something. Another + // way of handling this would be delaying incrementing of "machineSpeed" + // selector. + if (s->currentRoomNumber() == 290) + s->_throttleTrigger = true; + break; + case GID_ICEMAN: + // In ICEMAN the submarine control room is not animating much, so it runs way too fast + // we calm it down even more otherwise especially fighting against other submarines + // is almost impossible + if (s->currentRoomNumber() == 27) { + s->_throttleTrigger = true; + neededSleep = 60; + } + break; + default: + break; } s->speedThrottler(neededSleep); @@ -160,10 +172,10 @@ reg_t kSetDebug(EngineState *s, int argc, reg_t *argv) { } enum { - K_NEW_GETTIME_TICKS = 0, - K_NEW_GETTIME_TIME_12HOUR = 1, - K_NEW_GETTIME_TIME_24HOUR = 2, - K_NEW_GETTIME_DATE = 3 + KGETTIME_TICKS = 0, + KGETTIME_TIME_12HOUR = 1, + KGETTIME_TIME_24HOUR = 2, + KGETTIME_DATE = 3 }; reg_t kGetTime(EngineState *s, int argc, reg_t *argv) { @@ -180,19 +192,19 @@ reg_t kGetTime(EngineState *s, int argc, reg_t *argv) { error("kGetTime called in SCI0 with mode %d (expected 0 or 1)", mode); switch (mode) { - case K_NEW_GETTIME_TICKS : + case KGETTIME_TICKS : retval = elapsedTime * 60 / 1000; debugC(2, kDebugLevelTime, "GetTime(elapsed) returns %d", retval); break; - case K_NEW_GETTIME_TIME_12HOUR : + case KGETTIME_TIME_12HOUR : retval = ((loc_time.tm_hour % 12) << 12) | (loc_time.tm_min << 6) | (loc_time.tm_sec); debugC(2, kDebugLevelTime, "GetTime(12h) returns %d", retval); break; - case K_NEW_GETTIME_TIME_24HOUR : + case KGETTIME_TIME_24HOUR : retval = (loc_time.tm_hour << 11) | (loc_time.tm_min << 5) | (loc_time.tm_sec >> 1); debugC(2, kDebugLevelTime, "GetTime(24h) returns %d", retval); break; - case K_NEW_GETTIME_DATE : + case KGETTIME_DATE : retval = loc_time.tm_mday | ((loc_time.tm_mon + 1) << 5) | (((loc_time.tm_year + 1900) & 0x7f) << 9); debugC(2, kDebugLevelTime, "GetTime(date) returns %d", retval); break; @@ -215,17 +227,32 @@ enum { reg_t kMemory(EngineState *s, int argc, reg_t *argv) { switch (argv[0].toUint16()) { - case K_MEMORY_ALLOCATE_CRITICAL : - if (!s->_segMan->allocDynmem(argv[1].toUint16(), "kMemory() critical", &s->r_acc)) { + case K_MEMORY_ALLOCATE_CRITICAL: { + int byteCount = argv[1].toUint16(); + // WORKAROUND: pq3 (multilingual) when plotting crimes - allocates the + // returned bytes from kStrLen on "W" and "E" and wants to put a + // string in there, which doesn't fit of course. That's why we allocate + // one byte more all the time inside that room + if (g_sci->getGameId() == GID_PQ3) { + if (s->currentRoomNumber() == 202) + byteCount++; + } + if (!s->_segMan->allocDynmem(byteCount, "kMemory() critical", &s->r_acc)) { error("Critical heap allocation failed"); } break; - case K_MEMORY_ALLOCATE_NONCRITICAL : + } + case K_MEMORY_ALLOCATE_NONCRITICAL: s->_segMan->allocDynmem(argv[1].toUint16(), "kMemory() non-critical", &s->r_acc); break; case K_MEMORY_FREE : - if (s->_segMan->freeDynmem(argv[1])) { - error("Attempt to kMemory::free() non-dynmem pointer %04x:%04x", PRINT_REG(argv[1])); + if (!s->_segMan->freeDynmem(argv[1])) { + if (g_sci->getGameId() == GID_QFG1VGA) { + // Ignore script bug in QFG1VGA, when closing any conversation dialog with esc + } else { + // Usually, the result of a script bug. Non-critical + warning("Attempt to kMemory::free() non-dynmem pointer %04x:%04x", PRINT_REG(argv[1])); + } } break; case K_MEMORY_MEMCPY : { diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp index 114b6eb755..dfd1aa699e 100644 --- a/engines/sci/engine/kmovement.cpp +++ b/engines/sci/engine/kmovement.cpp @@ -30,6 +30,7 @@ #include "sci/engine/selector.h" #include "sci/engine/kernel.h" #include "sci/graphics/animate.h" +#include "sci/graphics/screen.h" namespace Sci { @@ -313,8 +314,15 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) { || ((y == desty) && (abs(dy) >= abs(dx))) /* Moving fast, reached? */ ))) { // Whew... in short: If we have reached or passed our target position - x = destx; - y = desty; + + // Sanity check: make sure that destx, desty are inside the screen coordinates. + // They can go off screen in some cases, e.g. in SQ5 while scrubbing the floor (bug #3037351) + if (destx < g_sci->_gfxScreen->getWidth() && desty < g_sci->_gfxScreen->getHeight()) { + x = destx; + y = desty; + } else { + warning("kDoBresen: destination x, y would be off-screen(%d, %d)", destx, desty); + } completed = 1; debugC(2, kDebugLevelBresen, "Finished mover %04x:%04x", PRINT_REG(mover)); @@ -437,7 +445,7 @@ reg_t kDoAvoider(EngineState *s, int argc, reg_t *argv) { debugC(2, kDebugLevelBresen, "Movement (%d,%d), angle %d is %sblocked", dx, dy, angle, (s->r_acc.offset) ? " " : "not "); if (s->r_acc.offset) { // isBlocked() returned non-zero - int rotation = (rand() & 1) ? 45 : (360 - 45); // Clockwise/counterclockwise + int rotation = (g_sci->getRNG().getRandomBit() == 1) ? 45 : (360 - 45); // Clockwise/counterclockwise int oldx = readSelectorValue(segMan, client, SELECTOR(x)); int oldy = readSelectorValue(segMan, client, SELECTOR(y)); int xstep = readSelectorValue(segMan, client, SELECTOR(xStep)); diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index e211867ef9..a5501c160f 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -95,6 +95,7 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) { ++itr; } + delete resources; } else { which = g_sci->getResMan()->findResource(id, 0); diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 4e5ddc5e96..2f00cd7da2 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -48,7 +48,7 @@ reg_t kDoSound(EngineState *s, int argc, reg_t *argv) { CREATE_DOSOUND_FORWARD(DoSoundInit) CREATE_DOSOUND_FORWARD(DoSoundPlay) -CREATE_DOSOUND_FORWARD(DoSoundDummy) +CREATE_DOSOUND_FORWARD(DoSoundRestore) CREATE_DOSOUND_FORWARD(DoSoundDispose) CREATE_DOSOUND_FORWARD(DoSoundMute) CREATE_DOSOUND_FORWARD(DoSoundStop) @@ -63,6 +63,7 @@ CREATE_DOSOUND_FORWARD(DoSoundUpdateCues) CREATE_DOSOUND_FORWARD(DoSoundSendMidi) CREATE_DOSOUND_FORWARD(DoSoundReverb) CREATE_DOSOUND_FORWARD(DoSoundSetHold) +CREATE_DOSOUND_FORWARD(DoSoundDummy) CREATE_DOSOUND_FORWARD(DoSoundGetAudioCapability) CREATE_DOSOUND_FORWARD(DoSoundSuspend) CREATE_DOSOUND_FORWARD(DoSoundSetVolume) @@ -222,16 +223,17 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) { // 3 new subops in Pharkas. kDoAudio in Pharkas sits at seg026:038C case 11: + // Not sure where this is used yet warning("kDoAudio: Unhandled case 11, %d extra arguments passed", argc - 1); break; case 12: - // Seems to be audio sync, used in Pharkas. Silenced the warning due to - // the high level of spam it produces. + // Seems to be some sort of audio sync, used in Pharkas. Silenced the + // warning due to the high level of spam it produces. (takes no params) //warning("kDoAudio: Unhandled case 12, %d extra arguments passed", argc - 1); break; case 13: - // Used in Pharkas whenever a speech sample starts - warning("kDoAudio: Unhandled case 13, %d extra arguments passed", argc - 1); + // Used in Pharkas whenever a speech sample starts (takes no params) + //warning("kDoAudio: Unhandled case 13, %d extra arguments passed", argc - 1); break; default: warning("kDoAudio: Unhandled case %d, %d extra arguments passed", argv[0].toUint16(), argc - 1); diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index cd103dade7..3ad2d95f58 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -205,11 +205,15 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) { videoDecoder = new VMDDecoder(g_system->getMixer()); + if (!videoDecoder->loadFile(fileName)) { + warning("Could not open VMD %s", fileName.c_str()); + break; + } + if (reshowCursor) g_sci->_gfxCursor->kernelHide(); - if (videoDecoder && videoDecoder->loadFile(fileName)) - playVideo(videoDecoder); + playVideo(videoDecoder); if (reshowCursor) g_sci->_gfxCursor->kernelShow(); @@ -280,8 +284,7 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) { // Looks to be setting the video size and position. Called with 4 extra integer // parameters (e.g. 86, 41, 235, 106) default: - warningMsg = "PlayVMD - unsupported subop. Params: " + - Common::String::printf("%d", argc) + " ("; + warningMsg = Common::String::printf("PlayVMD - unsupported subop %d. Params: %d (", operation, argc); for (int i = 0; i < argc; i++) { warningMsg += Common::String::printf("%04x:%04x", PRINT_REG(argv[i])); diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp index cdecc556e8..6e1b326c4f 100644 --- a/engines/sci/engine/message.cpp +++ b/engines/sci/engine/message.cpp @@ -166,6 +166,8 @@ bool MessageState::getRecord(CursorStack &stack, bool recurse, MessageRecord &re } if (!reader->init()) { + delete reader; + warning("Message: failed to read resource header"); return false; } @@ -180,6 +182,7 @@ bool MessageState::getRecord(CursorStack &stack, bool recurse, MessageRecord &re continue; } + delete reader; return false; } @@ -193,6 +196,7 @@ bool MessageState::getRecord(CursorStack &stack, bool recurse, MessageRecord &re } } + delete reader; return true; } } diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 806c8893b4..a7716516e7 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -53,42 +53,8 @@ namespace Sci { #define VER(x) Common::Serializer::Version(x) -// OBSOLETE: This const is used for backward compatibility only. -const uint32 INTMAPPER_MAGIC_KEY = 0xDEADBEEF; - - #pragma mark - -// TODO: Many of the following sync_*() methods should be turned into member funcs -// of the classes they are syncing. - -#define DEFROBNICATE_HANDLE(handle) (make_reg((handle >> 16) & 0xffff, handle & 0xffff)) - -void MusicEntry::saveLoadWithSerializer(Common::Serializer &s) { - soundObj.saveLoadWithSerializer(s); - s.syncAsSint16LE(resourceId); - s.syncAsSint16LE(dataInc); - s.syncAsSint16LE(ticker); - s.syncAsSint16LE(signal, VER(17)); - s.syncAsByte(priority); - s.syncAsSint16LE(loop, VER(17)); - s.syncAsByte(volume); - s.syncAsByte(hold, VER(17)); - s.syncAsByte(fadeTo); - s.syncAsSint16LE(fadeStep); - s.syncAsSint32LE(fadeTicker); - s.syncAsSint32LE(fadeTickerStep); - s.syncAsByte(status); - - // pMidiParser and pStreamAud will be initialized when the - // sound list is reconstructed in gamestate_restore() - if (s.isLoading()) { - soundRes = 0; - pMidiParser = 0; - pStreamAud = 0; - } -} - // Experimental hack: Use syncWithSerializer to sync. By default, this assume // the object to be synced is a subclass of Serializable and thus tries to invoke // the saveLoadWithSerializer() method. But it is possible to specialize this @@ -148,7 +114,8 @@ void syncArray(Common::Serializer &s, Common::Array<T> &arr) { template <> void syncWithSerializer(Common::Serializer &s, reg_t &obj) { - obj.saveLoadWithSerializer(s); + s.syncAsUint16LE(obj.segment); + s.syncAsUint16LE(obj.offset); } void SegManager::saveLoadWithSerializer(Common::Serializer &s) { @@ -206,7 +173,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { template <> void syncWithSerializer(Common::Serializer &s, Class &obj) { s.syncAsSint32LE(obj.script); - obj.reg.saveLoadWithSerializer(s); + syncWithSerializer(s, obj.reg); } static void sync_SavegameMetadata(Common::Serializer &s, SavegameMetadata &obj) { @@ -266,7 +233,7 @@ void LocalVariables::saveLoadWithSerializer(Common::Serializer &s) { void Object::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint32LE(_flags); - _pos.saveLoadWithSerializer(s); + syncWithSerializer(s, _pos); s.syncAsSint32LE(_methodCount); // that's actually a uint16 syncArray<reg_t>(s, _variables); @@ -283,18 +250,18 @@ template <> void syncWithSerializer(Common::Serializer &s, Table<List>::Entry &obj) { s.syncAsSint32LE(obj.next_free); - obj.first.saveLoadWithSerializer(s); - obj.last.saveLoadWithSerializer(s); + syncWithSerializer(s, obj.first); + syncWithSerializer(s, obj.last); } template <> void syncWithSerializer(Common::Serializer &s, Table<Node>::Entry &obj) { s.syncAsSint32LE(obj.next_free); - obj.pred.saveLoadWithSerializer(s); - obj.succ.saveLoadWithSerializer(s); - obj.key.saveLoadWithSerializer(s); - obj.value.saveLoadWithSerializer(s); + syncWithSerializer(s, obj.pred); + syncWithSerializer(s, obj.succ); + syncWithSerializer(s, obj.key); + syncWithSerializer(s, obj.value); } #ifdef ENABLE_SCI32 @@ -328,7 +295,7 @@ void syncWithSerializer(Common::Serializer &s, Table<SciArray<reg_t> >::Entry &o if (s.isSaving()) value = obj.getValue(i); - value.saveLoadWithSerializer(s); + syncWithSerializer(s, value); if (s.isLoading()) obj.setValue(i, value); @@ -414,14 +381,14 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) { _objects.clear(); Object tmp; for (uint i = 0; i < numObjs; ++i) { - syncWithSerializer<Object>(s, tmp); + syncWithSerializer(s, tmp); _objects[tmp.getPos().offset] = tmp; } } else { ObjMap::iterator it; const ObjMap::iterator end = _objects.end(); for (it = _objects.begin(); it != end; ++it) { - syncWithSerializer<Object>(s, it->_value); + syncWithSerializer(s, it->_value); } } @@ -526,6 +493,31 @@ void SciMusic::saveLoadWithSerializer(Common::Serializer &s) { } } +void MusicEntry::saveLoadWithSerializer(Common::Serializer &s) { + syncWithSerializer(s, soundObj); + s.syncAsSint16LE(resourceId); + s.syncAsSint16LE(dataInc); + s.syncAsSint16LE(ticker); + s.syncAsSint16LE(signal, VER(17)); + s.syncAsByte(priority); + s.syncAsSint16LE(loop, VER(17)); + s.syncAsByte(volume); + s.syncAsByte(hold, VER(17)); + s.syncAsByte(fadeTo); + s.syncAsSint16LE(fadeStep); + s.syncAsSint32LE(fadeTicker); + s.syncAsSint32LE(fadeTickerStep); + s.syncAsByte(status); + + // pMidiParser and pStreamAud will be initialized when the + // sound list is reconstructed in gamestate_restore() + if (s.isLoading()) { + soundRes = 0; + pMidiParser = 0; + pStreamAud = 0; + } +} + void SoundCommandParser::syncPlayList(Common::Serializer &s) { _music->saveLoadWithSerializer(s); } @@ -748,11 +740,7 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { } // We don't need the thumbnail here, so just read it and discard it - Graphics::Surface *thumbnail = new Graphics::Surface(); - assert(thumbnail); - Graphics::loadThumbnail(*fh, *thumbnail); - delete thumbnail; - thumbnail = 0; + Graphics::skipThumbnail(*fh); s->reset(true); s->saveLoadWithSerializer(ser); // FIXME: Error handling? @@ -770,12 +758,19 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { s->gameStartTime = g_system->getMillis(); s->_screenUpdateTime = g_system->getMillis(); + if (g_sci->_gfxPorts) + g_sci->_gfxPorts->reset(); + g_sci->_soundCmd->reconstructPlayList(meta.savegame_version); // Message state: + delete s->_msgState; s->_msgState = new MessageState(s->_segMan); s->abortScriptProcessing = kAbortLoadGame; + + // signal restored game to game scripts + s->gameIsRestarting = GAMEISRESTARTING_RESTORE; } bool get_savegame_metadata(Common::SeekableReadStream *stream, SavegameMetadata *meta) { diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 25cf1d069f..1fb37f458d 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -851,13 +851,13 @@ byte *SegManager::allocDynmem(int size, const char *descr, reg_t *addr) { return (byte *)(d._buf); } -int SegManager::freeDynmem(reg_t addr) { +bool SegManager::freeDynmem(reg_t addr) { if (addr.segment < 1 || addr.segment >= _heap.size() || !_heap[addr.segment] || _heap[addr.segment]->getType() != SEG_TYPE_DYNMEM) - return 1; // error + return false; // error deallocate(addr.segment, true); - return 0; // OK + return true; // OK } #ifdef ENABLE_SCI32 diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index e0808dbb1b..59ac6f39b6 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -274,7 +274,7 @@ public: * Deallocates a piece of dynamic memory * @param[in] addr Offset of the dynmem chunk to free */ - int freeDynmem(reg_t addr); + bool freeDynmem(reg_t addr); // Generic Operations on Segments and Addresses diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index 2465576302..c8cb4cd203 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -143,9 +143,6 @@ public: } }; - -struct IntMapper; - enum { SYS_STRINGS_MAX = 4, diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index f5eb9eb73a..f99a41e088 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -164,6 +164,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(vanishingX); FIND_SELECTOR(vanishingY); FIND_SELECTOR(iconIndex); + FIND_SELECTOR(port); #ifdef ENABLE_SCI32 FIND_SELECTOR(data); diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index 661290f58c..00e795c1b9 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -127,6 +127,8 @@ struct SelectorCache { // SCI1.1 Mac icon bar selectors Selector iconIndex; ///< Used to index icon bar objects + Selector port; // used by a hoyle 4 workaround + #ifdef ENABLE_SCI32 Selector data; // Used by Array()/String() Selector picture; // Used to hold the picture ID for SCI32 pictures diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 243a460645..4f1d686b17 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -87,6 +87,12 @@ enum { SAVEGAMEID_OFFICIALRANGE_END = 1999 }; +enum { + GAMEISRESTARTING_NONE = 0, + GAMEISRESTARTING_RESTART = 1, + GAMEISRESTARTING_RESTORE = 2 +}; + class FileHandle { public: Common::String _name; @@ -159,7 +165,7 @@ public: int variablesMax[4]; ///< Max. values for all variables AbortGameState abortScriptProcessing; - bool gameWasRestarted; + int16 gameIsRestarting; // is set when restarting (=1) or restoring the game (=2) int scriptStepCounter; // Counts the number of steps executed int scriptGCInterval; // Number of steps in between gcs diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp index 55e18613e0..aae6de01f1 100644 --- a/engines/sci/engine/static_selectors.cpp +++ b/engines/sci/engine/static_selectors.cpp @@ -38,66 +38,66 @@ struct SelectorRemap { }; static const char * const sci0Selectors[] = { - "y", "x", "view", "loop", "cel", // 0 - 4 - "underBits", "nsTop", "nsLeft", "nsBottom", "nsRight", // 5 - 9 - "lsTop", "lsLeft", "lsBottom", "lsRight", "signal", // 10 - 14 - "illegalBits", "brTop", "brLeft", "brBottom", "brRight", // 15 - 19 - "name", "key", "time", "text", "elements", // 20 - 25 - "color", "back", "mode", "style", "state", // 25 - 29 - "font", "type", "window", "cursor", "max", // 30 - 34 - "mark", "who", "message", "edit", "play", // 35 - 39 - "number", "handle", "client", "dx", "dy", // 40 - 44 - "b-moveCnt", "b-i1", "b-i2", "b-di", "b-xAxis", // 45 - 49 - "b-incr", "xStep", "yStep", "moveSpeed", "canBeHere", // 50 - 54 - "heading", "mover", "doit", "isBlocked", "looper", // 55 - 59 - "priority", "modifiers", "replay", "setPri", "at", // 60 - 64 - "next", "done", "width", "wordFail", "syntaxFail", // 65 - 69 - "semanticFail", "pragmaFail", "said", "claimed", "value", // 70 - 74 - "save", "restore", "title", "button", "icon", // 75 - 79 - "draw", "delete", "z" // 80 - 82 + "y", "x", "view", "loop", "cel", // 0 - 4 + "underBits", "nsTop", "nsLeft", "nsBottom", "nsRight", // 5 - 9 + "lsTop", "lsLeft", "lsBottom", "lsRight", "signal", // 10 - 14 + "illegalBits", "brTop", "brLeft", "brBottom", "brRight", // 15 - 19 + "name", "key", "time", "text", "elements", // 20 - 25 + "color", "back", "mode", "style", "state", // 25 - 29 + "font", "type", "window", "cursor", "max", // 30 - 34 + "mark", "who", "message", "edit", "play", // 35 - 39 + "number", "handle", "client", "dx", "dy", // 40 - 44 + "b-moveCnt", "b-i1", "b-i2", "b-di", "b-xAxis", // 45 - 49 + "b-incr", "xStep", "yStep", "moveSpeed", "canBeHere", // 50 - 54 + "heading", "mover", "doit", "isBlocked", "looper", // 55 - 59 + "priority", "modifiers", "replay", "setPri", "at", // 60 - 64 + "next", "done", "width", "wordFail", "syntaxFail", // 65 - 69 + "semanticFail", "pragmaFail", "said", "claimed", "value", // 70 - 74 + "save", "restore", "title", "button", "icon", // 75 - 79 + "draw", "delete", "z" // 80 - 82 }; static const char * const sci1Selectors[] = { - "parseLang", "printLang", "subtitleLang", "size", "points", // 83 - 87 - "palette", "dataInc", "handle", "min", "sec", // 88 - 92 - "frame", "vol", "pri", "perform", "moveDone" // 93 - 97 + "parseLang", "printLang", "subtitleLang", "size", "points", // 83 - 87 + "palette", "dataInc", "handle", "min", "sec", // 88 - 92 + "frame", "vol", "pri", "perform", "moveDone" // 93 - 97 }; #ifdef ENABLE_SCI32 static const char * const sci2Selectors[] = { - "plane", "x", "y", "z", "scaleX", // 0 - 4 - "scaleY", "maxScale", "priority", "fixPriority", "inLeft", // 5 - 9 - "inTop", "inRight", "inBottom", "useInsetRect", "view", // 10 - 14 - "loop", "cel", "bitmap", "nsLeft", "nsTop", // 15 - 19 - "nsRight", "nsBottom", "lsLeft", "lsTop", "lsRight", // 20 - 25 - "lsBottom", "signal", "illegalBits", "brLeft", "brTop", // 25 - 29 - "brRight", "brBottom", "name", "key", "time", // 30 - 34 - "text", "elements", "fore", "back", "mode", // 35 - 39 - "style", "state", "font", "type", "window", // 40 - 44 - "cursor", "max", "mark", "who", "message", // 45 - 49 - "edit", "play", "number", "nodePtr", "client", // 50 - 54 - "dx", "dy", "b-moveCnt", "b-i1", "b-i2", // 55 - 59 - "b-di", "b-xAxis", "b-incr", "xStep", "yStep", // 60 - 64 - "moveSpeed", "cantBeHere", "heading", "mover", "doit", // 65 - 69 - "isBlocked", "looper", "modifiers", "replay", "setPri", // 70 - 74 - "at", "next", "done", "width", "pragmaFail", // 75 - 79 - "claimed", "value", "save", "restore", "title", // 80 - 84 - "button", "icon", "draw", "delete", "printLang", // 85 - 89 - "size", "points", "palette", "dataInc", "handle", // 90 - 94 - "min", "sec", "frame", "vol", "perform", // 95 - 99 - "moveDone", "topString", "flags", "quitGame", "restart", // 100 - 104 - "hide", "scaleSignal", "vanishingX", "vanishingY", "picture", // 105 - 109 - "resX", "resY", "coordType", "data", "skip", // 110 - 104 - "center", "all", "show", "textLeft", "textTop", // 115 - 119 - "textRight", "textBottom", "borderColor", "titleFore", "titleBack", // 120 - 124 - "titleFont", "dimmed", "frameOut", "lastKey", "magnifier", // 125 - 129 - "magPower", "mirrored", "pitch", "roll", "yaw", // 130 - 134 - "left", "right", "top", "bottom", "numLines" // 135 - 139 + "plane", "x", "y", "z", "scaleX", // 0 - 4 + "scaleY", "maxScale", "priority", "fixPriority", "inLeft", // 5 - 9 + "inTop", "inRight", "inBottom", "useInsetRect", "view", // 10 - 14 + "loop", "cel", "bitmap", "nsLeft", "nsTop", // 15 - 19 + "nsRight", "nsBottom", "lsLeft", "lsTop", "lsRight", // 20 - 25 + "lsBottom", "signal", "illegalBits", "brLeft", "brTop", // 25 - 29 + "brRight", "brBottom", "name", "key", "time", // 30 - 34 + "text", "elements", "fore", "back", "mode", // 35 - 39 + "style", "state", "font", "type", "window", // 40 - 44 + "cursor", "max", "mark", "who", "message", // 45 - 49 + "edit", "play", "number", "nodePtr", "client", // 50 - 54 + "dx", "dy", "b-moveCnt", "b-i1", "b-i2", // 55 - 59 + "b-di", "b-xAxis", "b-incr", "xStep", "yStep", // 60 - 64 + "moveSpeed", "cantBeHere", "heading", "mover", "doit", // 65 - 69 + "isBlocked", "looper", "modifiers", "replay", "setPri", // 70 - 74 + "at", "next", "done", "width", "pragmaFail", // 75 - 79 + "claimed", "value", "save", "restore", "title", // 80 - 84 + "button", "icon", "draw", "delete", "printLang", // 85 - 89 + "size", "points", "palette", "dataInc", "handle", // 90 - 94 + "min", "sec", "frame", "vol", "perform", // 95 - 99 + "moveDone", "topString", "flags", "quitGame", "restart", // 100 - 104 + "hide", "scaleSignal", "vanishingX", "vanishingY", "picture", // 105 - 109 + "resX", "resY", "coordType", "data", "skip", // 110 - 104 + "center", "all", "show", "textLeft", "textTop", // 115 - 119 + "textRight", "textBottom", "borderColor", "titleFore", "titleBack", // 120 - 124 + "titleFont", "dimmed", "frameOut", "lastKey", "magnifier", // 125 - 129 + "magPower", "mirrored", "pitch", "roll", "yaw", // 130 - 134 + "left", "right", "top", "bottom", "numLines" // 135 - 139 }; #endif static const SelectorRemap sciSelectorRemap[] = { - { SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE, "moveDone", 170 }, + { SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE, "moveDone", 170 }, { SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE, "points", 316 }, { SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE, "flags", 368 }, { SCI_VERSION_1_EARLY, SCI_VERSION_1_LATE, "nodePtr", 44 }, @@ -176,11 +176,12 @@ Common::StringArray Kernel::checkStaticSelectorNames() { names[110] = "init"; } else if (g_sci->getGameId() == GID_LAURABOW2) { - // The floppy of version needs the open selector set to match up with the CD version's - // workaround - bug #3035694 + // The floppy of version needs the open and changeState selectors set to match up with the + // CD version's workarounds - bugs #3035694 and #3036291 if (names.size() < 190) names.resize(190); + names[144] = "changeState"; names[189] = "open"; } diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index b7f6896a48..7bcc5b43a3 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -135,9 +135,13 @@ static StackPtr validate_stack_addr(EngineState *s, StackPtr sp) { static int validate_arithmetic(reg_t reg) { if (reg.segment) { // The results of this are likely unpredictable... It most likely means that a kernel function is returning something wrong. - // If such an error occurs, we usually need to find the last kernel function called and check its return value. Check - // callKernelFunc() below - error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]. Address: %04x:%04x", reg.segment, PRINT_REG(reg)); + // If such an error occurs, we usually need to find the last kernel function called and check its return value. + if (g_sci->getGameId() == GID_QFG2 && g_sci->getEngineState()->currentRoomNumber() == 200) { + // WORKAROUND: This happens in QFG2, room 200, when talking to the astrologer (bug #3039879) - script bug. + // Returning 0 in this case. + } else { + error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]. Address: %04x:%04x", reg.segment, PRINT_REG(reg)); + } return 0; } @@ -231,7 +235,7 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i case VAR_PARAM: // Out-of-bounds read for a parameter that goes onto stack and hits an uninitialized temp // We return 0 currently in that case - warning("Read for a parameter goes out-of-bounds, onto the stack and gets uninitialized temp"); + debugC(2, kDebugLevelVM, "[VM] Read for a parameter goes out-of-bounds, onto the stack and gets uninitialized temp"); return NULL_REG; default: break; @@ -743,6 +747,11 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) { if (kernelCall.debugLogging) logKernelCall(&kernelCall, NULL, s, argc, argv, s->r_acc); + if (kernelCall.debugBreakpoint) { + printf("Break on k%s\n", kernelCall.name); + g_sci->_debugState.debugging = true; + g_sci->_debugState.breakpointWasHit = true; + } } else { // Sub-functions available, check signature and call that one directly if (argc < 1) @@ -793,6 +802,11 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) { if (kernelSubCall.debugLogging) logKernelCall(&kernelCall, &kernelSubCall, s, argc, argv, s->r_acc); + if (kernelSubCall.debugBreakpoint) { + printf("Break on k%s\n", kernelSubCall.name); + g_sci->_debugState.debugging = true; + g_sci->_debugState.breakpointWasHit = true; + } } // Remove callk stack frame again, if there's still an execution stack @@ -923,11 +937,7 @@ void run_vm(EngineState *s) { obj = s->_segMan->getObject(s->xs->objp); local_script = s->_segMan->getScriptIfLoaded(s->xs->local_segment); if (!local_script) { - // FIXME: Why does this happen? Is the script not loaded yet at this point? - warning("Could not find local script from segment %x", s->xs->local_segment); - local_script = NULL; - s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = NULL; - s->variablesMax[VAR_LOCAL] = 0; + error("Could not find local script from segment %x", s->xs->local_segment); } else { s->variablesSegment[VAR_LOCAL] = local_script->_localsSegment; if (local_script->_localsBlock) @@ -1053,7 +1063,7 @@ void run_vm(EngineState *s) { if (validate_signedInteger(s->r_acc, value1) && validate_signedInteger(r_temp, value2)) s->r_acc = make_reg(0, value1 * value2); else - s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, s->r_acc, r_temp); + s->r_acc = arithmetic_lookForWorkaround(opcode, opcodeMulWorkarounds, s->r_acc, r_temp); break; } @@ -1069,11 +1079,30 @@ void run_vm(EngineState *s) { case op_mod: { // 0x05 (05) r_temp = POP32(); - int16 modulo, value; - if (validate_signedInteger(s->r_acc, modulo) && validate_signedInteger(r_temp, value)) - s->r_acc = make_reg(0, (modulo != 0 ? value % modulo : 0)); - else - s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, s->r_acc, r_temp); + + if (getSciVersion() <= SCI_VERSION_0_LATE) { + uint16 modulo, value; + if (validate_unsignedInteger(s->r_acc, modulo) && validate_unsignedInteger(r_temp, value)) + s->r_acc = make_reg(0, (modulo != 0 ? value % modulo : 0)); + else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, s->r_acc, r_temp); + } else { + // In Iceman (and perhaps from SCI0 0.000.685 onwards in general), + // handling for negative numbers was added. Since Iceman doesn't + // seem to have issues with the older code, we exclude it for now + // for simplicity's sake and use the new code for SCI01 and newer + // games. Fixes the battlecruiser mini game in SQ5 (room 850), + // bug #3035755 + int16 modulo, value, result; + if (validate_signedInteger(s->r_acc, modulo) && validate_signedInteger(r_temp, value)) { + modulo = ABS(modulo); + result = (modulo != 0 ? value % modulo : 0); + if (result < 0) + result += modulo; + s->r_acc = make_reg(0, result); + } else + s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, s->r_acc, r_temp); + } break; } @@ -1196,7 +1225,7 @@ void run_vm(EngineState *s) { if (validate_signedInteger(r_temp, compare1) && validate_signedInteger(s->r_acc, compare2)) s->r_acc = make_reg(0, compare1 >= compare2); else - s->r_acc = arithmetic_lookForWorkaround(opcode, NULL, r_temp, s->r_acc); + s->r_acc = arithmetic_lookForWorkaround(opcode, opcodeGeWorkarounds, r_temp, s->r_acc); } break; diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h index 828fba3d7d..edf35a122a 100644 --- a/engines/sci/engine/vm_types.h +++ b/engines/sci/engine/vm_types.h @@ -27,7 +27,6 @@ #define SCI_ENGINE_VM_TYPES_H #include "common/scummsys.h" -#include "common/serializer.h" namespace Sci { @@ -57,11 +56,6 @@ struct reg_t { int16 toSint16() const { return (int16) offset; } - - void saveLoadWithSerializer(Common::Serializer &s) { - s.syncAsUint16LE(segment); - s.syncAsUint16LE(offset); - } }; static inline reg_t make_reg(SegmentId segment, uint16 offset) { diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 0db73e34d5..bc6d457f7f 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -38,12 +38,6 @@ const SciWorkaroundEntry opcodeDivWorkarounds[] = { SCI_WORKAROUNDENTRY_TERMINATOR }; -// gameID, room,script,lvl, object-name, method-name, call,index, workaround -const SciWorkaroundEntry opcodeOrWorkarounds[] = { - { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xcc6, 0, { WORKAROUND_FAKE, 0 } }, // when giving the papers to the customs officer, gets called against a pointer instead of a number - bug #3034464 - SCI_WORKAROUNDENTRY_TERMINATOR -}; - // gameID, room,script,lvl, object-name, method-name, call, index, workaround const SciWorkaroundEntry opcodeDptoaWorkarounds[] = { { GID_LSL6, 360, 938, 0, "ROsc", "cycleDone", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking through tile in the shower room initial cycles get set to an object instead of 2, we fix this by setting 1 after decrease @@ -52,16 +46,37 @@ const SciWorkaroundEntry opcodeDptoaWorkarounds[] = { SCI_WORKAROUNDENTRY_TERMINATOR }; +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry opcodeGeWorkarounds[] = { + { GID_PQ3, 31, 31, 0, "rm031", "init", -1, 0, { WORKAROUND_FAKE, 1 } }, // pq3 english: when exiting the car, while morales is making phonecalls - bug #3037565 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry opcodeMulWorkarounds[] = { + { GID_FANMADE, 516, 983, 0, "Wander", "setTarget", -1, 0, { WORKAROUND_FAKE, 0 } }, // The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #3038913 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry opcodeOrWorkarounds[] = { + { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xcc6, 0, { WORKAROUND_FAKE, 0 } }, // when giving the papers to the customs officer, gets called against a pointer instead of a number - bug #3034464 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry uninitializedReadWorkarounds[] = { - { GID_CNICK_KQ, 200, 0, 1, "Character", "<noname 446>", -1, 504, { WORKAROUND_FAKE, 0 } }, // checkers, like in hoyle 3 - { GID_CNICK_KQ, 200, 0, 1, "Character", "<noname 446>", -1, 505, { WORKAROUND_FAKE, 0 } }, // checkers, like in hoyle 3 - { GID_CNICK_KQ, -1, 700, 0, "gcWindow", "<noname 183>", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu, like in hoyle 3 - { GID_CNICK_LONGBOW, 0, 0, 0, "RH Budget", "<noname 110>", -1, 1, { WORKAROUND_FAKE, 0 } }, // when starting the game + { GID_CASTLEBRAIN, 280, 280, 0, "programmer", "dispatchEvent", -1, 0, { WORKAROUND_FAKE, 0xf } }, // pressing 'q' on the computer screen in the robot room, and closing the help dialog that pops up (bug #3039656). Moves the cursor to the view with the ID returned (in this case, the robot hand) + { GID_CNICK_KQ, 200, 0, 1, "Character", "<noname446>", -1, 504, { WORKAROUND_FAKE, 0 } }, // checkers, like in hoyle 3 + { GID_CNICK_KQ, 200, 0, 1, "Character", "<noname446>", -1, 505, { WORKAROUND_FAKE, 0 } }, // checkers, like in hoyle 3 + { GID_CNICK_KQ, -1, 700, 0, "gcWindow", "<noname183>", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu, like in hoyle 3 + { GID_CNICK_LONGBOW, 0, 0, 0, "RH Budget", "<noname110>", -1, 1, { WORKAROUND_FAKE, 0 } }, // when starting the game { GID_ECOQUEST, -1, -1, 0, NULL, "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // almost clicking anywhere triggers this in almost all rooms + { GID_FANMADE, 516, 979, 0, "", "export 0", -1, 20, { WORKAROUND_FAKE, 0 } }, // Happens in Grotesteing after the logos + { GID_FANMADE, 528, 990, 0, "GDialog", "doit", -1, 4, { WORKAROUND_FAKE, 0 } }, // Happens in Cascade Quest when closing the glossary - bug #3038757 { GID_FREDDYPHARKAS, -1, 24, 0, "gcWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu { GID_FREDDYPHARKAS, -1, 31, 0, "quitWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu - { GID_GK1, -1, 64950, 1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // sometimes when walk-clicking + { GID_GK1, -1, 64950, -1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // sometimes when walk-clicking { GID_GK2, -1, 11, 0, "", "export 10", -1, 3, { WORKAROUND_FAKE, 0 } }, // called when the game starts { GID_GK2, -1, 11, 0, "", "export 10", -1, 4, { WORKAROUND_FAKE, 0 } }, // called during the game { GID_HOYLE1, 4, 104, 0, "GinRummyCardList", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // Gin Rummy / right when the game starts @@ -69,6 +84,8 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_HOYLE3, -1, 0, 1, "Character", "say", -1, 504, { WORKAROUND_FAKE, 0 } }, // when starting checkers or dominoes, first time a character says something { GID_HOYLE3, -1, 0, 1, "Character", "say", -1, 505, { WORKAROUND_FAKE, 0 } }, // when starting checkers or dominoes, first time a character says something { GID_HOYLE3, -1, 700, 0, "gcWindow", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu + { GID_HOYLE4, -1, 0, 0, "gcWindow", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when selecting "Control" from the menu (temp vars 0-3) - bug #3039294 + { GID_HOYLE4, 910, 910, 0, "IconBarList", "setup", -1, 3, { WORKAROUND_FAKE, 0 } }, // when selecting "Tutorial" from the main menu - bug #3039294 { GID_ISLANDBRAIN, 140, 140, 0, "piece", "init", -1, 3, { WORKAROUND_FAKE, 1 } }, // first puzzle right at the start, some initialization variable. bnt is done on it, and it should be non-0 { GID_ISLANDBRAIN, 200, 268, 0, "anElement", "select", -1, 0, { WORKAROUND_FAKE, 0 } }, // elements puzzle, gets used before super TextIcon { GID_JONES, 1, 232, 0, "weekendText", "draw", 0x3d3, 0, { WORKAROUND_FAKE, 0 } }, // jones/cd only - gets called during the game @@ -84,17 +101,19 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_KQ6, 520, 520, 0, "rm520", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to boiling water trap on beast isle { GID_KQ6, -1, 903, 0, "controlWin", "open", -1, 4, { WORKAROUND_FAKE, 0 } }, // when opening the controls window (save, load etc) { GID_KQ7, 30, 64996, 0, "User", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key - { GID_LAURABOW, 44, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // second dialog box after the intro, when talking with Lillian - bug #3034985 + { GID_LAURABOW, 37, 0, 0, "CB1", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // when going up the stairs (bug #3037694) + { GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up (initial bug #3034985) { GID_LAURABOW2, -1, 24, 0, "gcWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu - { GID_LAURABOW2, -1, 21, 0, "dropCluesCode", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // when asking some questions (e.g. the reporter about the burglary, or the policeman about Ziggy) - bugs #3035068, #3036274 + { GID_LAURABOW2, -1, 21, 0, "dropCluesCode", "doit", -1, 1, { WORKAROUND_FAKE, 0x7fff } }, // when asking some questions (e.g. the reporter about the burglary, or the policeman about Ziggy). Must be big, as the game scripts perform lt on it and start deleting journal entries - bugs #3035068, #3036274 { GID_LAURABOW2, 240, 240, 0, "sSteveAnimates", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // Steve Dorian's idle animation at the docks - bug #3036291 - { GID_LONGBOW, -1, 213, 0, "clear", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When giving an aswer using the druid hand sign code in any room + { GID_LONGBOW, -1, 213, 0, "clear", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When giving an answer using the druid hand sign code in any room { GID_LONGBOW, -1, 213, 0, "letter", "handleEvent", 0xa8, 1, { WORKAROUND_FAKE, 0 } }, // When using the druid hand sign code in any room - bug #3036601 { GID_LSL1, 250, 250, 0, "increase", "handleEvent", -1, 2, { WORKAROUND_FAKE, 0 } }, // casino, playing game, increasing bet { GID_LSL1, 720, 720, 0, "rm720", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // age check room { GID_LSL2, 38, 38, 0, "cloudScript", "changeState", -1, 1, { WORKAROUND_FAKE, 0 } }, // entering the room in the middle deck of the ship - bug #3036483 { GID_LSL3, 340, 340, 0, "ComicScript", "changeState", -1, -1, { WORKAROUND_FAKE, 0 } }, // right after entering the 3 ethnic groups inside comedy club (temps 200, 201, 202, 203) { GID_LSL3, -1, 997, 0, "TheMenuBar", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0xf } }, // when setting volume the first time, this temp is used to set volume on entry (normally it would have been initialized to 's') + { GID_LSL6, 820, 82, 0, "", "export 0", -1, -1, { WORKAROUND_FAKE, 0 } }, // when touching the electric fence - bug #3038326 { GID_LSL6, -1, 85, 0, "washcloth", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // washcloth in inventory { GID_LSL6, -1, 928, -1, "Narrator", "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // used by various objects that are even translated in foreign versions, that's why we use the base-class { GID_LSL6HIRES, 0, 85, 0, "LL6Inv", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // on startup @@ -103,16 +122,22 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_MOTHERGOOSE, 18, 992, 0, "AIPath", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // DEMO: Called when walking north from mother goose's house two screens { GID_MOTHERGOOSEHIRES,-1,64950, 1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // right when clicking on a child at the start and probably also later { GID_MOTHERGOOSEHIRES,-1,64950, 1, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // see above + { GID_QFG1, -1, 210, 0, "Encounter", "init", 0xbd0, 0, { WORKAROUND_FAKE, 0 } }, // hq1: going to the brigands hideout + { GID_QFG1, -1, 210, 0, "Encounter", "init", 0xbe4, 0, { WORKAROUND_FAKE, 0 } }, // qfg1: going to the brigands hideout { GID_QFG2, -1, 71, 0, "theInvSheet", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // accessing the inventory - { GID_QFG2, -1, 701, 0, "Alley", "at", -1, 0, { WORKAROUND_FAKE, 0 } }, // when walking inside the alleys in the town - bug #3035835 - { GID_QFG3, 330, 330, 0, "rajahTeller", "doChild", -1, 0, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Tarna" - { GID_QFG3, 330, 330, 0, "rajahTeller", "doChild", -1, 1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" - bug #3036390 - { GID_SQ1, 103, 103, 0, "hand", "internalEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // spanish (and maybe early versions?) only: when moving cursor over input pad - { GID_SQ1, 103, 103, 0, "hand", "internalEvent", -1, 2, { WORKAROUND_FAKE, 0 } }, // spanish (and maybe early versions?) only: when moving cursor over input pad + { GID_QFG2, -1, 701, -1, "Alley", "at", -1, 0, { WORKAROUND_FAKE, 0 } }, // when walking inside the alleys in the town - bug #3035835 & #3038367 + { GID_QFG2, -1, 990, 0, "Restore", "doit", -1, 364, { WORKAROUND_FAKE, 0 } }, // when pressing enter in restore dialog w/o any saved games present + { GID_QFG2, 260, 260, 0, "abdulS", "changeState",0x2d22, -1, { WORKAROUND_FAKE, 0 } }, // During the thief's first mission (in the house), just before the second brother is about to enter the house (where you have to hide in the wardrobe), bug #3039891, temps 1 and 2 + { GID_QFG3, 330, 330, -1, "Teller", "doChild", -1, -1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" (bug #3036390, temp 1) or "Tarna" (temp 0), or when clicking on yourself and saying "Greet" (bug #3039774, temp 1) + { GID_QFG4, -1, 15, -1, "charInitScreen", "dispatchEvent", -1, 5, { WORKAROUND_FAKE, 0 } }, // floppy version, when viewing the character screen + { GID_QFG4, -1, 64917, -1, "controlPlane", "setBitmap", -1, 3, { WORKAROUND_FAKE, 0 } }, // floppy version, when entering the game menu + { GID_QFG4, -1, 64917, -1, "Plane", "setBitmap", -1, 3, { WORKAROUND_FAKE, 0 } }, // floppy version, happen sometimes in fights + { GID_SQ1, 103, 103, 0, "hand", "internalEvent", -1, -1, { WORKAROUND_FAKE, 0 } }, // Spanish (and maybe early versions?) only: when moving cursor over input pad, temps 1 and 2 { GID_SQ1, -1, 703, 0, "", "export 1", -1, 0, { WORKAROUND_FAKE, 0 } }, // sub that's called from several objects while on sarien battle cruiser { GID_SQ1, -1, 703, 0, "firePulsar", "changeState", 0x18a, 0, { WORKAROUND_FAKE, 0 } }, // export 1, but called locally (when shooting at aliens) { GID_SQ4, -1, 398, 0, "showBox", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // sq4cd: called when rummaging in Software Excess bargain bin { GID_SQ4, -1, 928, 0, "Narrator", "startText", -1, 1000, { WORKAROUND_FAKE, 1 } }, // sq4cd: method returns this to the caller + { GID_SQ5, 201, 201, 0, "buttonPanel", "doVerb", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking at the orange or red button - bug #3038563 { GID_SQ6, 100, 0, 0, "SQ6", "init", -1, 2, { WORKAROUND_FAKE, 0 } }, // called when the game starts { GID_SQ6, 100, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu { GID_SQ6, -1, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // during the game @@ -129,19 +154,38 @@ const SciWorkaroundEntry kAbs_workarounds[] = { // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kCelHigh_workarounds[] = { - { GID_SQ1, 1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu + { GID_KQ5, -1, 255, 0, "deathIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when getting beaten up in the inn and probably more, called with 2nd parameter as object - bug #3037003 + { GID_PQ2, -1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when showing picture within windows, called with 2nd/3rd parameters as objects + { GID_SQ1, 1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu - bug #3035720 SCI_WORKAROUNDENTRY_TERMINATOR }; // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kCelWide_workarounds[] = { + { GID_KQ5, -1, 255, 0, "deathIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when getting beaten up in the inn and probably more, called with 2nd parameter as object - bug #3037003 + { GID_PQ2, -1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when showing picture within windows, called with 2nd/3rd parameters as objects { GID_SQ1, 1, 255, 0, "DIcon", "setSize", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // DEMO: Called with 2nd/3rd parameters as objects when clicking on the menu - bug #3035720 SCI_WORKAROUNDENTRY_TERMINATOR }; // gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kDeviceInfo_workarounds[] = { + { GID_FANMADE, -1, 994, 1, "Game", "save", 0xd1c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Cascade Quest) + { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe55, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Demo Quest) + { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe57, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (I Want My C64 Back) + { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe5c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Most of them) + { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xd1c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Cascade Quest) + { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe55, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Demo Quest) + { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe57, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (I Want My C64 Back) + { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe5c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Most of them) + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kDisplay_workarounds[] = { { GID_ISLANDBRAIN, 300, 300, 0, "geneDude", "show", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the gene explanation chart - a parameter is an object + { GID_PQ2, 23, 23, 0, "rm23Script", "elements", 0x4ae, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the 2nd page of pate's file - 0x75 as id + { GID_QFG1, 11, 11, 0, "battle", "<noname90>", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: When entering battle, 0x75 as id { GID_SQ4, 391, 391, 0, "doCatalog", "mode", 0x84, 0, { WORKAROUND_IGNORE, 0 } }, // clicking on catalog in roboter sale - a parameter is an object { GID_SQ4, 391, 391, 0, "choosePlug", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // ordering connector in roboter sale - a parameter is an object SCI_WORKAROUNDENTRY_TERMINATOR @@ -160,6 +204,8 @@ const SciWorkaroundEntry kDisposeScript_workarounds[] = { const SciWorkaroundEntry kDoSoundFade_workarounds[] = { { GID_CAMELOT, -1, 989, 0, "rmMusic", "fade", -1, 0, { WORKAROUND_IGNORE, 0 } }, // gets called frequently with a NULL reference (i.e. 0:0) - bug #3035149 { GID_KQ1, -1, 989, 0, "gameSound", "fade", -1, 0, { WORKAROUND_IGNORE, 0 } }, // gets called in several scenes (e.g. graham cracker) with 0:0 + { GID_KQ4, -1, 989, 0, "mySound", "", -1, 0, { WORKAROUND_IGNORE, 0 } }, // gets called in the demo when trying to open the non-existent menu with 0:0 - bug #3036942 + { GID_KQ5, 213, 989, 0, "globalSound3", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when bandits leave the secret temple, parameter 4 is an object - bug #3037594 { GID_KQ6, 105, 989, 0, "globalSound", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // floppy: during intro, parameter 4 is an object { GID_KQ6, 460, 989, 0, "globalSound2", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // after pulling the black widow's web on the isle of wonder, parameter 4 is an object - bug #3034567 SCI_WORKAROUNDENTRY_TERMINATOR @@ -167,6 +213,7 @@ const SciWorkaroundEntry kDoSoundFade_workarounds[] = { // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kGetAngle_workarounds[] = { + { GID_FANMADE, 516, 992, 0, "Motion", "init", -1, 0, { WORKAROUND_IGNORE, 0 } }, // The Legend of the Lost Jewel Demo (fan made): called with third/fourth parameters as objects { GID_KQ6, 740, 752, 0, "throwDazzle", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // after the Genie is exposed in the Palace (short and long ending), it starts shooting lightning bolts around. An extra 5th parameter is passed - bug #3034610 SCI_WORKAROUNDENTRY_TERMINATOR }; @@ -190,6 +237,7 @@ const SciWorkaroundEntry kGraphSaveBox_workarounds[] = { { GID_ISLANDBRAIN, 290, 291, 0, "upElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // when testing in the elevator puzzle, gets called with 1 argument less - 15 is on stack - bug #3034485 { GID_ISLANDBRAIN, 290, 291, 0, "downElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // see above { GID_ISLANDBRAIN, 290, 291, 0, "correctElevator", "changeState",0x201f, 0, { WORKAROUND_STILLCALL, 0 } }, // see above (when testing the correct solution) + { GID_PQ3, 202, 202, 0, "MapEdit", "movePt", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #3038077 SCI_WORKAROUNDENTRY_TERMINATOR }; @@ -228,6 +276,13 @@ const SciWorkaroundEntry kGraphRedrawBox_workarounds[] = { }; // gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kGraphUpdateBox_workarounds[] = { + { GID_PQ3, 202, 202, 0, "MapEdit", "movePt", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #3038077 + { GID_PQ3, 202, 202, 0, "MapEdit", "addPt", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #3038077 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kIsObject_workarounds[] = { { GID_GK1, 50, 999, 0, "List", "eachElementDo", -1, 0, { WORKAROUND_FAKE, 0 } }, // GK1 demo, when asking Grace for messages it gets called with an invalid parameter (type "error") - bug #3034519 { GID_ISLANDBRAIN, -1, 999, 0, "List", "eachElementDo", -1, 0, { WORKAROUND_FAKE, 0 } }, // when going to the game options, choosing "Info" and selecting anything from the list, gets called with an invalid parameter (type "error") - bug #3035262 @@ -243,13 +298,19 @@ const SciWorkaroundEntry kMemory_workarounds[] = { // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kNewWindow_workarounds[] = { - { GID_ECOQUEST, -1, 981, 0, "SysWindow", "<noname 178>", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // EcoQuest 1 demo uses an in-between interpreter from SCI1 to SCI1.1. It's SCI1.1, but uses the SCI1 semantics for this call - bug #3035057 + { GID_ECOQUEST, -1, 981, 0, "SysWindow", "<noname178>", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // EcoQuest 1 demo uses an in-between interpreter from SCI1 to SCI1.1. It's SCI1.1, but uses the SCI1 semantics for this call - bug #3035057 SCI_WORKAROUNDENTRY_TERMINATOR }; // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[] = { - { GID_QFG4, 100, 100, 0, "doMovie", "<noname 144>", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after the Sierra logo, no flags are passed, thus the call is meaningless - bug #3034506 + { GID_QFG4, 100, 100, 0, "doMovie", "<noname144>", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after the Sierra logo, no flags are passed, thus the call is meaningless - bug #3034506 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kSetCursor_workarounds[] = { + { GID_KQ5, -1, 768, 0, "KQCursor", "init", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // CD: gets called with 4 additional "900d" parameters SCI_WORKAROUNDENTRY_TERMINATOR }; @@ -260,6 +321,12 @@ const SciWorkaroundEntry kSetPort_workarounds[] = { }; // gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kStrAt_workarounds[] = { + { GID_ISLANDBRAIN, 300, 310, 0, "childBreed", "changeState",0x1c7c, 0, { WORKAROUND_FAKE, 0 } }, // when clicking Breed to get the second-generation cyborg hybrid (Standard difficulty), the two parameters are swapped - bug #3037835 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kUnLoad_workarounds[] = { { GID_CAMELOT, 921, 921, 1, "Script", "changeState", 0x36, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: While showing Camelot (and other places), the reference is invalid - bug #3035000 { GID_CAMELOT, 921, 921, 1, "Script", "init", 0x36, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: When being attacked by the boar (and other places), the reference is invalid - bug #3035000 @@ -274,6 +341,7 @@ const SciWorkaroundEntry kUnLoad_workarounds[] = { { GID_LSL6, 130, 130, 0, "recruitLarryScr", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident { GID_LSL6, 740, 740, 0, "showCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during ending, 4 additional parameters are passed by accident { GID_LSL6HIRES, 130, 130, 0, "recruitLarryScr", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident + { GID_PQ3, 877, 998, 0, "View", "delete", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when getting run over on the freeway, the reference is invalid { GID_SQ1, 43, 303, 0, "slotGuy", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when leaving ulence flats bar, parameter 1 is not passed - script error SCI_WORKAROUNDENTRY_TERMINATOR }; diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h index d509d300d7..8a3edb6246 100644 --- a/engines/sci/engine/workarounds.h +++ b/engines/sci/engine/workarounds.h @@ -69,12 +69,15 @@ struct SciWorkaroundEntry { }; extern const SciWorkaroundEntry opcodeDivWorkarounds[]; -extern const SciWorkaroundEntry opcodeOrWorkarounds[]; extern const SciWorkaroundEntry opcodeDptoaWorkarounds[]; +extern const SciWorkaroundEntry opcodeGeWorkarounds[]; +extern const SciWorkaroundEntry opcodeMulWorkarounds[]; +extern const SciWorkaroundEntry opcodeOrWorkarounds[]; extern const SciWorkaroundEntry uninitializedReadWorkarounds[]; extern const SciWorkaroundEntry kAbs_workarounds[]; extern const SciWorkaroundEntry kCelHigh_workarounds[]; extern const SciWorkaroundEntry kCelWide_workarounds[]; +extern const SciWorkaroundEntry kDeviceInfo_workarounds[]; extern const SciWorkaroundEntry kDisplay_workarounds[]; extern const SciWorkaroundEntry kDisposeScript_workarounds[]; extern const SciWorkaroundEntry kDoSoundFade_workarounds[]; @@ -83,6 +86,7 @@ extern const SciWorkaroundEntry kGetAngle_workarounds[]; extern const SciWorkaroundEntry kGraphDrawLine_workarounds[]; extern const SciWorkaroundEntry kGraphSaveBox_workarounds[]; extern const SciWorkaroundEntry kGraphRestoreBox_workarounds[]; +extern const SciWorkaroundEntry kGraphUpdateBox_workarounds[]; extern const SciWorkaroundEntry kGraphFillBoxForeground_workarounds[]; extern const SciWorkaroundEntry kGraphFillBoxAny_workarounds[]; extern const SciWorkaroundEntry kGraphRedrawBox_workarounds[]; @@ -90,7 +94,9 @@ extern const SciWorkaroundEntry kIsObject_workarounds[]; extern const SciWorkaroundEntry kMemory_workarounds[]; extern const SciWorkaroundEntry kNewWindow_workarounds[]; extern const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[]; +extern const SciWorkaroundEntry kSetCursor_workarounds[]; extern const SciWorkaroundEntry kSetPort_workarounds[]; +extern const SciWorkaroundEntry kStrAt_workarounds[]; extern const SciWorkaroundEntry kUnLoad_workarounds[]; extern SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin); diff --git a/engines/sci/graphics/animate.cpp b/engines/sci/graphics/animate.cpp index c637ef8374..ab4362cda9 100644 --- a/engines/sci/graphics/animate.cpp +++ b/engines/sci/graphics/animate.cpp @@ -177,6 +177,15 @@ void GfxAnimate::makeSortedList(List *list) { curNode = _s->_segMan->lookupNode(curAddress); } + // Possible TODO: As noted in the comment in sortHelper we actually + // require a stable sorting algorithm here. Since Common::sort is not stable + // at the time of writing this comment, we work around that in our ordering + // comparator. If that changes in the future or we want to use some + // stable sorting algorithm here, we should change that. + // In that case we should test such changes intensively. A good place to test stable sort + // is iceman, cupboard within the submarine. If sort isn't stable, the cupboard will be + // half-open, half-closed. Of course that's just one of many special cases. + // Now sort the list according y and z (descending) Common::sort(_list.begin(), _list.end(), sortHelper); } @@ -190,6 +199,7 @@ void GfxAnimate::fill(byte &old_picNotValid) { for (it = _list.begin(); it != end; ++it) { curObject = it->object; + signal = it->signal; // Get the corresponding view view = _cache->getView(it->viewId); @@ -233,18 +243,30 @@ void GfxAnimate::fill(byte &old_picNotValid) { } } + if (!view->isScaleable()) { + // Laura Bow 2 (especially floppy) depends on this, some views are not supposed to be scaleable + // this "feature" was removed in later versions of SCI1.1 + it->scaleSignal = 0; + it->scaleY = it->scaleX = 128; + } + + bool setNsRect = true; + // Create rect according to coordinates and given cel if (it->scaleSignal & kScaleSignalDoScaling) { view->getCelScaledRect(it->loopNo, it->celNo, it->x, it->y, it->z, it->scaleX, it->scaleY, it->celRect); + // when being scaled, only set nsRect, if object will get drawn + if ((signal & kSignalHidden) && !(signal & kSignalAlwaysUpdate)) + setNsRect = false; } else { view->getCelRect(it->loopNo, it->celNo, it->x, it->y, it->z, it->celRect); } - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsLeft), it->celRect.left); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsTop), it->celRect.top); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsRight), it->celRect.right); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsBottom), it->celRect.bottom); - - signal = it->signal; + if (setNsRect) { + writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsLeft), it->celRect.left); + writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsTop), it->celRect.top); + writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsRight), it->celRect.right); + writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsBottom), it->celRect.bottom); + } // Calculate current priority according to y-coordinate if (!(signal & kSignalFixedPriority)) { @@ -521,13 +543,21 @@ void GfxAnimate::addToPicDrawCels() { } } -void GfxAnimate::addToPicDrawView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) { +void GfxAnimate::addToPicDrawView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 x, int16 y, int16 priority, int16 control) { GfxView *view = _cache->getView(viewId); Common::Rect celRect; + if (priority == -1) + priority = _ports->kernelCoordinateToPriority(y); + // Create rect according to coordinates and given cel - view->getCelRect(loopNo, celNo, leftPos, topPos, priority, celRect); + view->getCelRect(loopNo, celNo, x, y, 0, celRect); _paint16->drawCel(view, loopNo, celNo, celRect, priority, 0); + + if (control != -1) { + celRect.top = CLIP<int16>(_ports->kernelPriorityToCoordinate(priority) - 1, celRect.top, celRect.bottom - 1); + _paint16->fillRect(celRect, GFX_SCREEN_MASK_CONTROL, 0, 0, control); + } } @@ -595,14 +625,49 @@ void GfxAnimate::kernelAnimate(reg_t listReference, bool cycle, int argc, reg_t updateScreen(old_picNotValid); restoreAndDelete(argc, argv); - if (_lastCastData.size() > 1) - _s->_throttleTrigger = true; - // We update the screen here as well, some scenes like EQ1 credits run w/o calling kGetEvent thus we wouldn't update // screen at all g_sci->getEventManager()->updateScreen(); _ports->setPort(oldPort); + + + // Now trigger speed throttler + switch (_lastCastData.size()) { + case 0: + // No entries drawn -> no speed throttler triggering + break; + case 1: { + + // One entry drawn -> check if that entry was a speed benchmark view, if not enable speed throttler + AnimateEntry *onlyCast = &_lastCastData[0]; + if ((onlyCast->viewId == 0) && (onlyCast->loopNo == 13) && (onlyCast->celNo == 0)) { + // this one is used by jones talkie + if ((onlyCast->celRect.height() == 8) && (onlyCast->celRect.width() == 8)) + return; + } + // first loop and first cel used? + if ((onlyCast->loopNo == 0) && (onlyCast->celNo == 0)) { + // and that cel has a known speed benchmark resolution + int16 onlyHeight = onlyCast->celRect.height(); + int16 onlyWidth = onlyCast->celRect.width(); + if (((onlyWidth == 12) && (onlyHeight == 35)) || // regular benchmark view ("fred", "Speedy", "ego") + ((onlyWidth == 29) && (onlyHeight == 45)) || // King's Quest 5 french "fred" + ((onlyWidth == 1) && (onlyHeight == 1))) { // Laura Bow 2 Talkie + // check further that there is only one cel in that view + GfxView *onlyView = _cache->getView(onlyCast->viewId); + if ((onlyView->getLoopCount() == 1) && (onlyView->getCelCount(0))) + return; + } + } + _s->_throttleTrigger = true; + break; + } + default: + // More than 1 entry drawn -> time for speed throttling + _s->_throttleTrigger = true; + break; + } } void GfxAnimate::addToPicSetPicNotValid() { @@ -627,9 +692,9 @@ void GfxAnimate::kernelAddToPicList(reg_t listReference, int argc, reg_t *argv) addToPicSetPicNotValid(); } -void GfxAnimate::kernelAddToPicView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) { +void GfxAnimate::kernelAddToPicView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 x, int16 y, int16 priority, int16 control) { _ports->setPort((Port *)_ports->_picWind); - addToPicDrawView(viewId, loopNo, celNo, leftPos, topPos, priority, control); + addToPicDrawView(viewId, loopNo, celNo, x, y, priority, control); addToPicSetPicNotValid(); } diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 06dce6d111..a433b26ef2 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -68,6 +68,7 @@ void GfxFrameout::kernelAddPlane(reg_t object) { newPlane.object = object; newPlane.pictureId = 0xFFFF; + newPlane.priority = readSelectorValue(_segMan, object, SELECTOR(priority)); newPlane.lastPriority = 0xFFFF; // hidden _planes.push_back(newPlane); @@ -108,10 +109,12 @@ void GfxFrameout::kernelDeletePlane(reg_t object) { planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1; planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1; - planeRect.top = (planeRect.top * _screen->getHeight()) / scriptsRunningHeight; - planeRect.left = (planeRect.left * _screen->getWidth()) / scriptsRunningWidth; - planeRect.bottom = (planeRect.bottom * _screen->getHeight()) / scriptsRunningHeight; - planeRect.right = (planeRect.right * _screen->getWidth()) / scriptsRunningWidth; + Common::Rect screenRect(_screen->getWidth(), _screen->getHeight()); + planeRect.top = (planeRect.top * screenRect.height()) / scriptsRunningHeight; + planeRect.left = (planeRect.left * screenRect.width()) / scriptsRunningWidth; + planeRect.bottom = (planeRect.bottom * screenRect.height()) / scriptsRunningHeight; + planeRect.right = (planeRect.right * screenRect.width()) / scriptsRunningWidth; + planeRect.clip(screenRect); // we need to do this, at least in gk1 on cemetary we get bottom right -> 201, 321 // Blackout removed plane rect _paint32->fillRect(planeRect, 0); return; @@ -125,6 +128,7 @@ void GfxFrameout::addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 newPicture.pictureId = pictureId; newPicture.picture = new GfxPicture(_resMan, _coordAdjuster, 0, _screen, _palette, pictureId, false); newPicture.startX = startX; + newPicture.pictureCels = 0; _planePictures.push_back(newPicture); } @@ -218,10 +222,11 @@ void GfxFrameout::kernelFrameout() { // Update priority here, sq6 sets it w/o UpdatePlane uint16 planePriority = it->priority = readSelectorValue(_segMan, planeObject, SELECTOR(priority)); - planeRect.top = (planeRect.top * _screen->getHeight()) / scriptsRunningHeight; - planeRect.left = (planeRect.left * _screen->getWidth()) / scriptsRunningWidth; - planeRect.bottom = (planeRect.bottom * _screen->getHeight()) / scriptsRunningHeight; - planeRect.right = (planeRect.right * _screen->getWidth()) / scriptsRunningWidth; + Common::Rect screenRect(_screen->getWidth(), _screen->getHeight()); + planeRect.top = (planeRect.top * screenRect.height()) / scriptsRunningHeight; + planeRect.left = (planeRect.left * screenRect.width()) / scriptsRunningWidth; + planeRect.bottom = (planeRect.bottom * screenRect.height()) / scriptsRunningHeight; + planeRect.right = (planeRect.right * screenRect.width()) / scriptsRunningWidth; int16 planeOffsetX = 0; @@ -364,7 +369,7 @@ void GfxFrameout::kernelFrameout() { int16 pictureOffsetX = planeOffsetX; int16 pictureX = itemEntry->x; - if (planeOffsetX) { + if ((planeOffsetX) || (itemEntry->picStartX)) { if (planeOffsetX <= itemEntry->picStartX) { pictureX += itemEntry->picStartX - planeOffsetX; pictureOffsetX = 0; @@ -480,7 +485,15 @@ void GfxFrameout::kernelFrameout() { // This draws text the "SCI0-SCI11" way. In SCI2, text is prerendered in kCreateTextBitmap // TODO: rewrite this the "SCI2" way (i.e. implement the text buffer to draw inside kCreateTextBitmap) if (lookupSelector(_segMan, itemEntry->object, SELECTOR(text), NULL, NULL) == kSelectorVariable) { - Common::String text = _segMan->getString(readSelector(_segMan, itemEntry->object, SELECTOR(text))); + reg_t stringObject = readSelector(_segMan, itemEntry->object, SELECTOR(text)); + + // The object in the text selector of the item can be either a raw string + // or a Str object. In the latter case, we need to access the object's data + // selector to get the raw string. + if (_segMan->isHeapObject(stringObject)) + stringObject = readSelector(_segMan, stringObject, SELECTOR(data)); + + Common::String text = _segMan->getString(stringObject); GfxFont *font = _cache->getFont(readSelectorValue(_segMan, itemEntry->object, SELECTOR(font))); bool dimmed = readSelectorValue(_segMan, itemEntry->object, SELECTOR(dimmed)); uint16 foreColor = readSelectorValue(_segMan, itemEntry->object, SELECTOR(fore)); diff --git a/engines/sci/graphics/paint.cpp b/engines/sci/graphics/paint.cpp index 13dcebc27a..50b0534ba7 100644 --- a/engines/sci/graphics/paint.cpp +++ b/engines/sci/graphics/paint.cpp @@ -49,8 +49,4 @@ void GfxPaint::kernelDrawCel(GuiResourceId viewId, int16 loopNo, int16 celNo, ui void GfxPaint::kernelGraphDrawLine(Common::Point startPoint, Common::Point endPoint, int16 color, int16 priority, int16 control) { } -void GfxPaint::kernelShakeScreen(uint16 shakeCount, uint16 directions) { - warning("Unimplemented kShakeScreen"); -} - } // End of namespace Sci diff --git a/engines/sci/graphics/paint.h b/engines/sci/graphics/paint.h index 75a17461d4..994bc4e5e9 100644 --- a/engines/sci/graphics/paint.h +++ b/engines/sci/graphics/paint.h @@ -38,10 +38,6 @@ public: virtual void kernelDrawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo); virtual void kernelDrawCel(GuiResourceId viewId, int16 loopNo, int16 celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, bool hiresMode, reg_t upscaledHiresHandle); virtual void kernelGraphDrawLine(Common::Point startPoint, Common::Point endPoint, int16 color, int16 priority, int16 control); - - virtual void kernelShakeScreen(uint16 shakeCount, uint16 directions); - -private: }; } // End of namespace Sci diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp index bb3975e9ef..4551e9dafc 100644 --- a/engines/sci/graphics/paint16.cpp +++ b/engines/sci/graphics/paint16.cpp @@ -459,8 +459,8 @@ void GfxPaint16::kernelGraphRedrawBox(Common::Rect rect) { #define SCI_DISPLAY_WIDTH 106 #define SCI_DISPLAY_SAVEUNDER 107 #define SCI_DISPLAY_RESTOREUNDER 108 -#define SCI_DISPLAY_DUMMY1 114 // used in longbow-demo, not supported in sierra sci - no parameters -#define SCI_DISPLAY_DUMMY2 115 // used in longbow-demo, not supported in sierra sci - has 1 parameter +#define SCI_DISPLAY_DUMMY1 114 // used in longbow demo/qfg1 ega demo, not supported in sierra sci - no parameters +#define SCI_DISPLAY_DUMMY2 115 // used in longbow demo, not supported in sierra sci - has 1 parameter #define SCI_DISPLAY_DONTSHOWBITS 121 reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { @@ -531,15 +531,16 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { break; // 2 Dummy functions, longbow-demo is using those several times but sierra sci doesn't support them at all + // The Quest for Glory 1 EGA demo also calls kDisplay(114) case SCI_DISPLAY_DUMMY1: case SCI_DISPLAY_DUMMY2: - if (!((g_sci->getGameId() == GID_LONGBOW) && (g_sci->isDemo()))) - error("Unknown kDisplay argument %X", displayArg.offset); + if (!g_sci->isDemo() || (g_sci->getGameId() != GID_LONGBOW && g_sci->getGameId() != GID_QFG1)) + error("Unknown kDisplay argument %d", displayArg.offset); if (displayArg.offset == SCI_DISPLAY_DUMMY2) { if (argc) { argc--; argv++; } else { - error("No parameter left for kDisplay(0x73)"); + error("No parameter left for kDisplay(115)"); } } break; @@ -596,23 +597,6 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { return result; } -// TODO: If this matches the sci32 implementation, we may put it into GfxScreen -void GfxPaint16::kernelShakeScreen(uint16 shakeCount, uint16 directions) { - while (shakeCount--) { - if (directions & SCI_SHAKE_DIRECTION_VERTICAL) - _screen->setVerticalShakePos(10); - // TODO: horizontal shakes - g_system->updateScreen(); - g_sci->getEngineState()->wait(3); - - if (directions & SCI_SHAKE_DIRECTION_VERTICAL) - _screen->setVerticalShakePos(0); - - g_system->updateScreen(); - g_sci->getEngineState()->wait(3); - } -} - reg_t GfxPaint16::kernelPortraitLoad(const Common::String &resourceName) { //Portrait *myPortrait = new Portrait(g_sci->getResMan(), _screen, _palette, resourceName); return NULL_REG; diff --git a/engines/sci/graphics/paint16.h b/engines/sci/graphics/paint16.h index edffa8da6e..e944c71bdd 100644 --- a/engines/sci/graphics/paint16.h +++ b/engines/sci/graphics/paint16.h @@ -88,8 +88,6 @@ public: reg_t kernelDisplay(const char *text, int argc, reg_t *argv); - void kernelShakeScreen(uint16 shakeCount, uint16 directions); - reg_t kernelPortraitLoad(const Common::String &resourceName); void kernelPortraitShow(const Common::String &resourceName, Common::Point position, uint16 resourceNum, uint16 noun, uint16 verb, uint16 cond, uint16 seq); void kernelPortraitUnload(uint16 portraitId); diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp index 9268888b6c..2e9128cda6 100644 --- a/engines/sci/graphics/ports.cpp +++ b/engines/sci/graphics/ports.cpp @@ -27,7 +27,9 @@ #include "sci/sci.h" #include "sci/engine/features.h" +#include "sci/engine/kernel.h" #include "sci/engine/state.h" +#include "sci/engine/selector.h" #include "sci/graphics/screen.h" #include "sci/graphics/paint16.h" #include "sci/graphics/animate.h" @@ -50,7 +52,10 @@ GfxPorts::GfxPorts(SegManager *segMan, GfxScreen *screen) } GfxPorts::~GfxPorts() { - // TODO: Clear _windowList and delete all stuff in it? + // reset frees all windows but _picWind + reset(); + freeWindow(_picWind); + delete _wmgrPort; delete _menuPort; } @@ -99,8 +104,15 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te offTop = 0; break; case GID_MOTHERGOOSE: - if (getSciVersion() == SCI_VERSION_1_EARLY) + // TODO: if mother goose EGA also uses offTop we can simply remove this check altogether + switch (getSciVersion()) { + case SCI_VERSION_1_EARLY: + case SCI_VERSION_1_1: offTop = 0; + break; + default: + break; + } break; case GID_FAIRYTALES: // Mixed-Up Fairy Tales (& its demo) uses -w 26 0 200 320. If we don't @@ -128,7 +140,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te _wmgrPort->curLeft = 0; _windowList.push_front(_wmgrPort); - _picWind = newWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true); + _picWind = addWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true); // For SCI0 games till kq4 (.502 - not including) we set _picWind top to offTop instead // Because of the menu/status bar if (g_sci->_features->usesOldGfxFunctions()) @@ -137,6 +149,30 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te kernelInitPriorityBands(); } +// Removes any windows from windowList +// is used when restoring/restarting the game +// Sierra SCI actually saved the whole windowList, it seems we don't need to do this at all +// but in some games there are still windows active when restoring. Leaving those windows open +// would create all sorts of issues, that's why we remove them +void GfxPorts::reset() { + PortList::iterator it = _windowList.begin(); + const PortList::iterator end = _windowList.end(); + + setPort(_picWind); + + while (it != end) { + Port *pPort = *it; + if (pPort->id > 2) { + // found a window beyond _picWind + freeWindow((Window *)pPort); + } + it++; + } + _windowList.clear(); + _windowList.push_front(_wmgrPort); + _windowList.push_back(_picWind); +} + void GfxPorts::kernelSetActive(uint16 portId) { switch (portId) { case 0: @@ -145,8 +181,13 @@ void GfxPorts::kernelSetActive(uint16 portId) { case 0xFFFF: setPort(_menuPort); break; - default: - setPort(getPortById(portId)); + default: { + Port *newPort = getPortById(portId); + if (newPort) + setPort(newPort); + else + error("GfxPorts::kernelSetActive was requested to set invalid port id %d", portId); + } }; } @@ -172,9 +213,9 @@ reg_t GfxPorts::kernelNewWindow(Common::Rect dims, Common::Rect restoreRect, uin Window *wnd = NULL; if (restoreRect.bottom != 0 && restoreRect.right != 0) - wnd = newWindow(dims, &restoreRect, title, style, priority, false); + wnd = addWindow(dims, &restoreRect, title, style, priority, false); else - wnd = newWindow(dims, NULL, title, style, priority, false); + wnd = addWindow(dims, NULL, title, style, priority, false); wnd->penClr = colorPen; wnd->backClr = colorBack; drawWindow(wnd); @@ -184,7 +225,36 @@ reg_t GfxPorts::kernelNewWindow(Common::Rect dims, Common::Rect restoreRect, uin void GfxPorts::kernelDisposeWindow(uint16 windowId, bool reanimate) { Window *wnd = (Window *)getPortById(windowId); - disposeWindow(wnd, reanimate); + if (wnd) + removeWindow(wnd, reanimate); + else + error("GfxPorts::kernelDisposeWindow: Request to dispose invalid port id %d", windowId); + + if ((g_sci->getGameId() == GID_HOYLE4) && (!g_sci->isDemo())) { + // WORKAROUND: hoyle 4 has a broken User::handleEvent implementation + // first of all iconbar is always set and always gets called with + // events checking if event got claimed got removed inside that code + // and it will call handleEvent on gameObj afterwards. Iconbar windows + // are handled inside iconbar as well including disposing + // e.g. iconOK::doit, script 14) and claimed isn't even set. gameObj + // handleEvent calling will result in coordinate adjust with a now + // invalid port. + // We fix this by adjusting the port variable to be global + // again when hoyle4 is disposing windows. + // This worked because sierra sci leaves old port data, so the pointer + // was still valid for a short period of time + // TODO: maybe this could get implemented as script patch somehow + // although this could get quite tricky to implement (script 996) + // IconBar::handleEvent (script 937) + // maybe inside export 8 of script 0, which is called by iconOK + // and iconReplay + // or inside GameControls::hide (script 978) which is called to + // actually remove the window + reg_t eventObject = _segMan->findObjectByName("uEvt"); + if (!eventObject.isNull()) { + writeSelectorValue(_segMan, eventObject, SELECTOR(port), 0); + } + } } int16 GfxPorts::isFrontWindow(Window *pWnd) { @@ -221,7 +291,7 @@ void GfxPorts::endUpdate(Window *wnd) { setPort(oldPort); } -Window *GfxPorts::newWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw) { +Window *GfxPorts::addWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw) { // Find an unused window/port id uint id = 1; while (id < _windowsById.size() && _windowsById[id]) { @@ -371,7 +441,7 @@ void GfxPorts::drawWindow(Window *pWnd) { setPort(oldport); } -void GfxPorts::disposeWindow(Window *pWnd, bool reanimate) { +void GfxPorts::removeWindow(Window *pWnd, bool reanimate) { setPort(_wmgrPort); _paint16->bitsRestore(pWnd->hSaved1); _paint16->bitsRestore(pWnd->hSaved2); @@ -381,6 +451,15 @@ void GfxPorts::disposeWindow(Window *pWnd, bool reanimate) { _paint16->kernelGraphRedrawBox(pWnd->restoreRect); _windowList.remove(pWnd); setPort(_windowList.back()); + _windowsById[pWnd->id] = NULL; + delete pWnd; +} + +void GfxPorts::freeWindow(Window *pWnd) { + if (!pWnd->hSaved1.isNull()) + _segMan->freeHunkEntry(pWnd->hSaved1); + if (!pWnd->hSaved2.isNull()) + _segMan->freeHunkEntry(pWnd->hSaved1); _windowsById[pWnd->id] = 0; delete pWnd; } @@ -401,13 +480,9 @@ void GfxPorts::updateWindow(Window *wnd) { } Port *GfxPorts::getPortById(uint16 id) { - if (id > _windowsById.size()) - error("getPortById() received invalid id"); - return _windowsById[id]; + return (id < _windowsById.size()) ? _windowsById[id] : NULL; } - - Port *GfxPorts::setPort(Port *newPort) { Port *oldPort = _curPort; _curPort = newPort; diff --git a/engines/sci/graphics/ports.h b/engines/sci/graphics/ports.h index d10bc6772f..f7f0721eb7 100644 --- a/engines/sci/graphics/ports.h +++ b/engines/sci/graphics/ports.h @@ -46,6 +46,7 @@ public: ~GfxPorts(); void init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *text16); + void reset(); void kernelSetActive(uint16 portId); Common::Rect kernelGetPicWindow(int16 &picTop, int16 &picLeft); @@ -57,9 +58,10 @@ public: int16 isFrontWindow(Window *wnd); void beginUpdate(Window *wnd); void endUpdate(Window *wnd); - Window *newWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw); + Window *addWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw); void drawWindow(Window *wnd); - void disposeWindow(Window *pWnd, bool reanimate); + void removeWindow(Window *pWnd, bool reanimate); + void freeWindow(Window *pWnd); void updateWindow(Window *wnd); Port *getPortById(uint16 id); diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp index 131a3d2eb8..839b9975c5 100644 --- a/engines/sci/graphics/screen.cpp +++ b/engines/sci/graphics/screen.cpp @@ -534,6 +534,22 @@ void GfxScreen::setVerticalShakePos(uint16 shakePos) { g_system->setShakePos(shakePos * 2); } +void GfxScreen::kernelShakeScreen(uint16 shakeCount, uint16 directions) { + while (shakeCount--) { + if (directions & SCI_SHAKE_DIRECTION_VERTICAL) + setVerticalShakePos(10); + // TODO: horizontal shakes + g_system->updateScreen(); + g_sci->getEngineState()->wait(3); + + if (directions & SCI_SHAKE_DIRECTION_VERTICAL) + setVerticalShakePos(0); + + g_system->updateScreen(); + g_sci->getEngineState()->wait(3); + } +} + void GfxScreen::dither(bool addToFlag) { int y, x; byte color, ditheredColor; diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h index f1e3d028a8..97f5736289 100644 --- a/engines/sci/graphics/screen.h +++ b/engines/sci/graphics/screen.h @@ -109,8 +109,6 @@ public: void getPalette(Palette *pal); void setPalette(Palette *pal); - void setVerticalShakePos(uint16 shakePos); - void scale2x(const byte *src, byte *dst, int16 srcWidth, int16 srcHeight); void adjustToUpscaledCoordinates(int16 &y, int16 &x); @@ -126,6 +124,7 @@ public: int _picNotValidSci11; // another variable that is used by kPicNotValid in sci1.1 int16 kernelPicNotValid(int16 newPicNotValid); + void kernelShakeScreen(uint16 shakeCount, uint16 direction); private: uint16 _width; @@ -143,6 +142,8 @@ private: void bitsSaveScreen(Common::Rect rect, byte *screen, uint16 screenWidth, byte *&memoryPtr); void bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr); + void setVerticalShakePos(uint16 shakePos); + bool _unditherState; int16 _unditherMemorial[SCI_SCREEN_UNDITHERMEMORIAL_SIZE]; diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp index 08be203230..fc07febe14 100644 --- a/engines/sci/graphics/text16.cpp +++ b/engines/sci/graphics/text16.cpp @@ -142,8 +142,8 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF uint16 curChar = 0; int16 maxChars = 0, curCharCount = 0; uint16 width = 0; - GuiResourceId oldFontId = GetFontId(); - int16 oldPenColor = _ports->_curPort->penClr; + GuiResourceId previousFontId = GetFontId(); + int16 previousPenColor = _ports->_curPort->penClr; GetFont(); if (!_font) @@ -159,7 +159,7 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF case 0x7C: if (getSciVersion() >= SCI_VERSION_1_1) { curCharCount++; - curCharCount += CodeProcessing(text, orgFontId, oldPenColor); + curCharCount += CodeProcessing(text, orgFontId, previousPenColor); continue; } break; @@ -180,8 +180,8 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF curCharCount++; // and it's also meant to pass through here case 0: - SetFont(oldFontId); - _ports->penColor(oldPenColor); + SetFont(previousFontId); + _ports->penColor(previousPenColor); return curCharCount; case ' ': @@ -226,15 +226,15 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF } } } - SetFont(oldFontId); - _ports->penColor(oldPenColor); + SetFont(previousFontId); + _ports->penColor(previousPenColor); return maxChars; } -void GfxText16::Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) { +void GfxText16::Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont) { uint16 curChar; - GuiResourceId oldFontId = GetFontId(); - int16 oldPenColor = _ports->_curPort->penClr; + GuiResourceId previousFontId = GetFontId(); + int16 previousPenColor = _ports->_curPort->penClr; textWidth = 0; textHeight = 0; @@ -264,13 +264,18 @@ void GfxText16::Width(const char *text, int16 from, int16 len, GuiResourceId org } } } - SetFont(oldFontId); - _ports->penColor(oldPenColor); + // When calculating size, we do not restore font because we need the current (code modified) font active + // If we are drawing this is called inbetween, so font needs to get restored + // If we are calculating size of just one fixed string (::StringWidth), then we need to restore + if (restoreFont) { + SetFont(previousFontId); + _ports->penColor(previousPenColor); + } return; } void GfxText16::StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) { - Width(str, 0, (int16)strlen(str), orgFontId, textWidth, textHeight); + Width(str, 0, (int16)strlen(str), orgFontId, textWidth, textHeight, true); } void GfxText16::ShowString(const char *str, GuiResourceId orgFontId, int16 orgPenColor) { @@ -281,8 +286,8 @@ void GfxText16::DrawString(const char *str, GuiResourceId orgFontId, int16 orgPe } int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth) { - GuiResourceId oldFontId = GetFontId(); - int16 oldPenColor = _ports->_curPort->penClr; + GuiResourceId previousFontId = GetFontId(); + int16 previousPenColor = _ports->_curPort->penClr; int16 charCount; int16 maxTextWidth = 0, textWidth; int16 totalHeight = 0, textHeight; @@ -290,7 +295,7 @@ int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId if (fontId != -1) SetFont(fontId); else - fontId = oldFontId; + fontId = previousFontId; if (g_sci->getLanguage() == Common::JA_JPN) SwitchToFont900OnSjis(text); @@ -307,10 +312,10 @@ int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId rect.right = (maxWidth ? maxWidth : 192); const char *curPos = text; while (*curPos) { - charCount = GetLongest(curPos, rect.right, oldFontId); + charCount = GetLongest(curPos, rect.right, fontId); if (charCount == 0) break; - Width(curPos, 0, charCount, fontId, textWidth, textHeight); + Width(curPos, 0, charCount, fontId, textWidth, textHeight, false); maxTextWidth = MAX(textWidth, maxTextWidth); totalHeight += textHeight; curPos += charCount; @@ -320,8 +325,8 @@ int16 GfxText16::Size(Common::Rect &rect, const char *text, GuiResourceId fontId rect.bottom = totalHeight; rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth); } - SetFont(oldFontId); - _ports->penColor(oldPenColor); + SetFont(previousFontId); + _ports->penColor(previousPenColor); return rect.right; } @@ -386,14 +391,14 @@ void GfxText16::Box(const char *text, int16 bshow, const Common::Rect &rect, Tex int16 textWidth, maxTextWidth, textHeight, charCount; int16 offset = 0; int16 hline = 0; - GuiResourceId orgFontId = GetFontId(); - int16 orgPenColor = _ports->_curPort->penClr; + GuiResourceId previousFontId = GetFontId(); + int16 previousPenColor = _ports->_curPort->penClr; bool doubleByteMode = false; if (fontId != -1) SetFont(fontId); else - fontId = orgFontId; + fontId = previousFontId; if (g_sci->getLanguage() == Common::JA_JPN) { if (SwitchToFont900OnSjis(text)) @@ -402,10 +407,10 @@ void GfxText16::Box(const char *text, int16 bshow, const Common::Rect &rect, Tex maxTextWidth = 0; while (*text) { - charCount = GetLongest(text, rect.width(), orgFontId); + charCount = GetLongest(text, rect.width(), fontId); if (charCount == 0) break; - Width(text, 0, charCount, orgFontId, textWidth, textHeight); + Width(text, 0, charCount, fontId, textWidth, textHeight, true); maxTextWidth = MAX<int16>(maxTextWidth, textWidth); switch (alignment) { case SCI_TEXT16_ALIGNMENT_RIGHT: @@ -424,9 +429,9 @@ void GfxText16::Box(const char *text, int16 bshow, const Common::Rect &rect, Tex _ports->moveTo(rect.left + offset, rect.top + hline); if (bshow) { - Show(text, 0, charCount, fontId, orgPenColor); + Show(text, 0, charCount, fontId, previousPenColor); } else { - Draw(text, 0, charCount, fontId, orgPenColor); + Draw(text, 0, charCount, fontId, previousPenColor); } hline += textHeight; @@ -434,8 +439,8 @@ void GfxText16::Box(const char *text, int16 bshow, const Common::Rect &rect, Tex if (*text == ' ') text++; // skip over breaking space } - SetFont(orgFontId); - _ports->penColor(orgPenColor); + SetFont(previousFontId); + _ports->penColor(previousPenColor); if (doubleByteMode) { // Kanji is written by pc98 rom to screen directly. Because of @@ -458,12 +463,12 @@ void GfxText16::Box(const char *text, int16 bshow, const Common::Rect &rect, Tex } void GfxText16::Draw_String(const char *text) { - GuiResourceId orgFontId = GetFontId(); - int16 orgPenColor = _ports->_curPort->penClr; + GuiResourceId previousFontId = GetFontId(); + int16 previousPenColor = _ports->_curPort->penClr; - Draw(text, 0, strlen(text), orgFontId, orgPenColor); - SetFont(orgFontId); - _ports->penColor(orgPenColor); + Draw(text, 0, strlen(text), previousFontId, previousPenColor); + SetFont(previousFontId); + _ports->penColor(previousPenColor); } // Sierra did this in their PC98 interpreter only, they identify a text as being diff --git a/engines/sci/graphics/text16.h b/engines/sci/graphics/text16.h index 71b602d116..9b8b6d9f19 100644 --- a/engines/sci/graphics/text16.h +++ b/engines/sci/graphics/text16.h @@ -53,7 +53,7 @@ public: void ClearChar(int16 chr); int16 GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId); - void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight); + void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont); void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight); void ShowString(const char *str, GuiResourceId orgFontId, int16 orgPenColor); void DrawString(const char *str, GuiResourceId orgFontId, int16 orgPenColor); diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp index d32e60335f..1c865f6bcf 100644 --- a/engines/sci/graphics/view.cpp +++ b/engines/sci/graphics/view.cpp @@ -84,6 +84,10 @@ void GfxView::initData(GuiResourceId resourceId) { _embeddedPal = false; _EGAmapping = NULL; _isSci2Hires = false; + _isScaleable = true; + + // we adjust inside getCelRect for SCI0EARLY (that version didn't have the +1 when calculating bottom) + _adjustForSci0Early = getSciVersion() == SCI_VERSION_0_EARLY ? -1 : 0; // If we find an SCI1/SCI1.1 view (not amiga), we switch to that type for // EGA. This could get used to make view patches for EGA games, where the @@ -189,15 +193,30 @@ void GfxView::initData(GuiResourceId resourceId) { break; case kViewVga11: // View-format SCI1.1+ - // HeaderSize:WORD LoopCount:BYTE Unknown:BYTE Version:WORD Unknown:WORD PaletteOffset:WORD + // HeaderSize:WORD LoopCount:BYTE Flags:BYTE Version:WORD Unknown:WORD PaletteOffset:WORD headerSize = READ_SCI11ENDIAN_UINT16(_resourceData + 0) + 2; // headerSize is not part of the header, so it's added assert(headerSize >= 16); _loopCount = _resourceData[2]; assert(_loopCount); _isSci2Hires = _resourceData[5] == 1 ? true : false; palOffset = READ_SCI11ENDIAN_UINT32(_resourceData + 8); - // FIXME: After LoopCount there is another byte and its set for view 50 - // within Laura Bow 2 CD, check what it means. + // flags is actually a bit-mask + // it seems it was only used for some early sci1.1 games (or even just laura bow 2) + // later interpreters dont support it at all anymore + // we assume that if flags is 0h the view does not support flags and default to scaleable + // if it's 1h then we assume that the view is not to be scaled + // if it's 40h then we assume that the view is scaleable + switch (_resourceData[3]) { + case 1: + _isScaleable = false; + break; + case 0x40: + case 0: + break; // don't do anything, we already have _isScaleable set + default: + error("unsupported flags byte inside sci1.1 view"); + break; + } loopData = _resourceData + headerSize; loopSize = _resourceData[12]; @@ -318,11 +337,15 @@ bool GfxView::isSci2Hires() { return _isSci2Hires; } +bool GfxView::isScaleable() { + return _isScaleable; +} + void GfxView::getCelRect(int16 loopNo, int16 celNo, int16 x, int16 y, int16 z, Common::Rect &outRect) const { const CelInfo *celInfo = getCelInfo(loopNo, celNo); outRect.left = x + celInfo->displaceX - (celInfo->width >> 1); outRect.right = outRect.left + celInfo->width; - outRect.bottom = y + celInfo->displaceY - z + 1; + outRect.bottom = y + celInfo->displaceY - z + 1 + _adjustForSci0Early; outRect.top = outRect.bottom - celInfo->height; } @@ -637,7 +660,7 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect, uint16 scalingX[640]; uint16 scalingY[480]; int16 scaledWidth, scaledHeight; - int16 pixelNo, scaledPixel, scaledPixelNo, prevScaledPixelNo; + int pixelNo, scaledPixel, scaledPixelNo, prevScaledPixelNo; if (_embeddedPal) { // Merge view palette in... @@ -650,8 +673,8 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect, scaledHeight = CLIP<int16>(scaledHeight, 0, _screen->getHeight()); // Do we really need to do this?! - memset(scalingX, 0, sizeof(scalingX)); - memset(scalingY, 0, sizeof(scalingY)); + //memset(scalingX, 0, sizeof(scalingX)); + //memset(scalingY, 0, sizeof(scalingY)); // Create height scaling table pixelNo = 0; @@ -659,16 +682,15 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect, while (pixelNo < celHeight) { scaledPixelNo = scaledPixel >> 7; assert(scaledPixelNo < ARRAYSIZE(scalingY)); - if (prevScaledPixelNo < scaledPixelNo) - memset(&scalingY[prevScaledPixelNo], pixelNo, scaledPixelNo - prevScaledPixelNo); - scalingY[scaledPixelNo] = pixelNo; - prevScaledPixelNo = scaledPixelNo + 1; + for (; prevScaledPixelNo <= scaledPixelNo; prevScaledPixelNo++) + scalingY[prevScaledPixelNo] = pixelNo; pixelNo++; scaledPixel += scaleY; } + pixelNo--; scaledPixelNo++; - if (scaledPixelNo < scaledHeight) - memset(&scalingY[scaledPixelNo], pixelNo - 1, scaledHeight - scaledPixelNo); + for (; scaledPixelNo < scaledHeight; scaledPixelNo++) + scalingY[scaledPixelNo] = pixelNo; // Create width scaling table pixelNo = 0; @@ -676,16 +698,15 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect, while (pixelNo < celWidth) { scaledPixelNo = scaledPixel >> 7; assert(scaledPixelNo < ARRAYSIZE(scalingX)); - if (prevScaledPixelNo < scaledPixelNo) - memset(&scalingX[prevScaledPixelNo], pixelNo, scaledPixelNo - prevScaledPixelNo); - scalingX[scaledPixelNo] = pixelNo; - prevScaledPixelNo = scaledPixelNo + 1; + for (; prevScaledPixelNo <= scaledPixelNo; prevScaledPixelNo++) + scalingX[prevScaledPixelNo] = pixelNo; pixelNo++; scaledPixel += scaleX; } + pixelNo--; scaledPixelNo++; - if (scaledPixelNo < scaledWidth) - memset(&scalingX[scaledPixelNo], pixelNo - 1, scaledWidth - scaledPixelNo); + for (; scaledPixelNo < scaledWidth; scaledPixelNo++) + scalingX[scaledPixelNo] = pixelNo; scaledWidth = MIN(clipRect.width(), scaledWidth); scaledHeight = MIN(clipRect.height(), scaledHeight); diff --git a/engines/sci/graphics/view.h b/engines/sci/graphics/view.h index 25e110ad13..990a7e2f71 100644 --- a/engines/sci/graphics/view.h +++ b/engines/sci/graphics/view.h @@ -74,6 +74,7 @@ public: uint16 getCelCount(int16 loopNo) const; Palette *getPalette(); + bool isScaleable(); bool isSci2Hires(); private: @@ -100,6 +101,13 @@ private: bool _isSci2Hires; byte *_EGAmapping; + + // this is set for sci0early to adjust for the getCelRect() change + int16 _adjustForSci0Early; + + // this is not set for some views in laura bow 2 floppy and signals that the view shall never get scaled + // even if scaleX/Y are set (inside kAnimate) + bool _isScaleable; }; } // End of namespace Sci diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 111bf6ad9b..4bf26ff0bf 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -182,7 +182,7 @@ ResourceType ResourceManager::convertResType(byte type) { } //-- Resource main functions -- -Resource::Resource(ResourceId id) : _id(id) { +Resource::Resource(ResourceManager *resMan, ResourceId id) : _resMan(resMan), _id(id) { data = NULL; size = 0; _fileOffset = 0; @@ -665,6 +665,7 @@ int ResourceManager::addInternalSources() { ++itr; } + delete resources; return 1; } @@ -704,6 +705,86 @@ void IntMapResourceSource::scanSource(ResourceManager *resMan) { resMan->readAudioMapSCI11(this); } +#ifdef ENABLE_SCI32 + +// Chunk resources are resources that hold other resources. They are normally called +// when using the kLoadChunk SCI2.1 kernel function. However, for example, the Lighthouse +// SCI2.1 demo has a chunk but no scripts outside of the chunk. + +// A chunk resource is pretty straightforward in terms of layout +// It begins with 11-byte entries in the header: +// ========= +// b resType +// w nEntry +// dw offset +// dw length + +ChunkResourceSource::ChunkResourceSource(const Common::String &name, uint16 number) + : ResourceSource(kSourceChunk, name) { + + _number = 0; +} + +void ChunkResourceSource::scanSource(ResourceManager *resMan) { + Resource *chunk = resMan->findResource(ResourceId(kResourceTypeChunk, _number), false); + + if (!chunk) + error("Trying to load non-existent chunk"); + + byte *ptr = chunk->data; + uint32 firstOffset = 0; + + for (;;) { + ResourceType type = resMan->convertResType(*ptr); + uint16 number = READ_LE_UINT16(ptr + 1); + ResourceId id(type, number); + + ResourceEntry entry; + entry.offset = READ_LE_UINT32(ptr + 3); + entry.length = READ_LE_UINT32(ptr + 7); + + _resMap[id] = entry; + ptr += 11; + + debugC(kDebugLevelResMan, 2, "Found %s in chunk %d", id.toString().c_str(), _number); + + resMan->updateResource(id, this, entry.length); + + // There's no end marker to the data table, but the first resource + // begins directly after the entry table. So, when we hit the first + // resource, we're at the end of the entry table. + + if (!firstOffset) + firstOffset = entry.offset; + + if ((size_t)(ptr - chunk->data) >= firstOffset) + break; + } +} + +void ChunkResourceSource::loadResource(ResourceManager *resMan, Resource *res) { + Resource *chunk = resMan->findResource(ResourceId(kResourceTypeChunk, _number), false); + + if (!_resMap.contains(res->_id)) + error("Trying to load non-existent resource from chunk %d: %s %d", _number, getResourceTypeName(res->_id.getType()), res->_id.getNumber()); + + ResourceEntry entry = _resMap[res->_id]; + res->data = new byte[entry.length]; + res->size = entry.length; + res->_header = 0; + res->_headerSize = 0; + res->_status = kResStatusAllocated; + + // Copy the resource data over + memcpy(res->data, chunk->data + entry.offset, entry.length); +} + +void ResourceManager::addResourcesFromChunk(uint16 id) { + addSource(new ChunkResourceSource(Common::String::printf("Chunk %d", id), id)); + scanNewSources(); +} + +#endif void ResourceManager::freeResourceSources() { for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) @@ -769,6 +850,21 @@ void ResourceManager::init() { default: error("resMan: Couldn't determine view type"); } + +#ifdef ENABLE_SCI32 + if (getSciVersion() >= SCI_VERSION_2_1) { + // If we have no scripts, but chunk 0 is present, open up the chunk + // to try to get to any scripts in there. The Lighthouse SCI2.1 demo + // does exactly this. + + Common::List<ResourceId> *scriptList = listResources(kResourceTypeScript); + + if (scriptList->empty() && testResource(ResourceId(kResourceTypeChunk, 0))) + addResourcesFromChunk(0); + + delete scriptList; + } +#endif } ResourceManager::~ResourceManager() { @@ -1543,7 +1639,7 @@ void MacResourceForkResourceSource::scanSource(ResourceManager *resMan) { void ResourceManager::addResource(ResourceId resId, ResourceSource *src, uint32 offset, uint32 size) { // Adding new resource only if it does not exist if (_resMap.contains(resId) == false) { - Resource *res = new Resource(resId); + Resource *res = new Resource(this, resId); _resMap.setVal(resId, res); res->_source = src; res->_fileOffset = offset; @@ -1558,7 +1654,7 @@ Resource *ResourceManager::updateResource(ResourceId resId, ResourceSource *src, if (_resMap.contains(resId)) { res = _resMap.getVal(resId); } else { - res = new Resource(resId); + res = new Resource(this, resId); _resMap.setVal(resId, res); } @@ -1584,21 +1680,21 @@ int Resource::readResourceInfo(ResVersion volVersion, Common::SeekableReadStream case kResVersionSci0Sci1Early: case kResVersionSci1Middle: w = file->readUint16LE(); - type = (ResourceType)(w >> 11); + type = _resMan->convertResType(w >> 11); number = w & 0x7FF; szPacked = file->readUint16LE() - 4; szUnpacked = file->readUint16LE(); wCompression = file->readUint16LE(); break; case kResVersionSci1Late: - type = (ResourceType)(file->readByte() & 0x7F); + type = _resMan->convertResType(file->readByte()); number = file->readUint16LE(); szPacked = file->readUint16LE() - 4; szUnpacked = file->readUint16LE(); wCompression = file->readUint16LE(); break; case kResVersionSci11: - type = (ResourceType)(file->readByte() & 0x7F); + type = _resMan->convertResType(file->readByte()); number = file->readUint16LE(); szPacked = file->readUint16LE(); szUnpacked = file->readUint16LE(); @@ -1615,7 +1711,7 @@ int Resource::readResourceInfo(ResVersion volVersion, Common::SeekableReadStream break; #ifdef ENABLE_SCI32 case kResVersionSci32: - type = (ResourceType)(file->readByte() & 0x7F); + type = _resMan->convertResType(file->readByte()); number = file->readUint16LE(); szPacked = file->readUint32LE(); szUnpacked = file->readUint32LE(); @@ -1907,18 +2003,18 @@ void ResourceManager::detectSciVersion() { return; } + if (hasSci0Voc999()) { + s_sciVersion = SCI_VERSION_0_LATE; + return; + } + if (oldDecompressors) { // It's either SCI_VERSION_0_LATE or SCI_VERSION_01 // We first check for SCI1 vocab.999 if (testResource(ResourceId(kResourceTypeVocab, 999))) { - if (hasSci0Voc999()) { - s_sciVersion = SCI_VERSION_0_LATE; - return; - } else { - s_sciVersion = SCI_VERSION_01; - return; - } + s_sciVersion = SCI_VERSION_01; + return; } // If vocab.999 is missing, we try vocab.900 @@ -1938,15 +2034,10 @@ void ResourceManager::detectSciVersion() { return; } - // New decompressors. It's either SCI_VERSION_0_LATE, SCI_VERSION_1_EGA or SCI_VERSION_1_EARLY. - if (testResource(ResourceId(kResourceTypeVocab, 900))) { - if (hasSci1Voc900()) { - s_sciVersion = SCI_VERSION_1_EGA; - return; - } else { - s_sciVersion = SCI_VERSION_0_LATE; - return; - } + // New decompressors. It's either SCI_VERSION_1_EGA or SCI_VERSION_1_EARLY. + if (hasSci1Voc900()) { + s_sciVersion = SCI_VERSION_1_EGA; + return; } // SCI_VERSION_1_EARLY EGA versions lack the parser vocab diff --git a/engines/sci/resource.h b/engines/sci/resource.h index f1ea2f15f9..48210b835f 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -193,6 +193,9 @@ class Resource { friend class WaveResourceSource; friend class AudioVolumeResourceSource; friend class MacResourceForkResourceSource; +#ifdef ENABLE_SCI32 + friend class ChunkResourceSource; +#endif // NOTE : Currently most member variables lack the underscore prefix and have // public visibility to let the rest of the engine compile without changes. @@ -203,7 +206,7 @@ public: uint32 _headerSize; public: - Resource(ResourceId id); + Resource(ResourceManager *resMan, ResourceId id); ~Resource(); void unalloc(); @@ -227,6 +230,7 @@ protected: ResourceStatus _status; uint16 _lockers; /**< Number of places where this resource was locked */ ResourceSource *_source; + ResourceManager *_resMan; bool loadPatch(Common::SeekableReadStream *file); bool loadFromPatchFile(); @@ -251,6 +255,9 @@ class ResourceManager { friend class ExtAudioMapResourceSource; friend class WaveResourceSource; friend class MacResourceForkResourceSource; +#ifdef ENABLE_SCI32 + friend class ChunkResourceSource; +#endif public: /** @@ -324,6 +331,14 @@ public: */ void addNewGMPatch(SciGameId gameId); +#ifdef ENABLE_SCI32 + /** + * Parses all resources from a SCI2.1 chunk resource and adds them to the + * resource manager. + */ + void addResourcesFromChunk(uint16 id); +#endif + bool detectHires(); // Detects, if standard font of current game includes extended characters (>0x80) bool detectFontExtended(); diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp index 08e05f5ccd..a25505fe47 100644 --- a/engines/sci/resource_audio.cpp +++ b/engines/sci/resource_audio.cpp @@ -93,13 +93,13 @@ bool Resource::loadFromAudioVolumeSCI11(Common::SeekableReadStream *file) { uint32 riffTag = file->readUint32BE(); if (riffTag == MKID_BE('RIFF')) { _headerSize = 0; - size = file->readUint32LE(); + size = file->readUint32LE() + 8; file->seek(-8, SEEK_CUR); return loadFromWaveFile(file); } file->seek(-4, SEEK_CUR); - ResourceType type = (ResourceType)(file->readByte() & 0x7f); + ResourceType type = _resMan->convertResType(file->readByte()); if (((getType() == kResourceTypeAudio || getType() == kResourceTypeAudio36) && (type != kResourceTypeAudio)) || ((getType() == kResourceTypeSync || getType() == kResourceTypeSync36) && (type != kResourceTypeSync))) { warning("Resource type mismatch loading %s", _id.toString().c_str()); @@ -235,6 +235,20 @@ void ResourceManager::removeAudioResource(ResourceId resId) { // w nEntry // tb offset (cumulative) +// QFG3 Demo 0.MAP structure: +// ========= +// 10-byte entries: +// w nEntry +// dw offset +// dw size + +// LB2 Floppy/Mother Goose SCI1.1 0.MAP structure: +// ========= +// 8-byte entries: +// w nEntry +// w 0xffff +// dw offset + // Early SCI1.1 MAP structure: // =============== // 10-byte entries: @@ -318,6 +332,31 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) { addResource(ResourceId(kResourceTypeAudio, n), src, offset, size); } + } else if (map->_volumeNumber == 0 && entrySize == 8 && READ_LE_UINT16(ptr + 2) == 0xffff) { + // LB2 Floppy/Mother Goose SCI1.1 format + Common::SeekableReadStream *stream = getVolumeFile(src); + + while (ptr < mapRes->data + mapRes->size) { + uint16 n = READ_LE_UINT16(ptr); + ptr += 4; + + if (n == 0xffff) + break; + + offset = READ_LE_UINT32(ptr); + ptr += 4; + + // The size is not stored in the map and the entries have no order. + // We need to dig into the audio resource in the volume to get the size. + stream->seek(offset + 1); + byte headerSize = stream->readByte(); + assert(headerSize == 11 || headerSize == 12); + + stream->skip(5); + uint32 size = stream->readUint32LE() + headerSize + 2; + + addResource(ResourceId(kResourceTypeAudio, n), src, offset, size); + } } else { bool isEarly = (entrySize != 11); diff --git a/engines/sci/resource_intern.h b/engines/sci/resource_intern.h index 73986444a4..14f872b46e 100644 --- a/engines/sci/resource_intern.h +++ b/engines/sci/resource_intern.h @@ -43,7 +43,8 @@ enum ResSourceType { kSourceAudioVolume, kSourceExtAudioMap, kSourceWave, - kSourceMacResourceFork + kSourceMacResourceFork, + kSourceChunk }; @@ -188,6 +189,31 @@ public: virtual void loadResource(ResourceManager *resMan, Resource *res); }; +#ifdef ENABLE_SCI32 + +/** + * Reads resources from SCI2.1+ chunk resources + */ +class ChunkResourceSource : public ResourceSource { +public: + ChunkResourceSource(const Common::String &name, uint16 number); + + virtual void scanSource(ResourceManager *resMan); + virtual void loadResource(ResourceManager *resMan, Resource *res); + +protected: + uint16 _number; + + struct ResourceEntry { + uint32 offset; + uint32 length; + }; + + Common::HashMap<ResourceId, ResourceEntry, ResourceIdHash> _resMap; +}; + +#endif + } // End of namespace Sci #endif // SCI_RESOURCE_INTERN_H diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index f07cc257bd..d0c578bd45 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -26,6 +26,8 @@ #include "common/system.h" #include "common/config-manager.h" #include "common/debug-channels.h" +#include "common/EventRecorder.h" +#include "common/file.h" // for Common::File::exists() #include "engines/advancedDetector.h" #include "engines/util.h" @@ -117,12 +119,15 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam SearchMan.addSubDirectoryMatching(gameDataDir, "actors"); // KQ6 hi-res portraits SearchMan.addSubDirectoryMatching(gameDataDir, "aud"); // resource.aud and audio files + SearchMan.addSubDirectoryMatching(gameDataDir, "audio");// resource.aud and audio files + SearchMan.addSubDirectoryMatching(gameDataDir, "audiosfx");// resource.aud and audio files SearchMan.addSubDirectoryMatching(gameDataDir, "wav"); // speech files in WAV format SearchMan.addSubDirectoryMatching(gameDataDir, "sfx"); // music/sound files in WAV format SearchMan.addSubDirectoryMatching(gameDataDir, "avi"); // AVI movie files for Windows versions SearchMan.addSubDirectoryMatching(gameDataDir, "seq"); // SEQ movie files for DOS versions SearchMan.addSubDirectoryMatching(gameDataDir, "robot"); // robot movie files SearchMan.addSubDirectoryMatching(gameDataDir, "robots"); // robot movie files + SearchMan.addSubDirectoryMatching(gameDataDir, "movie"); // vmd movie files SearchMan.addSubDirectoryMatching(gameDataDir, "movies"); // vmd movie files SearchMan.addSubDirectoryMatching(gameDataDir, "vmd"); // vmd movie files @@ -169,6 +174,8 @@ SciEngine::~SciEngine() { } Common::Error SciEngine::run() { + g_eventRec.registerRandomSource(_rng, "sci"); + // Assign default values to the config manager, in case settings are missing ConfMan.registerDefault("undither", "true"); ConfMan.registerDefault("enable_fb01", "false"); @@ -232,12 +239,34 @@ Common::Error SciEngine::run() { debug("Emulating SCI version %s\n", getSciVersionDesc(getSciVersion())); + if (_gameDescription->flags & ADGF_ADDENGLISH) { + // if game is multilingual + Common::Language selectedLanguage = Common::parseLanguage(ConfMan.get("language")); + if (selectedLanguage == Common::EN_ANY) { + // and english was selected as language + if (SELECTOR(printLang) != -1) // set text language to english + writeSelectorValue(segMan, _gameObj, SELECTOR(printLang), 1); + if (SELECTOR(parseLang) != -1) // and set parser language to english as well + writeSelectorValue(segMan, _gameObj, SELECTOR(parseLang), 1); + } + } + // Check whether loading a savestate was requested int saveSlot = ConfMan.getInt("save_slot"); if (saveSlot >= 0) { reg_t restoreArgv[2] = { NULL_REG, make_reg(0, saveSlot) }; // special call (argv[0] is NULL) kRestoreGame(_gamestate, 2, restoreArgv); + // TODO: The best way to do the following would be to invoke Game::init + // here and stop when the room is about to be changed, otherwise some + // game initialization won't take place + + // Set audio language for KQ5CD (bug #3039477) + if (g_sci->getGameId() == GID_KQ5 && Common::File::exists("AUDIO001.002")) { + reg_t doAudioArgv[2] = { make_reg(0, 9), make_reg(0, 1) }; + kDoAudio(_gamestate, 2, doAudioArgv); + } + // Initialize the game menu, if there is one. // This is not done when loading, so we must do it manually. reg_t menuBarObj = _gamestate->_segMan->findObjectByName("MenuBar"); @@ -287,7 +316,7 @@ bool SciEngine::initGame() { _gamestate->_executionStackPosChanged = false; _gamestate->abortScriptProcessing = kAbortNone; - _gamestate->gameWasRestarted = false; + _gamestate->gameIsRestarting = GAMEISRESTARTING_NONE; _gamestate->stack_base = stack->_entries; _gamestate->stack_top = stack->_entries + stack->_capacity; @@ -304,8 +333,6 @@ bool SciEngine::initGame() { _gamestate->gameStartTime = _gamestate->lastWaitTime = _gamestate->_screenUpdateTime = g_system->getMillis(); - srand(g_system->getMillis()); // Initialize random number generator - // Load game language into printLang property of game object setSciLanguage(); @@ -415,7 +442,7 @@ void SciEngine::runGame() { _gamestate->_segMan->resetSegMan(); initGame(); initStackBaseWithSelector(SELECTOR(play)); - _gamestate->gameWasRestarted = true; + _gamestate->gameIsRestarting = GAMEISRESTARTING_RESTART; if (_gfxMenu) _gfxMenu->reset(); _gamestate->abortScriptProcessing = kAbortNone; diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 13c9d03614..72d6e7e0cb 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -28,6 +28,7 @@ #include "engines/engine.h" #include "common/util.h" +#include "common/random.h" #include "sci/engine/vm_types.h" // for Selector #include "sci/debug.h" // for DebugState @@ -233,6 +234,8 @@ public: inline EventManager *getEventManager() const { return _eventMan; } inline reg_t getGameObject() const { return _gameObj; } + Common::RandomSource &getRNG() { return _rng; } + Common::String getSavegameName(int nr) const; Common::String getSavegamePattern() const; @@ -340,6 +343,7 @@ private: EventManager *_eventMan; reg_t _gameObj; /**< Pointer to the game object */ Console *_console; + Common::RandomSource _rng; }; diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp index e58fa5120b..6ec28a8b02 100644 --- a/engines/sci/sound/midiparser_sci.cpp +++ b/engines/sci/sound/midiparser_sci.cpp @@ -425,7 +425,8 @@ void MidiParser_SCI::sendToDriver(uint32 midi) { // Channel remapping int16 realChannel = _channelRemap[midiChannel]; - assert(realChannel != -1); + if (realChannel == -1) + return; midi = (midi & 0xFFFFFFF0) | realChannel; if (_mainThreadCalled) diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index c3315bd2b5..061f380ebc 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -293,7 +293,10 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) { return channelNr; } } - error("no free channels"); + // nothing found, don't map channel at all + // sierra did this as well, although i'm not sure if we act exactly the same way + // maybe they removed channels from previous playing music + return -1; } void SciMusic::freeChannels(MusicEntry *caller) { diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index bd88a5fca8..567a1605f3 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -147,6 +147,12 @@ void SoundCommandParser::processPlaySound(reg_t obj) { _music->soundPlay(musicSlot); } +reg_t SoundCommandParser::kDoSoundRestore(int argc, reg_t *argv, reg_t acc) { + // Called after loading, to restore the playlist + // We don't really use or need this + return acc; +} + reg_t SoundCommandParser::kDoSoundDummy(int argc, reg_t *argv, reg_t acc) { warning("cmdDummy invoked"); // not supposed to occur return acc; @@ -246,7 +252,8 @@ reg_t SoundCommandParser::kDoSoundPause(int argc, reg_t *argv, reg_t acc) { } else { // pause a playlist slot MusicEntry *musicSlot = _music->getSlot(obj); if (!musicSlot) { - warning("kDoSound(pause): Slot not found (%04x:%04x)", PRINT_REG(obj)); + // This happens quite frequently + debugC(2, kDebugLevelSound, "kDoSound(pause): Slot not found (%04x:%04x)", PRINT_REG(obj)); return acc; } @@ -263,12 +270,13 @@ reg_t SoundCommandParser::kDoSoundResumeAfterRestore(int argc, reg_t *argv, reg_ } reg_t SoundCommandParser::kDoSoundMute(int argc, reg_t *argv, reg_t acc) { + uint16 previousState = _music->soundGetSoundOn(); if (argc > 0) { debugC(2, kDebugLevelSound, "kDoSound(mute): %d", argv[0].toUint16()); _music->soundSetSoundOn(argv[0].toUint16()); } - return make_reg(0, _music->soundGetSoundOn()); + return make_reg(0, previousState); } reg_t SoundCommandParser::kDoSoundMasterVolume(int argc, reg_t *argv, reg_t acc) { @@ -316,7 +324,11 @@ reg_t SoundCommandParser::kDoSoundFade(int argc, reg_t *argv, reg_t acc) { case 4: // SCI01+ case 5: // SCI1+ (SCI1 late sound scheme), with fade and continue musicSlot->fadeTo = CLIP<uint16>(argv[1].toUint16(), 0, MUSIC_VOLUME_MAX); - musicSlot->fadeStep = volume > argv[1].toUint16() ? -argv[3].toUint16() : argv[3].toUint16(); + // sometimes we get objects in that position, fix it up (ffs. workarounds) + if (!argv[1].segment) + musicSlot->fadeStep = volume > musicSlot->fadeTo ? -argv[3].toUint16() : argv[3].toUint16(); + else + musicSlot->fadeStep = volume > musicSlot->fadeTo ? -5 : 5; musicSlot->fadeTickerStep = argv[2].toUint16() * 16667 / _music->soundGetTempo(); musicSlot->fadeTicker = 0; musicSlot->stopAfterFading = (argc == 5) ? (argv[4].toUint16() != 0) : false; @@ -557,7 +569,7 @@ reg_t SoundCommandParser::kDoSoundSetPriority(int argc, reg_t *argv, reg_t acc) MusicEntry *musicSlot = _music->getSlot(obj); if (!musicSlot) { - warning("kDoSound(setPriority): Slot not found (%04x:%04x)", PRINT_REG(obj)); + debugC(2, kDebugLevelSound, "kDoSound(setPriority): Slot not found (%04x:%04x)", PRINT_REG(obj)); return acc; } diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h index 10915e8ea9..8e6fb81762 100644 --- a/engines/sci/sound/soundcmd.h +++ b/engines/sci/sound/soundcmd.h @@ -82,7 +82,7 @@ public: reg_t kDoSoundInit(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundPlay(int argc, reg_t *argv, reg_t acc); - reg_t kDoSoundDummy(int argc, reg_t *argv, reg_t acc); + reg_t kDoSoundRestore(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundMute(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundPause(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundResumeAfterRestore(int argc, reg_t *argv, reg_t acc); @@ -97,6 +97,7 @@ public: reg_t kDoSoundSendMidi(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundReverb(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundSetHold(int argc, reg_t *argv, reg_t acc); + reg_t kDoSoundDummy(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundGetAudioCapability(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundSetVolume(int argc, reg_t *argv, reg_t acc); reg_t kDoSoundSetPriority(int argc, reg_t *argv, reg_t acc); diff --git a/engines/sci/video/seq_decoder.cpp b/engines/sci/video/seq_decoder.cpp index 2c117ae329..58fd60621d 100644 --- a/engines/sci/video/seq_decoder.cpp +++ b/engines/sci/video/seq_decoder.cpp @@ -55,10 +55,10 @@ SeqDecoder::~SeqDecoder() { close(); } -bool SeqDecoder::load(Common::SeekableReadStream &stream) { +bool SeqDecoder::load(Common::SeekableReadStream *stream) { close(); - _fileStream = &stream; + _fileStream = stream; _surface = new Graphics::Surface(); _surface->create(SEQ_SCREEN_WIDTH, SEQ_SCREEN_HEIGHT, 1); @@ -76,6 +76,7 @@ bool SeqDecoder::load(Common::SeekableReadStream &stream) { uint16 palColorCount = READ_LE_UINT16(paletteData + 29); int palOffset = 37; + memset(_palette, 0, 256 * 3); for (uint16 colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) { if (palFormat == kSeqPalVariable) diff --git a/engines/sci/video/seq_decoder.h b/engines/sci/video/seq_decoder.h index 416abb78fa..1714477083 100644 --- a/engines/sci/video/seq_decoder.h +++ b/engines/sci/video/seq_decoder.h @@ -38,7 +38,7 @@ public: SeqDecoder(); virtual ~SeqDecoder(); - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void close(); void setFrameDelay(int frameDelay) { _frameDelay = frameDelay; } diff --git a/engines/sci/video/vmd_decoder.cpp b/engines/sci/video/vmd_decoder.cpp index 93132bc5d6..680a449207 100644 --- a/engines/sci/video/vmd_decoder.cpp +++ b/engines/sci/video/vmd_decoder.cpp @@ -50,13 +50,13 @@ VMDDecoder::~VMDDecoder() { close(); } -bool VMDDecoder::load(Common::SeekableReadStream &stream) { +bool VMDDecoder::load(Common::SeekableReadStream *stream) { close(); if (!_vmdDecoder->load(stream)) return false; - _fileStream = &stream; + _fileStream = stream; if (_vmdDecoder->getFeatures() & Graphics::CoktelVideo::kFeaturesPalette) loadPaletteFromVMD(); diff --git a/engines/sci/video/vmd_decoder.h b/engines/sci/video/vmd_decoder.h index 231da9202e..e79064b1f7 100644 --- a/engines/sci/video/vmd_decoder.h +++ b/engines/sci/video/vmd_decoder.h @@ -56,7 +56,7 @@ public: uint32 getFrameWaitTime(); - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void close(); bool isVideoLoaded() const { return _fileStream != 0; } diff --git a/engines/scumm/player_nes.cpp b/engines/scumm/player_nes.cpp index 4618de3175..96396e7a08 100644 --- a/engines/scumm/player_nes.cpp +++ b/engines/scumm/player_nes.cpp @@ -23,6 +23,7 @@ * */ +#ifndef DISABLE_NES_APU #include "engines/engine.h" #include "scumm/player_nes.h" @@ -1065,3 +1066,5 @@ byte Player_NES::APU_readStatus() { } } // End of namespace Scumm + +#endif // DISABLE_NES_APU diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 1d064cdf6a..81762d87a8 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -363,7 +363,7 @@ bool ScummEngine::loadState(int slot, bool compat) { } } - Graphics::skipThumbnailHeader(*in); + Graphics::skipThumbnail(*in); } // Since version 56 we save additional information about the creation of @@ -720,7 +720,7 @@ bool ScummEngine::loadInfosFromSlot(const char *target, int slot, InfoStuff *stu return false; } - if (!Graphics::skipThumbnailHeader(*in)) { + if (!Graphics::skipThumbnail(*in)) { delete in; return false; } diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 7e2db22c5b..ab7be02c48 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1723,7 +1723,9 @@ void ScummEngine::setupMusic(int midi) { _musicEngine = new Player_SID(this, _mixer); #endif } else if (_game.platform == Common::kPlatformNES && _game.version == 1) { +#ifndef DISABLE_NES_APU _musicEngine = new Player_NES(this, _mixer); +#endif } else if (_game.platform == Common::kPlatformAmiga && _game.version == 2) { _musicEngine = new Player_V2A(this, _mixer); } else if (_game.platform == Common::kPlatformAmiga && _game.version == 3) { diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp index d6a04513a8..8d9ca85829 100644 --- a/engines/sword1/control.cpp +++ b/engines/sword1/control.cpp @@ -1175,8 +1175,7 @@ bool Control::restoreGameFromFile(uint8 slot) { if (saveVersion < 2) // These older version of the savegames used a flag to signal presence of thumbnail inf->skip(1); - if (Graphics::checkThumbnailHeader(*inf)) - Graphics::skipThumbnailHeader(*inf); + Graphics::skipThumbnail(*inf); inf->readUint32BE(); // save date inf->readUint16BE(); // save time diff --git a/graphics/font.cpp b/graphics/font.cpp index 629f2f4b82..74247d4da1 100644 --- a/graphics/font.cpp +++ b/graphics/font.cpp @@ -609,8 +609,8 @@ bool NewFont::cacheFontData(const NewFont &font, const Common::String &filename) cacheFile.writeUint16BE(font.desc.height); cacheFile.writeUint16BE(font.desc.fbbw); cacheFile.writeUint16BE(font.desc.fbbh); - cacheFile.writeUint16BE(font.desc.fbbx); - cacheFile.writeUint16BE(font.desc.fbby); + cacheFile.writeSint16BE(font.desc.fbbx); + cacheFile.writeSint16BE(font.desc.fbby); cacheFile.writeUint16BE(font.desc.ascent); cacheFile.writeUint16BE(font.desc.firstchar); cacheFile.writeUint16BE(font.desc.size); @@ -667,8 +667,8 @@ NewFont *NewFont::loadFromCache(Common::SeekableReadStream &stream) { data->height = stream.readUint16BE(); data->fbbw = stream.readUint16BE(); data->fbbh = stream.readUint16BE(); - data->fbbx = stream.readUint16BE(); - data->fbby = stream.readUint16BE(); + data->fbbx = stream.readSint16BE(); + data->fbby = stream.readSint16BE(); data->ascent = stream.readUint16BE(); data->firstchar = stream.readUint16BE(); data->size = stream.readUint16BE(); diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp index 4c8ce289cf..ccde78806d 100644 --- a/graphics/thumbnail.cpp +++ b/graphics/thumbnail.cpp @@ -82,7 +82,7 @@ bool checkThumbnailHeader(Common::SeekableReadStream &in) { return hasHeader; } -bool skipThumbnailHeader(Common::SeekableReadStream &in) { +bool skipThumbnail(Common::SeekableReadStream &in) { uint32 position = in.pos(); ThumbnailHeader header; diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h index b3fdb70b95..9341582aa1 100644 --- a/graphics/thumbnail.h +++ b/graphics/thumbnail.h @@ -39,14 +39,14 @@ namespace Graphics { bool checkThumbnailHeader(Common::SeekableReadStream &in); /** - * Skips a thumbnail header, if present. + * Skips a thumbnail, if present. * * @param in stream to process */ -bool skipThumbnailHeader(Common::SeekableReadStream &in); +bool skipThumbnail(Common::SeekableReadStream &in); /** - * Lodas a thumbnail from the given input stream. + * Loads a thumbnail from the given input stream. * The loaded thumbnail will be automatically converted to the * current overlay pixelformat. */ diff --git a/graphics/video/avi_decoder.cpp b/graphics/video/avi_decoder.cpp index 4c3c770c60..06589d99b0 100644 --- a/graphics/video/avi_decoder.cpp +++ b/graphics/video/avi_decoder.cpp @@ -211,10 +211,10 @@ void AviDecoder::handleStreamHeader() { } } -bool AviDecoder::load(Common::SeekableReadStream &stream) { +bool AviDecoder::load(Common::SeekableReadStream *stream) { close(); - _fileStream = &stream; + _fileStream = stream; _decodedHeader = false; // Read chunks until we have decoded the header diff --git a/graphics/video/avi_decoder.h b/graphics/video/avi_decoder.h index 5f09992647..72cf2d7ef5 100644 --- a/graphics/video/avi_decoder.h +++ b/graphics/video/avi_decoder.h @@ -178,7 +178,7 @@ public: Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); virtual ~AviDecoder(); - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void close(); bool isVideoLoaded() const { return _fileStream != 0; } diff --git a/graphics/video/coktelvideo/coktelvideo.cpp b/graphics/video/coktelvideo/coktelvideo.cpp index 4d93815b44..9ee9fd68d0 100644 --- a/graphics/video/coktelvideo/coktelvideo.cpp +++ b/graphics/video/coktelvideo/coktelvideo.cpp @@ -127,14 +127,14 @@ Common::MemoryReadStream *PreImd::getExtraData(const char *fileName) { return 0; } -bool PreImd::load(Common::SeekableReadStream &stream) { +bool PreImd::load(Common::SeekableReadStream *stream) { // Since PreIMDs don't have any width and height values stored, // we need them to be specified in the constructor assert((_forcedWidth > 0) && (_forcedHeight > 0)); unload(); - _stream = &stream; + _stream = stream; _stream->seek(0); @@ -564,10 +564,10 @@ bool Imd::loadFrameTables(uint32 framesPosPos, uint32 framesCoordsPos) { return true; } -bool Imd::load(Common::SeekableReadStream &stream) { +bool Imd::load(Common::SeekableReadStream *stream) { unload(); - _stream = &stream; + _stream = stream; uint16 handle; @@ -1656,10 +1656,10 @@ void Vmd::readExtraData() { } } -bool Vmd::load(Common::SeekableReadStream &stream) { +bool Vmd::load(Common::SeekableReadStream *stream) { unload(); - _stream = &stream; + _stream = stream; uint16 headerLength; uint16 handle; diff --git a/graphics/video/coktelvideo/coktelvideo.h b/graphics/video/coktelvideo/coktelvideo.h index 8fbd861e82..f8b1965f41 100644 --- a/graphics/video/coktelvideo/coktelvideo.h +++ b/graphics/video/coktelvideo/coktelvideo.h @@ -23,12 +23,8 @@ * */ -// Currently, only GOB and SCI32 games play IMDs and VMDs, so skip compiling if GOB and SCI32 is disabled. -#if !(defined(ENABLE_GOB) || defined(ENABLE_SCI32) || defined(DYNAMIC_MODULES)) - -// Do not compile the CoktelVideo code - -#else +// Currently, only GOB and SCI32 games play IMDs and VMDs +#if defined(ENABLE_GOB) || defined(ENABLE_SCI32) || defined(DYNAMIC_MODULES) #ifndef GRAPHICS_VIDEO_COKTELVIDEO_H #define GRAPHICS_VIDEO_COKTELVIDEO_H @@ -153,7 +149,7 @@ public: virtual Common::MemoryReadStream *getExtraData(const char *fileName) = 0; /** Load a video out of a stream. */ - virtual bool load(Common::SeekableReadStream &stream) = 0; + virtual bool load(Common::SeekableReadStream *stream) = 0; /** Unload the currently loaded video. */ virtual void unload() = 0; @@ -243,7 +239,7 @@ public: bool hasExtraData(const char *fileName) const; Common::MemoryReadStream *getExtraData(const char *fileName); - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void unload(); void setXY(int16 x, int16 y); @@ -322,7 +318,7 @@ public: uint32 getSyncLag() const; - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void unload(); void setXY(int16 x, int16 y); @@ -451,7 +447,7 @@ public: bool hasExtraData(const char *fileName) const; Common::MemoryReadStream *getExtraData(const char *fileName); - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void unload(); int16 getWidth() const; diff --git a/graphics/video/dxa_decoder.cpp b/graphics/video/dxa_decoder.cpp index 3f26012f5e..5066e8cf37 100644 --- a/graphics/video/dxa_decoder.cpp +++ b/graphics/video/dxa_decoder.cpp @@ -66,10 +66,10 @@ DXADecoder::~DXADecoder() { close(); } -bool DXADecoder::load(Common::SeekableReadStream &stream) { +bool DXADecoder::load(Common::SeekableReadStream *stream) { close(); - _fileStream = &stream; + _fileStream = stream; uint32 tag = _fileStream->readUint32BE(); assert(tag == MKID_BE('DEXA')); diff --git a/graphics/video/dxa_decoder.h b/graphics/video/dxa_decoder.h index d61346324f..eb4426dbbc 100644 --- a/graphics/video/dxa_decoder.h +++ b/graphics/video/dxa_decoder.h @@ -43,7 +43,7 @@ public: DXADecoder(); virtual ~DXADecoder(); - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void close(); bool isVideoLoaded() const { return _fileStream != 0; } diff --git a/graphics/video/flic_decoder.cpp b/graphics/video/flic_decoder.cpp index b07e369cd8..843d3ee093 100644 --- a/graphics/video/flic_decoder.cpp +++ b/graphics/video/flic_decoder.cpp @@ -41,10 +41,10 @@ FlicDecoder::~FlicDecoder() { close(); } -bool FlicDecoder::load(Common::SeekableReadStream &stream) { +bool FlicDecoder::load(Common::SeekableReadStream *stream) { close(); - _fileStream = &stream; + _fileStream = stream; /* uint32 frameSize = */ _fileStream->readUint32LE(); uint16 frameType = _fileStream->readUint16LE(); @@ -71,9 +71,8 @@ bool FlicDecoder::load(Common::SeekableReadStream &stream) { _fileStream->readUint16LE(); // flags // Note: The normal delay is a 32-bit integer (dword), whereas the overriden delay is a 16-bit integer (word) - // frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here - uint32 frameDelay = 100 * _fileStream->readUint32LE(); - _frameRate = 100 * 1000 / frameDelay; + // the frame delay is the FLIC "speed", in milliseconds. + _frameRate = Common::Rational(1000, _fileStream->readUint32LE()); _fileStream->seek(80); _offsetFrame1 = _fileStream->readUint32LE(); @@ -209,10 +208,10 @@ Surface *FlicDecoder::decodeNextFrame() { chunkCount = _fileStream->readUint16LE(); // Note: The overriden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword) - // frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here + // the frame delay is the FLIC "speed", in milliseconds. uint16 newFrameDelay = _fileStream->readUint16LE(); // "speed", in milliseconds if (newFrameDelay > 0) - _frameRate = 1000 / newFrameDelay; + _frameRate = Common::Rational(1000, newFrameDelay); _fileStream->readUint16LE(); // reserved, always 0 uint16 newWidth = _fileStream->readUint16LE(); @@ -268,15 +267,15 @@ Surface *FlicDecoder::decodeNextFrame() { _curFrame++; - if (_curFrame == 0) - _startTime = g_system->getMillis(); - // If we just processed the ring frame, set the next frame if (_curFrame == (int32)_frameCount) { _curFrame = 0; _fileStream->seek(_offsetFrame2); } + if (_curFrame == 0) + _startTime = g_system->getMillis(); + return _surface; } diff --git a/graphics/video/flic_decoder.h b/graphics/video/flic_decoder.h index 60d68889a2..bba1403c22 100644 --- a/graphics/video/flic_decoder.h +++ b/graphics/video/flic_decoder.h @@ -51,7 +51,7 @@ public: * Load a video file * @param stream the stream to load */ - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void close(); /** @@ -72,7 +72,7 @@ public: void copyDirtyRectsToBuffer(uint8 *dst, uint pitch); byte *getPalette() { _paletteChanged = false; return _palette; } - bool hasDirtyPalette() { return _paletteChanged; } + bool hasDirtyPalette() const { return _paletteChanged; } void reset(); protected: @@ -91,7 +91,7 @@ private: Common::SeekableReadStream *_fileStream; Surface *_surface; uint32 _frameCount; - uint32 _frameRate; + Common::Rational _frameRate; Common::List<Common::Rect> _dirtyRects; }; diff --git a/graphics/video/qt_decoder.cpp b/graphics/video/qt_decoder.cpp index 61b0f5166d..470441dab8 100644 --- a/graphics/video/qt_decoder.cpp +++ b/graphics/video/qt_decoder.cpp @@ -308,8 +308,8 @@ bool QuickTimeDecoder::loadFile(const Common::String &filename) { return true; } -bool QuickTimeDecoder::load(Common::SeekableReadStream &stream) { - _fd = &stream; +bool QuickTimeDecoder::load(Common::SeekableReadStream *stream) { + _fd = stream; _foundMOOV = _foundMDAT = false; _numStreams = 0; _partial = 0; diff --git a/graphics/video/qt_decoder.h b/graphics/video/qt_decoder.h index db4ff8180b..196d4c02cb 100644 --- a/graphics/video/qt_decoder.h +++ b/graphics/video/qt_decoder.h @@ -89,7 +89,7 @@ public: * Load a QuickTime video file from a SeekableReadStream * @param stream the stream to load */ - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); /** * Close a QuickTime encoded video file diff --git a/graphics/video/smk_decoder.cpp b/graphics/video/smk_decoder.cpp index 0b7de774eb..4d03305cce 100644 --- a/graphics/video/smk_decoder.cpp +++ b/graphics/video/smk_decoder.cpp @@ -367,10 +367,10 @@ uint32 SmackerDecoder::getElapsedTime() const { return VideoDecoder::getElapsedTime(); } -bool SmackerDecoder::load(Common::SeekableReadStream &stream) { +bool SmackerDecoder::load(Common::SeekableReadStream *stream) { close(); - _fileStream = &stream; + _fileStream = stream; // Seek to the first frame _header.signature = _fileStream->readUint32BE(); diff --git a/graphics/video/smk_decoder.h b/graphics/video/smk_decoder.h index 6bf671f318..43bb84a4f8 100644 --- a/graphics/video/smk_decoder.h +++ b/graphics/video/smk_decoder.h @@ -57,7 +57,7 @@ public: Audio::Mixer::SoundType soundType = Audio::Mixer::kSFXSoundType); virtual ~SmackerDecoder(); - bool load(Common::SeekableReadStream &stream); + bool load(Common::SeekableReadStream *stream); void close(); bool isVideoLoaded() const { return _fileStream != 0; } diff --git a/graphics/video/video_decoder.cpp b/graphics/video/video_decoder.cpp index 9733afc5cc..081f47bf78 100644 --- a/graphics/video/video_decoder.cpp +++ b/graphics/video/video_decoder.cpp @@ -42,7 +42,7 @@ bool VideoDecoder::loadFile(const Common::String &filename) { return false; } - return load(*file); + return load(file); } uint32 VideoDecoder::getElapsedTime() const { @@ -81,9 +81,14 @@ bool VideoDecoder::endOfVideo() const { void VideoDecoder::pauseVideo(bool pause) { if (pause) { _pauseLevel++; - } else { - assert(_pauseLevel); // We can't go negative + + // We can't go negative + } else if (_pauseLevel) { _pauseLevel--; + + // Do nothing + } else { + return; } if (_pauseLevel == 1 && pause) { diff --git a/graphics/video/video_decoder.h b/graphics/video/video_decoder.h index d96545d2c1..a398a62009 100644 --- a/graphics/video/video_decoder.h +++ b/graphics/video/video_decoder.h @@ -93,7 +93,7 @@ public: * Load a video file * @param stream the stream to load */ - virtual bool load(Common::SeekableReadStream &stream) = 0; + virtual bool load(Common::SeekableReadStream *stream) = 0; /** * Close a video file diff --git a/gui/GuiManager.cpp b/gui/GuiManager.cpp index ab370425ab..bbd7718d71 100644 --- a/gui/GuiManager.cpp +++ b/gui/GuiManager.cpp @@ -249,6 +249,9 @@ void GuiManager::runLoop() { redraw(); } + _lastMousePosition.x = _lastMousePosition.y = -1; + _lastMousePosition.time = 0; + Common::EventManager *eventMan = _system->getEventManager(); uint32 lastRedraw = 0; const uint32 waitTime = 1000 / 45; diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index b491b12065..3a50b2c69c 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -1451,6 +1451,20 @@ const Graphics::Font *ThemeEngine::loadFontFromArchive(const Common::String &fil if (_themeArchive) stream = _themeArchive->createReadStreamForMember(filename); if (stream) { + font = Graphics::NewFont::loadFont(*stream); + delete stream; + } + + return font; +} + +const Graphics::Font *ThemeEngine::loadCachedFontFromArchive(const Common::String &filename) { + Common::SeekableReadStream *stream = 0; + const Graphics::Font *font = 0; + + if (_themeArchive) + stream = _themeArchive->createReadStreamForMember(filename); + if (stream) { font = Graphics::NewFont::loadFromCache(*stream); delete stream; } @@ -1464,13 +1478,14 @@ const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename) { Common::File fontFile; if (!cacheFilename.empty()) { - if (fontFile.open(cacheFilename)) + if (fontFile.open(cacheFilename)) { font = Graphics::NewFont::loadFromCache(fontFile); + } if (font) return font; - if ((font = loadFontFromArchive(cacheFilename))) + if ((font = loadCachedFontFromArchive(cacheFilename))) return font; } @@ -1485,7 +1500,7 @@ const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename) { if (font) { if (!cacheFilename.empty()) { - if (!Graphics::NewFont::cacheFontData(*(const Graphics::NewFont*)font, cacheFilename)) { + if (!Graphics::NewFont::cacheFontData(*(const Graphics::NewFont *)font, cacheFilename)) { warning("Couldn't create cache file for font '%s'", filename.c_str()); } } diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index e3cdb09b4e..e9ca1a919d 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -542,6 +542,7 @@ protected: const Graphics::Font *loadFont(const Common::String &filename); const Graphics::Font *loadFontFromArchive(const Common::String &filename); + const Graphics::Font *loadCachedFontFromArchive(const Common::String &filename); Common::String genCacheFilename(const char *filename); Common::String genLocalizedFontFilename(const char *filename); diff --git a/gui/credits.h b/gui/credits.h index c0e1870226..bd4ecffc9b 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -384,6 +384,12 @@ static const char *credits[] = { "C1""Russian", "C0""Eugene Sandulenko", "", +"C1""Spanish", +"C0""Tom\341s Maidagan", +"", +"C1""Ukrainian", +"C0""Lubomyr Lisen", +"", "", "C1""Websites (design)", "C0""Dob\363 Bal\341zs", diff --git a/gui/options.cpp b/gui/options.cpp index d3bda228a7..072b20b393 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -1001,7 +1001,7 @@ GlobalOptionsDialog::GlobalOptionsDialog() #endif // USE_DETECTLANG _guiLanguagePopUp->appendEntry(_("English"), Common::kTranslationBuiltinId); _guiLanguagePopUp->appendEntry("", 0); - Common::TLangArray languages = TransMan.getSupportedLanguages(); + Common::TLangArray languages = TransMan.getSupportedLanguageNames(); Common::TLangArray::iterator lang = languages.begin(); while (lang != languages.end()) { _guiLanguagePopUp->appendEntry(lang->name, lang->id); diff --git a/gui/themes/default.inc b/gui/themes/default.inc index f03b3fc61e..46ac4a1365 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -653,7 +653,6 @@ "width='80' " "/> " "</layout> " -"<space size='4' /> " "<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " @@ -673,7 +672,7 @@ "/> " "</layout> " "</layout> " -"<space size='4' /> " +"<space size='2' /> " "<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " @@ -685,7 +684,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<space size='20'/> " +"<space size='16'/> " "<layout type='horizontal' padding='0,0,0,0' spacing='4'> " "<widget name='Keys' " "type='Button' " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex 299bc41339..2507572e40 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc b/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc Binary files differnew file mode 100644 index 0000000000..d8e614211d --- /dev/null +++ b/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx index 622c23439e..65083f4bce 100644 --- a/gui/themes/scummclassic/classic_layout_lowres.stx +++ b/gui/themes/scummclassic/classic_layout_lowres.stx @@ -709,7 +709,6 @@ width = '80' /> </layout> - <space size = '4' /> <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '1' center = 'true'> <widget name = 'subToggleDesc' type = 'OptionsLabel' @@ -729,7 +728,7 @@ /> </layout> </layout> - <space size = '4' /> + <space size = '2' /> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> <widget name = 'subSubtitleSpeedDesc' type = 'OptionsLabel' @@ -741,7 +740,7 @@ type = 'SmallLabel' /> </layout> - <space size = '20'/> + <space size = '16'/> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4'> <widget name = 'Keys' type = 'Button' diff --git a/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc b/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc Binary files differnew file mode 100644 index 0000000000..e70388dd93 --- /dev/null +++ b/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc diff --git a/gui/themes/scummclassic/helvb12-iso-8859-5.fcc b/gui/themes/scummclassic/helvb12-iso-8859-5.fcc Binary files differnew file mode 100644 index 0000000000..8ad8f0eb22 --- /dev/null +++ b/gui/themes/scummclassic/helvb12-iso-8859-5.fcc diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex cd24d781bb..ea7ecd733c 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc b/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc Binary files differnew file mode 100644 index 0000000000..d8e614211d --- /dev/null +++ b/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc diff --git a/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc b/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc Binary files differnew file mode 100644 index 0000000000..e70388dd93 --- /dev/null +++ b/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc diff --git a/gui/themes/scummmodern/helvb12-iso-8859-5.fcc b/gui/themes/scummmodern/helvb12-iso-8859-5.fcc Binary files differnew file mode 100644 index 0000000000..8ad8f0eb22 --- /dev/null +++ b/gui/themes/scummmodern/helvb12-iso-8859-5.fcc diff --git a/po/ca_ES.po b/po/ca_ES.po index 7905fbdf16..6647dcc837 100644 --- a/po/ca_ES.po +++ b/po/ca_ES.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 1.2.0svn\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" -"POT-Creation-Date: 2010-07-12 17:44+0200\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" "PO-Revision-Date: 2010-06-26 16:45+0100\n" "Last-Translator: Jordi Vilalta Prat <jvprat@gmail.com>\n" "Language-Team: Catalan <scummvm-devel@lists.sf.net>\n" -"Language: Catalan\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" +"Language: Catalan\n" #: gui/about.cpp:96 #, c-format @@ -38,7 +38,7 @@ msgid "Go to previous directory level" msgstr "Torna al nivell de directoris anterior" #: gui/browser.cpp:70 gui/chooser.cpp:49 gui/KeysDialog.cpp:46 -#: gui/launcher.cpp:266 gui/massadd.cpp:95 gui/options.cpp:972 +#: gui/launcher.cpp:280 gui/massadd.cpp:95 gui/options.cpp:1029 #: gui/saveload.cpp:65 gui/saveload.cpp:157 gui/themebrowser.cpp:56 #: backends/platform/wii/options.cpp:48 msgid "Cancel" @@ -48,19 +48,19 @@ msgstr "Cancel·la" msgid "Choose" msgstr "Escull" -#: gui/GuiManager.cpp:102 backends/keymapper/remap-dialog.cpp:54 +#: gui/GuiManager.cpp:103 backends/keymapper/remap-dialog.cpp:54 msgid "Close" msgstr "Tanca" -#: gui/GuiManager.cpp:105 +#: gui/GuiManager.cpp:106 msgid "Mouse click" msgstr "Clic del ratolí" -#: gui/GuiManager.cpp:108 base/main.cpp:285 +#: gui/GuiManager.cpp:109 base/main.cpp:285 msgid "Display keyboard" msgstr "Mostra el teclat" -#: gui/GuiManager.cpp:111 base/main.cpp:288 +#: gui/GuiManager.cpp:112 base/main.cpp:288 msgid "Remap keys" msgstr "Remapeja les tecles" @@ -68,8 +68,8 @@ msgstr "Remapeja les tecles" msgid "Map" msgstr "Mapeja" -#: gui/KeysDialog.cpp:45 gui/launcher.cpp:267 gui/launcher.cpp:873 -#: gui/launcher.cpp:877 gui/massadd.cpp:92 gui/options.cpp:973 +#: gui/KeysDialog.cpp:45 gui/launcher.cpp:281 gui/launcher.cpp:893 +#: gui/launcher.cpp:897 gui/massadd.cpp:92 gui/options.cpp:1030 #: backends/platform/wii/options.cpp:47 #: backends/platform/wince/CELauncherDialog.cpp:56 msgid "OK" @@ -101,15 +101,15 @@ msgstr "Premeu la tecla a associar" msgid "Choose an action to map" msgstr "Sel·leccioneu una acció per mapejar" -#: gui/launcher.cpp:170 +#: gui/launcher.cpp:172 msgid "Game" msgstr "Joc" -#: gui/launcher.cpp:173 +#: gui/launcher.cpp:175 msgid "ID:" msgstr "Identificador:" -#: gui/launcher.cpp:173 gui/launcher.cpp:174 +#: gui/launcher.cpp:175 gui/launcher.cpp:176 msgid "" "Short game identifier used for referring to savegames and running the game " "from the command line" @@ -117,19 +117,19 @@ msgstr "" "Identificador de joc curt utilitzat per referir-se a les partides i per " "executar el joc des de la línia de comandes" -#: gui/launcher.cpp:177 +#: gui/launcher.cpp:179 msgid "Name:" msgstr "Nom:" -#: gui/launcher.cpp:177 gui/launcher.cpp:178 +#: gui/launcher.cpp:179 gui/launcher.cpp:180 msgid "Full title of the game" msgstr "Títol complet del joc" -#: gui/launcher.cpp:181 +#: gui/launcher.cpp:183 msgid "Language:" msgstr "Idioma:" -#: gui/launcher.cpp:181 gui/launcher.cpp:182 +#: gui/launcher.cpp:183 gui/launcher.cpp:184 msgid "" "Language of the game. This will not turn your Spanish game version into " "English" @@ -137,206 +137,215 @@ msgstr "" "Idioma del joc. Això no convertirà la vostra versió Espanyola del joc a " "Anglès" -#: gui/launcher.cpp:183 gui/launcher.cpp:194 gui/options.cpp:80 -#: gui/options.cpp:617 gui/options.cpp:627 gui/options.cpp:943 +#: gui/launcher.cpp:185 gui/launcher.cpp:196 gui/options.cpp:80 +#: gui/options.cpp:635 gui/options.cpp:645 gui/options.cpp:1000 #: sound/null.cpp:42 msgid "<default>" msgstr "<per defecte>" -#: gui/launcher.cpp:192 +#: gui/launcher.cpp:194 msgid "Platform:" msgstr "Plataforma:" -#: gui/launcher.cpp:192 gui/launcher.cpp:193 +#: gui/launcher.cpp:194 gui/launcher.cpp:195 msgid "Platform the game was originally designed for" msgstr "Plataforma per la que el joc es va dissenyar originalment" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "Graphics" msgstr "Gràfics" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "GFX" msgstr "GFX" -#: gui/launcher.cpp:206 +#: gui/launcher.cpp:208 msgid "Override global graphic settings" msgstr "Fer canvis sobre les opcions globals de gràfics" -#: gui/launcher.cpp:213 gui/options.cpp:873 +#: gui/launcher.cpp:215 gui/options.cpp:921 msgid "Audio" msgstr "Àudio" -#: gui/launcher.cpp:215 +#: gui/launcher.cpp:217 msgid "Override global audio settings" msgstr "Fer canvis sobre les opcions globals d'àudio" -#: gui/launcher.cpp:223 gui/options.cpp:877 +#: gui/launcher.cpp:225 gui/options.cpp:925 msgid "Volume" msgstr "Volum" -#: gui/launcher.cpp:225 +#: gui/launcher.cpp:227 msgid "Override global volume settings" msgstr "Fer canvis sobre les opcions globals de volum" -#: gui/launcher.cpp:232 gui/options.cpp:885 +#: gui/launcher.cpp:234 gui/options.cpp:933 msgid "MIDI" msgstr "MIDI" -#: gui/launcher.cpp:234 +#: gui/launcher.cpp:236 msgid "Override global MIDI settings" msgstr "Fer canvis sobre les opcions globals de MIDI" -#: gui/launcher.cpp:244 gui/options.cpp:891 +#: gui/launcher.cpp:246 gui/options.cpp:939 +msgid "MT-32" +msgstr "" + +#: gui/launcher.cpp:248 +#, fuzzy +msgid "Override global MT-32 settings" +msgstr "Fer canvis sobre les opcions globals de MIDI" + +#: gui/launcher.cpp:258 gui/options.cpp:945 msgid "Paths" msgstr "Camins" -#: gui/launcher.cpp:250 +#: gui/launcher.cpp:264 msgid "Game Path:" msgstr "Camí del Joc:" -#: gui/launcher.cpp:254 gui/options.cpp:904 +#: gui/launcher.cpp:268 gui/options.cpp:958 msgid "Extra Path:" msgstr "Camí Extra:" -#: gui/launcher.cpp:254 gui/launcher.cpp:255 +#: gui/launcher.cpp:268 gui/launcher.cpp:269 msgid "Specifies path to additional data used the game" msgstr "Especifica el camí de dades addicionals utilitzades pel joc" -#: gui/launcher.cpp:258 +#: gui/launcher.cpp:272 msgid "Save Path:" msgstr "Camí de les Partides:" -#: gui/launcher.cpp:258 gui/launcher.cpp:259 gui/options.cpp:898 -#: gui/options.cpp:899 +#: gui/launcher.cpp:272 gui/launcher.cpp:273 gui/options.cpp:952 +#: gui/options.cpp:953 msgid "Specifies where your savegames are put" msgstr "Especifica on es desaran les partides" -#: gui/launcher.cpp:275 gui/launcher.cpp:353 gui/launcher.cpp:398 -#: gui/options.cpp:245 gui/options.cpp:400 gui/options.cpp:486 -#: gui/options.cpp:545 gui/options.cpp:706 gui/options.cpp:902 -#: gui/options.cpp:905 gui/options.cpp:909 gui/options.cpp:996 -#: gui/options.cpp:1002 gui/options.cpp:1008 gui/options.cpp:1016 -#: gui/options.cpp:1040 gui/options.cpp:1044 gui/options.cpp:1050 -#: gui/options.cpp:1057 gui/options.cpp:1156 +#: gui/launcher.cpp:289 gui/launcher.cpp:369 gui/launcher.cpp:418 +#: gui/options.cpp:230 gui/options.cpp:399 gui/options.cpp:497 +#: gui/options.cpp:555 gui/options.cpp:732 gui/options.cpp:956 +#: gui/options.cpp:959 gui/options.cpp:963 gui/options.cpp:1053 +#: gui/options.cpp:1059 gui/options.cpp:1065 gui/options.cpp:1073 +#: gui/options.cpp:1097 gui/options.cpp:1101 gui/options.cpp:1107 +#: gui/options.cpp:1114 gui/options.cpp:1213 msgid "None" msgstr "Cap" -#: gui/launcher.cpp:280 gui/launcher.cpp:357 +#: gui/launcher.cpp:294 gui/launcher.cpp:373 #: backends/platform/wii/options.cpp:56 msgid "Default" msgstr "Per defecte" -#: gui/launcher.cpp:391 gui/options.cpp:1150 +#: gui/launcher.cpp:411 gui/options.cpp:1207 msgid "Select SoundFont" msgstr "Seleccioneu el fitxer SoundFont" -#: gui/launcher.cpp:410 gui/launcher.cpp:548 +#: gui/launcher.cpp:430 gui/launcher.cpp:568 msgid "Select directory with game data" msgstr "Seleccioneu el directori amb les dades del joc" -#: gui/launcher.cpp:428 +#: gui/launcher.cpp:448 msgid "Select additional game directory" msgstr "Seleccioneu el directori addicional del joc" -#: gui/launcher.cpp:440 +#: gui/launcher.cpp:460 msgid "Select directory for saved games" msgstr "Seleccioneu el directori de les partides desades" -#: gui/launcher.cpp:459 +#: gui/launcher.cpp:479 msgid "This game ID is already taken. Please choose another one." msgstr "" "Aquest identificador de joc ja està usat. Si us plau, trieu-ne un altre." -#: gui/launcher.cpp:500 engines/dialogs.cpp:113 +#: gui/launcher.cpp:520 engines/dialogs.cpp:113 msgid "~Q~uit" msgstr "~T~anca" -#: gui/launcher.cpp:500 +#: gui/launcher.cpp:520 msgid "Quit ScummVM" msgstr "Surt de ScummVM" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "A~b~out..." msgstr "~Q~uant a..." -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "About ScummVM" msgstr "Quant a ScummVM" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "~O~ptions..." msgstr "~O~pcions..." -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "Change global ScummVM options" msgstr "Canvia les opcions globals de ScummVM" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "~S~tart" msgstr "~I~nicia" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "Start selected game" msgstr "Iniciant el joc seleccionat" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "~L~oad..." msgstr "~C~arrega..." -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "Load savegame for selected game" msgstr "Carrega una partida pel joc seleccionat" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "~A~dd Game..." msgstr "~A~fegeix Joc..." -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "Hold Shift for Mass Add" msgstr "Mantingueu premut Shift per a l'Addició Massiva" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "~E~dit Game..." msgstr "~E~dita Joc..." -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "Change game options" msgstr "Canvia les opcions del joc" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "~R~emove Game" msgstr "~S~uprimeix Joc" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "Remove game from the list. The game data files stay intact" msgstr "" "Elimina un joc de la llista. Els fitxers de dades del joc es mantenen " "intactes" -#: gui/launcher.cpp:522 +#: gui/launcher.cpp:542 msgid "Search in game list" msgstr "Cerca a la llista de jocs" -#: gui/launcher.cpp:526 gui/launcher.cpp:1037 +#: gui/launcher.cpp:546 gui/launcher.cpp:1057 msgid "Search:" msgstr "Cerca:" -#: gui/launcher.cpp:529 gui/options.cpp:707 +#: gui/launcher.cpp:549 gui/options.cpp:733 msgid "Clear value" msgstr "Neteja el valor" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 msgid "Load game:" msgstr "Carrega partida:" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 #: backends/platform/wince/CEActionsPocket.cpp:263 #: backends/platform/wince/CEActionsSmartphone.cpp:225 msgid "Load" msgstr "Carrega" -#: gui/launcher.cpp:660 +#: gui/launcher.cpp:680 msgid "" "Do you really want to run the mass game detector? This could potentially add " "a huge number of games." @@ -344,7 +353,7 @@ msgstr "" "Esteu segur que voleu executar el detector massiu de jocs? Això pot afegir " "una gran quantitat de jocs." -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -352,7 +361,7 @@ msgstr "" msgid "Yes" msgstr "Sí" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -360,36 +369,36 @@ msgstr "Sí" msgid "No" msgstr "No" -#: gui/launcher.cpp:708 +#: gui/launcher.cpp:728 msgid "ScummVM couldn't open the specified directory!" msgstr "ScummVM no ha pogut obrir el directori especificat!" -#: gui/launcher.cpp:720 +#: gui/launcher.cpp:740 msgid "ScummVM could not find any game in the specified directory!" msgstr "ScummVM no ha pogut trobar cap joc al directori especificat!" -#: gui/launcher.cpp:734 +#: gui/launcher.cpp:754 msgid "Pick the game:" msgstr "Seleccioneu el joc:" -#: gui/launcher.cpp:810 +#: gui/launcher.cpp:830 msgid "Do you really want to remove this game configuration?" msgstr "Realment voleu suprimir la configuració d'aquest joc?" -#: gui/launcher.cpp:873 +#: gui/launcher.cpp:893 msgid "This game does not support loading games from the launcher." msgstr "Aquest joc no suporta la càrrega de partides des del llançador." -#: gui/launcher.cpp:877 +#: gui/launcher.cpp:897 msgid "ScummVM could not find any engine capable of running the selected game!" msgstr "" "ScummVM no ha pogut trobar cap motor capaç d'executar el joc seleccionat!" -#: gui/launcher.cpp:989 +#: gui/launcher.cpp:1009 msgid "Mass Add..." msgstr "Addició Massiva..." -#: gui/launcher.cpp:990 +#: gui/launcher.cpp:1010 msgid "Add Game..." msgstr "Afegeix Joc..." @@ -456,80 +465,60 @@ msgstr "44 kHz" msgid "48 kHz" msgstr "48 kHz" -#: gui/options.cpp:614 +#: gui/options.cpp:632 msgid "Graphics mode:" msgstr "Mode gràfic:" -#: gui/options.cpp:625 +#: gui/options.cpp:643 msgid "Render mode:" msgstr "Mode de pintat:" -#: gui/options.cpp:625 gui/options.cpp:626 +#: gui/options.cpp:643 gui/options.cpp:644 msgid "Special dithering modes supported by some games" msgstr "Modes de dispersió especials suportats per alguns jocs" -#: gui/options.cpp:635 +#: gui/options.cpp:653 msgid "Fullscreen mode" msgstr "Mode pantalla completa" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Aspect ratio correction" msgstr "Correcció del rati d'aspecte" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Correct aspect ratio for 320x200 games" msgstr "Corregeix la relació d'aspecte per jocs de 320x200" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Preferred Device:" msgstr "Dispositiu Preferit:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 #, fuzzy msgid "Music Device:" msgstr "Dispositiu GM:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Specifies preferred sound device or sound card emulator" msgstr "Especifica el dispositiu de so o l'emulador de tarja de so preferit" -#: gui/options.cpp:645 gui/options.cpp:646 +#: gui/options.cpp:663 gui/options.cpp:664 msgid "Specifies output sound device or sound card emulator" msgstr "Especifica el dispositiu de so o l'emulador de tarja de so de sortida" -#: gui/options.cpp:648 -#, fuzzy -msgid "MT-32 Device:" -msgstr "Dispositiu MT32:" - -#: gui/options.cpp:648 -msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" -msgstr "" -"Especifica el dispositiu de so per defecte per a la sortida de Roland MT-32/" -"LAPC1/CM32l/CM64" - -#: gui/options.cpp:650 -msgid "GM Device:" -msgstr "Dispositiu GM:" - -#: gui/options.cpp:650 -msgid "Specifies default sound device for General MIDI output" -msgstr "" -"Especifica el dispositiu de so per defecte per a la sortida General MIDI" - -#: gui/options.cpp:682 +#: gui/options.cpp:688 msgid "AdLib emulator:" msgstr "Emulador d'AdLib:" -#: gui/options.cpp:682 gui/options.cpp:683 +#: gui/options.cpp:688 gui/options.cpp:689 msgid "AdLib is used for music in many games" msgstr "AdLib s'utilitza per la música de molts jocs" -#: gui/options.cpp:693 +#: gui/options.cpp:699 msgid "Output rate:" msgstr "Freqüència de sortida:" -#: gui/options.cpp:693 gui/options.cpp:694 +#: gui/options.cpp:699 gui/options.cpp:700 msgid "" "Higher value specifies better sound quality but may be not supported by your " "soundcard" @@ -537,27 +526,51 @@ msgstr "" "Valors més alts especifiquen millor qualitat de so però pot ser que la " "vostra tarja de so no ho suporti" -#: gui/options.cpp:705 +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "Dispositiu GM:" + +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "" +"Especifica el dispositiu de so per defecte per a la sortida General MIDI" + +#: gui/options.cpp:731 msgid "SoundFont:" msgstr "Fitxer SoundFont:" -#: gui/options.cpp:705 gui/options.cpp:706 +#: gui/options.cpp:731 gui/options.cpp:732 msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" msgstr "Algunes targes de so, Fluidsynth i Timidity suporten SoundFont" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Mixed AdLib/MIDI mode" msgstr "Mode combinat AdLib/MIDI" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Use both MIDI and AdLib sound generation" msgstr "Utilitza MIDI i la generació de so AdLib alhora" -#: gui/options.cpp:713 +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "Guany MIDI:" + +#: gui/options.cpp:749 +#, fuzzy +msgid "MT-32 Device:" +msgstr "Dispositiu MT32:" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "" +"Especifica el dispositiu de so per defecte per a la sortida de Roland MT-32/" +"LAPC1/CM32l/CM64" + +#: gui/options.cpp:753 msgid "True Roland MT-32 (disable GM emulation)" msgstr "Roland MT-32 real (desactiva l'emulació GM)" -#: gui/options.cpp:713 +#: gui/options.cpp:753 msgid "" "Check if you want to use your real hardware Roland-compatible sound device " "connected to your computer" @@ -565,145 +578,141 @@ msgstr "" "Marqueu si voleu utilitzar el vostre dispositiu hardware real de so " "compatible amb Roland connectat al vostre ordinador" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Enable Roland GS Mode" msgstr "Activa el Mode Roland GS" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" msgstr "" "Desactiva la conversió General MIDI pels jocs que tenen banda sonora per a " "Roland MT-32" -#: gui/options.cpp:719 -msgid "MIDI gain:" -msgstr "Guany MIDI:" - -#: gui/options.cpp:732 +#: gui/options.cpp:780 msgid "Text and Speech:" msgstr "Text i Veus:" -#: gui/options.cpp:737 gui/options.cpp:743 +#: gui/options.cpp:785 gui/options.cpp:791 msgid "Speech" msgstr "Veus" -#: gui/options.cpp:738 gui/options.cpp:744 +#: gui/options.cpp:786 gui/options.cpp:792 msgid "Subtitles" msgstr "Subtítols" -#: gui/options.cpp:739 gui/options.cpp:745 +#: gui/options.cpp:787 gui/options.cpp:793 msgid "Both" msgstr "Ambdós" -#: gui/options.cpp:743 +#: gui/options.cpp:791 msgid "Spch" msgstr "Veus" -#: gui/options.cpp:744 +#: gui/options.cpp:792 msgid "Subs" msgstr "Subt" -#: gui/options.cpp:745 +#: gui/options.cpp:793 msgid "Show subtitles and play speech" msgstr "Mostra els subtítols i reprodueix la veu" -#: gui/options.cpp:749 +#: gui/options.cpp:797 msgid "Subtitle speed:" msgstr "Velocitat dels subtítols:" -#: gui/options.cpp:761 +#: gui/options.cpp:809 msgid "Music volume:" msgstr "Volum de la música:" -#: gui/options.cpp:768 +#: gui/options.cpp:816 msgid "Mute All" msgstr "Silenciar tot" -#: gui/options.cpp:771 +#: gui/options.cpp:819 msgid "SFX volume:" msgstr "Volum dels efectes:" -#: gui/options.cpp:771 gui/options.cpp:772 +#: gui/options.cpp:819 gui/options.cpp:820 msgid "Special sound effects volume" msgstr "Volum dels sons d'efectes especials" -#: gui/options.cpp:778 +#: gui/options.cpp:826 msgid "Speech volume:" msgstr "Volum de la veu:" -#: gui/options.cpp:898 +#: gui/options.cpp:952 msgid "Save Path: " msgstr "Camí de les Partides: " -#: gui/options.cpp:901 +#: gui/options.cpp:955 msgid "Theme Path:" msgstr "Camí dels Temes:" -#: gui/options.cpp:904 gui/options.cpp:905 +#: gui/options.cpp:958 gui/options.cpp:959 msgid "Specifies path to additional data used by all games or ScummVM" msgstr "" "Especifica el camí de les dades addicionals utilitzades per tots els jocs o " "pel ScummVM" -#: gui/options.cpp:908 +#: gui/options.cpp:962 msgid "Plugins Path:" msgstr "Camí dels connectors:" -#: gui/options.cpp:913 +#: gui/options.cpp:970 msgid "Misc" msgstr "Misc" -#: gui/options.cpp:915 +#: gui/options.cpp:972 msgid "Theme:" msgstr "Tema:" -#: gui/options.cpp:919 +#: gui/options.cpp:976 msgid "GUI Renderer:" msgstr "Mode de pintat de la interfície d'usuari:" -#: gui/options.cpp:925 +#: gui/options.cpp:982 msgid "Autosave:" msgstr "Desat automàtic:" -#: gui/options.cpp:933 +#: gui/options.cpp:990 msgid "Keys" msgstr "Tecles" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "GUI Language:" msgstr "Idioma de la interfície d'usuari:" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "Language of ScummVM GUI" msgstr "Idioma de la interfície d'usuari de ScummVM" -#: gui/options.cpp:945 +#: gui/options.cpp:1002 msgid "English" msgstr "Anglès" -#: gui/options.cpp:1089 +#: gui/options.cpp:1146 msgid "You have to restart ScummVM to take the effect." msgstr "Heu de reiniciar ScummVM perquè tots els canvis tingui efecte." -#: gui/options.cpp:1102 +#: gui/options.cpp:1159 msgid "Select directory for savegames" msgstr "Seleccioneu el directori de les partides desades" -#: gui/options.cpp:1109 +#: gui/options.cpp:1166 msgid "The chosen directory cannot be written to. Please select another one." msgstr "" "No es pot escriure al directori seleccionat. Si us plau, escolliu-ne un " "altre." -#: gui/options.cpp:1118 +#: gui/options.cpp:1175 msgid "Select directory for GUI themes" msgstr "Seleccioneu el directori dels temes de la Interfície d'Usuari" -#: gui/options.cpp:1128 +#: gui/options.cpp:1185 msgid "Select directory for extra files" msgstr "Seleccioneu el directori dels fitxers extra" -#: gui/options.cpp:1139 +#: gui/options.cpp:1196 msgid "Select directory for plugins" msgstr "Seleccioneu el directori dels connectors" @@ -747,15 +756,15 @@ msgstr "Partida sense títol" msgid "Select a Theme" msgstr "Seleccioneu un Tema" -#: gui/ThemeEngine.cpp:337 +#: gui/ThemeEngine.cpp:334 msgid "Disabled GFX" msgstr "GFX desactivats" -#: gui/ThemeEngine.cpp:338 +#: gui/ThemeEngine.cpp:335 msgid "Standard Renderer (16bpp)" msgstr "Pintat estàndard (16bpp)" -#: gui/ThemeEngine.cpp:340 +#: gui/ThemeEngine.cpp:337 msgid "Antialiased Renderer (16bpp)" msgstr "Pintat amb antialias (16bpp)" diff --git a/po/de_DE.po b/po/de_DE.po index 4b3f493a03..63e2307b43 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 1.2.0svn\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" -"POT-Creation-Date: 2010-07-12 17:44+0200\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" "PO-Revision-Date: 2010-07-09 20:37+0100\n" "Last-Translator: Simon Sawatzki\n" "Language-Team: Lothar Serra Mari <Lothar@Windowsbase.de> & Simon Sawatzki " "<SimSaw@gmx.de>\n" -"Language: Deutsch\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" +"Language: Deutsch\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" #: gui/about.cpp:96 @@ -40,7 +40,7 @@ msgid "Go to previous directory level" msgstr "Zu höherer Pfadebene wechseln" #: gui/browser.cpp:70 gui/chooser.cpp:49 gui/KeysDialog.cpp:46 -#: gui/launcher.cpp:266 gui/massadd.cpp:95 gui/options.cpp:972 +#: gui/launcher.cpp:280 gui/massadd.cpp:95 gui/options.cpp:1029 #: gui/saveload.cpp:65 gui/saveload.cpp:157 gui/themebrowser.cpp:56 #: backends/platform/wii/options.cpp:48 msgid "Cancel" @@ -50,19 +50,19 @@ msgstr "Abbrechen" msgid "Choose" msgstr "Auswählen" -#: gui/GuiManager.cpp:102 backends/keymapper/remap-dialog.cpp:54 +#: gui/GuiManager.cpp:103 backends/keymapper/remap-dialog.cpp:54 msgid "Close" msgstr "Schließen" -#: gui/GuiManager.cpp:105 +#: gui/GuiManager.cpp:106 msgid "Mouse click" msgstr "Mausklick" -#: gui/GuiManager.cpp:108 base/main.cpp:285 +#: gui/GuiManager.cpp:109 base/main.cpp:285 msgid "Display keyboard" msgstr "Tastatur anzeigen" -#: gui/GuiManager.cpp:111 base/main.cpp:288 +#: gui/GuiManager.cpp:112 base/main.cpp:288 msgid "Remap keys" msgstr "Tasten neu zuweisen" @@ -70,8 +70,8 @@ msgstr "Tasten neu zuweisen" msgid "Map" msgstr "Zuweisen" -#: gui/KeysDialog.cpp:45 gui/launcher.cpp:267 gui/launcher.cpp:873 -#: gui/launcher.cpp:877 gui/massadd.cpp:92 gui/options.cpp:973 +#: gui/KeysDialog.cpp:45 gui/launcher.cpp:281 gui/launcher.cpp:893 +#: gui/launcher.cpp:897 gui/massadd.cpp:92 gui/options.cpp:1030 #: backends/platform/wii/options.cpp:47 #: backends/platform/wince/CELauncherDialog.cpp:56 msgid "OK" @@ -103,15 +103,15 @@ msgstr "Taste drücken, um sie zuzuweisen" msgid "Choose an action to map" msgstr "Eine Aktion zum Zuweisen auswählen" -#: gui/launcher.cpp:170 +#: gui/launcher.cpp:172 msgid "Game" msgstr "Spiel" -#: gui/launcher.cpp:173 +#: gui/launcher.cpp:175 msgid "ID:" msgstr "Kennung:" -#: gui/launcher.cpp:173 gui/launcher.cpp:174 +#: gui/launcher.cpp:175 gui/launcher.cpp:176 msgid "" "Short game identifier used for referring to savegames and running the game " "from the command line" @@ -119,19 +119,19 @@ msgstr "" "Kurzer Spielname, um die Spielstände zuzuordnen und das Spiel von der " "Kommandozeile aus starten zu können" -#: gui/launcher.cpp:177 +#: gui/launcher.cpp:179 msgid "Name:" msgstr "Name:" -#: gui/launcher.cpp:177 gui/launcher.cpp:178 +#: gui/launcher.cpp:179 gui/launcher.cpp:180 msgid "Full title of the game" msgstr "Voller Name des Spiels" -#: gui/launcher.cpp:181 +#: gui/launcher.cpp:183 msgid "Language:" msgstr "Sprache:" -#: gui/launcher.cpp:181 gui/launcher.cpp:182 +#: gui/launcher.cpp:183 gui/launcher.cpp:184 msgid "" "Language of the game. This will not turn your Spanish game version into " "English" @@ -139,205 +139,214 @@ msgstr "" "Sprache des Spiels. Diese Funktion wird nicht eine spanische Version des " "Spiels in eine deutsche verwandeln." -#: gui/launcher.cpp:183 gui/launcher.cpp:194 gui/options.cpp:80 -#: gui/options.cpp:617 gui/options.cpp:627 gui/options.cpp:943 +#: gui/launcher.cpp:185 gui/launcher.cpp:196 gui/options.cpp:80 +#: gui/options.cpp:635 gui/options.cpp:645 gui/options.cpp:1000 #: sound/null.cpp:42 msgid "<default>" msgstr "<Standard>" -#: gui/launcher.cpp:192 +#: gui/launcher.cpp:194 msgid "Platform:" msgstr "Plattform:" -#: gui/launcher.cpp:192 gui/launcher.cpp:193 +#: gui/launcher.cpp:194 gui/launcher.cpp:195 msgid "Platform the game was originally designed for" msgstr "Plattform, für die das Spiel ursprünglich erstellt wurde" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "Graphics" msgstr "Grafik" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "GFX" msgstr "GFX" -#: gui/launcher.cpp:206 +#: gui/launcher.cpp:208 msgid "Override global graphic settings" msgstr "Globale Grafikeinstellungen übergehen" -#: gui/launcher.cpp:213 gui/options.cpp:873 +#: gui/launcher.cpp:215 gui/options.cpp:921 msgid "Audio" msgstr "Audio" -#: gui/launcher.cpp:215 +#: gui/launcher.cpp:217 msgid "Override global audio settings" msgstr "Globale Audioeinstellungen übergehen" -#: gui/launcher.cpp:223 gui/options.cpp:877 +#: gui/launcher.cpp:225 gui/options.cpp:925 msgid "Volume" msgstr "Lautstärke" -#: gui/launcher.cpp:225 +#: gui/launcher.cpp:227 msgid "Override global volume settings" msgstr "Globale Lautstärke-Einstellungen übergehen" -#: gui/launcher.cpp:232 gui/options.cpp:885 +#: gui/launcher.cpp:234 gui/options.cpp:933 msgid "MIDI" msgstr "MIDI" -#: gui/launcher.cpp:234 +#: gui/launcher.cpp:236 msgid "Override global MIDI settings" msgstr "Globale MIDI-Einstellungen übergehen" -#: gui/launcher.cpp:244 gui/options.cpp:891 +#: gui/launcher.cpp:246 gui/options.cpp:939 +msgid "MT-32" +msgstr "" + +#: gui/launcher.cpp:248 +#, fuzzy +msgid "Override global MT-32 settings" +msgstr "Globale MIDI-Einstellungen übergehen" + +#: gui/launcher.cpp:258 gui/options.cpp:945 msgid "Paths" msgstr "Pfade" -#: gui/launcher.cpp:250 +#: gui/launcher.cpp:264 msgid "Game Path:" msgstr "Spielpfad:" -#: gui/launcher.cpp:254 gui/options.cpp:904 +#: gui/launcher.cpp:268 gui/options.cpp:958 msgid "Extra Path:" msgstr "Extrapfad:" -#: gui/launcher.cpp:254 gui/launcher.cpp:255 +#: gui/launcher.cpp:268 gui/launcher.cpp:269 msgid "Specifies path to additional data used the game" msgstr "Legt das Verzeichnis für zusätzliche Spieldateien fest." -#: gui/launcher.cpp:258 +#: gui/launcher.cpp:272 msgid "Save Path:" msgstr "Spielstände:" -#: gui/launcher.cpp:258 gui/launcher.cpp:259 gui/options.cpp:898 -#: gui/options.cpp:899 +#: gui/launcher.cpp:272 gui/launcher.cpp:273 gui/options.cpp:952 +#: gui/options.cpp:953 msgid "Specifies where your savegames are put" msgstr "Legt fest, wo die Spielstände abgelegt werden." -#: gui/launcher.cpp:275 gui/launcher.cpp:353 gui/launcher.cpp:398 -#: gui/options.cpp:245 gui/options.cpp:400 gui/options.cpp:486 -#: gui/options.cpp:545 gui/options.cpp:706 gui/options.cpp:902 -#: gui/options.cpp:905 gui/options.cpp:909 gui/options.cpp:996 -#: gui/options.cpp:1002 gui/options.cpp:1008 gui/options.cpp:1016 -#: gui/options.cpp:1040 gui/options.cpp:1044 gui/options.cpp:1050 -#: gui/options.cpp:1057 gui/options.cpp:1156 +#: gui/launcher.cpp:289 gui/launcher.cpp:369 gui/launcher.cpp:418 +#: gui/options.cpp:230 gui/options.cpp:399 gui/options.cpp:497 +#: gui/options.cpp:555 gui/options.cpp:732 gui/options.cpp:956 +#: gui/options.cpp:959 gui/options.cpp:963 gui/options.cpp:1053 +#: gui/options.cpp:1059 gui/options.cpp:1065 gui/options.cpp:1073 +#: gui/options.cpp:1097 gui/options.cpp:1101 gui/options.cpp:1107 +#: gui/options.cpp:1114 gui/options.cpp:1213 msgid "None" msgstr "-" -#: gui/launcher.cpp:280 gui/launcher.cpp:357 +#: gui/launcher.cpp:294 gui/launcher.cpp:373 #: backends/platform/wii/options.cpp:56 msgid "Default" msgstr "Standard" -#: gui/launcher.cpp:391 gui/options.cpp:1150 +#: gui/launcher.cpp:411 gui/options.cpp:1207 msgid "Select SoundFont" msgstr "SoundFont auswählen" -#: gui/launcher.cpp:410 gui/launcher.cpp:548 +#: gui/launcher.cpp:430 gui/launcher.cpp:568 msgid "Select directory with game data" msgstr "Verzeichnis mit Spieldateien auswählen" -#: gui/launcher.cpp:428 +#: gui/launcher.cpp:448 msgid "Select additional game directory" msgstr "Verzeichnis mit zusätzlichen Dateien auswählen" -#: gui/launcher.cpp:440 +#: gui/launcher.cpp:460 msgid "Select directory for saved games" msgstr "Verzeichnis für Spielstände auswählen" -#: gui/launcher.cpp:459 +#: gui/launcher.cpp:479 msgid "This game ID is already taken. Please choose another one." msgstr "Diese Spielkennung ist schon vergeben. Bitte eine andere wählen." -#: gui/launcher.cpp:500 engines/dialogs.cpp:113 +#: gui/launcher.cpp:520 engines/dialogs.cpp:113 msgid "~Q~uit" msgstr "~B~eenden" -#: gui/launcher.cpp:500 +#: gui/launcher.cpp:520 msgid "Quit ScummVM" msgstr "ScummVM beenden" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "A~b~out..." msgstr "Übe~r~" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "About ScummVM" msgstr "Über ScummVM" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "~O~ptions..." msgstr "~O~ptionen" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "Change global ScummVM options" msgstr "Globale ScummVM-Einstellungen bearbeiten" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "~S~tart" msgstr "~S~tarten" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "Start selected game" msgstr "Ausgewähltes Spiel starten" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "~L~oad..." msgstr "~L~aden..." -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "Load savegame for selected game" msgstr "Spielstand für ausgewähltes Spiel laden" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "~A~dd Game..." msgstr "Spiel ~h~inzufügen" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "Hold Shift for Mass Add" msgstr "" "Umschalttaste (Shift) gedrückt halten, um Verzeichnisse nach Spielen zu " "durchsuchen" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "~E~dit Game..." msgstr "Spielo~p~tionen" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "Change game options" msgstr "Spieloptionen ändern" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "~R~emove Game" msgstr "Spiel ~e~ntfernen" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "Remove game from the list. The game data files stay intact" msgstr "Spiel aus der Liste entfernen. Die Spieldateien bleiben erhalten." -#: gui/launcher.cpp:522 +#: gui/launcher.cpp:542 msgid "Search in game list" msgstr "In Spieleliste suchen" -#: gui/launcher.cpp:526 gui/launcher.cpp:1037 +#: gui/launcher.cpp:546 gui/launcher.cpp:1057 msgid "Search:" msgstr "Suchen:" -#: gui/launcher.cpp:529 gui/options.cpp:707 +#: gui/launcher.cpp:549 gui/options.cpp:733 msgid "Clear value" msgstr "Wert löschen" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 msgid "Load game:" msgstr "Spiel laden:" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 #: backends/platform/wince/CEActionsPocket.cpp:263 #: backends/platform/wince/CEActionsSmartphone.cpp:225 msgid "Load" msgstr "Laden" -#: gui/launcher.cpp:660 +#: gui/launcher.cpp:680 msgid "" "Do you really want to run the mass game detector? This could potentially add " "a huge number of games." @@ -345,7 +354,7 @@ msgstr "" "Möchten Sie wirklich den PC nach Spielen durchsuchen? Möglicherweise wird " "dabei eine größere Menge an Spielen hinzugefügt." -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -353,7 +362,7 @@ msgstr "" msgid "Yes" msgstr "Ja" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -361,36 +370,36 @@ msgstr "Ja" msgid "No" msgstr "Nein" -#: gui/launcher.cpp:708 +#: gui/launcher.cpp:728 msgid "ScummVM couldn't open the specified directory!" msgstr "ScummVM kann das gewählte Verzeichnis nicht öffnen!" -#: gui/launcher.cpp:720 +#: gui/launcher.cpp:740 msgid "ScummVM could not find any game in the specified directory!" msgstr "ScummVM kann in dem gewählten Verzeichnis kein Spiel finden!" -#: gui/launcher.cpp:734 +#: gui/launcher.cpp:754 msgid "Pick the game:" msgstr "Spiel auswählen:" -#: gui/launcher.cpp:810 +#: gui/launcher.cpp:830 msgid "Do you really want to remove this game configuration?" msgstr "Möchten Sie wirklich diese Spielkonfiguration entfernen?" -#: gui/launcher.cpp:873 +#: gui/launcher.cpp:893 msgid "This game does not support loading games from the launcher." msgstr "" "Für dieses Spiel wird das Laden aus der Spieleliste heraus nicht unterstützt." -#: gui/launcher.cpp:877 +#: gui/launcher.cpp:897 msgid "ScummVM could not find any engine capable of running the selected game!" msgstr "ScummVM konnte keine Engine finden, um das Spiel zu starten!" -#: gui/launcher.cpp:989 +#: gui/launcher.cpp:1009 msgid "Mass Add..." msgstr "Durchsuchen" -#: gui/launcher.cpp:990 +#: gui/launcher.cpp:1010 msgid "Add Game..." msgstr "Spiel hinzufügen" @@ -457,81 +466,61 @@ msgstr "44 kHz" msgid "48 kHz" msgstr "48 kHz" -#: gui/options.cpp:614 +#: gui/options.cpp:632 msgid "Graphics mode:" msgstr "Grafikmodus:" -#: gui/options.cpp:625 +#: gui/options.cpp:643 msgid "Render mode:" msgstr "Render-Modus:" -#: gui/options.cpp:625 gui/options.cpp:626 +#: gui/options.cpp:643 gui/options.cpp:644 msgid "Special dithering modes supported by some games" msgstr "" "Spezielle Farbmischungsmethoden werden von manchen Spielen unterstützt." -#: gui/options.cpp:635 +#: gui/options.cpp:653 msgid "Fullscreen mode" msgstr "Vollbildmodus" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Aspect ratio correction" msgstr "Seitenverhältnis korrigieren" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Correct aspect ratio for 320x200 games" msgstr "Seitenverhältnis für Spiele mit der Auflösung 320x200 korrigieren" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Preferred Device:" msgstr "Standard-Gerät:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Music Device:" msgstr "Musikgerät:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Specifies preferred sound device or sound card emulator" msgstr "" "Legt das bevorzugte Tonwiedergabe-Gerät oder den Soundkarten-Emulator fest." -#: gui/options.cpp:645 gui/options.cpp:646 +#: gui/options.cpp:663 gui/options.cpp:664 msgid "Specifies output sound device or sound card emulator" msgstr "Legt das Musikwiedergabe-Gerät oder den Soundkarten-Emulator fest." -#: gui/options.cpp:648 -#, fuzzy -msgid "MT-32 Device:" -msgstr "MT32-Gerät:" - -#: gui/options.cpp:648 -msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" -msgstr "" -"Legt das standardmäßige Tonwiedergabe-Gerät für die Ausgabe von Roland MT-32/" -"LAPC1/CM32l/CM64 fest." - -#: gui/options.cpp:650 -msgid "GM Device:" -msgstr "GM-Gerät:" - -#: gui/options.cpp:650 -msgid "Specifies default sound device for General MIDI output" -msgstr "" -"Legt das standardmäßige Musikwiedergabe-Gerät für General-MIDI-Ausgabe fest." - -#: gui/options.cpp:682 +#: gui/options.cpp:688 msgid "AdLib emulator:" msgstr "AdLib-Emulator" -#: gui/options.cpp:682 gui/options.cpp:683 +#: gui/options.cpp:688 gui/options.cpp:689 msgid "AdLib is used for music in many games" msgstr "AdLib wird für die Musik in vielen Spielen verwendet." -#: gui/options.cpp:693 +#: gui/options.cpp:699 msgid "Output rate:" msgstr "Ausgabefrequenz:" -#: gui/options.cpp:693 gui/options.cpp:694 +#: gui/options.cpp:699 gui/options.cpp:700 msgid "" "Higher value specifies better sound quality but may be not supported by your " "soundcard" @@ -539,28 +528,52 @@ msgstr "" "Höhere Werte bewirken eine bessere Soundqualität, werden aber möglicherweise " "nicht von jeder Soundkarte unterstützt." -#: gui/options.cpp:705 +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "GM-Gerät:" + +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "" +"Legt das standardmäßige Musikwiedergabe-Gerät für General-MIDI-Ausgabe fest." + +#: gui/options.cpp:731 msgid "SoundFont:" msgstr "SoundFont:" -#: gui/options.cpp:705 gui/options.cpp:706 +#: gui/options.cpp:731 gui/options.cpp:732 msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" msgstr "" "SoundFont wird von einigen Soundkarten, Fluidsynth und Timidity unterstützt." -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Mixed AdLib/MIDI mode" msgstr "AdLib-/MIDI-Modus" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Use both MIDI and AdLib sound generation" msgstr "Benutzt MIDI und AdLib zur Sounderzeugung." -#: gui/options.cpp:713 +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "MIDI-Lautstärke:" + +#: gui/options.cpp:749 +#, fuzzy +msgid "MT-32 Device:" +msgstr "MT32-Gerät:" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "" +"Legt das standardmäßige Tonwiedergabe-Gerät für die Ausgabe von Roland MT-32/" +"LAPC1/CM32l/CM64 fest." + +#: gui/options.cpp:753 msgid "True Roland MT-32 (disable GM emulation)" msgstr "Echte Roland-MT-32-Emulation (GM-Emulation deaktiviert)" -#: gui/options.cpp:713 +#: gui/options.cpp:753 msgid "" "Check if you want to use your real hardware Roland-compatible sound device " "connected to your computer" @@ -568,145 +581,141 @@ msgstr "" "Wählen Sie dies aus, wenn Sie Ihre echte Hardware, die mit einer Roland-" "kompatiblen Soundkarte verbunden ist, verwenden möchten." -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Enable Roland GS Mode" msgstr "Roland-GS-Modus" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" msgstr "" "Schaltet die General-MIDI-Zuweisung für Spiele mit Roland-MT-32-Audiospur " "aus." -#: gui/options.cpp:719 -msgid "MIDI gain:" -msgstr "MIDI-Lautstärke:" - -#: gui/options.cpp:732 +#: gui/options.cpp:780 msgid "Text and Speech:" msgstr "Text und Sprache:" -#: gui/options.cpp:737 gui/options.cpp:743 +#: gui/options.cpp:785 gui/options.cpp:791 msgid "Speech" msgstr "Sprache" -#: gui/options.cpp:738 gui/options.cpp:744 +#: gui/options.cpp:786 gui/options.cpp:792 msgid "Subtitles" msgstr "Untertitel" -#: gui/options.cpp:739 gui/options.cpp:745 +#: gui/options.cpp:787 gui/options.cpp:793 msgid "Both" msgstr "Beides" -#: gui/options.cpp:743 +#: gui/options.cpp:791 msgid "Spch" msgstr "Spr." -#: gui/options.cpp:744 +#: gui/options.cpp:792 msgid "Subs" msgstr "Untert." -#: gui/options.cpp:745 +#: gui/options.cpp:793 msgid "Show subtitles and play speech" msgstr "Untertitel anzeigen und Sprachausgabe aktivieren" -#: gui/options.cpp:749 +#: gui/options.cpp:797 msgid "Subtitle speed:" msgstr "Untertitel-Tempo:" -#: gui/options.cpp:761 +#: gui/options.cpp:809 msgid "Music volume:" msgstr "Musiklautstärke:" -#: gui/options.cpp:768 +#: gui/options.cpp:816 msgid "Mute All" msgstr "Alles aus" -#: gui/options.cpp:771 +#: gui/options.cpp:819 msgid "SFX volume:" msgstr "Effektlautstärke:" -#: gui/options.cpp:771 gui/options.cpp:772 +#: gui/options.cpp:819 gui/options.cpp:820 msgid "Special sound effects volume" msgstr "Lautstärke spezieller Soundeffekte" -#: gui/options.cpp:778 +#: gui/options.cpp:826 msgid "Speech volume:" msgstr "Sprachlautstärke:" -#: gui/options.cpp:898 +#: gui/options.cpp:952 msgid "Save Path: " msgstr "Spielstände: " -#: gui/options.cpp:901 +#: gui/options.cpp:955 msgid "Theme Path:" msgstr "Themenpfad:" -#: gui/options.cpp:904 gui/options.cpp:905 +#: gui/options.cpp:958 gui/options.cpp:959 msgid "Specifies path to additional data used by all games or ScummVM" msgstr "" "Legt das Verzeichnis für zusätzliche Spieldateien für alle Spiele in ScummVM " "fest." -#: gui/options.cpp:908 +#: gui/options.cpp:962 msgid "Plugins Path:" msgstr "Plugin-Pfad:" -#: gui/options.cpp:913 +#: gui/options.cpp:970 msgid "Misc" msgstr "Sonstiges" -#: gui/options.cpp:915 +#: gui/options.cpp:972 msgid "Theme:" msgstr "Thema:" -#: gui/options.cpp:919 +#: gui/options.cpp:976 msgid "GUI Renderer:" msgstr "GUI-Renderer:" -#: gui/options.cpp:925 +#: gui/options.cpp:982 msgid "Autosave:" msgstr "Autom. Speichern:" -#: gui/options.cpp:933 +#: gui/options.cpp:990 msgid "Keys" msgstr "Tasten" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "GUI Language:" msgstr "GUI-Sprache:" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "Language of ScummVM GUI" msgstr "Sprache der ScummVM-Oberfläche" -#: gui/options.cpp:945 +#: gui/options.cpp:1002 msgid "English" msgstr "English" -#: gui/options.cpp:1089 +#: gui/options.cpp:1146 msgid "You have to restart ScummVM to take the effect." msgstr "Sie müssen ScummVM neustarten, um die Einstellungen zu übernehmen." -#: gui/options.cpp:1102 +#: gui/options.cpp:1159 msgid "Select directory for savegames" msgstr "Verzeichnis für Spielstände auswählen" -#: gui/options.cpp:1109 +#: gui/options.cpp:1166 msgid "The chosen directory cannot be written to. Please select another one." msgstr "" "In das gewählte Verzeichnis kann nicht geschrieben werden. Bitte ein anderes " "auswählen." -#: gui/options.cpp:1118 +#: gui/options.cpp:1175 msgid "Select directory for GUI themes" msgstr "Verzeichnis für Oberflächen-Themen" -#: gui/options.cpp:1128 +#: gui/options.cpp:1185 msgid "Select directory for extra files" msgstr "Verzeichnis für zusätzliche Dateien auswählen" -#: gui/options.cpp:1139 +#: gui/options.cpp:1196 msgid "Select directory for plugins" msgstr "Verzeichnis für Erweiterungen auswählen" @@ -750,15 +759,15 @@ msgstr "Unbenannt" msgid "Select a Theme" msgstr "Thema auswählen" -#: gui/ThemeEngine.cpp:337 +#: gui/ThemeEngine.cpp:334 msgid "Disabled GFX" msgstr "GFX ausgeschalten" -#: gui/ThemeEngine.cpp:338 +#: gui/ThemeEngine.cpp:335 msgid "Standard Renderer (16bpp)" msgstr "Standard-Renderer (16bpp)" -#: gui/ThemeEngine.cpp:340 +#: gui/ThemeEngine.cpp:337 msgid "Antialiased Renderer (16bpp)" msgstr "Kantenglättung (16bpp)" diff --git a/po/es_ES.po b/po/es_ES.po new file mode 100644 index 0000000000..de9374f844 --- /dev/null +++ b/po/es_ES.po @@ -0,0 +1,1428 @@ +# LANGUAGE translation for ScummVM. +# Copyright (C) YEAR ScummVM Team +# This file is distributed under the same license as the ScummVM package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: ScummVM 1.2.0svn\n" +"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" +"PO-Revision-Date: 2010-07-30 22:17+0100\n" +"Last-Translator: Tomás Maidagan\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: Espanol\n" + +#: gui/about.cpp:96 +#, c-format +msgid "(built on %s)" +msgstr "(compilado el %s)" + +#: gui/about.cpp:103 +msgid "Features compiled in:" +msgstr "Características compiladas:" + +#: gui/about.cpp:112 +msgid "Available engines:" +msgstr "Motores disponibles:" + +#: gui/browser.cpp:69 +msgid "Go up" +msgstr "Arriba" + +#: gui/browser.cpp:69 +msgid "Go to previous directory level" +msgstr "Ir al directorio anterior" + +#: gui/browser.cpp:70 +#: gui/chooser.cpp:49 +#: gui/KeysDialog.cpp:46 +#: gui/launcher.cpp:280 +#: gui/massadd.cpp:95 +#: gui/options.cpp:1029 +#: gui/saveload.cpp:65 +#: gui/saveload.cpp:157 +#: gui/themebrowser.cpp:56 +#: backends/platform/wii/options.cpp:48 +msgid "Cancel" +msgstr "Cancelar" + +#: gui/browser.cpp:71 +#: gui/chooser.cpp:50 +#: gui/themebrowser.cpp:57 +msgid "Choose" +msgstr "Elegir" + +#: gui/GuiManager.cpp:103 +#: backends/keymapper/remap-dialog.cpp:54 +msgid "Close" +msgstr "Cerrar" + +#: gui/GuiManager.cpp:106 +msgid "Mouse click" +msgstr "Clic de ratón" + +#: gui/GuiManager.cpp:109 +#: base/main.cpp:285 +msgid "Display keyboard" +msgstr "Mostrar el teclado" + +#: gui/GuiManager.cpp:112 +#: base/main.cpp:288 +msgid "Remap keys" +msgstr "Asignar teclas" + +#: gui/KeysDialog.cpp:44 +msgid "Map" +msgstr "Asignar" + +#: gui/KeysDialog.cpp:45 +#: gui/launcher.cpp:281 +#: gui/launcher.cpp:893 +#: gui/launcher.cpp:897 +#: gui/massadd.cpp:92 +#: gui/options.cpp:1030 +#: backends/platform/wii/options.cpp:47 +#: backends/platform/wince/CELauncherDialog.cpp:56 +msgid "OK" +msgstr "De acuerdo" + +#: gui/KeysDialog.cpp:52 +msgid "Select an action and click 'Map'" +msgstr "Selecciona una acción y pulsa \"Asignar\"" + +#: gui/KeysDialog.cpp:83 +#: gui/KeysDialog.cpp:105 +#: gui/KeysDialog.cpp:144 +#, c-format +msgid "Associated key : %s" +msgstr "Tecla asociada: %s" + +#: gui/KeysDialog.cpp:85 +#: gui/KeysDialog.cpp:107 +#: gui/KeysDialog.cpp:146 +#, c-format +msgid "Associated key : none" +msgstr "Tecla asociada: ninguna" + +#: gui/KeysDialog.cpp:93 +msgid "Please select an action" +msgstr "Por favor, selecciona una acción" + +#: gui/KeysDialog.cpp:109 +msgid "Press the key to associate" +msgstr "Pulsa la tecla a asignar" + +#: gui/KeysDialog.cpp:148 +msgid "Choose an action to map" +msgstr "Elige la acción a asociar" + +#: gui/launcher.cpp:172 +msgid "Game" +msgstr "Juego" + +#: gui/launcher.cpp:175 +msgid "ID:" +msgstr "ID:" + +#: gui/launcher.cpp:175 +#: gui/launcher.cpp:176 +msgid "Short game identifier used for referring to savegames and running the game from the command line" +msgstr "Identificador usado para las partidas guardadas y para ejecutar el juego desde la línea de comando" + +#: gui/launcher.cpp:179 +msgid "Name:" +msgstr "Nombre:" + +#: gui/launcher.cpp:179 +#: gui/launcher.cpp:180 +msgid "Full title of the game" +msgstr "Título completo del juego" + +#: gui/launcher.cpp:183 +msgid "Language:" +msgstr "Idioma:" + +#: gui/launcher.cpp:183 +#: gui/launcher.cpp:184 +msgid "Language of the game. This will not turn your Spanish game version into English" +msgstr "Idioma del juego. No sirve para pasar al inglés la versión española de un juego" + +#: gui/launcher.cpp:185 +#: gui/launcher.cpp:196 +#: gui/options.cpp:80 +#: gui/options.cpp:635 +#: gui/options.cpp:645 +#: gui/options.cpp:1000 +#: sound/null.cpp:42 +msgid "<default>" +msgstr "<por defecto>" + +#: gui/launcher.cpp:194 +msgid "Platform:" +msgstr "Plataforma:" + +#: gui/launcher.cpp:194 +#: gui/launcher.cpp:195 +msgid "Platform the game was originally designed for" +msgstr "Plataforma para la que se diseñó el juego" + +#: gui/launcher.cpp:206 +#: gui/options.cpp:898 +#: gui/options.cpp:915 +msgid "Graphics" +msgstr "Gráficos" + +#: gui/launcher.cpp:206 +#: gui/options.cpp:898 +#: gui/options.cpp:915 +msgid "GFX" +msgstr "GFX" + +#: gui/launcher.cpp:208 +msgid "Override global graphic settings" +msgstr "Ignorar opciones gráficas generales" + +#: gui/launcher.cpp:215 +#: gui/options.cpp:921 +msgid "Audio" +msgstr "Sonido" + +#: gui/launcher.cpp:217 +msgid "Override global audio settings" +msgstr "Ignorar opciones de sonido generales" + +#: gui/launcher.cpp:225 +#: gui/options.cpp:925 +msgid "Volume" +msgstr "Volumen" + +#: gui/launcher.cpp:227 +msgid "Override global volume settings" +msgstr "Ignorar opciones de volumen generales" + +#: gui/launcher.cpp:234 +#: gui/options.cpp:933 +msgid "MIDI" +msgstr "MIDI" + +#: gui/launcher.cpp:236 +msgid "Override global MIDI settings" +msgstr "Ignorar opciones MIDI generales" + +#: gui/launcher.cpp:246 +#: gui/options.cpp:939 +msgid "MT-32" +msgstr "MT-32" + +#: gui/launcher.cpp:248 +msgid "Override global MT-32 settings" +msgstr "Ignorar opciones MT-32 generales" + +#: gui/launcher.cpp:258 +#: gui/options.cpp:945 +msgid "Paths" +msgstr "Rutas" + +#: gui/launcher.cpp:264 +msgid "Game Path:" +msgstr "Juego:" + +#: gui/launcher.cpp:268 +#: gui/options.cpp:958 +msgid "Extra Path:" +msgstr "Adicional:" + +#: gui/launcher.cpp:268 +#: gui/launcher.cpp:269 +msgid "Specifies path to additional data used the game" +msgstr "Especifica un directorio para datos adicionales del juego" + +#: gui/launcher.cpp:272 +msgid "Save Path:" +msgstr "Partidas:" + +#: gui/launcher.cpp:272 +#: gui/launcher.cpp:273 +#: gui/options.cpp:952 +#: gui/options.cpp:953 +msgid "Specifies where your savegames are put" +msgstr "Especifica dónde guardar tus partidas" + +#: gui/launcher.cpp:289 +#: gui/launcher.cpp:369 +#: gui/launcher.cpp:418 +#: gui/options.cpp:230 +#: gui/options.cpp:399 +#: gui/options.cpp:497 +#: gui/options.cpp:555 +#: gui/options.cpp:732 +#: gui/options.cpp:956 +#: gui/options.cpp:959 +#: gui/options.cpp:963 +#: gui/options.cpp:1053 +#: gui/options.cpp:1059 +#: gui/options.cpp:1065 +#: gui/options.cpp:1073 +#: gui/options.cpp:1097 +#: gui/options.cpp:1101 +#: gui/options.cpp:1107 +#: gui/options.cpp:1114 +#: gui/options.cpp:1213 +msgid "None" +msgstr "Ninguno" + +#: gui/launcher.cpp:294 +#: gui/launcher.cpp:373 +#: backends/platform/wii/options.cpp:56 +msgid "Default" +msgstr "Por defecto" + +#: gui/launcher.cpp:411 +#: gui/options.cpp:1207 +msgid "Select SoundFont" +msgstr "Seleccionar SoundFont" + +#: gui/launcher.cpp:430 +#: gui/launcher.cpp:568 +msgid "Select directory with game data" +msgstr "Seleccionar directorio con los archivos del juego" + +#: gui/launcher.cpp:448 +msgid "Select additional game directory" +msgstr "Seleccionar directorio de juego adicional" + +#: gui/launcher.cpp:460 +msgid "Select directory for saved games" +msgstr "Seleccionar directorio para partidas guardadas" + +#: gui/launcher.cpp:479 +msgid "This game ID is already taken. Please choose another one." +msgstr "Esta ID ya está siendo usada. Por favor, elige otra." + +#: gui/launcher.cpp:520 +#: engines/dialogs.cpp:113 +msgid "~Q~uit" +msgstr "~S~alir" + +#: gui/launcher.cpp:520 +msgid "Quit ScummVM" +msgstr "Cerrar ScummVM" + +#: gui/launcher.cpp:521 +msgid "A~b~out..." +msgstr "Acerca ~d~e" + +#: gui/launcher.cpp:521 +msgid "About ScummVM" +msgstr "Acerca de ScummVM" + +#: gui/launcher.cpp:522 +msgid "~O~ptions..." +msgstr "~O~opciones..." + +#: gui/launcher.cpp:522 +msgid "Change global ScummVM options" +msgstr "Cambiar opciones generales de ScummVM" + +#: gui/launcher.cpp:524 +msgid "~S~tart" +msgstr "~J~ugar" + +#: gui/launcher.cpp:524 +msgid "Start selected game" +msgstr "Jugar al juego seleccionado" + +#: gui/launcher.cpp:527 +msgid "~L~oad..." +msgstr "~C~argar..." + +#: gui/launcher.cpp:527 +msgid "Load savegame for selected game" +msgstr "Cargar partida del juego seleccionado" + +#: gui/launcher.cpp:531 +msgid "~A~dd Game..." +msgstr "~A~ñadir juego..." + +#: gui/launcher.cpp:531 +msgid "Hold Shift for Mass Add" +msgstr "Mantén pulsado Mayús para añadir varios" + +#: gui/launcher.cpp:533 +msgid "~E~dit Game..." +msgstr "~E~ditar juego..." + +#: gui/launcher.cpp:533 +msgid "Change game options" +msgstr "Cambiar opciones de juego" + +#: gui/launcher.cpp:535 +msgid "~R~emove Game" +msgstr "E~l~iminar juego" + +#: gui/launcher.cpp:535 +msgid "Remove game from the list. The game data files stay intact" +msgstr "Elimina el juego de la lista. Los archivos no se borran" + +#: gui/launcher.cpp:542 +msgid "Search in game list" +msgstr "Buscar en la lista de juegos" + +#: gui/launcher.cpp:546 +#: gui/launcher.cpp:1057 +msgid "Search:" +msgstr "Buscar:" + +#: gui/launcher.cpp:549 +#: gui/options.cpp:733 +msgid "Clear value" +msgstr "Eliminar valor" + +#: gui/launcher.cpp:571 +#: engines/dialogs.cpp:117 +msgid "Load game:" +msgstr "Cargar juego:" + +#: gui/launcher.cpp:571 +#: engines/dialogs.cpp:117 +#: backends/platform/wince/CEActionsPocket.cpp:263 +#: backends/platform/wince/CEActionsSmartphone.cpp:225 +msgid "Load" +msgstr "Cargar" + +#: gui/launcher.cpp:680 +msgid "Do you really want to run the mass game detector? This could potentially add a huge number of games." +msgstr "¿Seguro que quieres ejecutar la detección masiva? Puede que se añada un gran número de juegos." + +#: gui/launcher.cpp:681 +#: gui/launcher.cpp:830 +#: backends/platform/symbian/src/SymbianOS.cpp:446 +#: backends/platform/wince/CEActionsPocket.cpp:313 +#: backends/platform/wince/CEActionsSmartphone.cpp:272 +#: backends/platform/wince/CELauncherDialog.cpp:104 +msgid "Yes" +msgstr "Sí" + +#: gui/launcher.cpp:681 +#: gui/launcher.cpp:830 +#: backends/platform/symbian/src/SymbianOS.cpp:446 +#: backends/platform/wince/CEActionsPocket.cpp:313 +#: backends/platform/wince/CEActionsSmartphone.cpp:272 +#: backends/platform/wince/CELauncherDialog.cpp:104 +msgid "No" +msgstr "No" + +#: gui/launcher.cpp:728 +msgid "ScummVM couldn't open the specified directory!" +msgstr "¡ScummVM no ha podido abrir el directorio!" + +#: gui/launcher.cpp:740 +msgid "ScummVM could not find any game in the specified directory!" +msgstr "¡ScummVM no ha encontrado ningún juego en el directorio!" + +#: gui/launcher.cpp:754 +msgid "Pick the game:" +msgstr "Elige el juego:" + +#: gui/launcher.cpp:830 +msgid "Do you really want to remove this game configuration?" +msgstr "¿Seguro que quieres eliminar la configuración de este juego?" + +#: gui/launcher.cpp:893 +msgid "This game does not support loading games from the launcher." +msgstr "Este juego no permite cargar partidas desde el lanzador." + +#: gui/launcher.cpp:897 +msgid "ScummVM could not find any engine capable of running the selected game!" +msgstr "¡ScummVM no ha podido encontrar ningún motor capaz de ejecutar el juego!" + +#: gui/launcher.cpp:1009 +msgid "Mass Add..." +msgstr "Añadir varios..." + +#: gui/launcher.cpp:1010 +msgid "Add Game..." +msgstr "Añadir juego..." + +#: gui/massadd.cpp:79 +#: gui/massadd.cpp:82 +msgid "... progress ..." +msgstr "... progreso..." + +#: gui/massadd.cpp:244 +msgid "Scan complete!" +msgstr "¡Búsqueda completada!" + +#: gui/massadd.cpp:247 +#, c-format +msgid "Discovered %d new games." +msgstr "Se han encontrado %d juegos nuevos." + +#: gui/massadd.cpp:251 +#, c-format +msgid "Scanned %d directories ..." +msgstr "Se ha buscado en %d directorios..." + +#: gui/massadd.cpp:254 +#, c-format +msgid "Discovered %d new games ..." +msgstr "Se han encontrado %d juegos nuevos..." + +#: gui/options.cpp:78 +msgid "Never" +msgstr "Nunca" + +#: gui/options.cpp:78 +msgid "every 5 mins" +msgstr "cada 5 minutos" + +#: gui/options.cpp:78 +msgid "every 10 mins" +msgstr "cada 10 minutos" + +#: gui/options.cpp:78 +msgid "every 15 mins" +msgstr "cada 15 minutos" + +#: gui/options.cpp:78 +msgid "every 30 mins" +msgstr "cada 30 minutos" + +#: gui/options.cpp:80 +msgid "8 kHz" +msgstr "8 kHz" + +#: gui/options.cpp:80 +msgid "11kHz" +msgstr "11kHz" + +#: gui/options.cpp:80 +msgid "22 kHz" +msgstr "22 kHz" + +#: gui/options.cpp:80 +msgid "44 kHz" +msgstr "44 kHz" + +#: gui/options.cpp:80 +msgid "48 kHz" +msgstr "48 kHz" + +#: gui/options.cpp:632 +msgid "Graphics mode:" +msgstr "Modo gráfico:" + +#: gui/options.cpp:643 +msgid "Render mode:" +msgstr "Modo de renderizado:" + +#: gui/options.cpp:643 +#: gui/options.cpp:644 +msgid "Special dithering modes supported by some games" +msgstr "Modos especiales de expansión soportados por algunos juegos" + +#: gui/options.cpp:653 +msgid "Fullscreen mode" +msgstr "Pantalla completa" + +#: gui/options.cpp:656 +msgid "Aspect ratio correction" +msgstr "Corrección de aspecto" + +#: gui/options.cpp:656 +msgid "Correct aspect ratio for 320x200 games" +msgstr "Corregir relación de aspecto en juegos 320x200" + +#: gui/options.cpp:663 +msgid "Preferred Device:" +msgstr "Dispositivo preferido:" + +#: gui/options.cpp:663 +msgid "Music Device:" +msgstr "Dispositivo de música:" + +#: gui/options.cpp:663 +msgid "Specifies preferred sound device or sound card emulator" +msgstr "Especifica qué dispositivo de sonido o emulador de tarjeta de sonido prefieres" + +#: gui/options.cpp:663 +#: gui/options.cpp:664 +msgid "Specifies output sound device or sound card emulator" +msgstr "Especifica el dispositivo de sonido o emulador de tarjeta de sonido de salida" + +#: gui/options.cpp:688 +msgid "AdLib emulator:" +msgstr "Emulador de AdLib:" + +#: gui/options.cpp:688 +#: gui/options.cpp:689 +msgid "AdLib is used for music in many games" +msgstr "AdLib se usa para la música en muchos juegos" + +#: gui/options.cpp:699 +msgid "Output rate:" +msgstr "Frecuencia de salida:" + +#: gui/options.cpp:699 +#: gui/options.cpp:700 +msgid "Higher value specifies better sound quality but may be not supported by your soundcard" +msgstr "Los valores más altos ofrecen mayor calidad, pero puede que tu tarjeta de sonido no sea compatible" + +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "Dispositivo GM:" + +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "Especifica el dispositivo de salida General MIDI por defecto" + +#: gui/options.cpp:731 +msgid "SoundFont:" +msgstr "SoundFont:" + +#: gui/options.cpp:731 +#: gui/options.cpp:732 +msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" +msgstr "Algunas tarjetas de sonido, Fluidsynth y Timidity soportan SoundFont" + +#: gui/options.cpp:736 +msgid "Mixed AdLib/MIDI mode" +msgstr "Modo AdLib/MIDI" + +#: gui/options.cpp:736 +msgid "Use both MIDI and AdLib sound generation" +msgstr "Usar tanto MIDI como AdLib en la generación de sonido" + +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "Ganancia MIDI:" + +#: gui/options.cpp:749 +msgid "MT-32 Device:" +msgstr "Dispositivo MT-32:" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "Especifica el dispositivo de sonido para la salida Roland MT-32/LAPC1/CM32l/CM64 por defecto" + +#: gui/options.cpp:753 +msgid "True Roland MT-32 (disable GM emulation)" +msgstr "Roland MT-32 auténtica (desactivar emulación GM)" + +#: gui/options.cpp:753 +msgid "Check if you want to use your real hardware Roland-compatible sound device connected to your computer" +msgstr "Marcar si se quiere usar un dispositivo de sonido real conectado al ordenador y compatible con Roland" + +#: gui/options.cpp:756 +msgid "Enable Roland GS Mode" +msgstr "Activar modo Roland GS" + +#: gui/options.cpp:756 +msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" +msgstr "Desactiva la conversión General MIDI en juegos con sonido Roland MT-32" + +#: gui/options.cpp:780 +msgid "Text and Speech:" +msgstr "Texto y voces:" + +#: gui/options.cpp:785 +#: gui/options.cpp:791 +msgid "Speech" +msgstr "Voces" + +#: gui/options.cpp:786 +#: gui/options.cpp:792 +msgid "Subtitles" +msgstr "Subtítulos" + +#: gui/options.cpp:787 +#: gui/options.cpp:793 +msgid "Both" +msgstr "Ambos" + +#: gui/options.cpp:791 +msgid "Spch" +msgstr "Voces" + +#: gui/options.cpp:792 +msgid "Subs" +msgstr "Subt." + +#: gui/options.cpp:793 +msgid "Show subtitles and play speech" +msgstr "Reproducir voces y subtítulos" + +#: gui/options.cpp:797 +msgid "Subtitle speed:" +msgstr "Velocidad de los subtítulos:" + +#: gui/options.cpp:809 +msgid "Music volume:" +msgstr "Volumen de la música:" + +#: gui/options.cpp:816 +msgid "Mute All" +msgstr "Silenciar" + +#: gui/options.cpp:819 +msgid "SFX volume:" +msgstr "Volumen de los efectos" + +#: gui/options.cpp:819 +#: gui/options.cpp:820 +msgid "Special sound effects volume" +msgstr "Volumen de los efectos de sonido" + +#: gui/options.cpp:826 +msgid "Speech volume:" +msgstr "Volumen de las voces" + +#: gui/options.cpp:952 +msgid "Save Path: " +msgstr "Partidas:" + +#: gui/options.cpp:955 +msgid "Theme Path:" +msgstr "Temas:" + +#: gui/options.cpp:958 +#: gui/options.cpp:959 +msgid "Specifies path to additional data used by all games or ScummVM" +msgstr "Especifica el directorio adicional usado por los juegos y ScummVM" + +#: gui/options.cpp:962 +msgid "Plugins Path:" +msgstr "Plugins:" + +#: gui/options.cpp:970 +msgid "Misc" +msgstr "Otros" + +#: gui/options.cpp:972 +msgid "Theme:" +msgstr "Tema:" + +#: gui/options.cpp:976 +msgid "GUI Renderer:" +msgstr "Render de la interfaz" + +#: gui/options.cpp:982 +msgid "Autosave:" +msgstr "Autoguardado:" + +#: gui/options.cpp:990 +msgid "Keys" +msgstr "Teclas" + +#: gui/options.cpp:997 +msgid "GUI Language:" +msgstr "Idioma de la interfaz:" + +#: gui/options.cpp:997 +msgid "Language of ScummVM GUI" +msgstr "Idioma de la interfaz de ScummVM" + +#: gui/options.cpp:1002 +msgid "English" +msgstr "Inglés" + +#: gui/options.cpp:1146 +msgid "You have to restart ScummVM to take the effect." +msgstr "Tienes que reiniciar ScummVM para aplicar los cambios." + +#: gui/options.cpp:1159 +msgid "Select directory for savegames" +msgstr "Selecciona el directorio para partidas guardadas." + +#: gui/options.cpp:1166 +msgid "The chosen directory cannot be written to. Please select another one." +msgstr "No se puede escribir en el directorio elegido. Por favor, selecciona otro." + +#: gui/options.cpp:1175 +msgid "Select directory for GUI themes" +msgstr "Selecciona el directorio para temas de interfaz" + +#: gui/options.cpp:1185 +msgid "Select directory for extra files" +msgstr "Selecciona el directorio para archivos adicionales" + +#: gui/options.cpp:1196 +msgid "Select directory for plugins" +msgstr "Selecciona el directorio para plugins" + +#: gui/saveload.cpp:60 +#: gui/saveload.cpp:241 +msgid "No date saved" +msgstr "No hay fecha guardada" + +#: gui/saveload.cpp:61 +#: gui/saveload.cpp:242 +msgid "No time saved" +msgstr "No hay hora guardada" + +#: gui/saveload.cpp:62 +#: gui/saveload.cpp:243 +msgid "No playtime saved" +msgstr "No hay tiempo de juego guardado" + +#: gui/saveload.cpp:69 +#: gui/saveload.cpp:157 +msgid "Delete" +msgstr "Borrar" + +#: gui/saveload.cpp:156 +msgid "Do you really want to delete this savegame?" +msgstr "¿Seguro que quieres borrar esta partida?" + +#: gui/saveload.cpp:265 +msgid "Date: " +msgstr "Fecha:" + +#: gui/saveload.cpp:268 +msgid "Time: " +msgstr "Hora:" + +#: gui/saveload.cpp:273 +msgid "Playtime: " +msgstr "Tiempo de juego:" + +#: gui/saveload.cpp:286 +#: gui/saveload.cpp:353 +msgid "Untitled savestate" +msgstr "Partida sin nombre" + +#: gui/themebrowser.cpp:46 +msgid "Select a Theme" +msgstr "Selecciona un tema" + +#: gui/ThemeEngine.cpp:334 +msgid "Disabled GFX" +msgstr "GFX desactivados" + +#: gui/ThemeEngine.cpp:335 +msgid "Standard Renderer (16bpp)" +msgstr "Estándar (16bpp)" + +#: gui/ThemeEngine.cpp:337 +msgid "Antialiased Renderer (16bpp)" +msgstr "Antialiasing (16bpp)" + +#: base/main.cpp:205 +#, c-format +msgid "Engine does not support debug level '%s'" +msgstr "El motor no soporta el nivel de debug '%s'" + +#: base/main.cpp:273 +msgid "Menu" +msgstr "Menú" + +#: base/main.cpp:276 +#: backends/platform/symbian/src/SymbianActions.cpp:48 +#: backends/platform/wince/CEActionsPocket.cpp:44 +#: backends/platform/wince/CEActionsSmartphone.cpp:45 +msgid "Skip" +msgstr "Saltar" + +#: base/main.cpp:279 +#: backends/platform/symbian/src/SymbianActions.cpp:53 +#: backends/platform/wince/CEActionsPocket.cpp:41 +msgid "Pause" +msgstr "Pausar" + +#: base/main.cpp:282 +msgid "Skip line" +msgstr "Saltar frase" + +#: base/main.cpp:404 +msgid "Error running game:" +msgstr "Error al ejecutar el juego:" + +#: base/main.cpp:430 +#: base/main.cpp:431 +msgid "Could not find any engine capable of running the selected game" +msgstr "No se ha podido encontrar ningún motor capaz de ejecutar el juego" + +#: common/error.cpp:43 +msgid "Invalid Path" +msgstr "Ruta no válida" + +#: common/error.cpp:44 +msgid "Game Data not found" +msgstr "No se han encontrado datos de juego" + +#: common/error.cpp:45 +msgid "Game Id not supported" +msgstr "ID del juego no soportada" + +#: common/error.cpp:46 +msgid "Unsupported Color Mode" +msgstr "Modo de color no soportado" + +#: common/error.cpp:48 +msgid "Read permission denied" +msgstr "Permiso de lectura denegado" + +#: common/error.cpp:49 +msgid "Write permission denied" +msgstr "Permiso de escritura denegado" + +#: common/error.cpp:52 +msgid "Path not exists" +msgstr "La ruta no existe" + +#: common/error.cpp:53 +msgid "Path not a directory" +msgstr "La ruta no es un directorio" + +#: common/error.cpp:54 +msgid "Path not a file" +msgstr "La ruta no es un archivo" + +#: common/error.cpp:56 +msgid "Cannot create file" +msgstr "Imposible crear el archivo" + +#: common/error.cpp:57 +msgid "Reading failed" +msgstr "Lectura fallida" + +#: common/error.cpp:58 +msgid "Writing data failed" +msgstr "Escritura de datos fallida" + +#: common/error.cpp:60 +#: common/error.cpp:71 +msgid "Unknown Error" +msgstr "Error desconocido" + +#: common/util.cpp:254 +msgid "Hercules Green" +msgstr "Hercules verde" + +#: common/util.cpp:255 +msgid "Hercules Amber" +msgstr "Hercules ámbar" + +#: engines/dialogs.cpp:89 +msgid "~R~esume" +msgstr "~R~eanudar" + +#: engines/dialogs.cpp:91 +msgid "~L~oad" +msgstr "~C~argar" + +#: engines/dialogs.cpp:95 +msgid "~S~ave" +msgstr "~G~uardar" + +#: engines/dialogs.cpp:99 +msgid "~O~ptions" +msgstr "~O~opciones" + +#: engines/dialogs.cpp:104 +msgid "~H~elp" +msgstr "~A~yuda" + +#: engines/dialogs.cpp:107 +msgid "~A~bout" +msgstr "Acerca ~d~e" + +#: engines/dialogs.cpp:109 +msgid "~R~eturn to Launcher" +msgstr "~V~olver al lanzador" + +#: engines/dialogs.cpp:119 +msgid "Save game:" +msgstr "Guardar partida" + +#: engines/dialogs.cpp:119 +#: backends/platform/symbian/src/SymbianActions.cpp:47 +#: backends/platform/wince/CEActionsPocket.cpp:42 +#: backends/platform/wince/CEActionsPocket.cpp:263 +#: backends/platform/wince/CEActionsSmartphone.cpp:44 +#: backends/platform/wince/CEActionsSmartphone.cpp:225 +msgid "Save" +msgstr "Guardar" + +#: engines/dialogs.cpp:301 +#: engines/mohawk/dialogs.cpp:84 +#: engines/mohawk/dialogs.cpp:118 +msgid "~O~K" +msgstr "~S~í" + +#: engines/dialogs.cpp:302 +#: engines/mohawk/dialogs.cpp:85 +#: engines/mohawk/dialogs.cpp:119 +msgid "~C~ancel" +msgstr "~C~ancelar" + +#: engines/dialogs.cpp:305 +msgid "~K~eys" +msgstr "~T~eclas" + +#: engines/scumm/dialogs.cpp:287 +msgid "~P~revious" +msgstr "~A~nterior" + +#: engines/scumm/dialogs.cpp:288 +msgid "~N~ext" +msgstr "Si~g~uiente" + +#: engines/scumm/dialogs.cpp:289 +#: backends/platform/ds/arm9/source/dsoptions.cpp:59 +msgid "~C~lose" +msgstr "Cerra~r~" + +#: engines/mohawk/dialogs.cpp:81 +#: engines/mohawk/dialogs.cpp:115 +msgid "~Z~ip Mode Activated" +msgstr "Modo ~Z~ip activado" + +#: engines/mohawk/dialogs.cpp:82 +msgid "~T~ransitions Enabled" +msgstr "Tra~n~siciones activadas" + +#: engines/mohawk/dialogs.cpp:116 +msgid "~W~ater Effect Enabled" +msgstr "Efecto ag~u~a activado" + +#: sound/fmopl.cpp:51 +msgid "MAME OPL emulator" +msgstr "Emulador de MAME OPL" + +#: sound/fmopl.cpp:53 +msgid "DOSBox OPL emulator" +msgstr "Emulador de DOSBox OPL" + +#: sound/null.h:45 +msgid "No music" +msgstr "Sin música" + +#: sound/softsynth/adlib.cpp:1590 +msgid "AdLib Emulator" +msgstr "Emulador de AdLib" + +#: sound/softsynth/mt32.cpp:327 +msgid "Initialising MT-32 Emulator" +msgstr "Iniciando emulador de MT-32" + +#: sound/softsynth/mt32.cpp:541 +msgid "MT-32 Emulator" +msgstr "Emulador de MT-32" + +#: sound/softsynth/pcspk.cpp:142 +msgid "PC Speaker Emulator" +msgstr "Emulador del altavoz de PC" + +#: sound/softsynth/pcspk.cpp:161 +msgid "IBM PCjr Emulator" +msgstr "Emulador de IBM PCjr" + +#: sound/softsynth/ym2612.cpp:762 +msgid "FM Towns Emulator" +msgstr "Emulador de FM Towns" + +#: backends/keymapper/remap-dialog.cpp:49 +msgid "Keymap:" +msgstr "Asignación de teclas:" + +#: backends/keymapper/remap-dialog.cpp:66 +msgid " (Active)" +msgstr "(Activa)" + +#: backends/keymapper/remap-dialog.cpp:100 +msgid " (Global)" +msgstr "(General)" + +#: backends/keymapper/remap-dialog.cpp:110 +msgid " (Game)" +msgstr "(Juego)" + +#: backends/midi/windows.cpp:157 +msgid "Windows MIDI" +msgstr "Windows MIDI" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:60 +msgid "ScummVM Main Menu" +msgstr "Menú principal de ScummVM" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:66 +msgid "~L~eft handed mode" +msgstr "Modo para ~z~urdos" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:67 +msgid "~I~ndy fight controls" +msgstr "Controles para pelear de ~I~ndy" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:68 +msgid "Show mouse cursor" +msgstr "Mostrar el cursor" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:69 +msgid "Snap to edges" +msgstr "Pegar a los bordes" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:71 +msgid "Touch X Offset" +msgstr "Compensación X del toque" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:78 +msgid "Touch Y Offset" +msgstr "Compensación Y del toque" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:90 +msgid "Use laptop trackpad-style cursor control" +msgstr "Activar el sistema de control tipo trackpad de los portátiles" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:91 +msgid "Tap for left click, double tap right click" +msgstr "Un toque para clic izquierdo, dos para clic derecho" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:93 +msgid "Sensitivity" +msgstr "Sensibilidad" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:102 +msgid "Initial top screen scale:" +msgstr "Escalado de la pantalla inicial superior:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:108 +msgid "Main screen scaling:" +msgstr "Escalado de la pantalla principal:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:110 +msgid "Hardware scale (fast, but low quality)" +msgstr "Escalado por hardware (rápido, pero de baja calidad)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:111 +msgid "Software scale (good quality, but slower)" +msgstr "Escalado por software (buena calidad, pero más lento)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:112 +msgid "Unscaled (you must scroll left and right)" +msgstr "Sin escalado (debes desplazar la pantalla a los lados)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:114 +msgid "Brightness:" +msgstr "Brillo:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:124 +msgid "High quality audio (slower) (reboot)" +msgstr "Sonido de alta calidad (más lento) (reinicio)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:125 +msgid "Disable power off" +msgstr "Desactivar apagado" + +#: backends/platform/iphone/osys_events.cpp:339 +msgid "Touchpad mode enabled." +msgstr "Modo Touchpad activado." + +#: backends/platform/iphone/osys_events.cpp:341 +msgid "Touchpad mode disabled." +msgstr "Modo Touchpad desactivado." + +#: backends/platform/sdl/graphics.cpp:40 +#: backends/platform/wince/wince-sdl.cpp:111 +#: backends/platform/wince/wince-sdl.cpp:118 +msgid "Normal (no scaling)" +msgstr "Normal (sin escalado)" + +#: backends/platform/symbian/src/SymbianActions.cpp:41 +#: backends/platform/wince/CEActionsSmartphone.cpp:38 +msgid "Up" +msgstr "Arriba" + +#: backends/platform/symbian/src/SymbianActions.cpp:42 +#: backends/platform/wince/CEActionsSmartphone.cpp:39 +msgid "Down" +msgstr "Abajo" + +#: backends/platform/symbian/src/SymbianActions.cpp:43 +#: backends/platform/wince/CEActionsSmartphone.cpp:40 +msgid "Left" +msgstr "Izquierda" + +#: backends/platform/symbian/src/SymbianActions.cpp:44 +#: backends/platform/wince/CEActionsSmartphone.cpp:41 +msgid "Right" +msgstr "Derecha" + +#: backends/platform/symbian/src/SymbianActions.cpp:45 +#: backends/platform/wince/CEActionsPocket.cpp:59 +#: backends/platform/wince/CEActionsSmartphone.cpp:42 +msgid "Left Click" +msgstr "Clic izquierdo" + +#: backends/platform/symbian/src/SymbianActions.cpp:46 +#: backends/platform/wince/CEActionsSmartphone.cpp:43 +msgid "Right Click" +msgstr "Clic derecho" + +#: backends/platform/symbian/src/SymbianActions.cpp:49 +#: backends/platform/wince/CEActionsSmartphone.cpp:46 +msgid "Zone" +msgstr "Zona" + +#: backends/platform/symbian/src/SymbianActions.cpp:50 +#: backends/platform/wince/CEActionsPocket.cpp:53 +#: backends/platform/wince/CEActionsSmartphone.cpp:47 +msgid "Multi Function" +msgstr "Multifunción" + +#: backends/platform/symbian/src/SymbianActions.cpp:51 +msgid "Swap character" +msgstr "Cambiar personaje" + +#: backends/platform/symbian/src/SymbianActions.cpp:52 +msgid "Skip text" +msgstr "Saltar texto" + +#: backends/platform/symbian/src/SymbianActions.cpp:54 +msgid "Fast mode" +msgstr "Modo rápido" + +#: backends/platform/symbian/src/SymbianActions.cpp:55 +#: backends/platform/wince/CEActionsPocket.cpp:43 +#: backends/platform/wince/CEActionsSmartphone.cpp:51 +msgid "Quit" +msgstr "Salir" + +#: backends/platform/symbian/src/SymbianActions.cpp:56 +msgid "Debugger" +msgstr "Debugger" + +#: backends/platform/symbian/src/SymbianActions.cpp:57 +msgid "Global menu" +msgstr "Menú general" + +#: backends/platform/symbian/src/SymbianActions.cpp:58 +msgid "Virtual keyboard" +msgstr "Teclado virtual" + +#: backends/platform/symbian/src/SymbianActions.cpp:59 +msgid "Key mapper" +msgstr "Asignación de teclas" + +#: backends/platform/symbian/src/SymbianOS.cpp:446 +msgid "Do you want to quit ?" +msgstr "¿Quieres salir?" + +#: backends/platform/wii/options.cpp:51 +msgid "Video" +msgstr "Vídeo" + +#: backends/platform/wii/options.cpp:54 +msgid "Current video mode:" +msgstr "Modo de vídeo actual:" + +#: backends/platform/wii/options.cpp:56 +msgid "Double-strike" +msgstr "Doble golpe" + +#: backends/platform/wii/options.cpp:60 +msgid "Horizontal underscan:" +msgstr "Underscan horizontal" + +#: backends/platform/wii/options.cpp:66 +msgid "Vertical underscan:" +msgstr "Underscan vertical:" + +#: backends/platform/wii/options.cpp:71 +msgid "Input" +msgstr "Entrada" + +#: backends/platform/wii/options.cpp:74 +msgid "GC Pad sensitivity:" +msgstr "Sensibilidad del pad GC:" + +#: backends/platform/wii/options.cpp:80 +msgid "GC Pad acceleration:" +msgstr "Aceleración del pad GC:" + +#: backends/platform/wii/options.cpp:86 +msgid "DVD" +msgstr "DVD" + +#: backends/platform/wii/options.cpp:89 +#: backends/platform/wii/options.cpp:101 +msgid "Status:" +msgstr "Estado:" + +#: backends/platform/wii/options.cpp:90 +#: backends/platform/wii/options.cpp:102 +msgid "Unknown" +msgstr "Desconocido" + +#: backends/platform/wii/options.cpp:93 +msgid "Mount DVD" +msgstr "Montar DVD" + +#: backends/platform/wii/options.cpp:94 +msgid "Unmount DVD" +msgstr "Desmontar DVD" + +#: backends/platform/wii/options.cpp:98 +msgid "SMB" +msgstr "SMB" + +#: backends/platform/wii/options.cpp:106 +msgid "Server:" +msgstr "Servidor:" + +#: backends/platform/wii/options.cpp:110 +msgid "Share:" +msgstr "Disco compartido:" + +#: backends/platform/wii/options.cpp:114 +msgid "Username:" +msgstr "Usuario:" + +#: backends/platform/wii/options.cpp:118 +msgid "Password:" +msgstr "Contraseña:" + +#: backends/platform/wii/options.cpp:121 +msgid "Init network" +msgstr "Inicializar red" + +#: backends/platform/wii/options.cpp:123 +msgid "Mount SMB" +msgstr "Montar SMB" + +#: backends/platform/wii/options.cpp:124 +msgid "Unmount SMB" +msgstr "Desmontar SMB" + +#: backends/platform/wii/options.cpp:145 +msgid "DVD Mounted successfully" +msgstr "DVD montado con éxito" + +#: backends/platform/wii/options.cpp:148 +msgid "Error while mounting the DVD" +msgstr "Error al montar el DVD" + +#: backends/platform/wii/options.cpp:150 +msgid "DVD not mounted" +msgstr "DVD no montado" + +#: backends/platform/wii/options.cpp:163 +msgid "Network up, share mounted" +msgstr "Red conectada, disco compartido montado" + +#: backends/platform/wii/options.cpp:165 +msgid "Network up" +msgstr "Red conectada" + +#: backends/platform/wii/options.cpp:168 +msgid ", error while mounting the share" +msgstr ", error al montar el disco compartido" + +#: backends/platform/wii/options.cpp:170 +msgid ", share not mounted" +msgstr ", disco compartido no montado" + +#: backends/platform/wii/options.cpp:176 +msgid "Network down" +msgstr "Red desconectada" + +#: backends/platform/wii/options.cpp:180 +msgid "Initialising network" +msgstr "Inicializando red" + +#: backends/platform/wii/options.cpp:184 +msgid "Timeout while initialising network" +msgstr "Se ha excedido el tiempo de inicialización de red" + +#: backends/platform/wii/options.cpp:188 +#, c-format +msgid "Network not initialsed (%d)" +msgstr "Red no inicializada (%d)" + +#: backends/platform/wince/CEActionsPocket.cpp:45 +msgid "Hide Toolbar" +msgstr "Ocultar barra de tareas" + +#: backends/platform/wince/CEActionsPocket.cpp:46 +msgid "Show Keyboard" +msgstr "Mostrar teclado" + +#: backends/platform/wince/CEActionsPocket.cpp:47 +msgid "Sound on/off" +msgstr "Sonido activado/desactivado" + +#: backends/platform/wince/CEActionsPocket.cpp:48 +msgid "Right click" +msgstr "Clic derecho" + +#: backends/platform/wince/CEActionsPocket.cpp:49 +msgid "Show/Hide Cursor" +msgstr "Mostrar/ocultar cursor" + +#: backends/platform/wince/CEActionsPocket.cpp:50 +msgid "Free look" +msgstr "Vista libre" + +#: backends/platform/wince/CEActionsPocket.cpp:51 +msgid "Zoom up" +msgstr "Aumentar zoom" + +#: backends/platform/wince/CEActionsPocket.cpp:52 +msgid "Zoom down" +msgstr "Disminuir zoom" + +#: backends/platform/wince/CEActionsPocket.cpp:54 +#: backends/platform/wince/CEActionsSmartphone.cpp:48 +msgid "Bind Keys" +msgstr "Asignar teclas" + +#: backends/platform/wince/CEActionsPocket.cpp:55 +msgid "Cursor Up" +msgstr "Arriba" + +#: backends/platform/wince/CEActionsPocket.cpp:56 +msgid "Cursor Down" +msgstr "Abajo" + +#: backends/platform/wince/CEActionsPocket.cpp:57 +msgid "Cursor Left" +msgstr "Izquierda" + +#: backends/platform/wince/CEActionsPocket.cpp:58 +msgid "Cursor Right" +msgstr "Derecha" + +#: backends/platform/wince/CEActionsPocket.cpp:263 +#: backends/platform/wince/CEActionsSmartphone.cpp:225 +msgid "Do you want to load or save the game?" +msgstr "¿Quieres cargar o guardar el juego?" + +#: backends/platform/wince/CEActionsPocket.cpp:313 +#: backends/platform/wince/CEActionsSmartphone.cpp:272 +msgid " Are you sure you want to quit ? " +msgstr "¿Seguro que quieres salir?" + +#: backends/platform/wince/CEActionsSmartphone.cpp:49 +msgid "Keyboard" +msgstr "Teclado" + +#: backends/platform/wince/CEActionsSmartphone.cpp:50 +msgid "Rotate" +msgstr "Rotar" + +#: backends/platform/wince/CELauncherDialog.cpp:58 +msgid "Using SDL driver " +msgstr "Usando driver SDL" + +#: backends/platform/wince/CELauncherDialog.cpp:62 +msgid "Display " +msgstr "Pantalla" + +#: backends/platform/wince/CELauncherDialog.cpp:104 +msgid "Do you want to perform an automatic scan ?" +msgstr "¿Quieres realizar una búsqueda automática?" + diff --git a/po/fr_FR.po b/po/fr_FR.po index d4e9e9f53c..51af254072 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 1.2.0svn\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" -"POT-Creation-Date: 2010-07-12 17:44+0200\n" -"PO-Revision-Date: 2010-07-09 18:17+0100\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" +"PO-Revision-Date: 2010-07-30 22:18+0100\n" "Last-Translator: Thierry Crozat <criezy@scummvm.org>\n" "Language-Team: French <scummvm-devel@lists.sf.net>\n" -"Language: Francais\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" +"Language: Francais\n" "Plural-Forms: nplurals=2; plural=n>1;\n" #: gui/about.cpp:96 @@ -38,30 +38,41 @@ msgstr "Remonter" msgid "Go to previous directory level" msgstr "Remonte d'un niveau dans la hiérarchie de répertoire" -#: gui/browser.cpp:70 gui/chooser.cpp:49 gui/KeysDialog.cpp:46 -#: gui/launcher.cpp:266 gui/massadd.cpp:95 gui/options.cpp:972 -#: gui/saveload.cpp:65 gui/saveload.cpp:157 gui/themebrowser.cpp:56 +#: gui/browser.cpp:70 +#: gui/chooser.cpp:49 +#: gui/KeysDialog.cpp:46 +#: gui/launcher.cpp:280 +#: gui/massadd.cpp:95 +#: gui/options.cpp:1029 +#: gui/saveload.cpp:65 +#: gui/saveload.cpp:157 +#: gui/themebrowser.cpp:56 #: backends/platform/wii/options.cpp:48 msgid "Cancel" msgstr "Annuler" -#: gui/browser.cpp:71 gui/chooser.cpp:50 gui/themebrowser.cpp:57 +#: gui/browser.cpp:71 +#: gui/chooser.cpp:50 +#: gui/themebrowser.cpp:57 msgid "Choose" msgstr "Choisir" -#: gui/GuiManager.cpp:102 backends/keymapper/remap-dialog.cpp:54 +#: gui/GuiManager.cpp:103 +#: backends/keymapper/remap-dialog.cpp:54 msgid "Close" msgstr "Fermer" -#: gui/GuiManager.cpp:105 +#: gui/GuiManager.cpp:106 msgid "Mouse click" msgstr "Clic de souris" -#: gui/GuiManager.cpp:108 base/main.cpp:285 +#: gui/GuiManager.cpp:109 +#: base/main.cpp:285 msgid "Display keyboard" msgstr "Afficher le clavier" -#: gui/GuiManager.cpp:111 base/main.cpp:288 +#: gui/GuiManager.cpp:112 +#: base/main.cpp:288 msgid "Remap keys" msgstr "Changer l'affectation des touches" @@ -69,8 +80,12 @@ msgstr "Changer l'affectation des touches" msgid "Map" msgstr "Affecter" -#: gui/KeysDialog.cpp:45 gui/launcher.cpp:267 gui/launcher.cpp:873 -#: gui/launcher.cpp:877 gui/massadd.cpp:92 gui/options.cpp:973 +#: gui/KeysDialog.cpp:45 +#: gui/launcher.cpp:281 +#: gui/launcher.cpp:893 +#: gui/launcher.cpp:897 +#: gui/massadd.cpp:92 +#: gui/options.cpp:1030 #: backends/platform/wii/options.cpp:47 #: backends/platform/wince/CELauncherDialog.cpp:56 msgid "OK" @@ -80,12 +95,16 @@ msgstr "OK" msgid "Select an action and click 'Map'" msgstr "Selectionez une action et cliquez 'Affecter'" -#: gui/KeysDialog.cpp:83 gui/KeysDialog.cpp:105 gui/KeysDialog.cpp:144 +#: gui/KeysDialog.cpp:83 +#: gui/KeysDialog.cpp:105 +#: gui/KeysDialog.cpp:144 #, c-format msgid "Associated key : %s" msgstr "Touche associée: %s" -#: gui/KeysDialog.cpp:85 gui/KeysDialog.cpp:107 gui/KeysDialog.cpp:146 +#: gui/KeysDialog.cpp:85 +#: gui/KeysDialog.cpp:107 +#: gui/KeysDialog.cpp:146 #, c-format msgid "Associated key : none" msgstr "Touche associée: aucune" @@ -102,248 +121,286 @@ msgstr "Appuyez sur la touche à associer" msgid "Choose an action to map" msgstr "Sélectionnez une action à affecter" -#: gui/launcher.cpp:170 +#: gui/launcher.cpp:172 msgid "Game" msgstr "Jeu" -#: gui/launcher.cpp:173 +#: gui/launcher.cpp:175 msgid "ID:" msgstr "ID:" -#: gui/launcher.cpp:173 gui/launcher.cpp:174 -msgid "" -"Short game identifier used for referring to savegames and running the game " -"from the command line" -msgstr "" -"ID compact du jeu utilisé pour identifier les sauvegardes et démarrer le jeu " -"depuis la ligne de commande" +#: gui/launcher.cpp:175 +#: gui/launcher.cpp:176 +msgid "Short game identifier used for referring to savegames and running the game from the command line" +msgstr "ID compact du jeu utilisé pour identifier les sauvegardes et démarrer le jeu depuis la ligne de commande" -#: gui/launcher.cpp:177 +#: gui/launcher.cpp:179 msgid "Name:" msgstr "Nom:" -#: gui/launcher.cpp:177 gui/launcher.cpp:178 +#: gui/launcher.cpp:179 +#: gui/launcher.cpp:180 msgid "Full title of the game" msgstr "Nom complet du jeu" -#: gui/launcher.cpp:181 +#: gui/launcher.cpp:183 msgid "Language:" msgstr "Langue:" -#: gui/launcher.cpp:181 gui/launcher.cpp:182 -msgid "" -"Language of the game. This will not turn your Spanish game version into " -"English" -msgstr "" -"Langue du jeu. Cela ne traduira pas en anglais par magie votre version " -"espagnole du jeu." +#: gui/launcher.cpp:183 +#: gui/launcher.cpp:184 +msgid "Language of the game. This will not turn your Spanish game version into English" +msgstr "Langue du jeu. Cela ne traduira pas en anglais par magie votre version espagnole du jeu." -#: gui/launcher.cpp:183 gui/launcher.cpp:194 gui/options.cpp:80 -#: gui/options.cpp:617 gui/options.cpp:627 gui/options.cpp:943 +#: gui/launcher.cpp:185 +#: gui/launcher.cpp:196 +#: gui/options.cpp:80 +#: gui/options.cpp:635 +#: gui/options.cpp:645 +#: gui/options.cpp:1000 #: sound/null.cpp:42 msgid "<default>" msgstr "<defaut>" -#: gui/launcher.cpp:192 +#: gui/launcher.cpp:194 msgid "Platform:" msgstr "Plateforme:" -#: gui/launcher.cpp:192 gui/launcher.cpp:193 +#: gui/launcher.cpp:194 +#: gui/launcher.cpp:195 msgid "Platform the game was originally designed for" msgstr "Plateforme pour laquelle votre jeu a été conçu" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 +#: gui/options.cpp:898 +#: gui/options.cpp:915 msgid "Graphics" msgstr "Graphique" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 +#: gui/options.cpp:898 +#: gui/options.cpp:915 msgid "GFX" msgstr "GFX" -#: gui/launcher.cpp:206 +#: gui/launcher.cpp:208 msgid "Override global graphic settings" msgstr "Utiliser des réglages graphiques spécifiques à ce jeux" -#: gui/launcher.cpp:213 gui/options.cpp:873 +#: gui/launcher.cpp:215 +#: gui/options.cpp:921 msgid "Audio" msgstr "Audio" -#: gui/launcher.cpp:215 +#: gui/launcher.cpp:217 msgid "Override global audio settings" msgstr "Utiliser des réglages audio spécifiques à ce jeux" -#: gui/launcher.cpp:223 gui/options.cpp:877 +#: gui/launcher.cpp:225 +#: gui/options.cpp:925 msgid "Volume" msgstr "Volume" -#: gui/launcher.cpp:225 +#: gui/launcher.cpp:227 msgid "Override global volume settings" msgstr "Utiliser des réglages de volume sonore spécifiques à ce jeux" -#: gui/launcher.cpp:232 gui/options.cpp:885 +#: gui/launcher.cpp:234 +#: gui/options.cpp:933 msgid "MIDI" msgstr "MIDI" -#: gui/launcher.cpp:234 +#: gui/launcher.cpp:236 msgid "Override global MIDI settings" msgstr "Utiliser des réglages MIDI spécifiques à ce jeux" -#: gui/launcher.cpp:244 gui/options.cpp:891 +#: gui/launcher.cpp:246 +#: gui/options.cpp:939 +msgid "MT-32" +msgstr "MT-32" + +#: gui/launcher.cpp:248 +msgid "Override global MT-32 settings" +msgstr "Utiliser des réglages MT-32 spécifiques à ce jeux" + +#: gui/launcher.cpp:258 +#: gui/options.cpp:945 msgid "Paths" msgstr "Chemins" -#: gui/launcher.cpp:250 +#: gui/launcher.cpp:264 msgid "Game Path:" msgstr "Chemin du Jeu:" -#: gui/launcher.cpp:254 gui/options.cpp:904 +#: gui/launcher.cpp:268 +#: gui/options.cpp:958 msgid "Extra Path:" msgstr "Extra:" -#: gui/launcher.cpp:254 gui/launcher.cpp:255 +#: gui/launcher.cpp:268 +#: gui/launcher.cpp:269 msgid "Specifies path to additional data used the game" msgstr "Définie un chemin vers des données suplémentaires utilisées par le jeu" -#: gui/launcher.cpp:258 +#: gui/launcher.cpp:272 msgid "Save Path:" msgstr "Sauvegardes:" -#: gui/launcher.cpp:258 gui/launcher.cpp:259 gui/options.cpp:898 -#: gui/options.cpp:899 +#: gui/launcher.cpp:272 +#: gui/launcher.cpp:273 +#: gui/options.cpp:952 +#: gui/options.cpp:953 msgid "Specifies where your savegames are put" msgstr "Définie l'emplacement où les fichiers de sauvegarde sont créés" -#: gui/launcher.cpp:275 gui/launcher.cpp:353 gui/launcher.cpp:398 -#: gui/options.cpp:245 gui/options.cpp:400 gui/options.cpp:486 -#: gui/options.cpp:545 gui/options.cpp:706 gui/options.cpp:902 -#: gui/options.cpp:905 gui/options.cpp:909 gui/options.cpp:996 -#: gui/options.cpp:1002 gui/options.cpp:1008 gui/options.cpp:1016 -#: gui/options.cpp:1040 gui/options.cpp:1044 gui/options.cpp:1050 -#: gui/options.cpp:1057 gui/options.cpp:1156 +#: gui/launcher.cpp:289 +#: gui/launcher.cpp:369 +#: gui/launcher.cpp:418 +#: gui/options.cpp:230 +#: gui/options.cpp:399 +#: gui/options.cpp:497 +#: gui/options.cpp:555 +#: gui/options.cpp:732 +#: gui/options.cpp:956 +#: gui/options.cpp:959 +#: gui/options.cpp:963 +#: gui/options.cpp:1053 +#: gui/options.cpp:1059 +#: gui/options.cpp:1065 +#: gui/options.cpp:1073 +#: gui/options.cpp:1097 +#: gui/options.cpp:1101 +#: gui/options.cpp:1107 +#: gui/options.cpp:1114 +#: gui/options.cpp:1213 msgid "None" msgstr "Aucun" -#: gui/launcher.cpp:280 gui/launcher.cpp:357 +#: gui/launcher.cpp:294 +#: gui/launcher.cpp:373 #: backends/platform/wii/options.cpp:56 msgid "Default" msgstr "Défaut" -#: gui/launcher.cpp:391 gui/options.cpp:1150 +#: gui/launcher.cpp:411 +#: gui/options.cpp:1207 msgid "Select SoundFont" msgstr "Choisir une banque de sons" -#: gui/launcher.cpp:410 gui/launcher.cpp:548 +#: gui/launcher.cpp:430 +#: gui/launcher.cpp:568 msgid "Select directory with game data" msgstr "Sélectionner le répertoire contenant les données du jeu" -#: gui/launcher.cpp:428 +#: gui/launcher.cpp:448 msgid "Select additional game directory" msgstr "Sélectionner un répertoire supplémentaire" -#: gui/launcher.cpp:440 +#: gui/launcher.cpp:460 msgid "Select directory for saved games" msgstr "Sélectionner le répertoire pour les sauvegardes" -#: gui/launcher.cpp:459 +#: gui/launcher.cpp:479 msgid "This game ID is already taken. Please choose another one." msgstr "Cet ID est déjà utilisé par un autre jeu. Choisissez en un autre svp." -#: gui/launcher.cpp:500 engines/dialogs.cpp:113 +#: gui/launcher.cpp:520 +#: engines/dialogs.cpp:113 msgid "~Q~uit" msgstr "~Q~uitter" -#: gui/launcher.cpp:500 +#: gui/launcher.cpp:520 msgid "Quit ScummVM" msgstr "Quitter ScummVM" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "A~b~out..." msgstr "À ~P~ropos..." -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "About ScummVM" msgstr "À propos de ScummVM" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "~O~ptions..." msgstr "~O~ptions..." -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "Change global ScummVM options" msgstr "Change les options globales de ScummVM" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "~S~tart" msgstr "~D~émarrer" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "Start selected game" msgstr "Démarre le jeu sélectionné" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "~L~oad..." msgstr "~C~harger" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "Load savegame for selected game" msgstr "Charge une sauvegarde pour le jeu sélectionné" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "~A~dd Game..." msgstr "~A~jouter..." -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "Hold Shift for Mass Add" -msgstr "" -"Ajoute un jeu à la Liste. Maintenez Shift enfoncée pour un Ajout Massif" +msgstr "Ajoute un jeu à la Liste. Maintenez Shift enfoncée pour un Ajout Massif" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "~E~dit Game..." msgstr "~E~diter..." -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "Change game options" msgstr "Change les options du jeu" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "~R~emove Game" msgstr "~S~upprimer" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "Remove game from the list. The game data files stay intact" msgstr "Supprime le jeu de la liste. Les fichiers sont conservés" -#: gui/launcher.cpp:522 +#: gui/launcher.cpp:542 msgid "Search in game list" msgstr "Recherche dans la liste de jeux" -#: gui/launcher.cpp:526 gui/launcher.cpp:1037 +#: gui/launcher.cpp:546 +#: gui/launcher.cpp:1057 msgid "Search:" msgstr "Filtre:" -#: gui/launcher.cpp:529 gui/options.cpp:707 +#: gui/launcher.cpp:549 +#: gui/options.cpp:733 msgid "Clear value" msgstr "Effacer la valeur" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 +#: engines/dialogs.cpp:117 msgid "Load game:" msgstr "Charger le jeu:" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 +#: engines/dialogs.cpp:117 #: backends/platform/wince/CEActionsPocket.cpp:263 #: backends/platform/wince/CEActionsSmartphone.cpp:225 msgid "Load" msgstr "Charger" -#: gui/launcher.cpp:660 -msgid "" -"Do you really want to run the mass game detector? This could potentially add " -"a huge number of games." -msgstr "" -"Voulez-vous vraiment lancer la détection automatique des jeux? Cela peut " -"potentiellement ajouter un grand nombre de jeux." +#: gui/launcher.cpp:680 +msgid "Do you really want to run the mass game detector? This could potentially add a huge number of games." +msgstr "Voulez-vous vraiment lancer la détection automatique des jeux? Cela peut potentiellement ajouter un grand nombre de jeux." -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 +#: gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -351,7 +408,8 @@ msgstr "" msgid "Yes" msgstr "Oui" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 +#: gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -359,40 +417,40 @@ msgstr "Oui" msgid "No" msgstr "Non" -#: gui/launcher.cpp:708 +#: gui/launcher.cpp:728 msgid "ScummVM couldn't open the specified directory!" msgstr "ScummVM n'a pas pu ouvrir le répertoire sélectionné." -#: gui/launcher.cpp:720 +#: gui/launcher.cpp:740 msgid "ScummVM could not find any game in the specified directory!" msgstr "ScummVM n'a pas trouvé de jeux dans le répertoire sélectionné." -#: gui/launcher.cpp:734 +#: gui/launcher.cpp:754 msgid "Pick the game:" msgstr "Choisissez le jeu:" -#: gui/launcher.cpp:810 +#: gui/launcher.cpp:830 msgid "Do you really want to remove this game configuration?" msgstr "Voulez-vous vraiment supprimer ce jeu?" -#: gui/launcher.cpp:873 +#: gui/launcher.cpp:893 msgid "This game does not support loading games from the launcher." -msgstr "" -"Le chargement de sauvegarde depuis le lanceur n'est pas supporté pour ce jeu." +msgstr "Le chargement de sauvegarde depuis le lanceur n'est pas supporté pour ce jeu." -#: gui/launcher.cpp:877 +#: gui/launcher.cpp:897 msgid "ScummVM could not find any engine capable of running the selected game!" msgstr "ScummVM n'a pas pu trouvé de moteur pour lancer le jeu sélectionné." -#: gui/launcher.cpp:989 +#: gui/launcher.cpp:1009 msgid "Mass Add..." msgstr "Ajout Massif..." -#: gui/launcher.cpp:990 +#: gui/launcher.cpp:1010 msgid "Add Game..." msgstr "Ajouter..." -#: gui/massadd.cpp:79 gui/massadd.cpp:82 +#: gui/massadd.cpp:79 +#: gui/massadd.cpp:82 msgid "... progress ..." msgstr "... en cours ..." @@ -455,271 +513,265 @@ msgstr "44 kHz" msgid "48 kHz" msgstr "48 kHz" -#: gui/options.cpp:614 +#: gui/options.cpp:632 msgid "Graphics mode:" msgstr "Mode graphique:" -#: gui/options.cpp:625 +#: gui/options.cpp:643 msgid "Render mode:" msgstr "Mode de rendu:" -#: gui/options.cpp:625 gui/options.cpp:626 +#: gui/options.cpp:643 +#: gui/options.cpp:644 msgid "Special dithering modes supported by some games" msgstr "Mode spécial de tramage supporté par certains jeux" -#: gui/options.cpp:635 +#: gui/options.cpp:653 msgid "Fullscreen mode" msgstr "Plein écran" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Aspect ratio correction" msgstr "Correction du rapport d'aspect" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Correct aspect ratio for 320x200 games" msgstr "Corrige le rapport d'aspect pour les jeu 320x200" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Preferred Device:" msgstr "Sortie Préféré:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Music Device:" msgstr "Sortie Audio:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Specifies preferred sound device or sound card emulator" -msgstr "" -"Spécifie le périphérique de sortie audio ou l'émulateur de carte audio " -"préféré" +msgstr "Spécifie le périphérique de sortie audio ou l'émulateur de carte audio préféré" -#: gui/options.cpp:645 gui/options.cpp:646 +#: gui/options.cpp:663 +#: gui/options.cpp:664 msgid "Specifies output sound device or sound card emulator" msgstr "Spécifie le périphérique de sortie audio ou l'émulateur de carte audio" -#: gui/options.cpp:648 -#, fuzzy -msgid "MT-32 Device:" -msgstr "Sortie MT-32:" - -#: gui/options.cpp:648 -msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" -msgstr "" -"Spécifie le périphérique audio par défaut pour la sortie Roland MT-32/LAPC1/" -"CM32l/CM64" - -#: gui/options.cpp:650 -msgid "GM Device:" -msgstr "Sortie GM:" - -#: gui/options.cpp:650 -msgid "Specifies default sound device for General MIDI output" -msgstr "Spécifie le périphérique audio par défaut pour la sortie General MIDI" - -#: gui/options.cpp:682 +#: gui/options.cpp:688 msgid "AdLib emulator:" msgstr "Émulateur AdLib:" -#: gui/options.cpp:682 gui/options.cpp:683 +#: gui/options.cpp:688 +#: gui/options.cpp:689 msgid "AdLib is used for music in many games" msgstr "AdLib est utilisé pour la musique dans de nombreux jeux" -#: gui/options.cpp:693 +#: gui/options.cpp:699 msgid "Output rate:" msgstr "Fréquence:" -#: gui/options.cpp:693 gui/options.cpp:694 -msgid "" -"Higher value specifies better sound quality but may be not supported by your " -"soundcard" -msgstr "" -"Une valeur plus élevée donne une meilleure qualité audio mais peut ne pas " -"être supporté par votre carte son" +#: gui/options.cpp:699 +#: gui/options.cpp:700 +msgid "Higher value specifies better sound quality but may be not supported by your soundcard" +msgstr "Une valeur plus élevée donne une meilleure qualité audio mais peut ne pas être supporté par votre carte son" + +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "Sortie GM:" -#: gui/options.cpp:705 +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "Spécifie le périphérique audio par défaut pour la sortie General MIDI" + +#: gui/options.cpp:731 msgid "SoundFont:" msgstr "Banque de sons:" -#: gui/options.cpp:705 gui/options.cpp:706 +#: gui/options.cpp:731 +#: gui/options.cpp:732 msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" -msgstr "" -"La banque de sons est utilisée par certaines cartes audio, Fluidsynth et " -"Timidity" +msgstr "La banque de sons est utilisée par certaines cartes audio, Fluidsynth et Timidity" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Mixed AdLib/MIDI mode" msgstr "Mode mixe AdLib/MIDI" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Use both MIDI and AdLib sound generation" msgstr "Utiliser à la fois MIDI et AdLib" -#: gui/options.cpp:713 +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "Gain MIDI:" + +#: gui/options.cpp:749 +msgid "MT-32 Device:" +msgstr "Sortie MT-32:" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "Spécifie le périphérique audio par défaut pour la sortie Roland MT-32/LAPC1/CM32l/CM64" + +#: gui/options.cpp:753 msgid "True Roland MT-32 (disable GM emulation)" msgstr "Roland MT-32 exacte (désactive l'émulation GM)" -#: gui/options.cpp:713 -msgid "" -"Check if you want to use your real hardware Roland-compatible sound device " -"connected to your computer" -msgstr "" -"Vérifie si vous voulez utiliser un périphérique audio compatible Roland " -"connecté à l'ordinateur" +#: gui/options.cpp:753 +msgid "Check if you want to use your real hardware Roland-compatible sound device connected to your computer" +msgstr "Vérifie si vous voulez utiliser un périphérique audio compatible Roland connecté à l'ordinateur" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Enable Roland GS Mode" msgstr "Activer le mode Roland GS" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" msgstr "Désactiver la conversion des pistes MT-32 en General MIDI" -#: gui/options.cpp:719 -msgid "MIDI gain:" -msgstr "Gain MIDI:" - -#: gui/options.cpp:732 +#: gui/options.cpp:780 msgid "Text and Speech:" msgstr "Dialogue:" -#: gui/options.cpp:737 gui/options.cpp:743 +#: gui/options.cpp:785 +#: gui/options.cpp:791 msgid "Speech" msgstr "Audio" -#: gui/options.cpp:738 gui/options.cpp:744 +#: gui/options.cpp:786 +#: gui/options.cpp:792 msgid "Subtitles" msgstr "Sous-titres" -#: gui/options.cpp:739 gui/options.cpp:745 +#: gui/options.cpp:787 +#: gui/options.cpp:793 msgid "Both" msgstr "Les deux" -#: gui/options.cpp:743 +#: gui/options.cpp:791 msgid "Spch" msgstr "Audio" -#: gui/options.cpp:744 +#: gui/options.cpp:792 msgid "Subs" msgstr "Subs" -#: gui/options.cpp:745 +#: gui/options.cpp:793 msgid "Show subtitles and play speech" msgstr "Affiche les sous-titres et joue les dialogues audio" -#: gui/options.cpp:749 +#: gui/options.cpp:797 msgid "Subtitle speed:" msgstr "Vitesse des ST:" -#: gui/options.cpp:761 +#: gui/options.cpp:809 msgid "Music volume:" msgstr "Volume Musique:" -#: gui/options.cpp:768 +#: gui/options.cpp:816 msgid "Mute All" msgstr "Silence" -#: gui/options.cpp:771 +#: gui/options.cpp:819 msgid "SFX volume:" msgstr "Volume Bruitage:" -#: gui/options.cpp:771 gui/options.cpp:772 +#: gui/options.cpp:819 +#: gui/options.cpp:820 msgid "Special sound effects volume" msgstr "Volume des effets spéciaux sonores" -#: gui/options.cpp:778 +#: gui/options.cpp:826 msgid "Speech volume:" msgstr "Volume Dialogues:" -#: gui/options.cpp:898 +#: gui/options.cpp:952 msgid "Save Path: " msgstr "Sauvegardes:" -#: gui/options.cpp:901 +#: gui/options.cpp:955 msgid "Theme Path:" msgstr "Thèmes:" -#: gui/options.cpp:904 gui/options.cpp:905 +#: gui/options.cpp:958 +#: gui/options.cpp:959 msgid "Specifies path to additional data used by all games or ScummVM" -msgstr "" -"Spécifie un chemin vers des données supplémentaires utilisées par tous les " -"jeux ou ScummVM" +msgstr "Spécifie un chemin vers des données supplémentaires utilisées par tous les jeux ou ScummVM" -#: gui/options.cpp:908 +#: gui/options.cpp:962 msgid "Plugins Path:" msgstr "Plugins:" -#: gui/options.cpp:913 +#: gui/options.cpp:970 msgid "Misc" msgstr "Divers" -#: gui/options.cpp:915 +#: gui/options.cpp:972 msgid "Theme:" msgstr "Thème:" -#: gui/options.cpp:919 +#: gui/options.cpp:976 msgid "GUI Renderer:" msgstr "Interface:" -#: gui/options.cpp:925 +#: gui/options.cpp:982 msgid "Autosave:" msgstr "Sauvegarde auto:" -#: gui/options.cpp:933 +#: gui/options.cpp:990 msgid "Keys" msgstr "Touches" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "GUI Language:" msgstr "Langue:" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "Language of ScummVM GUI" msgstr "Langue de l'interface graphique de ScummVM" -#: gui/options.cpp:945 +#: gui/options.cpp:1002 msgid "English" msgstr "Anglais" -#: gui/options.cpp:1089 +#: gui/options.cpp:1146 msgid "You have to restart ScummVM to take the effect." -msgstr "" -"Vous devez relancer ScummVM pour que le changement soit pris en compte." +msgstr "Vous devez relancer ScummVM pour que le changement soit pris en compte." -#: gui/options.cpp:1102 +#: gui/options.cpp:1159 msgid "Select directory for savegames" msgstr "Sélectionner le répertoire pour les sauvegardes" -#: gui/options.cpp:1109 +#: gui/options.cpp:1166 msgid "The chosen directory cannot be written to. Please select another one." -msgstr "" -"Le répertoire sélectionné est vérouillé en écriture. Sélectionnez un autre " -"répertoire." +msgstr "Le répertoire sélectionné est vérouillé en écriture. Sélectionnez un autre répertoire." -#: gui/options.cpp:1118 +#: gui/options.cpp:1175 msgid "Select directory for GUI themes" msgstr "Sélectionner le répertoire des thèmes d'interface" -#: gui/options.cpp:1128 +#: gui/options.cpp:1185 msgid "Select directory for extra files" msgstr "Sélectionner le répertoire pour les fichiers suplémentaires" -#: gui/options.cpp:1139 +#: gui/options.cpp:1196 msgid "Select directory for plugins" msgstr "Sélectionner le répertoire des plugins" -#: gui/saveload.cpp:60 gui/saveload.cpp:241 +#: gui/saveload.cpp:60 +#: gui/saveload.cpp:241 msgid "No date saved" msgstr "Date non sauvée" -#: gui/saveload.cpp:61 gui/saveload.cpp:242 +#: gui/saveload.cpp:61 +#: gui/saveload.cpp:242 msgid "No time saved" msgstr "Heure non sauvée" -#: gui/saveload.cpp:62 gui/saveload.cpp:243 +#: gui/saveload.cpp:62 +#: gui/saveload.cpp:243 msgid "No playtime saved" msgstr "Durée de jeu non sauvée" -#: gui/saveload.cpp:69 gui/saveload.cpp:157 +#: gui/saveload.cpp:69 +#: gui/saveload.cpp:157 msgid "Delete" msgstr "Supprimer" @@ -739,7 +791,8 @@ msgstr "Heure:" msgid "Playtime: " msgstr "Durée de jeu:" -#: gui/saveload.cpp:286 gui/saveload.cpp:353 +#: gui/saveload.cpp:286 +#: gui/saveload.cpp:353 msgid "Untitled savestate" msgstr "Sauvegarde sans nom" @@ -747,15 +800,15 @@ msgstr "Sauvegarde sans nom" msgid "Select a Theme" msgstr "Sélectionnez un Thème" -#: gui/ThemeEngine.cpp:337 +#: gui/ThemeEngine.cpp:334 msgid "Disabled GFX" msgstr "GFX désactivé" -#: gui/ThemeEngine.cpp:338 +#: gui/ThemeEngine.cpp:335 msgid "Standard Renderer (16bpp)" msgstr "Standard (16bpp)" -#: gui/ThemeEngine.cpp:340 +#: gui/ThemeEngine.cpp:337 msgid "Antialiased Renderer (16bpp)" msgstr "Anti-crénelé (16 bpp)" @@ -768,13 +821,15 @@ msgstr "Le niveau de debug '%s' n'est pas supporté par ce moteur de jeu" msgid "Menu" msgstr "Menu" -#: base/main.cpp:276 backends/platform/symbian/src/SymbianActions.cpp:48 +#: base/main.cpp:276 +#: backends/platform/symbian/src/SymbianActions.cpp:48 #: backends/platform/wince/CEActionsPocket.cpp:44 #: backends/platform/wince/CEActionsSmartphone.cpp:45 msgid "Skip" msgstr "Passer" -#: base/main.cpp:279 backends/platform/symbian/src/SymbianActions.cpp:53 +#: base/main.cpp:279 +#: backends/platform/symbian/src/SymbianActions.cpp:53 #: backends/platform/wince/CEActionsPocket.cpp:41 msgid "Pause" msgstr "Mettre en pause" @@ -787,7 +842,8 @@ msgstr "Passer la phrase" msgid "Error running game:" msgstr "Erreur lors de l'éxécution du jeu:" -#: base/main.cpp:430 base/main.cpp:431 +#: base/main.cpp:430 +#: base/main.cpp:431 msgid "Could not find any engine capable of running the selected game" msgstr "Impossible de trouver un moteur pour exécuter le jeu sélectionné" @@ -839,7 +895,8 @@ msgstr "Echec de la lecture" msgid "Writing data failed" msgstr "Echec de l'écriture des données" -#: common/error.cpp:60 common/error.cpp:71 +#: common/error.cpp:60 +#: common/error.cpp:71 msgid "Unknown Error" msgstr "Erreur inconnue" @@ -883,7 +940,8 @@ msgstr "Retour au ~L~anceur" msgid "Save game:" msgstr "Sauvegarde:" -#: engines/dialogs.cpp:119 backends/platform/symbian/src/SymbianActions.cpp:47 +#: engines/dialogs.cpp:119 +#: backends/platform/symbian/src/SymbianActions.cpp:47 #: backends/platform/wince/CEActionsPocket.cpp:42 #: backends/platform/wince/CEActionsPocket.cpp:263 #: backends/platform/wince/CEActionsSmartphone.cpp:44 @@ -891,12 +949,14 @@ msgstr "Sauvegarde:" msgid "Save" msgstr "Sauver" -#: engines/dialogs.cpp:301 engines/mohawk/dialogs.cpp:84 +#: engines/dialogs.cpp:301 +#: engines/mohawk/dialogs.cpp:84 #: engines/mohawk/dialogs.cpp:118 msgid "~O~K" msgstr "~O~K" -#: engines/dialogs.cpp:302 engines/mohawk/dialogs.cpp:85 +#: engines/dialogs.cpp:302 +#: engines/mohawk/dialogs.cpp:85 #: engines/mohawk/dialogs.cpp:119 msgid "~C~ancel" msgstr "~A~nnuler" @@ -918,7 +978,8 @@ msgstr "~S~uivant" msgid "~C~lose" msgstr "~F~ermer" -#: engines/mohawk/dialogs.cpp:81 engines/mohawk/dialogs.cpp:115 +#: engines/mohawk/dialogs.cpp:81 +#: engines/mohawk/dialogs.cpp:115 msgid "~Z~ip Mode Activated" msgstr "Mode ~Z~ip Activé" @@ -1190,11 +1251,13 @@ msgstr "Acceleration du pad GC:" msgid "DVD" msgstr "DVD" -#: backends/platform/wii/options.cpp:89 backends/platform/wii/options.cpp:101 +#: backends/platform/wii/options.cpp:89 +#: backends/platform/wii/options.cpp:101 msgid "Status:" msgstr "Status:" -#: backends/platform/wii/options.cpp:90 backends/platform/wii/options.cpp:102 +#: backends/platform/wii/options.cpp:90 +#: backends/platform/wii/options.cpp:102 msgid "Unknown" msgstr "Inconue" @@ -1404,8 +1467,8 @@ msgstr "Voulez-vous exécuter une recherche automatique?" #~ msgid "%s failed to instantiate engine: %s (target '%s', path '%s')" #~ msgstr "" -#~ "Le plugin %s a échoué dans l'instanciation du moteur de jeu: %s (cible " -#~ "'%s', chemin '%s')" +#~ "Le plugin %s a échoué dans l'instanciation du moteur de jeu: %s (cible '%" +#~ "s', chemin '%s')" #~ msgid "Ok" #~ msgstr "Ok" diff --git a/po/hu_HU.po b/po/hu_HU.po index 1d9a6c3268..8478f2ffaa 100644 --- a/po/hu_HU.po +++ b/po/hu_HU.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM VERSION\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" -"POT-Creation-Date: 2010-07-12 17:44+0200\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" "PO-Revision-Date: 2009-11-25 07:42-0500\n" "Last-Translator: Alex Bevilacqua <alexbevi@gmail.com>\n" "Language-Team: Hungarian\n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=cp1250\n" "Content-Transfer-Encoding: 8bit\n" +"Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: gui/about.cpp:96 @@ -39,7 +39,7 @@ msgid "Go to previous directory level" msgstr "" #: gui/browser.cpp:70 gui/chooser.cpp:49 gui/KeysDialog.cpp:46 -#: gui/launcher.cpp:266 gui/massadd.cpp:95 gui/options.cpp:972 +#: gui/launcher.cpp:280 gui/massadd.cpp:95 gui/options.cpp:1029 #: gui/saveload.cpp:65 gui/saveload.cpp:157 gui/themebrowser.cpp:56 #: backends/platform/wii/options.cpp:48 msgid "Cancel" @@ -49,19 +49,19 @@ msgstr "" msgid "Choose" msgstr "" -#: gui/GuiManager.cpp:102 backends/keymapper/remap-dialog.cpp:54 +#: gui/GuiManager.cpp:103 backends/keymapper/remap-dialog.cpp:54 msgid "Close" msgstr "" -#: gui/GuiManager.cpp:105 +#: gui/GuiManager.cpp:106 msgid "Mouse click" msgstr "" -#: gui/GuiManager.cpp:108 base/main.cpp:285 +#: gui/GuiManager.cpp:109 base/main.cpp:285 msgid "Display keyboard" msgstr "" -#: gui/GuiManager.cpp:111 base/main.cpp:288 +#: gui/GuiManager.cpp:112 base/main.cpp:288 msgid "Remap keys" msgstr "" @@ -69,8 +69,8 @@ msgstr "" msgid "Map" msgstr "" -#: gui/KeysDialog.cpp:45 gui/launcher.cpp:267 gui/launcher.cpp:873 -#: gui/launcher.cpp:877 gui/massadd.cpp:92 gui/options.cpp:973 +#: gui/KeysDialog.cpp:45 gui/launcher.cpp:281 gui/launcher.cpp:893 +#: gui/launcher.cpp:897 gui/massadd.cpp:92 gui/options.cpp:1030 #: backends/platform/wii/options.cpp:47 #: backends/platform/wince/CELauncherDialog.cpp:56 msgid "OK" @@ -102,244 +102,252 @@ msgstr "" msgid "Choose an action to map" msgstr "" -#: gui/launcher.cpp:170 +#: gui/launcher.cpp:172 msgid "Game" msgstr "" -#: gui/launcher.cpp:173 +#: gui/launcher.cpp:175 msgid "ID:" msgstr "" -#: gui/launcher.cpp:173 gui/launcher.cpp:174 +#: gui/launcher.cpp:175 gui/launcher.cpp:176 msgid "" "Short game identifier used for referring to savegames and running the game " "from the command line" msgstr "" -#: gui/launcher.cpp:177 +#: gui/launcher.cpp:179 msgid "Name:" msgstr "" -#: gui/launcher.cpp:177 gui/launcher.cpp:178 +#: gui/launcher.cpp:179 gui/launcher.cpp:180 msgid "Full title of the game" msgstr "" -#: gui/launcher.cpp:181 +#: gui/launcher.cpp:183 msgid "Language:" msgstr "" -#: gui/launcher.cpp:181 gui/launcher.cpp:182 +#: gui/launcher.cpp:183 gui/launcher.cpp:184 msgid "" "Language of the game. This will not turn your Spanish game version into " "English" msgstr "" -#: gui/launcher.cpp:183 gui/launcher.cpp:194 gui/options.cpp:80 -#: gui/options.cpp:617 gui/options.cpp:627 gui/options.cpp:943 +#: gui/launcher.cpp:185 gui/launcher.cpp:196 gui/options.cpp:80 +#: gui/options.cpp:635 gui/options.cpp:645 gui/options.cpp:1000 #: sound/null.cpp:42 msgid "<default>" msgstr "<alapértelmezett>" -#: gui/launcher.cpp:192 +#: gui/launcher.cpp:194 msgid "Platform:" msgstr "" -#: gui/launcher.cpp:192 gui/launcher.cpp:193 +#: gui/launcher.cpp:194 gui/launcher.cpp:195 msgid "Platform the game was originally designed for" msgstr "" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "Graphics" msgstr "Grafikával" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "GFX" msgstr "" -#: gui/launcher.cpp:206 +#: gui/launcher.cpp:208 msgid "Override global graphic settings" msgstr "" -#: gui/launcher.cpp:213 gui/options.cpp:873 +#: gui/launcher.cpp:215 gui/options.cpp:921 msgid "Audio" msgstr "Hang" -#: gui/launcher.cpp:215 +#: gui/launcher.cpp:217 msgid "Override global audio settings" msgstr "" -#: gui/launcher.cpp:223 gui/options.cpp:877 +#: gui/launcher.cpp:225 gui/options.cpp:925 msgid "Volume" msgstr "Volumene" -#: gui/launcher.cpp:225 +#: gui/launcher.cpp:227 msgid "Override global volume settings" msgstr "" -#: gui/launcher.cpp:232 gui/options.cpp:885 +#: gui/launcher.cpp:234 gui/options.cpp:933 msgid "MIDI" msgstr "" -#: gui/launcher.cpp:234 +#: gui/launcher.cpp:236 msgid "Override global MIDI settings" msgstr "" -#: gui/launcher.cpp:244 gui/options.cpp:891 +#: gui/launcher.cpp:246 gui/options.cpp:939 +msgid "MT-32" +msgstr "" + +#: gui/launcher.cpp:248 +msgid "Override global MT-32 settings" +msgstr "" + +#: gui/launcher.cpp:258 gui/options.cpp:945 msgid "Paths" msgstr "Ösvények" -#: gui/launcher.cpp:250 +#: gui/launcher.cpp:264 #, fuzzy msgid "Game Path:" msgstr "Extra Útvonal:" -#: gui/launcher.cpp:254 gui/options.cpp:904 +#: gui/launcher.cpp:268 gui/options.cpp:958 msgid "Extra Path:" msgstr "Extra Útvonal:" -#: gui/launcher.cpp:254 gui/launcher.cpp:255 +#: gui/launcher.cpp:268 gui/launcher.cpp:269 msgid "Specifies path to additional data used the game" msgstr "" -#: gui/launcher.cpp:258 +#: gui/launcher.cpp:272 #, fuzzy msgid "Save Path:" msgstr "Extra Útvonal:" -#: gui/launcher.cpp:258 gui/launcher.cpp:259 gui/options.cpp:898 -#: gui/options.cpp:899 +#: gui/launcher.cpp:272 gui/launcher.cpp:273 gui/options.cpp:952 +#: gui/options.cpp:953 msgid "Specifies where your savegames are put" msgstr "" -#: gui/launcher.cpp:275 gui/launcher.cpp:353 gui/launcher.cpp:398 -#: gui/options.cpp:245 gui/options.cpp:400 gui/options.cpp:486 -#: gui/options.cpp:545 gui/options.cpp:706 gui/options.cpp:902 -#: gui/options.cpp:905 gui/options.cpp:909 gui/options.cpp:996 -#: gui/options.cpp:1002 gui/options.cpp:1008 gui/options.cpp:1016 -#: gui/options.cpp:1040 gui/options.cpp:1044 gui/options.cpp:1050 -#: gui/options.cpp:1057 gui/options.cpp:1156 +#: gui/launcher.cpp:289 gui/launcher.cpp:369 gui/launcher.cpp:418 +#: gui/options.cpp:230 gui/options.cpp:399 gui/options.cpp:497 +#: gui/options.cpp:555 gui/options.cpp:732 gui/options.cpp:956 +#: gui/options.cpp:959 gui/options.cpp:963 gui/options.cpp:1053 +#: gui/options.cpp:1059 gui/options.cpp:1065 gui/options.cpp:1073 +#: gui/options.cpp:1097 gui/options.cpp:1101 gui/options.cpp:1107 +#: gui/options.cpp:1114 gui/options.cpp:1213 msgid "None" msgstr "Semmi" -#: gui/launcher.cpp:280 gui/launcher.cpp:357 +#: gui/launcher.cpp:294 gui/launcher.cpp:373 #: backends/platform/wii/options.cpp:56 #, fuzzy msgid "Default" msgstr "<alapértelmezett>" -#: gui/launcher.cpp:391 gui/options.cpp:1150 +#: gui/launcher.cpp:411 gui/options.cpp:1207 msgid "Select SoundFont" msgstr "" -#: gui/launcher.cpp:410 gui/launcher.cpp:548 +#: gui/launcher.cpp:430 gui/launcher.cpp:568 msgid "Select directory with game data" msgstr "" -#: gui/launcher.cpp:428 +#: gui/launcher.cpp:448 msgid "Select additional game directory" msgstr "" -#: gui/launcher.cpp:440 +#: gui/launcher.cpp:460 msgid "Select directory for saved games" msgstr "" -#: gui/launcher.cpp:459 +#: gui/launcher.cpp:479 msgid "This game ID is already taken. Please choose another one." msgstr "" -#: gui/launcher.cpp:500 engines/dialogs.cpp:113 +#: gui/launcher.cpp:520 engines/dialogs.cpp:113 msgid "~Q~uit" msgstr "" -#: gui/launcher.cpp:500 +#: gui/launcher.cpp:520 msgid "Quit ScummVM" msgstr "" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "A~b~out..." msgstr "" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "About ScummVM" msgstr "" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "~O~ptions..." msgstr "" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "Change global ScummVM options" msgstr "" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "~S~tart" msgstr "" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "Start selected game" msgstr "" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "~L~oad..." msgstr "" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "Load savegame for selected game" msgstr "" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "~A~dd Game..." msgstr "" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "Hold Shift for Mass Add" msgstr "" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "~E~dit Game..." msgstr "" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "Change game options" msgstr "" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "~R~emove Game" msgstr "" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "Remove game from the list. The game data files stay intact" msgstr "" -#: gui/launcher.cpp:522 +#: gui/launcher.cpp:542 msgid "Search in game list" msgstr "" -#: gui/launcher.cpp:526 gui/launcher.cpp:1037 +#: gui/launcher.cpp:546 gui/launcher.cpp:1057 msgid "Search:" msgstr "" -#: gui/launcher.cpp:529 gui/options.cpp:707 +#: gui/launcher.cpp:549 gui/options.cpp:733 msgid "Clear value" msgstr "" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 msgid "Load game:" msgstr "" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 #: backends/platform/wince/CEActionsPocket.cpp:263 #: backends/platform/wince/CEActionsSmartphone.cpp:225 msgid "Load" msgstr "" -#: gui/launcher.cpp:660 +#: gui/launcher.cpp:680 msgid "" "Do you really want to run the mass game detector? This could potentially add " "a huge number of games." msgstr "" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -347,7 +355,7 @@ msgstr "" msgid "Yes" msgstr "" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -356,35 +364,35 @@ msgstr "" msgid "No" msgstr "Semmi" -#: gui/launcher.cpp:708 +#: gui/launcher.cpp:728 msgid "ScummVM couldn't open the specified directory!" msgstr "" -#: gui/launcher.cpp:720 +#: gui/launcher.cpp:740 msgid "ScummVM could not find any game in the specified directory!" msgstr "" -#: gui/launcher.cpp:734 +#: gui/launcher.cpp:754 msgid "Pick the game:" msgstr "" -#: gui/launcher.cpp:810 +#: gui/launcher.cpp:830 msgid "Do you really want to remove this game configuration?" msgstr "" -#: gui/launcher.cpp:873 +#: gui/launcher.cpp:893 msgid "This game does not support loading games from the launcher." msgstr "" -#: gui/launcher.cpp:877 +#: gui/launcher.cpp:897 msgid "ScummVM could not find any engine capable of running the selected game!" msgstr "" -#: gui/launcher.cpp:989 +#: gui/launcher.cpp:1009 msgid "Mass Add..." msgstr "" -#: gui/launcher.cpp:990 +#: gui/launcher.cpp:1010 msgid "Add Game..." msgstr "" @@ -451,243 +459,243 @@ msgstr "" msgid "48 kHz" msgstr "" -#: gui/options.cpp:614 +#: gui/options.cpp:632 msgid "Graphics mode:" msgstr "Grafikus mód:" -#: gui/options.cpp:625 +#: gui/options.cpp:643 msgid "Render mode:" msgstr "Renderelési mód:" -#: gui/options.cpp:625 gui/options.cpp:626 +#: gui/options.cpp:643 gui/options.cpp:644 msgid "Special dithering modes supported by some games" msgstr "" -#: gui/options.cpp:635 +#: gui/options.cpp:653 msgid "Fullscreen mode" msgstr "Teljes képerny s mód:" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Aspect ratio correction" msgstr "Aspect adag korrekció" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Correct aspect ratio for 320x200 games" msgstr "" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Preferred Device:" msgstr "" -#: gui/options.cpp:645 +#: gui/options.cpp:663 #, fuzzy msgid "Music Device:" msgstr "Zene mennyiség:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Specifies preferred sound device or sound card emulator" msgstr "" -#: gui/options.cpp:645 gui/options.cpp:646 +#: gui/options.cpp:663 gui/options.cpp:664 msgid "Specifies output sound device or sound card emulator" msgstr "" -#: gui/options.cpp:648 -#, fuzzy -msgid "MT-32 Device:" -msgstr "Zene mennyiség:" - -#: gui/options.cpp:648 -msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" -msgstr "" - -#: gui/options.cpp:650 -msgid "GM Device:" -msgstr "" - -#: gui/options.cpp:650 -msgid "Specifies default sound device for General MIDI output" -msgstr "" - -#: gui/options.cpp:682 +#: gui/options.cpp:688 msgid "AdLib emulator:" msgstr "AdLib vezet :" -#: gui/options.cpp:682 gui/options.cpp:683 +#: gui/options.cpp:688 gui/options.cpp:689 msgid "AdLib is used for music in many games" msgstr "" -#: gui/options.cpp:693 +#: gui/options.cpp:699 msgid "Output rate:" msgstr "Kimeneti teljesítmény:" -#: gui/options.cpp:693 gui/options.cpp:694 +#: gui/options.cpp:699 gui/options.cpp:700 msgid "" "Higher value specifies better sound quality but may be not supported by your " "soundcard" msgstr "" -#: gui/options.cpp:705 +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "" + +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "" + +#: gui/options.cpp:731 msgid "SoundFont:" msgstr "" -#: gui/options.cpp:705 gui/options.cpp:706 +#: gui/options.cpp:731 gui/options.cpp:732 msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" msgstr "" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Mixed AdLib/MIDI mode" msgstr "Vegyes AdLib/MIDI mód" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Use both MIDI and AdLib sound generation" msgstr "" -#: gui/options.cpp:713 +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "MIDI nyereség:" + +#: gui/options.cpp:749 +#, fuzzy +msgid "MT-32 Device:" +msgstr "Zene mennyiség:" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "" + +#: gui/options.cpp:753 msgid "True Roland MT-32 (disable GM emulation)" msgstr "Igaz Roland MT-32 (megbénít GM emuláció)" -#: gui/options.cpp:713 +#: gui/options.cpp:753 msgid "" "Check if you want to use your real hardware Roland-compatible sound device " "connected to your computer" msgstr "" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Enable Roland GS Mode" msgstr "Képessé Roland GS Mode" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" msgstr "" -#: gui/options.cpp:719 -msgid "MIDI gain:" -msgstr "MIDI nyereség:" - -#: gui/options.cpp:732 +#: gui/options.cpp:780 msgid "Text and Speech:" msgstr "Szöveg és beszéd:" -#: gui/options.cpp:737 gui/options.cpp:743 +#: gui/options.cpp:785 gui/options.cpp:791 #, fuzzy msgid "Speech" msgstr "Csak a beszéd" -#: gui/options.cpp:738 gui/options.cpp:744 +#: gui/options.cpp:786 gui/options.cpp:792 #, fuzzy msgid "Subtitles" msgstr "Csak feliratok" -#: gui/options.cpp:739 gui/options.cpp:745 +#: gui/options.cpp:787 gui/options.cpp:793 msgid "Both" msgstr "" -#: gui/options.cpp:743 +#: gui/options.cpp:791 msgid "Spch" msgstr "" -#: gui/options.cpp:744 +#: gui/options.cpp:792 msgid "Subs" msgstr "" -#: gui/options.cpp:745 +#: gui/options.cpp:793 msgid "Show subtitles and play speech" msgstr "" -#: gui/options.cpp:749 +#: gui/options.cpp:797 msgid "Subtitle speed:" msgstr "Felirat sebesség:" -#: gui/options.cpp:761 +#: gui/options.cpp:809 msgid "Music volume:" msgstr "Zene mennyiség:" -#: gui/options.cpp:768 +#: gui/options.cpp:816 msgid "Mute All" msgstr "Muta Összes" -#: gui/options.cpp:771 +#: gui/options.cpp:819 msgid "SFX volume:" msgstr "SFX mennyisége" -#: gui/options.cpp:771 gui/options.cpp:772 +#: gui/options.cpp:819 gui/options.cpp:820 msgid "Special sound effects volume" msgstr "" -#: gui/options.cpp:778 +#: gui/options.cpp:826 msgid "Speech volume:" msgstr "Beszéd mennyiség:" -#: gui/options.cpp:898 +#: gui/options.cpp:952 msgid "Save Path: " msgstr "" -#: gui/options.cpp:901 +#: gui/options.cpp:955 msgid "Theme Path:" msgstr "" -#: gui/options.cpp:904 gui/options.cpp:905 +#: gui/options.cpp:958 gui/options.cpp:959 msgid "Specifies path to additional data used by all games or ScummVM" msgstr "" -#: gui/options.cpp:908 +#: gui/options.cpp:962 msgid "Plugins Path:" msgstr "" -#: gui/options.cpp:913 +#: gui/options.cpp:970 msgid "Misc" msgstr "" -#: gui/options.cpp:915 +#: gui/options.cpp:972 msgid "Theme:" msgstr "Téma:" -#: gui/options.cpp:919 +#: gui/options.cpp:976 msgid "GUI Renderer:" msgstr "Leképez eszköz GUI:" -#: gui/options.cpp:925 +#: gui/options.cpp:982 msgid "Autosave:" msgstr "Automatikus mentés:" -#: gui/options.cpp:933 +#: gui/options.cpp:990 msgid "Keys" msgstr "Kulcsok" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "GUI Language:" msgstr "" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "Language of ScummVM GUI" msgstr "" -#: gui/options.cpp:945 +#: gui/options.cpp:1002 msgid "English" msgstr "" -#: gui/options.cpp:1089 +#: gui/options.cpp:1146 msgid "You have to restart ScummVM to take the effect." msgstr "" -#: gui/options.cpp:1102 +#: gui/options.cpp:1159 msgid "Select directory for savegames" msgstr "" -#: gui/options.cpp:1109 +#: gui/options.cpp:1166 msgid "The chosen directory cannot be written to. Please select another one." msgstr "" -#: gui/options.cpp:1118 +#: gui/options.cpp:1175 msgid "Select directory for GUI themes" msgstr "" -#: gui/options.cpp:1128 +#: gui/options.cpp:1185 msgid "Select directory for extra files" msgstr "" -#: gui/options.cpp:1139 +#: gui/options.cpp:1196 msgid "Select directory for plugins" msgstr "" @@ -732,15 +740,15 @@ msgstr "" msgid "Select a Theme" msgstr "" -#: gui/ThemeEngine.cpp:337 +#: gui/ThemeEngine.cpp:334 msgid "Disabled GFX" msgstr "" -#: gui/ThemeEngine.cpp:338 +#: gui/ThemeEngine.cpp:335 msgid "Standard Renderer (16bpp)" msgstr "" -#: gui/ThemeEngine.cpp:340 +#: gui/ThemeEngine.cpp:337 msgid "Antialiased Renderer (16bpp)" msgstr "" diff --git a/po/it_IT.po b/po/it_IT.po index bbe6e92e95..efb92c9db9 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 1.2.0svn\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" -"POT-Creation-Date: 2010-07-12 17:44+0200\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" "PO-Revision-Date: 2010-06-30 23:56+0100\n" "Last-Translator: Maff <matteo.maff at gmail dot com>\n" "Language-Team: Italian\n" -"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" +"Language: Italiano\n" #: gui/about.cpp:96 #, c-format @@ -38,7 +38,7 @@ msgid "Go to previous directory level" msgstr "Vai alla cartella superiore" #: gui/browser.cpp:70 gui/chooser.cpp:49 gui/KeysDialog.cpp:46 -#: gui/launcher.cpp:266 gui/massadd.cpp:95 gui/options.cpp:972 +#: gui/launcher.cpp:280 gui/massadd.cpp:95 gui/options.cpp:1029 #: gui/saveload.cpp:65 gui/saveload.cpp:157 gui/themebrowser.cpp:56 #: backends/platform/wii/options.cpp:48 msgid "Cancel" @@ -48,19 +48,19 @@ msgstr "Annulla" msgid "Choose" msgstr "Scegli" -#: gui/GuiManager.cpp:102 backends/keymapper/remap-dialog.cpp:54 +#: gui/GuiManager.cpp:103 backends/keymapper/remap-dialog.cpp:54 msgid "Close" msgstr "Chiudi" -#: gui/GuiManager.cpp:105 +#: gui/GuiManager.cpp:106 msgid "Mouse click" msgstr "Clic del mouse" -#: gui/GuiManager.cpp:108 base/main.cpp:285 +#: gui/GuiManager.cpp:109 base/main.cpp:285 msgid "Display keyboard" msgstr "Mostra tastiera" -#: gui/GuiManager.cpp:111 base/main.cpp:288 +#: gui/GuiManager.cpp:112 base/main.cpp:288 msgid "Remap keys" msgstr "Riprogramma tasti" @@ -68,8 +68,8 @@ msgstr "Riprogramma tasti" msgid "Map" msgstr "Mappa" -#: gui/KeysDialog.cpp:45 gui/launcher.cpp:267 gui/launcher.cpp:873 -#: gui/launcher.cpp:877 gui/massadd.cpp:92 gui/options.cpp:973 +#: gui/KeysDialog.cpp:45 gui/launcher.cpp:281 gui/launcher.cpp:893 +#: gui/launcher.cpp:897 gui/massadd.cpp:92 gui/options.cpp:1030 #: backends/platform/wii/options.cpp:47 #: backends/platform/wince/CELauncherDialog.cpp:56 msgid "OK" @@ -101,15 +101,15 @@ msgstr "Premi il tasto da associare" msgid "Choose an action to map" msgstr "Scegli un'azione da mappare" -#: gui/launcher.cpp:170 +#: gui/launcher.cpp:172 msgid "Game" msgstr "Gioco" -#: gui/launcher.cpp:173 +#: gui/launcher.cpp:175 msgid "ID:" msgstr "ID:" -#: gui/launcher.cpp:173 gui/launcher.cpp:174 +#: gui/launcher.cpp:175 gui/launcher.cpp:176 msgid "" "Short game identifier used for referring to savegames and running the game " "from the command line" @@ -117,222 +117,231 @@ msgstr "" "Breve identificatore di gioco utilizzato per il riferimento a salvataggi e " "per l'esecuzione del gioco dalla riga di comando" -#: gui/launcher.cpp:177 +#: gui/launcher.cpp:179 msgid "Name:" msgstr "Nome:" -#: gui/launcher.cpp:177 gui/launcher.cpp:178 +#: gui/launcher.cpp:179 gui/launcher.cpp:180 msgid "Full title of the game" msgstr "Titolo completo del gioco" -#: gui/launcher.cpp:181 +#: gui/launcher.cpp:183 msgid "Language:" msgstr "Lingua:" -#: gui/launcher.cpp:181 gui/launcher.cpp:182 +#: gui/launcher.cpp:183 gui/launcher.cpp:184 msgid "" "Language of the game. This will not turn your Spanish game version into " "English" msgstr "" "Lingua del gioco. Un gioco inglese non potrà risultare tradotto in italiano" -#: gui/launcher.cpp:183 gui/launcher.cpp:194 gui/options.cpp:80 -#: gui/options.cpp:617 gui/options.cpp:627 gui/options.cpp:943 +#: gui/launcher.cpp:185 gui/launcher.cpp:196 gui/options.cpp:80 +#: gui/options.cpp:635 gui/options.cpp:645 gui/options.cpp:1000 #: sound/null.cpp:42 msgid "<default>" msgstr "<predefinito>" -#: gui/launcher.cpp:192 +#: gui/launcher.cpp:194 msgid "Platform:" msgstr "Piattaforma:" -#: gui/launcher.cpp:192 gui/launcher.cpp:193 +#: gui/launcher.cpp:194 gui/launcher.cpp:195 msgid "Platform the game was originally designed for" msgstr "La piattaforma per la quale il gioco è stato concepito" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "Graphics" msgstr "Grafica" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "GFX" msgstr "Grafica" -#: gui/launcher.cpp:206 +#: gui/launcher.cpp:208 msgid "Override global graphic settings" msgstr "Ignora le impostazioni grafiche globali" -#: gui/launcher.cpp:213 gui/options.cpp:873 +#: gui/launcher.cpp:215 gui/options.cpp:921 msgid "Audio" msgstr "Audio" -#: gui/launcher.cpp:215 +#: gui/launcher.cpp:217 msgid "Override global audio settings" msgstr "Ignora le impostazioni audio globali" -#: gui/launcher.cpp:223 gui/options.cpp:877 +#: gui/launcher.cpp:225 gui/options.cpp:925 msgid "Volume" msgstr "Volume" -#: gui/launcher.cpp:225 +#: gui/launcher.cpp:227 msgid "Override global volume settings" msgstr "Ignora le impostazioni globali di volume" -#: gui/launcher.cpp:232 gui/options.cpp:885 +#: gui/launcher.cpp:234 gui/options.cpp:933 msgid "MIDI" msgstr "MIDI" -#: gui/launcher.cpp:234 +#: gui/launcher.cpp:236 msgid "Override global MIDI settings" msgstr "Ignora le impostazioni MIDI globali" -#: gui/launcher.cpp:244 gui/options.cpp:891 +#: gui/launcher.cpp:246 gui/options.cpp:939 +msgid "MT-32" +msgstr "" + +#: gui/launcher.cpp:248 +#, fuzzy +msgid "Override global MT-32 settings" +msgstr "Ignora le impostazioni MIDI globali" + +#: gui/launcher.cpp:258 gui/options.cpp:945 msgid "Paths" msgstr "Percorsi" -#: gui/launcher.cpp:250 +#: gui/launcher.cpp:264 msgid "Game Path:" msgstr "Percorso gioco:" -#: gui/launcher.cpp:254 gui/options.cpp:904 +#: gui/launcher.cpp:268 gui/options.cpp:958 msgid "Extra Path:" msgstr "Percorso extra:" -#: gui/launcher.cpp:254 gui/launcher.cpp:255 +#: gui/launcher.cpp:268 gui/launcher.cpp:269 msgid "Specifies path to additional data used the game" msgstr "Specifica il percorso di ulteriori dati usati dal gioco" -#: gui/launcher.cpp:258 +#: gui/launcher.cpp:272 msgid "Save Path:" msgstr "Salvataggi:" -#: gui/launcher.cpp:258 gui/launcher.cpp:259 gui/options.cpp:898 -#: gui/options.cpp:899 +#: gui/launcher.cpp:272 gui/launcher.cpp:273 gui/options.cpp:952 +#: gui/options.cpp:953 msgid "Specifies where your savegames are put" msgstr "Specifica dove archiviare i salvataggi" -#: gui/launcher.cpp:275 gui/launcher.cpp:353 gui/launcher.cpp:398 -#: gui/options.cpp:245 gui/options.cpp:400 gui/options.cpp:486 -#: gui/options.cpp:545 gui/options.cpp:706 gui/options.cpp:902 -#: gui/options.cpp:905 gui/options.cpp:909 gui/options.cpp:996 -#: gui/options.cpp:1002 gui/options.cpp:1008 gui/options.cpp:1016 -#: gui/options.cpp:1040 gui/options.cpp:1044 gui/options.cpp:1050 -#: gui/options.cpp:1057 gui/options.cpp:1156 +#: gui/launcher.cpp:289 gui/launcher.cpp:369 gui/launcher.cpp:418 +#: gui/options.cpp:230 gui/options.cpp:399 gui/options.cpp:497 +#: gui/options.cpp:555 gui/options.cpp:732 gui/options.cpp:956 +#: gui/options.cpp:959 gui/options.cpp:963 gui/options.cpp:1053 +#: gui/options.cpp:1059 gui/options.cpp:1065 gui/options.cpp:1073 +#: gui/options.cpp:1097 gui/options.cpp:1101 gui/options.cpp:1107 +#: gui/options.cpp:1114 gui/options.cpp:1213 msgid "None" msgstr "Nessuno" -#: gui/launcher.cpp:280 gui/launcher.cpp:357 +#: gui/launcher.cpp:294 gui/launcher.cpp:373 #: backends/platform/wii/options.cpp:56 msgid "Default" msgstr "Predefinito" -#: gui/launcher.cpp:391 gui/options.cpp:1150 +#: gui/launcher.cpp:411 gui/options.cpp:1207 msgid "Select SoundFont" msgstr "Seleziona SoundFont" -#: gui/launcher.cpp:410 gui/launcher.cpp:548 +#: gui/launcher.cpp:430 gui/launcher.cpp:568 msgid "Select directory with game data" msgstr "Seleziona la cartella contenente i file di gioco" -#: gui/launcher.cpp:428 +#: gui/launcher.cpp:448 msgid "Select additional game directory" msgstr "Seleziona la cartella di gioco aggiuntiva" -#: gui/launcher.cpp:440 +#: gui/launcher.cpp:460 msgid "Select directory for saved games" msgstr "Seleziona la cartella dei salvataggi" -#: gui/launcher.cpp:459 +#: gui/launcher.cpp:479 msgid "This game ID is already taken. Please choose another one." msgstr "Questo ID di gioco è già in uso. Si prega di sceglierne un'altro." -#: gui/launcher.cpp:500 engines/dialogs.cpp:113 +#: gui/launcher.cpp:520 engines/dialogs.cpp:113 msgid "~Q~uit" msgstr "C~h~iudi" -#: gui/launcher.cpp:500 +#: gui/launcher.cpp:520 msgid "Quit ScummVM" msgstr "Chiudi ScummVM" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "A~b~out..." msgstr "~I~nfo..." -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "About ScummVM" msgstr "Informazioni su ScummVM" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "~O~ptions..." msgstr "~O~pzioni..." -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "Change global ScummVM options" msgstr "Modifica le opzioni globali di ScummVM" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "~S~tart" msgstr "~G~ioca" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "Start selected game" msgstr "Esegue il gioco selezionato" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "~L~oad..." msgstr "~C~arica..." -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "Load savegame for selected game" msgstr "Carica un salvataggio del gioco selezionato" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "~A~dd Game..." msgstr "~A~ggiungi gioco..." -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "Hold Shift for Mass Add" msgstr "Tieni premuto Shift per l'aggiunta in massa" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "~E~dit Game..." msgstr "~M~odifica gioco..." -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "Change game options" msgstr "Modifica le opzioni di gioco" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "~R~emove Game" msgstr "~R~imuovi gioco" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "Remove game from the list. The game data files stay intact" msgstr "Rimuove il gioco dalla lista. I file del gioco rimarranno intatti" -#: gui/launcher.cpp:522 +#: gui/launcher.cpp:542 msgid "Search in game list" msgstr "Cerca nella lista dei giochi" -#: gui/launcher.cpp:526 gui/launcher.cpp:1037 +#: gui/launcher.cpp:546 gui/launcher.cpp:1057 msgid "Search:" msgstr "Cerca:" -#: gui/launcher.cpp:529 gui/options.cpp:707 +#: gui/launcher.cpp:549 gui/options.cpp:733 msgid "Clear value" msgstr "Cancella" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 msgid "Load game:" msgstr "Carica gioco:" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 #: backends/platform/wince/CEActionsPocket.cpp:263 #: backends/platform/wince/CEActionsSmartphone.cpp:225 msgid "Load" msgstr "Carica" -#: gui/launcher.cpp:660 +#: gui/launcher.cpp:680 msgid "" "Do you really want to run the mass game detector? This could potentially add " "a huge number of games." @@ -340,7 +349,7 @@ msgstr "" "Vuoi davvero eseguire il rilevatore di giochi in massa? Potrebbe aggiungere " "un numero enorme di giochi." -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -348,7 +357,7 @@ msgstr "" msgid "Yes" msgstr "Sì" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -356,39 +365,39 @@ msgstr "Sì" msgid "No" msgstr "No" -#: gui/launcher.cpp:708 +#: gui/launcher.cpp:728 msgid "ScummVM couldn't open the specified directory!" msgstr "ScummVM non ha potuto aprire la cartella specificata!" -#: gui/launcher.cpp:720 +#: gui/launcher.cpp:740 msgid "ScummVM could not find any game in the specified directory!" msgstr "ScummVM non ha potuto trovare nessun gioco nella cartella specificata!" -#: gui/launcher.cpp:734 +#: gui/launcher.cpp:754 msgid "Pick the game:" msgstr "Scegli il gioco:" -#: gui/launcher.cpp:810 +#: gui/launcher.cpp:830 msgid "Do you really want to remove this game configuration?" msgstr "Sei sicuro di voler rimuovere questa configurazione di gioco?" -#: gui/launcher.cpp:873 +#: gui/launcher.cpp:893 msgid "This game does not support loading games from the launcher." msgstr "" "Questo gioco non supporta il caricamento di salvataggi dalla schermata di " "avvio." -#: gui/launcher.cpp:877 +#: gui/launcher.cpp:897 msgid "ScummVM could not find any engine capable of running the selected game!" msgstr "" "ScummVM non ha potuto trovare un motore in grado di eseguire il gioco " "selezionato!" -#: gui/launcher.cpp:989 +#: gui/launcher.cpp:1009 msgid "Mass Add..." msgstr "Agg. in massa..." -#: gui/launcher.cpp:990 +#: gui/launcher.cpp:1010 msgid "Add Game..." msgstr "Aggiungi gioco..." @@ -455,81 +464,62 @@ msgstr "44 kHz" msgid "48 kHz" msgstr "48 kHz" -#: gui/options.cpp:614 +#: gui/options.cpp:632 msgid "Graphics mode:" msgstr "Modalità:" -#: gui/options.cpp:625 +#: gui/options.cpp:643 msgid "Render mode:" msgstr "Resa grafica:" -#: gui/options.cpp:625 gui/options.cpp:626 +#: gui/options.cpp:643 gui/options.cpp:644 msgid "Special dithering modes supported by some games" msgstr "Modalità di resa grafica speciali supportate da alcuni giochi" -#: gui/options.cpp:635 +#: gui/options.cpp:653 msgid "Fullscreen mode" msgstr "Modalità a schermo intero" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Aspect ratio correction" msgstr "Correzione proporzioni" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Correct aspect ratio for 320x200 games" msgstr "Corregge le proporzioni dei giochi 320x200" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Preferred Device:" msgstr "Disp. preferito:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 #, fuzzy msgid "Music Device:" msgstr "Dispositivo GM:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Specifies preferred sound device or sound card emulator" msgstr "" "Specifica il dispositivo audio o l'emulatore della scheda audio preferiti" -#: gui/options.cpp:645 gui/options.cpp:646 +#: gui/options.cpp:663 gui/options.cpp:664 msgid "Specifies output sound device or sound card emulator" msgstr "" "Specifica il dispositivo di output audio o l'emulatore della scheda audio" -#: gui/options.cpp:648 -#, fuzzy -msgid "MT-32 Device:" -msgstr "Disposit. MT32:" - -#: gui/options.cpp:648 -msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" -msgstr "" -"Specifica il dispositivo audio predefinito per l'output Roland MT-32/LAPC1/" -"CM32l/CM64" - -#: gui/options.cpp:650 -msgid "GM Device:" -msgstr "Dispositivo GM:" - -#: gui/options.cpp:650 -msgid "Specifies default sound device for General MIDI output" -msgstr "Specifica il dispositivo audio predefinito per l'output General MIDI" - -#: gui/options.cpp:682 +#: gui/options.cpp:688 msgid "AdLib emulator:" msgstr "Emulatore AdLib:" -#: gui/options.cpp:682 gui/options.cpp:683 +#: gui/options.cpp:688 gui/options.cpp:689 msgid "AdLib is used for music in many games" msgstr "AdLib è utilizzato per la musica in molti giochi" -#: gui/options.cpp:693 +#: gui/options.cpp:699 msgid "Output rate:" msgstr "Frequenza:" -#: gui/options.cpp:693 gui/options.cpp:694 +#: gui/options.cpp:699 gui/options.cpp:700 msgid "" "Higher value specifies better sound quality but may be not supported by your " "soundcard" @@ -537,27 +527,50 @@ msgstr "" "Valori più alti restituiscono un suono di maggior qualità, ma potrebbero non " "essere supportati dalla tua scheda audio" -#: gui/options.cpp:705 +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "Dispositivo GM:" + +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "Specifica il dispositivo audio predefinito per l'output General MIDI" + +#: gui/options.cpp:731 msgid "SoundFont:" msgstr "SoundFont:" -#: gui/options.cpp:705 gui/options.cpp:706 +#: gui/options.cpp:731 gui/options.cpp:732 msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" msgstr "SoundFont è supportato da alcune schede audio, Fluidsynth e Timidity" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Mixed AdLib/MIDI mode" msgstr "Modalità mista AdLib/MIDI" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Use both MIDI and AdLib sound generation" msgstr "Utilizza generazione di suono sia MIDI che AdLib" -#: gui/options.cpp:713 +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "Guadagno MIDI:" + +#: gui/options.cpp:749 +#, fuzzy +msgid "MT-32 Device:" +msgstr "Disposit. MT32:" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "" +"Specifica il dispositivo audio predefinito per l'output Roland MT-32/LAPC1/" +"CM32l/CM64" + +#: gui/options.cpp:753 msgid "True Roland MT-32 (disable GM emulation)" msgstr "Roland MT-32 effettivo (disattiva emulazione GM)" -#: gui/options.cpp:713 +#: gui/options.cpp:753 msgid "" "Check if you want to use your real hardware Roland-compatible sound device " "connected to your computer" @@ -565,141 +578,137 @@ msgstr "" "Seleziona se vuoi usare il dispositivo hardware audio compatibile con Roland " "che è connesso al tuo computer" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Enable Roland GS Mode" msgstr "Attiva la modalità Roland GS" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" msgstr "" "Disattiva la mappatura General MIDI per i giochi con colonna sonora Roland " "MT-32" -#: gui/options.cpp:719 -msgid "MIDI gain:" -msgstr "Guadagno MIDI:" - -#: gui/options.cpp:732 +#: gui/options.cpp:780 msgid "Text and Speech:" msgstr "Testo e voci:" -#: gui/options.cpp:737 gui/options.cpp:743 +#: gui/options.cpp:785 gui/options.cpp:791 msgid "Speech" msgstr "Voci" -#: gui/options.cpp:738 gui/options.cpp:744 +#: gui/options.cpp:786 gui/options.cpp:792 msgid "Subtitles" msgstr "Sottotitoli" -#: gui/options.cpp:739 gui/options.cpp:745 +#: gui/options.cpp:787 gui/options.cpp:793 msgid "Both" msgstr "Entrambi" -#: gui/options.cpp:743 +#: gui/options.cpp:791 msgid "Spch" msgstr "Voci" -#: gui/options.cpp:744 +#: gui/options.cpp:792 msgid "Subs" msgstr "Sub" -#: gui/options.cpp:745 +#: gui/options.cpp:793 msgid "Show subtitles and play speech" msgstr "Mostra i sottotitoli e attiva le voci" -#: gui/options.cpp:749 +#: gui/options.cpp:797 msgid "Subtitle speed:" msgstr "Velocità testo:" -#: gui/options.cpp:761 +#: gui/options.cpp:809 msgid "Music volume:" msgstr "Volume musica:" -#: gui/options.cpp:768 +#: gui/options.cpp:816 msgid "Mute All" msgstr "Disattiva audio" -#: gui/options.cpp:771 +#: gui/options.cpp:819 msgid "SFX volume:" msgstr "Volume effetti:" -#: gui/options.cpp:771 gui/options.cpp:772 +#: gui/options.cpp:819 gui/options.cpp:820 msgid "Special sound effects volume" msgstr "Volume degli effetti sonori" -#: gui/options.cpp:778 +#: gui/options.cpp:826 msgid "Speech volume:" msgstr "Volume voci:" -#: gui/options.cpp:898 +#: gui/options.cpp:952 msgid "Save Path: " msgstr "Salvataggi:" -#: gui/options.cpp:901 +#: gui/options.cpp:955 msgid "Theme Path:" msgstr "Percorso tema:" -#: gui/options.cpp:904 gui/options.cpp:905 +#: gui/options.cpp:958 gui/options.cpp:959 msgid "Specifies path to additional data used by all games or ScummVM" msgstr "Specifica il percorso di ulteriori dati usati dai giochi o da ScummVM" -#: gui/options.cpp:908 +#: gui/options.cpp:962 msgid "Plugins Path:" msgstr "Percorso plugin:" -#: gui/options.cpp:913 +#: gui/options.cpp:970 msgid "Misc" msgstr "Varie" -#: gui/options.cpp:915 +#: gui/options.cpp:972 msgid "Theme:" msgstr "Tema:" -#: gui/options.cpp:919 +#: gui/options.cpp:976 msgid "GUI Renderer:" msgstr "Renderer GUI:" -#: gui/options.cpp:925 +#: gui/options.cpp:982 msgid "Autosave:" msgstr "Autosalva:" -#: gui/options.cpp:933 +#: gui/options.cpp:990 msgid "Keys" msgstr "Tasti" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "GUI Language:" msgstr "Lingua GUI:" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "Language of ScummVM GUI" msgstr "Lingua dell'interfaccia grafica di ScummVM" -#: gui/options.cpp:945 +#: gui/options.cpp:1002 msgid "English" msgstr "Inglese" -#: gui/options.cpp:1089 +#: gui/options.cpp:1146 msgid "You have to restart ScummVM to take the effect." msgstr "Devi riavviare ScummVM affinché le modifiche abbiano effetto." -#: gui/options.cpp:1102 +#: gui/options.cpp:1159 msgid "Select directory for savegames" msgstr "Seleziona la cartella per i salvataggi" -#: gui/options.cpp:1109 +#: gui/options.cpp:1166 msgid "The chosen directory cannot be written to. Please select another one." msgstr "La cartella scelta è in sola lettura. Si prega di sceglierne un'altra." -#: gui/options.cpp:1118 +#: gui/options.cpp:1175 msgid "Select directory for GUI themes" msgstr "Seleziona la cartella dei temi dell'interfaccia" -#: gui/options.cpp:1128 +#: gui/options.cpp:1185 msgid "Select directory for extra files" msgstr "Seleziona la cartella dei file aggiuntivi" -#: gui/options.cpp:1139 +#: gui/options.cpp:1196 msgid "Select directory for plugins" msgstr "Seleziona la cartella dei plugin" @@ -743,15 +752,15 @@ msgstr "Salvataggio senza titolo" msgid "Select a Theme" msgstr "Seleziona un tema" -#: gui/ThemeEngine.cpp:337 +#: gui/ThemeEngine.cpp:334 msgid "Disabled GFX" msgstr "Grafica disattivata" -#: gui/ThemeEngine.cpp:338 +#: gui/ThemeEngine.cpp:335 msgid "Standard Renderer (16bpp)" msgstr "Renderer standard (16bpp)" -#: gui/ThemeEngine.cpp:340 +#: gui/ThemeEngine.cpp:337 msgid "Antialiased Renderer (16bpp)" msgstr "Renderer con antialiasing (16bpp)" diff --git a/po/ru_RU.po b/po/ru_RU.po index 2d4a96b63c..45bd5ceae2 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -7,16 +7,16 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM VERSION\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" -"POT-Creation-Date: 2010-07-12 17:44+0200\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" "PO-Revision-Date: 2010-06-13 20:55+0300\n" "Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n" "Language-Team: Russian\n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-5\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n" -"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Language: Russian\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%" +"10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" #: gui/about.cpp:96 #, c-format @@ -40,7 +40,7 @@ msgid "Go to previous directory level" msgstr "¿ÕàÕÙâØ ÝÐ ÔØàÕÚâÞàØî ãàÞÒÝÕÜ ÒëèÕ" #: gui/browser.cpp:70 gui/chooser.cpp:49 gui/KeysDialog.cpp:46 -#: gui/launcher.cpp:266 gui/massadd.cpp:95 gui/options.cpp:972 +#: gui/launcher.cpp:280 gui/massadd.cpp:95 gui/options.cpp:1029 #: gui/saveload.cpp:65 gui/saveload.cpp:157 gui/themebrowser.cpp:56 #: backends/platform/wii/options.cpp:48 msgid "Cancel" @@ -50,19 +50,19 @@ msgstr "¾âÜÕÝÐ" msgid "Choose" msgstr "²ëÑàÐâì" -#: gui/GuiManager.cpp:102 backends/keymapper/remap-dialog.cpp:54 +#: gui/GuiManager.cpp:103 backends/keymapper/remap-dialog.cpp:54 msgid "Close" msgstr "·ÐÚàëâì" -#: gui/GuiManager.cpp:105 +#: gui/GuiManager.cpp:106 msgid "Mouse click" msgstr "ºÛØÚ Üëèìî" -#: gui/GuiManager.cpp:108 base/main.cpp:285 +#: gui/GuiManager.cpp:109 base/main.cpp:285 msgid "Display keyboard" msgstr "¿ÞÚÐ×Ðâì ÚÛÐÒØÐâãàã" -#: gui/GuiManager.cpp:111 base/main.cpp:288 +#: gui/GuiManager.cpp:112 base/main.cpp:288 msgid "Remap keys" msgstr "¿ÕàÕÝÐ×ÝÐçØâì ÚÛÐÒØèØ" @@ -70,8 +70,8 @@ msgstr "¿ÕàÕÝÐ×ÝÐçØâì ÚÛÐÒØèØ" msgid "Map" msgstr "½Ð×ÝÐçØâì" -#: gui/KeysDialog.cpp:45 gui/launcher.cpp:267 gui/launcher.cpp:873 -#: gui/launcher.cpp:877 gui/massadd.cpp:92 gui/options.cpp:973 +#: gui/KeysDialog.cpp:45 gui/launcher.cpp:281 gui/launcher.cpp:893 +#: gui/launcher.cpp:897 gui/massadd.cpp:92 gui/options.cpp:1030 #: backends/platform/wii/options.cpp:47 #: backends/platform/wince/CELauncherDialog.cpp:56 msgid "OK" @@ -103,15 +103,15 @@ msgstr "½ÐÖÜØâÕ ÚÛÐÒØèã ÔÛï ÝÐ×ÝÐçÕÝØï" msgid "Choose an action to map" msgstr "²ëÑÕàØâÕ ÔÕÙáâÒØÕ ÔÛï ÝÐ×ÝÐçÕÝØï" -#: gui/launcher.cpp:170 +#: gui/launcher.cpp:172 msgid "Game" msgstr "¸ÓàÐ" -#: gui/launcher.cpp:173 +#: gui/launcher.cpp:175 msgid "ID:" msgstr "ID:" -#: gui/launcher.cpp:173 gui/launcher.cpp:174 +#: gui/launcher.cpp:175 gui/launcher.cpp:176 msgid "" "Short game identifier used for referring to savegames and running the game " "from the command line" @@ -119,19 +119,19 @@ msgstr "" "ºÞàÞâÚØÙ ØÔÕÝâØäØÚÐâÞà, ØáßÞÛì×ãÕÜëÙ ÔÛï ØÜÕÝ áÞåàÐÝÕÝØÙ ØÓà Ø ÔÛï ×ÐßãáÚÐ " "Ø× ÚÞÜÐÝÔÝÞÙ áâàÞÚØ" -#: gui/launcher.cpp:177 +#: gui/launcher.cpp:179 msgid "Name:" -msgstr "½Ð×ÒÐÝØÕ:" +msgstr "½Ð×Ò:" -#: gui/launcher.cpp:177 gui/launcher.cpp:178 +#: gui/launcher.cpp:179 gui/launcher.cpp:180 msgid "Full title of the game" msgstr "¿ÞÛÝÞÕ ÝÐ×ÒÐÝØÕ ØÓàë" -#: gui/launcher.cpp:181 +#: gui/launcher.cpp:183 msgid "Language:" msgstr "Ï×ëÚ:" -#: gui/launcher.cpp:181 gui/launcher.cpp:182 +#: gui/launcher.cpp:183 gui/launcher.cpp:184 msgid "" "Language of the game. This will not turn your Spanish game version into " "English" @@ -139,203 +139,211 @@ msgstr "" "Ï×ëÚ ØÓàë. ¸×ÜÕÝÕÝØÕ íâÞÓÞ ßÐàÐÜÕâàÐ ÝÕ ßàÕÒàÐâØâ ØÓàã ÝÐ ÐÝÓÛØÙáÚÞÜ Ò " "àãááÚãî" -#: gui/launcher.cpp:183 gui/launcher.cpp:194 gui/options.cpp:80 -#: gui/options.cpp:617 gui/options.cpp:627 gui/options.cpp:943 +#: gui/launcher.cpp:185 gui/launcher.cpp:196 gui/options.cpp:80 +#: gui/options.cpp:635 gui/options.cpp:645 gui/options.cpp:1000 #: sound/null.cpp:42 msgid "<default>" msgstr "<ßÞ ãÜÞÛçÐÝØî>" -#: gui/launcher.cpp:192 +#: gui/launcher.cpp:194 msgid "Platform:" msgstr "¿ÛÐâäÞàÜÐ:" -#: gui/launcher.cpp:192 gui/launcher.cpp:193 +#: gui/launcher.cpp:194 gui/launcher.cpp:195 msgid "Platform the game was originally designed for" msgstr "¿ÛÐâäÞàÜÐ, ÔÛï ÚÞâÞàÞÙ ØÓàÐ ÑëÛÐ Ø×ÝÐçÐÛìÝÞ àÐ×àÐÑÞâÐÝÐ" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "Graphics" msgstr "³àÐäØÚÐ" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "GFX" msgstr "³àä" -#: gui/launcher.cpp:206 +#: gui/launcher.cpp:208 msgid "Override global graphic settings" msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÓàÐäØÚØ" -#: gui/launcher.cpp:213 gui/options.cpp:873 +#: gui/launcher.cpp:215 gui/options.cpp:921 msgid "Audio" msgstr "°ãÔØÞ" -#: gui/launcher.cpp:215 +#: gui/launcher.cpp:217 msgid "Override global audio settings" msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÐãÔØÞ" -#: gui/launcher.cpp:223 gui/options.cpp:877 +#: gui/launcher.cpp:225 gui/options.cpp:925 msgid "Volume" msgstr "³àÞÜÚÞáâì" -#: gui/launcher.cpp:225 +#: gui/launcher.cpp:227 msgid "Override global volume settings" msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÓàÞÜÚÞáâØ" -#: gui/launcher.cpp:232 gui/options.cpp:885 +#: gui/launcher.cpp:234 gui/options.cpp:933 msgid "MIDI" msgstr "MIDI" -#: gui/launcher.cpp:234 +#: gui/launcher.cpp:236 msgid "Override global MIDI settings" msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ MIDI" -#: gui/launcher.cpp:244 gui/options.cpp:891 +#: gui/launcher.cpp:246 gui/options.cpp:939 +msgid "MT-32" +msgstr "MT-32" + +#: gui/launcher.cpp:248 +msgid "Override global MT-32 settings" +msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ MT-32" + +#: gui/launcher.cpp:258 gui/options.cpp:945 msgid "Paths" msgstr "¿ãâØ" -#: gui/launcher.cpp:250 +#: gui/launcher.cpp:264 msgid "Game Path:" -msgstr "¿ãâì Ú ØÓàÕ: " +msgstr "³ÔÕ ØÓàÐ: " -#: gui/launcher.cpp:254 gui/options.cpp:904 +#: gui/launcher.cpp:268 gui/options.cpp:958 msgid "Extra Path:" msgstr "´Þß. ßãâì:" -#: gui/launcher.cpp:254 gui/launcher.cpp:255 +#: gui/launcher.cpp:268 gui/launcher.cpp:269 msgid "Specifies path to additional data used the game" msgstr "ÃÚÐ×ëÒÐÕâ ßãâì Ú ÔÞßÞÛÝØâÕÛìÝëÜ äÐÙÛÐÜ ÔÐÝÝëå ÔÛï ØÓàë" -#: gui/launcher.cpp:258 +#: gui/launcher.cpp:272 msgid "Save Path:" -msgstr "¿ãâì áÞåà.: " +msgstr "¿ãâì áÞåà: " -#: gui/launcher.cpp:258 gui/launcher.cpp:259 gui/options.cpp:898 -#: gui/options.cpp:899 +#: gui/launcher.cpp:272 gui/launcher.cpp:273 gui/options.cpp:952 +#: gui/options.cpp:953 msgid "Specifies where your savegames are put" msgstr "ÃÚÐ×ëÒÐÕâ ßãâì Ú áÞåàÐÝÕÝØïÜ ØÓàë" -#: gui/launcher.cpp:275 gui/launcher.cpp:353 gui/launcher.cpp:398 -#: gui/options.cpp:245 gui/options.cpp:400 gui/options.cpp:486 -#: gui/options.cpp:545 gui/options.cpp:706 gui/options.cpp:902 -#: gui/options.cpp:905 gui/options.cpp:909 gui/options.cpp:996 -#: gui/options.cpp:1002 gui/options.cpp:1008 gui/options.cpp:1016 -#: gui/options.cpp:1040 gui/options.cpp:1044 gui/options.cpp:1050 -#: gui/options.cpp:1057 gui/options.cpp:1156 +#: gui/launcher.cpp:289 gui/launcher.cpp:369 gui/launcher.cpp:418 +#: gui/options.cpp:230 gui/options.cpp:399 gui/options.cpp:497 +#: gui/options.cpp:555 gui/options.cpp:732 gui/options.cpp:956 +#: gui/options.cpp:959 gui/options.cpp:963 gui/options.cpp:1053 +#: gui/options.cpp:1059 gui/options.cpp:1065 gui/options.cpp:1073 +#: gui/options.cpp:1097 gui/options.cpp:1101 gui/options.cpp:1107 +#: gui/options.cpp:1114 gui/options.cpp:1213 msgid "None" msgstr "½Õ ×ÐÔÐÝ" -#: gui/launcher.cpp:280 gui/launcher.cpp:357 +#: gui/launcher.cpp:294 gui/launcher.cpp:373 #: backends/platform/wii/options.cpp:56 msgid "Default" msgstr "¿Þ ãÜÞÛçÐÝØî" -#: gui/launcher.cpp:391 gui/options.cpp:1150 +#: gui/launcher.cpp:411 gui/options.cpp:1207 msgid "Select SoundFont" msgstr "²ëÑÕàØâÕ SoundFont" -#: gui/launcher.cpp:410 gui/launcher.cpp:548 +#: gui/launcher.cpp:430 gui/launcher.cpp:568 msgid "Select directory with game data" msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî á äÐÙÛÐÜØ ØÓàë" -#: gui/launcher.cpp:428 +#: gui/launcher.cpp:448 msgid "Select additional game directory" msgstr "²ëÑÕàØâÕ ÔÞßÞÛÝØâÕÛìÝãî ÔØàÕÚâÞàØî ØÓàë" -#: gui/launcher.cpp:440 +#: gui/launcher.cpp:460 msgid "Select directory for saved games" msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî ÔÛï áÞåàÐÝÕÝØÙ" -#: gui/launcher.cpp:459 +#: gui/launcher.cpp:479 msgid "This game ID is already taken. Please choose another one." msgstr "ÍâÞâ ID ØÓàë ãÖÕ ØáßÞÛì×ãÕâáï. ¿ÞÖÐÛãÙáâÐ, ÒëÑÕàØâÕ ÔàãÓÞÙ." -#: gui/launcher.cpp:500 engines/dialogs.cpp:113 +#: gui/launcher.cpp:520 engines/dialogs.cpp:113 msgid "~Q~uit" msgstr "~²~ëåÞÔ" -#: gui/launcher.cpp:500 +#: gui/launcher.cpp:520 msgid "Quit ScummVM" msgstr "²ëåÞÔ Ø× ScummVM" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "A~b~out..." msgstr "¾ ß~à~ÞÓàÐÜÜÕ..." -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "About ScummVM" msgstr "¾ ßàÞÓàÐÜÜÕ ScummVM" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "~O~ptions..." msgstr "~¾~ßæØØ..." -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "Change global ScummVM options" msgstr "¸×ÜÕÝØâì ÓÛÞÑÐÛìÝëÕ ÞßæØØ ScummVM" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "~S~tart" msgstr "¿~ã~áÚ" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "Start selected game" msgstr "·ÐßãáâØâì ÒëÑàÐÝÝãî ØÓàã" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "~L~oad..." -msgstr "~·~ÐÓà...." +msgstr "~·~ÐÓàã×Øâì..." -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "Load savegame for selected game" msgstr "·ÐÓàã×Øâì áÞåàÝÕÝØÕ ÔÛï ÒëÑàÐÝÝÞÙ ØÓàë" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "~A~dd Game..." msgstr "~´~ÞÑ. ØÓàã..." -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "Hold Shift for Mass Add" msgstr "ÃÔÕàÖØÒÐÙâÕ ÚÛÐÒØèã Shift ÔÛï âÞÓÞ, çâÞÑë ÔÞÑÐÒØâì ÝÕáÚÞÛìÚÞ ØÓà" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "~E~dit Game..." -msgstr "¸×~Ü~. ØÓàã..." +msgstr "¾~ß~æØØ ØÓàë..." -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "Change game options" msgstr "¸×ÜÕÝØâì ÞßæØØ ØÓàë" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "~R~emove Game" msgstr "~Ã~ÔÐÛØâì ØÓàã" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "Remove game from the list. The game data files stay intact" msgstr "ÃÔÐÛØâì ØÓàã Ø× áßØáÚÐ. ½Õ ãÔÐÛïÕâ ØÓàã á ÖÕáâÚÞÓÞ ÔØáÚÐ" -#: gui/launcher.cpp:522 +#: gui/launcher.cpp:542 msgid "Search in game list" msgstr "¿ÞØáÚ Ò áßØáÚÕ ØÓà" -#: gui/launcher.cpp:526 gui/launcher.cpp:1037 +#: gui/launcher.cpp:546 gui/launcher.cpp:1057 msgid "Search:" msgstr "¿ÞØáÚ:" -#: gui/launcher.cpp:529 gui/options.cpp:707 +#: gui/launcher.cpp:549 gui/options.cpp:733 msgid "Clear value" msgstr "¾çØáâØâì ×ÝÐçÕÝØÕ" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 msgid "Load game:" msgstr "·ÐÓàã×Øâì ØÓàã:" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 #: backends/platform/wince/CEActionsPocket.cpp:263 #: backends/platform/wince/CEActionsSmartphone.cpp:225 msgid "Load" msgstr "·ÐÓàã×Øâì" -#: gui/launcher.cpp:660 +#: gui/launcher.cpp:680 msgid "" "Do you really want to run the mass game detector? This could potentially add " "a huge number of games." @@ -343,7 +351,7 @@ msgstr "" "²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ×ÐßãáâØâì ÔÕâÕÚâÞà ÒáÕå ØÓà? ÍâÞ ßÞâÕÝæØÐÛìÝÞ ÜÞÖÕâ " "ÔÞÑÐÒØâì ÑÞÛìèÞÕ ÚÞÛØçÕáâÒÞ ØÓà." -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -351,7 +359,7 @@ msgstr "" msgid "Yes" msgstr "´Ð" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -359,37 +367,37 @@ msgstr "´Ð" msgid "No" msgstr "½Õâ" -#: gui/launcher.cpp:708 +#: gui/launcher.cpp:728 msgid "ScummVM couldn't open the specified directory!" msgstr "ScummVM ÝÕ ÜÞÖÕâ ÞâÚàëâì ãÚÐ×ÐÝÝãî ÔØàÕÚâÞàØî!" -#: gui/launcher.cpp:720 +#: gui/launcher.cpp:740 msgid "ScummVM could not find any game in the specified directory!" msgstr "ScummVM ÝÕ ÜÞÖÕâ ÝÐÙâØ ØÓàã Ò ãÚÐ×ÐÝÝÞÙ ÔØàÕÚâÞàØØ!" -#: gui/launcher.cpp:734 +#: gui/launcher.cpp:754 msgid "Pick the game:" msgstr "²ëÑÕàØâÕ ØÓàã:" -#: gui/launcher.cpp:810 +#: gui/launcher.cpp:830 msgid "Do you really want to remove this game configuration?" msgstr "²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ãÔÐÛØâì ãáâÐÝÞÒÚØ ÔÛï íâÞÙ ØÓàë?" -#: gui/launcher.cpp:873 +#: gui/launcher.cpp:893 msgid "This game does not support loading games from the launcher." msgstr "ÍâÐ ØÓàÐ ÝÕ ßÞÔÔÕàÖØÒÐÕâ ×ÐÓàã×Úã áÞåàÐÝÕÝØÙ çÕàÕ× ÓÛÐÒÝÞÕ ÜÕÝî." -#: gui/launcher.cpp:877 +#: gui/launcher.cpp:897 msgid "ScummVM could not find any engine capable of running the selected game!" msgstr "ScummVM ÝÕ áÜÞÓ ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚÐ ÒëÑàÐÝÝÞÙ ØÓàë!" -#: gui/launcher.cpp:989 +#: gui/launcher.cpp:1009 msgid "Mass Add..." -msgstr "´ÞÑ. ÜÝÞÓÞ..." +msgstr "¼ÝÞÓÞ ØÓà..." -#: gui/launcher.cpp:990 +#: gui/launcher.cpp:1010 msgid "Add Game..." -msgstr "½ÞÒ. ØÓàÐ..." +msgstr "½ÞÒÐï ØÓàÐ..." #: gui/massadd.cpp:79 gui/massadd.cpp:82 msgid "... progress ..." @@ -454,79 +462,59 @@ msgstr "44 Ú³æ" msgid "48 kHz" msgstr "48 Ú³æ" -#: gui/options.cpp:614 +#: gui/options.cpp:632 msgid "Graphics mode:" -msgstr "³àÐäØçÕáÚØÙ àÕÖØÜ:" +msgstr "³àÐä. àÕÖØÜ:" -#: gui/options.cpp:625 +#: gui/options.cpp:643 msgid "Render mode:" -msgstr "ÀÕÖØÜ àÐáâàØàÞÒÐÝØï:" +msgstr "ÀÕÖØÜ àÐáâàÐ:" -#: gui/options.cpp:625 gui/options.cpp:626 +#: gui/options.cpp:643 gui/options.cpp:644 msgid "Special dithering modes supported by some games" msgstr "ÁßÕæØÐÛìÝëÕ àÕÖØÜë àÕÝÔÕàØÝÓÐ, ßÞÔÔÕàÖØÒÐÕÜëÕ ÝÕÚÞâÞàëÜØ ØÓàÐÜØ" -#: gui/options.cpp:635 +#: gui/options.cpp:653 msgid "Fullscreen mode" msgstr "¿ÞÛÝÞíÚàÐÝÝëÙ àÕÖØÜ" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Aspect ratio correction" msgstr "ºÞààÕÚæØï áÞÞâÝÞèÕÝØï áâÞàÞÝ" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Correct aspect ratio for 320x200 games" msgstr "ºÞààÕÚâØàÞÒÐâì áÞÞâÝÞèÕÝØÕ áâÞàÞÝ ÔÛï ØÓà á àÐ×àÕèÕÝØÕÜ 320x200" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Preferred Device:" -msgstr "¿àÕÔßÞçØâÐÕÜÞÕ ãáâàÞÙáâÒÞ:" +msgstr "·ÒãÚÞÒÞÕ ãáâ-ÒÞ:" -#: gui/options.cpp:645 -#, fuzzy +#: gui/options.cpp:663 msgid "Music Device:" -msgstr "ÃáâàÞÙâáÒÞ GM:" +msgstr "·ÒãÚÞÒÞÕ ãáâ-ÒÞ:" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Specifies preferred sound device or sound card emulator" msgstr "ÃÚÐ×ëÒÐÕâ ÒëåÞÔÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ØÛØ íÜãÛïâÞà ×ÒãÚÞÒÞÙ ÚÐàâë" -#: gui/options.cpp:645 gui/options.cpp:646 +#: gui/options.cpp:663 gui/options.cpp:664 msgid "Specifies output sound device or sound card emulator" msgstr "ÃÚÐ×ëÒÐÕâ ÒëåÞÔÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ØÛØ íÜãÛïâÞà ×ÒãÚÞÒÞÙ ÚÐàâë" -#: gui/options.cpp:648 -#, fuzzy -msgid "MT-32 Device:" -msgstr "ÃáâàÞÙáâÒÞ MT32:" - -#: gui/options.cpp:648 -msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" -msgstr "" -"ÃÚÐ×ëÒÐÕâ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ßÞ ãÜÞÛçÐÝØï ÔÛï ÒëÒÞÔÐ ÝÐ Roland MT-32/LAPC1/" -"CM32l/CM64" - -#: gui/options.cpp:650 -msgid "GM Device:" -msgstr "ÃáâàÞÙâáÒÞ GM:" - -#: gui/options.cpp:650 -msgid "Specifies default sound device for General MIDI output" -msgstr "ÃÚÐ×ëÒÐÕâ ÒëåÞÔÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ÔÛï MIDI" - -#: gui/options.cpp:682 +#: gui/options.cpp:688 msgid "AdLib emulator:" msgstr "ÍÜãÛïâÞà AdLib:" -#: gui/options.cpp:682 gui/options.cpp:683 +#: gui/options.cpp:688 gui/options.cpp:689 msgid "AdLib is used for music in many games" msgstr "·ÒãÚÞÒÐï ÚÐàâÐ AdLib ØáßÞÛì×ãÕâáï ÜÝÞÓØÜØ ØÓàÐÜØ" -#: gui/options.cpp:693 +#: gui/options.cpp:699 msgid "Output rate:" -msgstr "²ëåÞÔÝÐï çÐáâÞâÐ:" +msgstr "ÇÐáâÞâÐ ×ÒãÚÐ:" -#: gui/options.cpp:693 gui/options.cpp:694 +#: gui/options.cpp:699 gui/options.cpp:700 msgid "" "Higher value specifies better sound quality but may be not supported by your " "soundcard" @@ -534,29 +522,51 @@ msgstr "" "±¾ÛìèØÕ ×ÝÐçÕÝØï ×ÐÔÐîâ ÛãçèÕÕ ÚÐçÕáâÒÞ ×ÒãÚÐ, ÞÔÝÐÚÞ ÞÝØ ÜÞÓãâ ÝÕ " "ßÞÔÔÕàÖØÒÐâìáï ÒÐèÕÙ ×ÒãÚÞÒÞÙ ÚÐàâÞÙ" -#: gui/options.cpp:705 +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "ÃáâàÞÙáâÒÞ GM:" + +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "ÃÚÐ×ëÒÐÕâ ÒëåÞÔÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ÔÛï MIDI" + +#: gui/options.cpp:731 msgid "SoundFont:" msgstr "SoundFont:" -#: gui/options.cpp:705 gui/options.cpp:706 +#: gui/options.cpp:731 gui/options.cpp:732 msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" msgstr "" "SoundFontë ßÞÔÔÕàÔÖØÒÐîâáï ÝÕÚÞâÞàëÜØ ×ÒãÚÞÒëÜØ ÚÐàâÐÜØ, Fluidsynth Ø " "Timidity" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Mixed AdLib/MIDI mode" msgstr "ÁÜÕèÐÝÝëÙ àÕÖØÜ AdLib/MIDI" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Use both MIDI and AdLib sound generation" msgstr "¸áßÞÛì×ÞÒÐâì Ø MIDI Ø AdLib ÔÛï ÓÕÝÕàÐæØØ ×ÒãÚÐ" -#: gui/options.cpp:713 +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "ÃáØÛÕÝØÕ MIDI:" + +#: gui/options.cpp:749 +msgid "MT-32 Device:" +msgstr "Ãáâà. MT-32:" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "" +"ÃÚÐ×ëÒÐÕâ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ßÞ ãÜÞÛçÐÝØï ÔÛï ÒëÒÞÔÐ ÝÐ Roland MT-32/LAPC1/" +"CM32l/CM64" + +#: gui/options.cpp:753 msgid "True Roland MT-32 (disable GM emulation)" msgstr "½ÐáâÞïéØÙ Roland MT-32 (×ÐßàÕâØâì íÜãÛïæØî GM)" -#: gui/options.cpp:713 +#: gui/options.cpp:753 msgid "" "Check if you want to use your real hardware Roland-compatible sound device " "connected to your computer" @@ -564,142 +574,138 @@ msgstr "" "¾âÜÕâìâÕ, ÕáÛØ ã ÒÐá ßÞÔÚÛîçÕÝÞ Roland-áÞÒÜÕáâØÜÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ Ø Òë " "åÞâØâÕ ÕÓÞ ØáßÞÛì×ÞÒÐâì" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Enable Roland GS Mode" msgstr "²ÚÛîçØâì àÕÖØÜ Roland GS" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" msgstr "" "²ëÚÛîçÐÕâ ÜÐßßØÝÓ General MIDI ÔÛï ØÓà á ×ÒãÚÞÒÞÙ ÔÞàÞÖÚÞÙ ÔÛï Roland MT-32" -#: gui/options.cpp:719 -msgid "MIDI gain:" -msgstr "ÃáØÛÕÝØÕ MIDI:" - -#: gui/options.cpp:732 +#: gui/options.cpp:780 msgid "Text and Speech:" msgstr "ÂÕÚáâ Ø Þ×ÒãçÚÐ:" -#: gui/options.cpp:737 gui/options.cpp:743 +#: gui/options.cpp:785 gui/options.cpp:791 msgid "Speech" msgstr "¾×ÒãçÚÐ" -#: gui/options.cpp:738 gui/options.cpp:744 +#: gui/options.cpp:786 gui/options.cpp:792 msgid "Subtitles" msgstr "ÁãÑâØâàë" -#: gui/options.cpp:739 gui/options.cpp:745 +#: gui/options.cpp:787 gui/options.cpp:793 msgid "Both" msgstr "²áñ" -#: gui/options.cpp:743 +#: gui/options.cpp:791 msgid "Spch" msgstr "¾×Ò" -#: gui/options.cpp:744 +#: gui/options.cpp:792 msgid "Subs" msgstr "ÁãÑ" -#: gui/options.cpp:745 +#: gui/options.cpp:793 msgid "Show subtitles and play speech" msgstr "¿ÞÚÐ×ëÒÐâì áãÑâØâàë Ø ÒÞáßàÞØ×ÒÞÔØâì àÕçì" -#: gui/options.cpp:749 +#: gui/options.cpp:797 msgid "Subtitle speed:" -msgstr "ÁÚÞàÞáâì áãÑâØâàÞÒ:" +msgstr "ÁÚÞàÞáâì âØâàÞÒ:" -#: gui/options.cpp:761 +#: gui/options.cpp:809 msgid "Music volume:" -msgstr "³àÞÜÚÞáâì Üã×ëÚØ:" +msgstr "³àÞÜÚ. Üã×ëÚØ:" -#: gui/options.cpp:768 +#: gui/options.cpp:816 msgid "Mute All" -msgstr "²ëÚÛîçØâì Òáñ" +msgstr "²ëÚÛ. Òáñ" -#: gui/options.cpp:771 +#: gui/options.cpp:819 msgid "SFX volume:" -msgstr "³àÞÜÚÞáâì íääÕÚâÞÒ:" +msgstr "³àÞÜÚ. SFX:" -#: gui/options.cpp:771 gui/options.cpp:772 +#: gui/options.cpp:819 gui/options.cpp:820 msgid "Special sound effects volume" msgstr "³àÞÜÚÞáâì áßÕæØÐÛìÝëå ×ÒãÚÞÒëå íääÕÚâÞÒ" -#: gui/options.cpp:778 +#: gui/options.cpp:826 msgid "Speech volume:" -msgstr "³àÞÜÚÞáâì Þ×ÒãçÚØ:" +msgstr "³àÞÜÚ. Þ×ÒãçÚØ:" -#: gui/options.cpp:898 +#: gui/options.cpp:952 msgid "Save Path: " -msgstr "¿ãâì ÔÛï áÞåàÐÝÕÝØÙ: " +msgstr "ÁÞåàÐÝÕÝØï ØÓà:" -#: gui/options.cpp:901 +#: gui/options.cpp:955 msgid "Theme Path:" -msgstr "¿ãâì Ú âÕÜÐÜ:" +msgstr "³ÔÕ âÕÜë:" -#: gui/options.cpp:904 gui/options.cpp:905 +#: gui/options.cpp:958 gui/options.cpp:959 msgid "Specifies path to additional data used by all games or ScummVM" msgstr "" "ÃÚÐ×ëÒÐÕâ ßãâì Ú ÔÞßÞÛÝØâÕÛìÝëÜ äÐÙÛÐÜ ÔÐÝÝëå, ØáßÞÛì×ãÕÜëå ÒáÕÜØ ØÓàÐÜØ, " "ÛØÑÞ ScummVM" -#: gui/options.cpp:908 +#: gui/options.cpp:962 msgid "Plugins Path:" msgstr "¿ãâì Ú ßÛÐÓØÝÐÜ:" -#: gui/options.cpp:913 +#: gui/options.cpp:970 msgid "Misc" msgstr "ÀÐ×ÝÞÕ" -#: gui/options.cpp:915 +#: gui/options.cpp:972 msgid "Theme:" msgstr "ÂÕÜÐ:" -#: gui/options.cpp:919 +#: gui/options.cpp:976 msgid "GUI Renderer:" -msgstr "ÀÐáâÕàØ×ÐâÞà GUI:" +msgstr "ÀØáÞÒÐÛÚÐ GUI:" -#: gui/options.cpp:925 +#: gui/options.cpp:982 msgid "Autosave:" msgstr "°ÒâÞáÞåàÐÝÕÝØÕ:" -#: gui/options.cpp:933 +#: gui/options.cpp:990 msgid "Keys" msgstr "ºÛÐÒØèØ" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "GUI Language:" -msgstr "Ï×ëÚ ØÝâÕàäÕÙáÐ:" +msgstr "Ï×ëÚ GUI:" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "Language of ScummVM GUI" msgstr "Ï×ëÚ ÓàÐäØçÕáÚÞÓÞ ØÝâÕàäÕÙáÐ ScummVM" -#: gui/options.cpp:945 +#: gui/options.cpp:1002 msgid "English" msgstr "English" -#: gui/options.cpp:1089 +#: gui/options.cpp:1146 msgid "You have to restart ScummVM to take the effect." msgstr "²ë ÔÞÛÖÝë ßÕàÕ×ÐßãáâØâì ScummVM çâÞÑë ßàØÜÕÝØâì Ø×ÜÕÝÕÝØï." -#: gui/options.cpp:1102 +#: gui/options.cpp:1159 msgid "Select directory for savegames" msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî ÔÛï áÞåàÐÝÕÝØÙ" -#: gui/options.cpp:1109 +#: gui/options.cpp:1166 msgid "The chosen directory cannot be written to. Please select another one." msgstr "½Õ ÜÞÓã ßØáÐâì Ò ÒëÑàÐÝÝãî ÔØàÕÚâÞàØî. ¿ÞÖÐÛãÙáâÐ, ãÚÐÖØâÕ ÔàãÓãî." -#: gui/options.cpp:1118 +#: gui/options.cpp:1175 msgid "Select directory for GUI themes" msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî ÔÛï âÕÜ GUI" -#: gui/options.cpp:1128 +#: gui/options.cpp:1185 msgid "Select directory for extra files" msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî á ÔÞßÞÛÝØâÕÛìÝëÜØ äÐÙÛÐÜØ" -#: gui/options.cpp:1139 +#: gui/options.cpp:1196 msgid "Select directory for plugins" msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî á ßÛÐÓØÝÐÜØ" @@ -743,15 +749,15 @@ msgstr "ÁÞåàÐÝÕÝØÕ ÑÕ× ØÜÕÝØ" msgid "Select a Theme" msgstr "²ëÑÕàØâÕ âÕÜã" -#: gui/ThemeEngine.cpp:337 +#: gui/ThemeEngine.cpp:334 msgid "Disabled GFX" msgstr "±Õ× ÓàÐäØÚØ" -#: gui/ThemeEngine.cpp:338 +#: gui/ThemeEngine.cpp:335 msgid "Standard Renderer (16bpp)" msgstr "ÁâÐÝÔÐàâÝëÙ àÐáâÕàØ×ÐâÞà (16bpp)" -#: gui/ThemeEngine.cpp:340 +#: gui/ThemeEngine.cpp:337 msgid "Antialiased Renderer (16bpp)" msgstr "ÀÐáâÕàØ×ÐâÞà áÞ áÓÛÐÖØÒÐÝØÕÜ (16bpp)" @@ -873,7 +879,7 @@ msgstr "¾ ßàÞ~Ó~àÐÜÜÕ" #: engines/dialogs.cpp:109 msgid "~R~eturn to Launcher" -msgstr "~²~ÕàÝãâìáï Ò ÓÛÐÒÝÞÕ ÜÕÝî" +msgstr "~²~ëÙâØ Ò ÓÛÐÒÝÞÕ ÜÕÝî" #: engines/dialogs.cpp:119 msgid "Save game:" @@ -928,7 +934,7 @@ msgstr "ÍääÕÚâë ÒÞÔë ÒÚÛîçÕÝë" #: sound/fmopl.cpp:51 msgid "MAME OPL emulator" -msgstr "ÍÜãÛïâÞà MAME OPL:" +msgstr "ÍÜãÛïâÞà MAME OPL" #: sound/fmopl.cpp:53 msgid "DOSBox OPL emulator" @@ -1174,7 +1180,7 @@ msgstr "²ÒÞÔ" #: backends/platform/wii/options.cpp:74 msgid "GC Pad sensitivity:" -msgstr "ÇãÒáâÐØâÕÛìÝÞáâì GC ßÐÔÐ:" +msgstr "ÇãÒáâÒØâÕÛìÝÞáâì GC ßÐÔÐ:" #: backends/platform/wii/options.cpp:80 msgid "GC Pad acceleration:" diff --git a/po/scummvm.pot b/po/scummvm.pot index 6fe4989982..38ce9b1a48 100644 --- a/po/scummvm.pot +++ b/po/scummvm.pot @@ -8,11 +8,10 @@ msgid "" msgstr "" "Project-Id-Version: ScummVM 1.2.0svn\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" -"POT-Creation-Date: 2010-07-12 17:44+0200\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" @@ -39,7 +38,7 @@ msgid "Go to previous directory level" msgstr "" #: gui/browser.cpp:70 gui/chooser.cpp:49 gui/KeysDialog.cpp:46 -#: gui/launcher.cpp:266 gui/massadd.cpp:95 gui/options.cpp:972 +#: gui/launcher.cpp:280 gui/massadd.cpp:95 gui/options.cpp:1029 #: gui/saveload.cpp:65 gui/saveload.cpp:157 gui/themebrowser.cpp:56 #: backends/platform/wii/options.cpp:48 msgid "Cancel" @@ -49,19 +48,19 @@ msgstr "" msgid "Choose" msgstr "" -#: gui/GuiManager.cpp:102 backends/keymapper/remap-dialog.cpp:54 +#: gui/GuiManager.cpp:103 backends/keymapper/remap-dialog.cpp:54 msgid "Close" msgstr "" -#: gui/GuiManager.cpp:105 +#: gui/GuiManager.cpp:106 msgid "Mouse click" msgstr "" -#: gui/GuiManager.cpp:108 base/main.cpp:285 +#: gui/GuiManager.cpp:109 base/main.cpp:285 msgid "Display keyboard" msgstr "" -#: gui/GuiManager.cpp:111 base/main.cpp:288 +#: gui/GuiManager.cpp:112 base/main.cpp:288 msgid "Remap keys" msgstr "" @@ -69,8 +68,8 @@ msgstr "" msgid "Map" msgstr "" -#: gui/KeysDialog.cpp:45 gui/launcher.cpp:267 gui/launcher.cpp:873 -#: gui/launcher.cpp:877 gui/massadd.cpp:92 gui/options.cpp:973 +#: gui/KeysDialog.cpp:45 gui/launcher.cpp:281 gui/launcher.cpp:893 +#: gui/launcher.cpp:897 gui/massadd.cpp:92 gui/options.cpp:1030 #: backends/platform/wii/options.cpp:47 #: backends/platform/wince/CELauncherDialog.cpp:56 msgid "OK" @@ -102,241 +101,249 @@ msgstr "" msgid "Choose an action to map" msgstr "" -#: gui/launcher.cpp:170 +#: gui/launcher.cpp:172 msgid "Game" msgstr "" -#: gui/launcher.cpp:173 +#: gui/launcher.cpp:175 msgid "ID:" msgstr "" -#: gui/launcher.cpp:173 gui/launcher.cpp:174 +#: gui/launcher.cpp:175 gui/launcher.cpp:176 msgid "" "Short game identifier used for referring to savegames and running the game " "from the command line" msgstr "" -#: gui/launcher.cpp:177 +#: gui/launcher.cpp:179 msgid "Name:" msgstr "" -#: gui/launcher.cpp:177 gui/launcher.cpp:178 +#: gui/launcher.cpp:179 gui/launcher.cpp:180 msgid "Full title of the game" msgstr "" -#: gui/launcher.cpp:181 +#: gui/launcher.cpp:183 msgid "Language:" msgstr "" -#: gui/launcher.cpp:181 gui/launcher.cpp:182 +#: gui/launcher.cpp:183 gui/launcher.cpp:184 msgid "" "Language of the game. This will not turn your Spanish game version into " "English" msgstr "" -#: gui/launcher.cpp:183 gui/launcher.cpp:194 gui/options.cpp:80 -#: gui/options.cpp:617 gui/options.cpp:627 gui/options.cpp:943 +#: gui/launcher.cpp:185 gui/launcher.cpp:196 gui/options.cpp:80 +#: gui/options.cpp:635 gui/options.cpp:645 gui/options.cpp:1000 #: sound/null.cpp:42 msgid "<default>" msgstr "" -#: gui/launcher.cpp:192 +#: gui/launcher.cpp:194 msgid "Platform:" msgstr "" -#: gui/launcher.cpp:192 gui/launcher.cpp:193 +#: gui/launcher.cpp:194 gui/launcher.cpp:195 msgid "Platform the game was originally designed for" msgstr "" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "Graphics" msgstr "" -#: gui/launcher.cpp:204 gui/options.cpp:850 gui/options.cpp:867 +#: gui/launcher.cpp:206 gui/options.cpp:898 gui/options.cpp:915 msgid "GFX" msgstr "" -#: gui/launcher.cpp:206 +#: gui/launcher.cpp:208 msgid "Override global graphic settings" msgstr "" -#: gui/launcher.cpp:213 gui/options.cpp:873 +#: gui/launcher.cpp:215 gui/options.cpp:921 msgid "Audio" msgstr "" -#: gui/launcher.cpp:215 +#: gui/launcher.cpp:217 msgid "Override global audio settings" msgstr "" -#: gui/launcher.cpp:223 gui/options.cpp:877 +#: gui/launcher.cpp:225 gui/options.cpp:925 msgid "Volume" msgstr "" -#: gui/launcher.cpp:225 +#: gui/launcher.cpp:227 msgid "Override global volume settings" msgstr "" -#: gui/launcher.cpp:232 gui/options.cpp:885 +#: gui/launcher.cpp:234 gui/options.cpp:933 msgid "MIDI" msgstr "" -#: gui/launcher.cpp:234 +#: gui/launcher.cpp:236 msgid "Override global MIDI settings" msgstr "" -#: gui/launcher.cpp:244 gui/options.cpp:891 +#: gui/launcher.cpp:246 gui/options.cpp:939 +msgid "MT-32" +msgstr "" + +#: gui/launcher.cpp:248 +msgid "Override global MT-32 settings" +msgstr "" + +#: gui/launcher.cpp:258 gui/options.cpp:945 msgid "Paths" msgstr "" -#: gui/launcher.cpp:250 +#: gui/launcher.cpp:264 msgid "Game Path:" msgstr "" -#: gui/launcher.cpp:254 gui/options.cpp:904 +#: gui/launcher.cpp:268 gui/options.cpp:958 msgid "Extra Path:" msgstr "" -#: gui/launcher.cpp:254 gui/launcher.cpp:255 +#: gui/launcher.cpp:268 gui/launcher.cpp:269 msgid "Specifies path to additional data used the game" msgstr "" -#: gui/launcher.cpp:258 +#: gui/launcher.cpp:272 msgid "Save Path:" msgstr "" -#: gui/launcher.cpp:258 gui/launcher.cpp:259 gui/options.cpp:898 -#: gui/options.cpp:899 +#: gui/launcher.cpp:272 gui/launcher.cpp:273 gui/options.cpp:952 +#: gui/options.cpp:953 msgid "Specifies where your savegames are put" msgstr "" -#: gui/launcher.cpp:275 gui/launcher.cpp:353 gui/launcher.cpp:398 -#: gui/options.cpp:245 gui/options.cpp:400 gui/options.cpp:486 -#: gui/options.cpp:545 gui/options.cpp:706 gui/options.cpp:902 -#: gui/options.cpp:905 gui/options.cpp:909 gui/options.cpp:996 -#: gui/options.cpp:1002 gui/options.cpp:1008 gui/options.cpp:1016 -#: gui/options.cpp:1040 gui/options.cpp:1044 gui/options.cpp:1050 -#: gui/options.cpp:1057 gui/options.cpp:1156 +#: gui/launcher.cpp:289 gui/launcher.cpp:369 gui/launcher.cpp:418 +#: gui/options.cpp:230 gui/options.cpp:399 gui/options.cpp:497 +#: gui/options.cpp:555 gui/options.cpp:732 gui/options.cpp:956 +#: gui/options.cpp:959 gui/options.cpp:963 gui/options.cpp:1053 +#: gui/options.cpp:1059 gui/options.cpp:1065 gui/options.cpp:1073 +#: gui/options.cpp:1097 gui/options.cpp:1101 gui/options.cpp:1107 +#: gui/options.cpp:1114 gui/options.cpp:1213 msgid "None" msgstr "" -#: gui/launcher.cpp:280 gui/launcher.cpp:357 +#: gui/launcher.cpp:294 gui/launcher.cpp:373 #: backends/platform/wii/options.cpp:56 msgid "Default" msgstr "" -#: gui/launcher.cpp:391 gui/options.cpp:1150 +#: gui/launcher.cpp:411 gui/options.cpp:1207 msgid "Select SoundFont" msgstr "" -#: gui/launcher.cpp:410 gui/launcher.cpp:548 +#: gui/launcher.cpp:430 gui/launcher.cpp:568 msgid "Select directory with game data" msgstr "" -#: gui/launcher.cpp:428 +#: gui/launcher.cpp:448 msgid "Select additional game directory" msgstr "" -#: gui/launcher.cpp:440 +#: gui/launcher.cpp:460 msgid "Select directory for saved games" msgstr "" -#: gui/launcher.cpp:459 +#: gui/launcher.cpp:479 msgid "This game ID is already taken. Please choose another one." msgstr "" -#: gui/launcher.cpp:500 engines/dialogs.cpp:113 +#: gui/launcher.cpp:520 engines/dialogs.cpp:113 msgid "~Q~uit" msgstr "" -#: gui/launcher.cpp:500 +#: gui/launcher.cpp:520 msgid "Quit ScummVM" msgstr "" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "A~b~out..." msgstr "" -#: gui/launcher.cpp:501 +#: gui/launcher.cpp:521 msgid "About ScummVM" msgstr "" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "~O~ptions..." msgstr "" -#: gui/launcher.cpp:502 +#: gui/launcher.cpp:522 msgid "Change global ScummVM options" msgstr "" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "~S~tart" msgstr "" -#: gui/launcher.cpp:504 +#: gui/launcher.cpp:524 msgid "Start selected game" msgstr "" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "~L~oad..." msgstr "" -#: gui/launcher.cpp:507 +#: gui/launcher.cpp:527 msgid "Load savegame for selected game" msgstr "" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "~A~dd Game..." msgstr "" -#: gui/launcher.cpp:511 +#: gui/launcher.cpp:531 msgid "Hold Shift for Mass Add" msgstr "" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "~E~dit Game..." msgstr "" -#: gui/launcher.cpp:513 +#: gui/launcher.cpp:533 msgid "Change game options" msgstr "" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "~R~emove Game" msgstr "" -#: gui/launcher.cpp:515 +#: gui/launcher.cpp:535 msgid "Remove game from the list. The game data files stay intact" msgstr "" -#: gui/launcher.cpp:522 +#: gui/launcher.cpp:542 msgid "Search in game list" msgstr "" -#: gui/launcher.cpp:526 gui/launcher.cpp:1037 +#: gui/launcher.cpp:546 gui/launcher.cpp:1057 msgid "Search:" msgstr "" -#: gui/launcher.cpp:529 gui/options.cpp:707 +#: gui/launcher.cpp:549 gui/options.cpp:733 msgid "Clear value" msgstr "" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 msgid "Load game:" msgstr "" -#: gui/launcher.cpp:551 engines/dialogs.cpp:117 +#: gui/launcher.cpp:571 engines/dialogs.cpp:117 #: backends/platform/wince/CEActionsPocket.cpp:263 #: backends/platform/wince/CEActionsSmartphone.cpp:225 msgid "Load" msgstr "" -#: gui/launcher.cpp:660 +#: gui/launcher.cpp:680 msgid "" "Do you really want to run the mass game detector? This could potentially add " "a huge number of games." msgstr "" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -344,7 +351,7 @@ msgstr "" msgid "Yes" msgstr "" -#: gui/launcher.cpp:661 gui/launcher.cpp:810 +#: gui/launcher.cpp:681 gui/launcher.cpp:830 #: backends/platform/symbian/src/SymbianOS.cpp:446 #: backends/platform/wince/CEActionsPocket.cpp:313 #: backends/platform/wince/CEActionsSmartphone.cpp:272 @@ -352,35 +359,35 @@ msgstr "" msgid "No" msgstr "" -#: gui/launcher.cpp:708 +#: gui/launcher.cpp:728 msgid "ScummVM couldn't open the specified directory!" msgstr "" -#: gui/launcher.cpp:720 +#: gui/launcher.cpp:740 msgid "ScummVM could not find any game in the specified directory!" msgstr "" -#: gui/launcher.cpp:734 +#: gui/launcher.cpp:754 msgid "Pick the game:" msgstr "" -#: gui/launcher.cpp:810 +#: gui/launcher.cpp:830 msgid "Do you really want to remove this game configuration?" msgstr "" -#: gui/launcher.cpp:873 +#: gui/launcher.cpp:893 msgid "This game does not support loading games from the launcher." msgstr "" -#: gui/launcher.cpp:877 +#: gui/launcher.cpp:897 msgid "ScummVM could not find any engine capable of running the selected game!" msgstr "" -#: gui/launcher.cpp:989 +#: gui/launcher.cpp:1009 msgid "Mass Add..." msgstr "" -#: gui/launcher.cpp:990 +#: gui/launcher.cpp:1010 msgid "Add Game..." msgstr "" @@ -447,239 +454,239 @@ msgstr "" msgid "48 kHz" msgstr "" -#: gui/options.cpp:614 +#: gui/options.cpp:632 msgid "Graphics mode:" msgstr "" -#: gui/options.cpp:625 +#: gui/options.cpp:643 msgid "Render mode:" msgstr "" -#: gui/options.cpp:625 gui/options.cpp:626 +#: gui/options.cpp:643 gui/options.cpp:644 msgid "Special dithering modes supported by some games" msgstr "" -#: gui/options.cpp:635 +#: gui/options.cpp:653 msgid "Fullscreen mode" msgstr "" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Aspect ratio correction" msgstr "" -#: gui/options.cpp:638 +#: gui/options.cpp:656 msgid "Correct aspect ratio for 320x200 games" msgstr "" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Preferred Device:" msgstr "" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Music Device:" msgstr "" -#: gui/options.cpp:645 +#: gui/options.cpp:663 msgid "Specifies preferred sound device or sound card emulator" msgstr "" -#: gui/options.cpp:645 gui/options.cpp:646 +#: gui/options.cpp:663 gui/options.cpp:664 msgid "Specifies output sound device or sound card emulator" msgstr "" -#: gui/options.cpp:648 -msgid "MT-32 Device:" -msgstr "" - -#: gui/options.cpp:648 -msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" -msgstr "" - -#: gui/options.cpp:650 -msgid "GM Device:" -msgstr "" - -#: gui/options.cpp:650 -msgid "Specifies default sound device for General MIDI output" -msgstr "" - -#: gui/options.cpp:682 +#: gui/options.cpp:688 msgid "AdLib emulator:" msgstr "" -#: gui/options.cpp:682 gui/options.cpp:683 +#: gui/options.cpp:688 gui/options.cpp:689 msgid "AdLib is used for music in many games" msgstr "" -#: gui/options.cpp:693 +#: gui/options.cpp:699 msgid "Output rate:" msgstr "" -#: gui/options.cpp:693 gui/options.cpp:694 +#: gui/options.cpp:699 gui/options.cpp:700 msgid "" "Higher value specifies better sound quality but may be not supported by your " "soundcard" msgstr "" -#: gui/options.cpp:705 +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "" + +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "" + +#: gui/options.cpp:731 msgid "SoundFont:" msgstr "" -#: gui/options.cpp:705 gui/options.cpp:706 +#: gui/options.cpp:731 gui/options.cpp:732 msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" msgstr "" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Mixed AdLib/MIDI mode" msgstr "" -#: gui/options.cpp:710 +#: gui/options.cpp:736 msgid "Use both MIDI and AdLib sound generation" msgstr "" -#: gui/options.cpp:713 +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "" + +#: gui/options.cpp:749 +msgid "MT-32 Device:" +msgstr "" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "" + +#: gui/options.cpp:753 msgid "True Roland MT-32 (disable GM emulation)" msgstr "" -#: gui/options.cpp:713 +#: gui/options.cpp:753 msgid "" "Check if you want to use your real hardware Roland-compatible sound device " "connected to your computer" msgstr "" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Enable Roland GS Mode" msgstr "" -#: gui/options.cpp:716 +#: gui/options.cpp:756 msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" msgstr "" -#: gui/options.cpp:719 -msgid "MIDI gain:" -msgstr "" - -#: gui/options.cpp:732 +#: gui/options.cpp:780 msgid "Text and Speech:" msgstr "" -#: gui/options.cpp:737 gui/options.cpp:743 +#: gui/options.cpp:785 gui/options.cpp:791 msgid "Speech" msgstr "" -#: gui/options.cpp:738 gui/options.cpp:744 +#: gui/options.cpp:786 gui/options.cpp:792 msgid "Subtitles" msgstr "" -#: gui/options.cpp:739 gui/options.cpp:745 +#: gui/options.cpp:787 gui/options.cpp:793 msgid "Both" msgstr "" -#: gui/options.cpp:743 +#: gui/options.cpp:791 msgid "Spch" msgstr "" -#: gui/options.cpp:744 +#: gui/options.cpp:792 msgid "Subs" msgstr "" -#: gui/options.cpp:745 +#: gui/options.cpp:793 msgid "Show subtitles and play speech" msgstr "" -#: gui/options.cpp:749 +#: gui/options.cpp:797 msgid "Subtitle speed:" msgstr "" -#: gui/options.cpp:761 +#: gui/options.cpp:809 msgid "Music volume:" msgstr "" -#: gui/options.cpp:768 +#: gui/options.cpp:816 msgid "Mute All" msgstr "" -#: gui/options.cpp:771 +#: gui/options.cpp:819 msgid "SFX volume:" msgstr "" -#: gui/options.cpp:771 gui/options.cpp:772 +#: gui/options.cpp:819 gui/options.cpp:820 msgid "Special sound effects volume" msgstr "" -#: gui/options.cpp:778 +#: gui/options.cpp:826 msgid "Speech volume:" msgstr "" -#: gui/options.cpp:898 +#: gui/options.cpp:952 msgid "Save Path: " msgstr "" -#: gui/options.cpp:901 +#: gui/options.cpp:955 msgid "Theme Path:" msgstr "" -#: gui/options.cpp:904 gui/options.cpp:905 +#: gui/options.cpp:958 gui/options.cpp:959 msgid "Specifies path to additional data used by all games or ScummVM" msgstr "" -#: gui/options.cpp:908 +#: gui/options.cpp:962 msgid "Plugins Path:" msgstr "" -#: gui/options.cpp:913 +#: gui/options.cpp:970 msgid "Misc" msgstr "" -#: gui/options.cpp:915 +#: gui/options.cpp:972 msgid "Theme:" msgstr "" -#: gui/options.cpp:919 +#: gui/options.cpp:976 msgid "GUI Renderer:" msgstr "" -#: gui/options.cpp:925 +#: gui/options.cpp:982 msgid "Autosave:" msgstr "" -#: gui/options.cpp:933 +#: gui/options.cpp:990 msgid "Keys" msgstr "" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "GUI Language:" msgstr "" -#: gui/options.cpp:940 +#: gui/options.cpp:997 msgid "Language of ScummVM GUI" msgstr "" -#: gui/options.cpp:945 +#: gui/options.cpp:1002 msgid "English" msgstr "" -#: gui/options.cpp:1089 +#: gui/options.cpp:1146 msgid "You have to restart ScummVM to take the effect." msgstr "" -#: gui/options.cpp:1102 +#: gui/options.cpp:1159 msgid "Select directory for savegames" msgstr "" -#: gui/options.cpp:1109 +#: gui/options.cpp:1166 msgid "The chosen directory cannot be written to. Please select another one." msgstr "" -#: gui/options.cpp:1118 +#: gui/options.cpp:1175 msgid "Select directory for GUI themes" msgstr "" -#: gui/options.cpp:1128 +#: gui/options.cpp:1185 msgid "Select directory for extra files" msgstr "" -#: gui/options.cpp:1139 +#: gui/options.cpp:1196 msgid "Select directory for plugins" msgstr "" @@ -723,15 +730,15 @@ msgstr "" msgid "Select a Theme" msgstr "" -#: gui/ThemeEngine.cpp:337 +#: gui/ThemeEngine.cpp:334 msgid "Disabled GFX" msgstr "" -#: gui/ThemeEngine.cpp:338 +#: gui/ThemeEngine.cpp:335 msgid "Standard Renderer (16bpp)" msgstr "" -#: gui/ThemeEngine.cpp:340 +#: gui/ThemeEngine.cpp:337 msgid "Antialiased Renderer (16bpp)" msgstr "" diff --git a/po/uk_UA.po b/po/uk_UA.po new file mode 100644 index 0000000000..fdbfcb89a4 --- /dev/null +++ b/po/uk_UA.po @@ -0,0 +1,1433 @@ +# Ukrainian translation for ScummVM. +# Copyright (C) 2010 ScummVM +# This file is distributed under the same license as the ScummVM package. +# Lubomyr Lisen , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: ScummVM VERSION\n" +"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" +"POT-Creation-Date: 2010-07-30 22:14+0100\n" +"PO-Revision-Date: 2010-07-30 22:19+0100\n" +"Last-Translator: Lubomyr Lisen\n" +"Language-Team: Ukrainian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-5\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: Ukrainian\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: gui/about.cpp:96 +#, c-format +msgid "(built on %s)" +msgstr "(×öÑàÐÝØÙ %s)" + +#: gui/about.cpp:103 +msgid "Features compiled in:" +msgstr "²ÚÛîçÕÝö Ò ÑöÛÔ Þßæö÷:" + +#: gui/about.cpp:112 +msgid "Available engines:" +msgstr "´ÞáâãßÝö ÔÒØÖÚØ:" + +#: gui/browser.cpp:69 +msgid "Go up" +msgstr "²ÒÕàå" + +#: gui/browser.cpp:69 +msgid "Go to previous directory level" +msgstr "¿ÕàÕÙâØ ÝÐ ßÐßÚã àöÒÝÕÜ ÒØéÕ" + +#: gui/browser.cpp:70 +#: gui/chooser.cpp:49 +#: gui/KeysDialog.cpp:46 +#: gui/launcher.cpp:280 +#: gui/massadd.cpp:95 +#: gui/options.cpp:1029 +#: gui/saveload.cpp:65 +#: gui/saveload.cpp:157 +#: gui/themebrowser.cpp:56 +#: backends/platform/wii/options.cpp:48 +msgid "Cancel" +msgstr "²öÔÜöÝÐ" + +#: gui/browser.cpp:71 +#: gui/chooser.cpp:50 +#: gui/themebrowser.cpp:57 +msgid "Choose" +msgstr "²ØÑàÐâØ" + +#: gui/GuiManager.cpp:103 +#: backends/keymapper/remap-dialog.cpp:54 +msgid "Close" +msgstr "·ÐÚàØâØ" + +#: gui/GuiManager.cpp:106 +msgid "Mouse click" +msgstr "ºÛöÚ ÜØèÚÞî" + +#: gui/GuiManager.cpp:109 +#: base/main.cpp:285 +msgid "Display keyboard" +msgstr "¿ÞÚÐ×ÐâØ ÚÛÐÒöÐâãàã" + +#: gui/GuiManager.cpp:112 +#: base/main.cpp:288 +msgid "Remap keys" +msgstr "¿ÕàÕßàØ×ÝÐçØâØ ÚÛÐÒöèö" + +#: gui/KeysDialog.cpp:44 +msgid "Map" +msgstr "¿àØ×ÝÐçØâØ" + +#: gui/KeysDialog.cpp:45 +#: gui/launcher.cpp:281 +#: gui/launcher.cpp:893 +#: gui/launcher.cpp:897 +#: gui/massadd.cpp:92 +#: gui/options.cpp:1030 +#: backends/platform/wii/options.cpp:47 +#: backends/platform/wince/CELauncherDialog.cpp:56 +msgid "OK" +msgstr "OK" + +#: gui/KeysDialog.cpp:52 +msgid "Select an action and click 'Map'" +msgstr "²ØÑÕàöâì Ôöî ö ÚÛöÚÝöâì '¿àØ×ÝÐçØâØ'" + +#: gui/KeysDialog.cpp:83 +#: gui/KeysDialog.cpp:105 +#: gui/KeysDialog.cpp:144 +#, c-format +msgid "Associated key : %s" +msgstr "¿àØ×ÝÐçÕÝÐ ÚÛÐÒöèÐ : %s" + +#: gui/KeysDialog.cpp:85 +#: gui/KeysDialog.cpp:107 +#: gui/KeysDialog.cpp:146 +#, c-format +msgid "Associated key : none" +msgstr "¿àØ×ÝÐçÕÝÐ ÚÛÐÒöèÐ : ÝÕÜÐô" + +#: gui/KeysDialog.cpp:93 +msgid "Please select an action" +msgstr "±ãÔì ÛÐáÚÐ, ÒØÑÕàöâì Ôöî" + +#: gui/KeysDialog.cpp:109 +msgid "Press the key to associate" +msgstr "½ÐâØáÝöâì ÚÛÐÒöèã ÔÛï ßàØ×ÝÐçÕÝÝï" + +#: gui/KeysDialog.cpp:148 +msgid "Choose an action to map" +msgstr "²ØÑÕàöâì Ôöî ÔÛï ßàØ×ÝÐçÕÝÝï" + +#: gui/launcher.cpp:172 +msgid "Game" +msgstr "³àÐ" + +#: gui/launcher.cpp:175 +msgid "ID:" +msgstr "ID:" + +#: gui/launcher.cpp:175 +#: gui/launcher.cpp:176 +msgid "Short game identifier used for referring to savegames and running the game from the command line" +msgstr "ºÞàÞâÚØÙ öÔÕÝâØäöÚÐâÞà, ïÚØÙ ÒØÚÞàØáâÞÒãôâìáï ÔÛï ÝÐ×Ò ×ÑÕàÕÖÕÝØå öÓÞà ö ÔÛï ×ÐßãáÚã × ÚÞÜÐÝÔÝÞ÷ áâàöçÚØ" + +#: gui/launcher.cpp:179 +msgid "Name:" +msgstr "½Ð×ÒÐ:" + +#: gui/launcher.cpp:179 +#: gui/launcher.cpp:180 +msgid "Full title of the game" +msgstr "¿ÞÒÝÐ ÝÐ×ÒÐ ÓàØ" + +#: gui/launcher.cpp:183 +msgid "Language:" +msgstr "¼ÞÒÐ:" + +#: gui/launcher.cpp:183 +#: gui/launcher.cpp:184 +msgid "Language of the game. This will not turn your Spanish game version into English" +msgstr "¼ÞÒÐ ÓàØ. ·ÜöÝÐ æìÞÓÞ ßÐàÐÜÕâàã ÝÕ ßÕàÕâÒÞàØâì Óàã ÝÐ ÐÝÓÛöÙáìÚöÙ Ò ãÚàÐ÷ÝáìÚã" + +#: gui/launcher.cpp:185 +#: gui/launcher.cpp:196 +#: gui/options.cpp:80 +#: gui/options.cpp:635 +#: gui/options.cpp:645 +#: gui/options.cpp:1000 +#: sound/null.cpp:42 +msgid "<default>" +msgstr "<×Ð ãÜÞÒçÐÝÝïÜ>" + +#: gui/launcher.cpp:194 +msgid "Platform:" +msgstr "¿ÛÐâäÞàÜÐ:" + +#: gui/launcher.cpp:194 +#: gui/launcher.cpp:195 +msgid "Platform the game was originally designed for" +msgstr "¿ÛÐâäÞàÜÐ, ÔÛï ïÚÞ÷ ÓàÐ ÑãÛÐ áßÞçÐâÚã àÞ×àÞÑÛÕÝÐ" + +#: gui/launcher.cpp:206 +#: gui/options.cpp:898 +#: gui/options.cpp:915 +msgid "Graphics" +msgstr "³àÐäöÚÐ" + +#: gui/launcher.cpp:206 +#: gui/options.cpp:898 +#: gui/options.cpp:915 +msgid "GFX" +msgstr "³àä" + +#: gui/launcher.cpp:208 +msgid "Override global graphic settings" +msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÓàÐäöÚØ" + +#: gui/launcher.cpp:215 +#: gui/options.cpp:921 +msgid "Audio" +msgstr "°ãÔöÞ" + +#: gui/launcher.cpp:217 +msgid "Override global audio settings" +msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÐãÔöÞ" + +#: gui/launcher.cpp:225 +#: gui/options.cpp:925 +msgid "Volume" +msgstr "³ãçÝöáâì" + +#: gui/launcher.cpp:227 +msgid "Override global volume settings" +msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÓãçÝÞáâö" + +#: gui/launcher.cpp:234 +#: gui/options.cpp:933 +msgid "MIDI" +msgstr "MIDI" + +#: gui/launcher.cpp:236 +msgid "Override global MIDI settings" +msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ MIDI" + +#: gui/launcher.cpp:246 +#: gui/options.cpp:939 +#, fuzzy +msgid "MT-32" +msgstr "MT-32" + +#: gui/launcher.cpp:248 +#, fuzzy +msgid "Override global MT-32 settings" +msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ MT-32" + +#: gui/launcher.cpp:258 +#: gui/options.cpp:945 +msgid "Paths" +msgstr "ÈÛïåØ" + +#: gui/launcher.cpp:264 +msgid "Game Path:" +msgstr "ÈÛïå ÔÞ ÓàØ: " + +#: gui/launcher.cpp:268 +#: gui/options.cpp:958 +msgid "Extra Path:" +msgstr "´ÞÔ. èÛïå:" + +#: gui/launcher.cpp:268 +#: gui/launcher.cpp:269 +msgid "Specifies path to additional data used the game" +msgstr "²ÚÐ×ãô èÛïå ÔÞ ÔÞÔÐâÚÞÒØå äÐÙÛöÒ ÔÐÝØå ÔÛï ÓàØ" + +#: gui/launcher.cpp:272 +msgid "Save Path:" +msgstr "ÈÛïå ×ÑÕà.: " + +#: gui/launcher.cpp:272 +#: gui/launcher.cpp:273 +#: gui/options.cpp:952 +#: gui/options.cpp:953 +msgid "Specifies where your savegames are put" +msgstr "²ÚÐ×ãô èÛïå ÔÞ ×ÑÕàÕÖÕÝì ÓàØ" + +#: gui/launcher.cpp:289 +#: gui/launcher.cpp:369 +#: gui/launcher.cpp:418 +#: gui/options.cpp:230 +#: gui/options.cpp:399 +#: gui/options.cpp:497 +#: gui/options.cpp:555 +#: gui/options.cpp:732 +#: gui/options.cpp:956 +#: gui/options.cpp:959 +#: gui/options.cpp:963 +#: gui/options.cpp:1053 +#: gui/options.cpp:1059 +#: gui/options.cpp:1065 +#: gui/options.cpp:1073 +#: gui/options.cpp:1097 +#: gui/options.cpp:1101 +#: gui/options.cpp:1107 +#: gui/options.cpp:1114 +#: gui/options.cpp:1213 +msgid "None" +msgstr "½Õ ×ÐÔÐÝØÙ" + +#: gui/launcher.cpp:294 +#: gui/launcher.cpp:373 +#: backends/platform/wii/options.cpp:56 +msgid "Default" +msgstr "·Ð ãÜÞÒçÐÝÝïÜ" + +#: gui/launcher.cpp:411 +#: gui/options.cpp:1207 +msgid "Select SoundFont" +msgstr "²ØÑÕàöâì SoundFont" + +#: gui/launcher.cpp:430 +#: gui/launcher.cpp:568 +msgid "Select directory with game data" +msgstr "²ØÑÕàöâì ßÐßÚã × äÐÙÛÐÜØ ÓàØ" + +#: gui/launcher.cpp:448 +msgid "Select additional game directory" +msgstr "²ØÑÕàöâì ÔÞÔÐâÚÞÒã ßÐßÚã ÓàØ" + +#: gui/launcher.cpp:460 +msgid "Select directory for saved games" +msgstr "²ØÑÕàöâì ßÐßÚã ÔÛï ×ÑÕàÕÖÕÝì" + +#: gui/launcher.cpp:479 +msgid "This game ID is already taken. Please choose another one." +msgstr "ÆÕÙ ID ÓàØ ÒÖÕ ÒØÚÞàØáâÞÒãôâìáï. ±ãÔì ÛÐáÚÐ, ÒØÑÕàöâì öÝèØÙ." + +#: gui/launcher.cpp:520 +#: engines/dialogs.cpp:113 +msgid "~Q~uit" +msgstr "~²~ØåöÔ" + +#: gui/launcher.cpp:520 +msgid "Quit ScummVM" +msgstr "²ØåöÔ × ScummVM" + +#: gui/launcher.cpp:521 +msgid "A~b~out..." +msgstr "¿àÞ ß~à~ÞÓàÐÜã..." + +#: gui/launcher.cpp:521 +msgid "About ScummVM" +msgstr "¿àÞ ScummVM" + +#: gui/launcher.cpp:522 +msgid "~O~ptions..." +msgstr "~¾~ßæö÷..." + +#: gui/launcher.cpp:522 +msgid "Change global ScummVM options" +msgstr "·ÜöÝØâØ ÓÛÞÑÐÛìÝö Þßæö÷ ScummVM" + +#: gui/launcher.cpp:524 +msgid "~S~tart" +msgstr "·~Ð~ßãáÚ" + +#: gui/launcher.cpp:524 +msgid "Start selected game" +msgstr "·ÐßãáâØâØ ÒØÑàÐÝã Óàã" + +#: gui/launcher.cpp:527 +msgid "~L~oad..." +msgstr "~·~ÐÒÐÝ..." + +#: gui/launcher.cpp:527 +msgid "Load savegame for selected game" +msgstr "·ÐÒÐÝâÐÖØâØ ×ÑÕàÕÖÕÝÝï ÔÛï ÒØÑàÐÝÞ÷ ÓàØ" + +#: gui/launcher.cpp:531 +msgid "~A~dd Game..." +msgstr "~´~ÞÔ. Óàã..." + +#: gui/launcher.cpp:531 +msgid "Hold Shift for Mass Add" +msgstr "ÃâàØÜãÙâÕ ÚÛÐÒöèã Shift ÔÛï âÞÓÞ, éÞÑ ÔÞÔÐâØ ÔÕÚöÛìÚÐ öÓÞà" + +#: gui/launcher.cpp:533 +msgid "~E~dit Game..." +msgstr "ÀÕÔÐ~Ó~. Óàã..." + +#: gui/launcher.cpp:533 +msgid "Change game options" +msgstr "·ÜöÝØâØ Þßæö÷ ÓàØ" + +#: gui/launcher.cpp:535 +msgid "~R~emove Game" +msgstr "~²~ØÔÐÛØâØ Óàã" + +#: gui/launcher.cpp:535 +msgid "Remove game from the list. The game data files stay intact" +msgstr "²ØÔÐÛØâØ Óàã ×ö áßØáÚã. ½Õ ÒØÔÐÛïô Óàã × ÖÞàáâÚÞÓÞ ÔØáÚÐ" + +#: gui/launcher.cpp:542 +msgid "Search in game list" +msgstr "¿ÞèãÚ Ò áßØáÚã öÓÞà" + +#: gui/launcher.cpp:546 +#: gui/launcher.cpp:1057 +msgid "Search:" +msgstr "¿ÞèãÚ:" + +#: gui/launcher.cpp:549 +#: gui/options.cpp:733 +msgid "Clear value" +msgstr "¾çØáâØâØ ×ÝÐçÕÝÝï" + +#: gui/launcher.cpp:571 +#: engines/dialogs.cpp:117 +msgid "Load game:" +msgstr "·ÐÒÐÝâÐÖØâØ Óàã:" + +#: gui/launcher.cpp:571 +#: engines/dialogs.cpp:117 +#: backends/platform/wince/CEActionsPocket.cpp:263 +#: backends/platform/wince/CEActionsSmartphone.cpp:225 +msgid "Load" +msgstr "·ÐÒÐÝâÐÖØâØ" + +#: gui/launcher.cpp:680 +msgid "Do you really want to run the mass game detector? This could potentially add a huge number of games." +msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ×ÐßãáâØâØ ÔÕâÕÚâÞà ãáöå öÓÞà? ÆÕ ßÞâÕÝæöÙÝÞ ÜÞÖÕ ÔÞÔÐâØ ÒÕÛØÚã ÚöÛìÚöáâì öÓÞà." + +#: gui/launcher.cpp:681 +#: gui/launcher.cpp:830 +#: backends/platform/symbian/src/SymbianOS.cpp:446 +#: backends/platform/wince/CEActionsPocket.cpp:313 +#: backends/platform/wince/CEActionsSmartphone.cpp:272 +#: backends/platform/wince/CELauncherDialog.cpp:104 +msgid "Yes" +msgstr "ÂÐÚ" + +#: gui/launcher.cpp:681 +#: gui/launcher.cpp:830 +#: backends/platform/symbian/src/SymbianOS.cpp:446 +#: backends/platform/wince/CEActionsPocket.cpp:313 +#: backends/platform/wince/CEActionsSmartphone.cpp:272 +#: backends/platform/wince/CELauncherDialog.cpp:104 +msgid "No" +msgstr "½ö" + +#: gui/launcher.cpp:728 +msgid "ScummVM couldn't open the specified directory!" +msgstr "ScummVM ÝÕ ÜÞÖÕ ÒöÔÚàØâØ ÒÚÐ×ÐÝã ßÐßÚã!" + +#: gui/launcher.cpp:740 +msgid "ScummVM could not find any game in the specified directory!" +msgstr "ScummVM ÝÕ ÜÞÖÕ ×ÝÐÙâØ Óàã ã ÒÚÐ×ÐÝöÙ ßÐßæö!" + +#: gui/launcher.cpp:754 +msgid "Pick the game:" +msgstr "²ØÑÕàöâì Óàã:" + +#: gui/launcher.cpp:830 +msgid "Do you really want to remove this game configuration?" +msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ÒØÔÐÛØâØ ãáâÐÝÞÒÚØ ÔÛï æöô÷ ÓàØ?" + +#: gui/launcher.cpp:893 +msgid "This game does not support loading games from the launcher." +msgstr "Æï ÓàÐ ÝÕ ßöÔâàØÜãô ×ÐÒÐÝâÐÖÕÝÝï ×ÑÕàÕÖÕÝì çÕàÕ× ÓÞÛÞÒÝÕ ÜÕÝî." + +#: gui/launcher.cpp:897 +msgid "ScummVM could not find any engine capable of running the selected game!" +msgstr "ScummVM ÝÕ ×ÜöÓ ×ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚã ÒØÑàÐÝÞ÷ ÓàØ!" + +#: gui/launcher.cpp:1009 +msgid "Mass Add..." +msgstr "´ÞÔ. ÑÐÓÐâÞ..." + +#: gui/launcher.cpp:1010 +msgid "Add Game..." +msgstr "´ÞÔ. Óàã..." + +#: gui/massadd.cpp:79 +#: gui/massadd.cpp:82 +msgid "... progress ..." +msgstr "... ßÞèãÚ ..." + +#: gui/massadd.cpp:244 +msgid "Scan complete!" +msgstr "¿ÞèãÚ ×ÐÚöÝçÕÝØÙ!" + +#: gui/massadd.cpp:247 +#, c-format +msgid "Discovered %d new games." +msgstr "·ÝÐÙÔÕÝÞ %d ÝÞÒØå öÓÞà." + +#: gui/massadd.cpp:251 +#, c-format +msgid "Scanned %d directories ..." +msgstr "¿àÞÓÛïÝãâÞ %d ßÐßÞÚ ..." + +#: gui/massadd.cpp:254 +#, c-format +msgid "Discovered %d new games ..." +msgstr "·ÝÐÙÔÕÝÞ %d ÝÞÒØå öÓÞà ..." + +#: gui/options.cpp:78 +msgid "Never" +msgstr "½öÚÞÛØ" + +#: gui/options.cpp:78 +msgid "every 5 mins" +msgstr "ÚÞÖÝö 5 åÒ" + +#: gui/options.cpp:78 +msgid "every 10 mins" +msgstr "ÚÞÖÝö 10 åÒ" + +#: gui/options.cpp:78 +msgid "every 15 mins" +msgstr "ÚÞÖÝö 15 åÒ" + +#: gui/options.cpp:78 +msgid "every 30 mins" +msgstr "ÚÞÖÝö 30 åÒ" + +#: gui/options.cpp:80 +msgid "8 kHz" +msgstr "8 Ú³æ" + +#: gui/options.cpp:80 +msgid "11kHz" +msgstr "11 Ú³æ" + +#: gui/options.cpp:80 +msgid "22 kHz" +msgstr "22 Ú³æ" + +#: gui/options.cpp:80 +msgid "44 kHz" +msgstr "44 Ú³æ" + +#: gui/options.cpp:80 +msgid "48 kHz" +msgstr "48 Ú³æ" + +#: gui/options.cpp:632 +msgid "Graphics mode:" +msgstr "³àÐäöçÝØÙ àÕÖØÜ:" + +#: gui/options.cpp:643 +msgid "Render mode:" +msgstr "ÀÕÖØÜ àÐáâàãÒÐÝÝï:" + +#: gui/options.cpp:643 +#: gui/options.cpp:644 +msgid "Special dithering modes supported by some games" +msgstr "ÁßÕæöÐÛìÝö àÕÖØÜØ àÕÝÔÕàØÝÓã, ïÚö ßöÔâàØÜãîâì ÔÕïÚö öÓàØ" + +#: gui/options.cpp:653 +msgid "Fullscreen mode" +msgstr "¿ÞÒÝÞÕÚàÐÝÝØÙ àÕÖØÜ" + +#: gui/options.cpp:656 +msgid "Aspect ratio correction" +msgstr "ºÞàÕÚæöï áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ" + +#: gui/options.cpp:656 +msgid "Correct aspect ratio for 320x200 games" +msgstr "ºÞàØÓãÒÐâØ áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ ÔÛï öÓÞà × ÓàÐäöÚÞî 320x200" + +#: gui/options.cpp:663 +msgid "Preferred Device:" +msgstr "¿àØáâàöÙ ïÚÞÜã ÒöÔÔÐôâìáï ßÕàÕÒÐÓÐ:" + +#: gui/options.cpp:663 +#, fuzzy +msgid "Music Device:" +msgstr "¼ã×ØçÝØÙ ¿àØáâàöÙ:" + +#: gui/options.cpp:663 +msgid "Specifies preferred sound device or sound card emulator" +msgstr "²ÚÐ×ãô ÒØåöÔÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ ÐÑÞ ÕÜãÛïâÞà ×ÒãÚÞÒÞ÷ ÚÐàâØ" + +#: gui/options.cpp:663 +#: gui/options.cpp:664 +msgid "Specifies output sound device or sound card emulator" +msgstr "²ÚÐ×ãô ÒØåöÔÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ ÐÑÞ ÕÜãÛïâÞà ×ÒãÚÞÒÞ÷ ÚÐàâØ" + +#: gui/options.cpp:688 +msgid "AdLib emulator:" +msgstr "µÜãÛïâÞà AdLib:" + +#: gui/options.cpp:688 +#: gui/options.cpp:689 +msgid "AdLib is used for music in many games" +msgstr "·ÒãÚÞÒÐ ÚÐàâÐ AdLib ÒØÚÞàØáâÞÒãôâìáï ÑÐÓÐâìÜÐ öÓàÐÜØ" + +#: gui/options.cpp:699 +msgid "Output rate:" +msgstr "²ØåöÔÝÐ çÐáâÞâÐ:" + +#: gui/options.cpp:699 +#: gui/options.cpp:700 +msgid "Higher value specifies better sound quality but may be not supported by your soundcard" +msgstr "²ÕÛØÚö ×ÝÐçÕÝÝï ×ÐÔÐîâì ÚàÐéã ïÚöáâì ×ÒãÚã, ßàÞâÕ ÒÞÝØ ÜÞÖãâì ÝÕ ßöÔâàØÜãÒÐâØáï ÒÐèÞî ×ÒãÚÞÒÞî ÚÐàâÞî" + +#: gui/options.cpp:710 +msgid "GM Device:" +msgstr "¿àØáâàöÙ GM:" + +#: gui/options.cpp:710 +msgid "Specifies default sound device for General MIDI output" +msgstr "²ÚÐ×ãô ÒØåöÔÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ ÔÛï MIDI" + +#: gui/options.cpp:731 +msgid "SoundFont:" +msgstr "SoundFont:" + +#: gui/options.cpp:731 +#: gui/options.cpp:732 +msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity" +msgstr "SoundFont ßöÔâàØÜãôâìáï ÔÕïÚØÜØ ×ÒãÚÞÒØÜØ ÚÐàâÐÜØ, Fluidsynth ö Timidity" + +#: gui/options.cpp:736 +msgid "Mixed AdLib/MIDI mode" +msgstr "·ÜöèÐÝØÙ àÕÖØÜ AdLib/MIDI" + +#: gui/options.cpp:736 +msgid "Use both MIDI and AdLib sound generation" +msgstr "²ØÚÞàØáâÞÒãÒÐâØ ö MIDI ö AdLib ÔÛï ÓÕÝÕàÐæö÷ ×ÒãÚã" + +#: gui/options.cpp:739 +msgid "MIDI gain:" +msgstr "¿ÞáØÛÕÝÝï MIDI:" + +#: gui/options.cpp:749 +#, fuzzy +msgid "MT-32 Device:" +msgstr "¿àØáâàöÙ MT-32:" + +#: gui/options.cpp:749 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "²ÚÐ×ãô ×ÒãÚÞÒØÙ ßàØáâàöÙ ßÞ ãÜÞÒçÐÝÝî ÔÛï ÒØÒÞÔã ÝÐ Roland MT-32/LAPC1/CM32l/CM64" + +#: gui/options.cpp:753 +msgid "True Roland MT-32 (disable GM emulation)" +msgstr "ÁßàÐÒÖÝöÙ Roland MT-32 (ÒØÜÚÝãâØ ÕÜãÛïæØî GM)" + +#: gui/options.cpp:753 +msgid "Check if you want to use your real hardware Roland-compatible sound device connected to your computer" +msgstr "²öÔÜöâìâÕ, ïÚéÞ ã ÒÐá ßöÔÚÛîçÕÝØÙ Roland-áãÜöáÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ ö ÒØ åÞçÕâÕ ÙÞÓÞ ÒØÚÞàØáâÐâØ" + +#: gui/options.cpp:756 +msgid "Enable Roland GS Mode" +msgstr "ÃÒöÜÚÝãâØ àÕÖØÜ Roland GS" + +#: gui/options.cpp:756 +msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" +msgstr "²ØÜØÚÐô ÜÐßßöÝÓ General MIDI ÔÛï öÓÞà ö× ×ÒãÚÞÒÞî ÔÞàöÖÚÞî ÔÛï Roland MT-32" + +#: gui/options.cpp:780 +msgid "Text and Speech:" +msgstr "ÂÕÚáâ ö Þ×ÒãçÕÝÝï:" + +#: gui/options.cpp:785 +#: gui/options.cpp:791 +msgid "Speech" +msgstr "¾×ÒãçÕÝÝï" + +#: gui/options.cpp:786 +#: gui/options.cpp:792 +msgid "Subtitles" +msgstr "ÁãÑâØâàØ" + +#: gui/options.cpp:787 +#: gui/options.cpp:793 +msgid "Both" +msgstr "²áÕ" + +#: gui/options.cpp:791 +msgid "Spch" +msgstr "¾×Ò" + +#: gui/options.cpp:792 +msgid "Subs" +msgstr "ÁãÑ" + +#: gui/options.cpp:793 +msgid "Show subtitles and play speech" +msgstr "¿ÞÚÐ×ãÒÐâØ áãÑâØâàØ ö ÒöÔâÒÞàîÒÐâØ ÜÞÒã" + +#: gui/options.cpp:797 +msgid "Subtitle speed:" +msgstr "ÈÒØÔÚöáâì áãÑâØâàöÒ:" + +#: gui/options.cpp:809 +msgid "Music volume:" +msgstr "³ãçÝöáâì Üã×ØÚØ:" + +#: gui/options.cpp:816 +msgid "Mute All" +msgstr "²ØÜÚÝãâØ ãáÕ" + +#: gui/options.cpp:819 +msgid "SFX volume:" +msgstr "³ãçÝöáâì ÕäÕÚâöÒ:" + +#: gui/options.cpp:819 +#: gui/options.cpp:820 +msgid "Special sound effects volume" +msgstr "³ãçÝöáâì áßÕæöÐÛìÝØå ×ÒãÚÞÒØå ÕäÕÚâöÒ" + +#: gui/options.cpp:826 +msgid "Speech volume:" +msgstr "³ãçÝöáâì Þ×ÒãçÕÝÝï:" + +#: gui/options.cpp:952 +msgid "Save Path: " +msgstr "ÈÛïå ÔÛï ×ÑÕàÕÖÕÝì: " + +#: gui/options.cpp:955 +msgid "Theme Path:" +msgstr "ÈÛïå ÔÞ âÕÜ:" + +#: gui/options.cpp:958 +#: gui/options.cpp:959 +msgid "Specifies path to additional data used by all games or ScummVM" +msgstr "²ÚÐ×ãô èÛïå ÔÞ ÔÞÔÐâÚÞÒØå äÐÙÛöÒ ÔÐÝØå, ÒØÚÞàØáâÞÒãÒÐÝØå ãáöÜÐ öÓàÐÜØ, ÐÑÞ ScummVM" + +#: gui/options.cpp:962 +msgid "Plugins Path:" +msgstr "ÈÛïå ÔÞ ßÛÐÓöÝöÒ:" + +#: gui/options.cpp:970 +msgid "Misc" +msgstr "Àö×ÝÕ" + +#: gui/options.cpp:972 +msgid "Theme:" +msgstr "ÂÕÜÐ:" + +#: gui/options.cpp:976 +msgid "GUI Renderer:" +msgstr "ÀÐáâÕàØ×ÐâÞà GUI:" + +#: gui/options.cpp:982 +msgid "Autosave:" +msgstr "°ÒâÞ×ÑÕàÕÖÕÝÝï:" + +#: gui/options.cpp:990 +msgid "Keys" +msgstr "ºÛÐÒöèö" + +#: gui/options.cpp:997 +msgid "GUI Language:" +msgstr "¼ÞÒÐ öÝâÕàäÕÙáã:" + +#: gui/options.cpp:997 +msgid "Language of ScummVM GUI" +msgstr "¼ÞÒÐ ÓàÐäöçÝÞÓÞ öÝâÕàäÕÙáã ScummVM" + +#: gui/options.cpp:1002 +msgid "English" +msgstr "English" + +#: gui/options.cpp:1146 +msgid "You have to restart ScummVM to take the effect." +msgstr "²Ø ßÞÒØÝÝö ßÕàÕ×ÐßãáâØâØ ScummVM éÞÑ ×ÐáâÞáãÒÐâØ ×ÜöÝØ." + +#: gui/options.cpp:1159 +msgid "Select directory for savegames" +msgstr "²ØÑÕàöâì ßÐßÚã ÔÛï ×ÑÕàÕÖÕÝì" + +#: gui/options.cpp:1166 +msgid "The chosen directory cannot be written to. Please select another one." +msgstr "½Õ ÜÞÖã ßØáÐâØ ã ÒØÑàÐÝã ßÐßÚã. ±ãÔì ÛÐáÚÐ, ÒÚÐÖöâì öÝèã." + +#: gui/options.cpp:1175 +msgid "Select directory for GUI themes" +msgstr "²ØÑÕàöâì ßÐßÚã ÔÛï âÕÜ GUI" + +#: gui/options.cpp:1185 +msgid "Select directory for extra files" +msgstr "²ØÑÕàöâì ßÐßÚã × ÔÞÔÐâÚÞÒØÜØ äÐÙÛÐÜØ" + +#: gui/options.cpp:1196 +msgid "Select directory for plugins" +msgstr "²ØÑÕàöâì ßÐßÚã × ßÛÐÓØÝÐÜØ" + +#: gui/saveload.cpp:60 +#: gui/saveload.cpp:241 +msgid "No date saved" +msgstr "´ÐâÐ ÝÕ ×ÐßØáÐÝÐ" + +#: gui/saveload.cpp:61 +#: gui/saveload.cpp:242 +msgid "No time saved" +msgstr "ÇÐá ÝÕ ×ÐßØáÐÝØÙ" + +#: gui/saveload.cpp:62 +#: gui/saveload.cpp:243 +msgid "No playtime saved" +msgstr "ÇÐá ÓàØ ÝÕ ×ÐßØáÐÝÞ" + +#: gui/saveload.cpp:69 +#: gui/saveload.cpp:157 +msgid "Delete" +msgstr "²ØÔÐÛØâØ" + +#: gui/saveload.cpp:156 +msgid "Do you really want to delete this savegame?" +msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ÒØÔÐÛØâØ æÕ ×ÑÕàÕÖÕÝÝï?" + +#: gui/saveload.cpp:265 +msgid "Date: " +msgstr "´ÐâÐ: " + +#: gui/saveload.cpp:268 +msgid "Time: " +msgstr "ÇÐá: " + +#: gui/saveload.cpp:273 +msgid "Playtime: " +msgstr "ÇÐá ÓàØ: " + +#: gui/saveload.cpp:286 +#: gui/saveload.cpp:353 +msgid "Untitled savestate" +msgstr "·ÑÕàÕÖÕÝÝï ÑÕ× öÜÕÝö" + +#: gui/themebrowser.cpp:46 +msgid "Select a Theme" +msgstr "²ØÑÕàöâì âÕÜã" + +#: gui/ThemeEngine.cpp:334 +msgid "Disabled GFX" +msgstr "±Õ× ÓàÐäöÚØ" + +#: gui/ThemeEngine.cpp:335 +msgid "Standard Renderer (16bpp)" +msgstr "ÁâÐÝÔÐàâÝØÙ àÐáâÕàØ×ÐâÞà (16bpp)" + +#: gui/ThemeEngine.cpp:337 +msgid "Antialiased Renderer (16bpp)" +msgstr "ÀÐáâÕàØ×ÐâÞà ×ö ×ÓÛÐÔÖãÒÐÝÝïÜ (16bpp)" + +#: base/main.cpp:205 +#, c-format +msgid "Engine does not support debug level '%s'" +msgstr "´ÒØÖÞÚ ÝÕ ßöÔâàØÜãô àöÒÕÝì ÒöÔÛÐÔÚØ '%s'" + +#: base/main.cpp:273 +msgid "Menu" +msgstr "¼ÕÝî" + +#: base/main.cpp:276 +#: backends/platform/symbian/src/SymbianActions.cpp:48 +#: backends/platform/wince/CEActionsPocket.cpp:44 +#: backends/platform/wince/CEActionsSmartphone.cpp:45 +msgid "Skip" +msgstr "¿àÞßãáâØâØ" + +#: base/main.cpp:279 +#: backends/platform/symbian/src/SymbianActions.cpp:53 +#: backends/platform/wince/CEActionsPocket.cpp:41 +msgid "Pause" +msgstr "¿Ðã×Ð" + +#: base/main.cpp:282 +msgid "Skip line" +msgstr "¿àÞßãáâØâØ àïÔÞÚ" + +#: base/main.cpp:404 +msgid "Error running game:" +msgstr "¿ÞÜØÛÚÐ ×ÐßãáÚã ÓàØ:" + +#: base/main.cpp:430 +#: base/main.cpp:431 +msgid "Could not find any engine capable of running the selected game" +msgstr "½Õ ÜÞÖã ×ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚã ÒØÑàÐÝÞ÷ ÓàØ" + +#: common/error.cpp:43 +msgid "Invalid Path" +msgstr "½ÕßàÐÒØÛìÝØÙ èÛïå" + +#: common/error.cpp:44 +msgid "Game Data not found" +msgstr "½ÕÜÐô äÐÙÛöÒ ÓàØ" + +#: common/error.cpp:45 +msgid "Game Id not supported" +msgstr "Game Id ÝÕ ßöÔâàØÜãôâìáï" + +#: common/error.cpp:46 +msgid "Unsupported Color Mode" +msgstr "ÀÕÖØÜ ºÞÛìÞàã ÝÕ ßöÔâàØÜãôâìáï" + +#: common/error.cpp:48 +msgid "Read permission denied" +msgstr "½ÕÔÞáâÐâÝìÞ ßàÐÒ ÔÛï çØâÐÝÝï" + +#: common/error.cpp:49 +msgid "Write permission denied" +msgstr "½ÕÔÞáâÐâÝìÞ ßàÐÒ ÔÛï ×ÐßØáã" + +#: common/error.cpp:52 +msgid "Path not exists" +msgstr "ÈÛïå ÝÕ ×ÝÐÙÔÕÝØÙ" + +#: common/error.cpp:53 +msgid "Path not a directory" +msgstr "ÈÛïå ÝÕ ô ßÐßÚÞî" + +#: common/error.cpp:54 +msgid "Path not a file" +msgstr "ÈÛïå ÝÕ ô äÐÙÛÞÜ" + +#: common/error.cpp:56 +msgid "Cannot create file" +msgstr "½Õ ÜÞÖã áâÒÞàØâØ äÐÙÛ" + +#: common/error.cpp:57 +msgid "Reading failed" +msgstr "¿ÞÜØÛÚÐ çØâÐÝÝï" + +#: common/error.cpp:58 +msgid "Writing data failed" +msgstr "¿ÞÜØÛÚÐ ×ÐßØáã ÔÐÝØå" + +#: common/error.cpp:60 +#: common/error.cpp:71 +msgid "Unknown Error" +msgstr "½ÕÒöÔÞÜÐ ßÞÜØÛÚÐ" + +#: common/util.cpp:254 +msgid "Hercules Green" +msgstr "Hercules ·ÕÛÕÝØÙ" + +#: common/util.cpp:255 +msgid "Hercules Amber" +msgstr "Hercules ÏÝâÐàÝØÙ" + +#: engines/dialogs.cpp:89 +msgid "~R~esume" +msgstr "¿àÞÔÞÒ~Ö~ØâØ" + +#: engines/dialogs.cpp:91 +msgid "~L~oad" +msgstr "~·~ÐÒÐÝâÐÖØâØ" + +#: engines/dialogs.cpp:95 +msgid "~S~ave" +msgstr "~·~ÐßØáÐâØ" + +#: engines/dialogs.cpp:99 +msgid "~O~ptions" +msgstr "~¾~ßæö÷" + +#: engines/dialogs.cpp:104 +msgid "~H~elp" +msgstr "~´~ÞßÞÜÞÓÐ" + +#: engines/dialogs.cpp:107 +msgid "~A~bout" +msgstr "¿àÞ ßàÞ~Ó~àÐÜã" + +#: engines/dialogs.cpp:109 +msgid "~R~eturn to Launcher" +msgstr "~¿~ÞÒÕàÝãâØáì Ò ÓÞÛÞÒÝÕ ÜÕÝî" + +#: engines/dialogs.cpp:119 +msgid "Save game:" +msgstr "·ÑÕàÕÓâØ Óàã: " + +#: engines/dialogs.cpp:119 +#: backends/platform/symbian/src/SymbianActions.cpp:47 +#: backends/platform/wince/CEActionsPocket.cpp:42 +#: backends/platform/wince/CEActionsPocket.cpp:263 +#: backends/platform/wince/CEActionsSmartphone.cpp:44 +#: backends/platform/wince/CEActionsSmartphone.cpp:225 +msgid "Save" +msgstr "·ÐßØáÐâØ" + +#: engines/dialogs.cpp:301 +#: engines/mohawk/dialogs.cpp:84 +#: engines/mohawk/dialogs.cpp:118 +msgid "~O~K" +msgstr "~O~K" + +#: engines/dialogs.cpp:302 +#: engines/mohawk/dialogs.cpp:85 +#: engines/mohawk/dialogs.cpp:119 +msgid "~C~ancel" +msgstr "²ö~Ô~ÜöÝÐ" + +#: engines/dialogs.cpp:305 +msgid "~K~eys" +msgstr "~º~ÛÐÒöèö" + +#: engines/scumm/dialogs.cpp:287 +msgid "~P~revious" +msgstr "~¿~ÞßÕà" + +#: engines/scumm/dialogs.cpp:288 +msgid "~N~ext" +msgstr "~½~Ðáâ" + +#: engines/scumm/dialogs.cpp:289 +#: backends/platform/ds/arm9/source/dsoptions.cpp:59 +msgid "~C~lose" +msgstr "~·~ÐÚàØâØ" + +#: engines/mohawk/dialogs.cpp:81 +#: engines/mohawk/dialogs.cpp:115 +msgid "~Z~ip Mode Activated" +msgstr "ÀÕÖØÜ èÒØÔÚÞÓÞ ßÕàÕåÞÔã ÐÚâØÒÞÒÐÝØÙ" + +#: engines/mohawk/dialogs.cpp:82 +msgid "~T~ransitions Enabled" +msgstr "¿ÕàÕåÞÔØ ÐÚâØÒÞÒÐÝö" + +#: engines/mohawk/dialogs.cpp:116 +msgid "~W~ater Effect Enabled" +msgstr "µäÕÚâØ ÒÞÔØ ÒÚÛîçÕÝö" + +#: sound/fmopl.cpp:51 +msgid "MAME OPL emulator" +msgstr "µÜãÛïâÞà MAME OPL:" + +#: sound/fmopl.cpp:53 +msgid "DOSBox OPL emulator" +msgstr "µÜãÛïâÞà DOSBox OPL" + +#: sound/null.h:45 +msgid "No music" +msgstr "±Õ× Üã×ØÚØ" + +#: sound/softsynth/adlib.cpp:1590 +msgid "AdLib Emulator" +msgstr "µÜãÛïâÞà AdLib" + +#: sound/softsynth/mt32.cpp:327 +msgid "Initialising MT-32 Emulator" +msgstr "½ÐáâàÞîî ÕÜãÛïâÞà MT-32" + +#: sound/softsynth/mt32.cpp:541 +msgid "MT-32 Emulator" +msgstr "µÜãÛïâÞà MT-32" + +#: sound/softsynth/pcspk.cpp:142 +msgid "PC Speaker Emulator" +msgstr "µÜãÛïâÞà PC áßöÚÕàÐ" + +#: sound/softsynth/pcspk.cpp:161 +msgid "IBM PCjr Emulator" +msgstr "µÜãÛïâÞà IBM PCjr" + +#: sound/softsynth/ym2612.cpp:762 +msgid "FM Towns Emulator" +msgstr "µÜãÛïâÞà FM Towns" + +#: backends/keymapper/remap-dialog.cpp:49 +msgid "Keymap:" +msgstr "ÂÐÑÛØæï ÚÛÐÒöè:" + +#: backends/keymapper/remap-dialog.cpp:66 +msgid " (Active)" +msgstr " (°ÚâØÒÝÐ)" + +#: backends/keymapper/remap-dialog.cpp:100 +msgid " (Global)" +msgstr " (³ÛÞÑÐÛìÝÐ)" + +#: backends/keymapper/remap-dialog.cpp:110 +msgid " (Game)" +msgstr " (¦ÓàØ)" + +#: backends/midi/windows.cpp:157 +msgid "Windows MIDI" +msgstr "Windows MIDI" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:60 +msgid "ScummVM Main Menu" +msgstr "³ÞÛÞÒÝÕ ÜÕÝî ScummVM" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:66 +msgid "~L~eft handed mode" +msgstr "»öÒÞàãÚØÙ àÕÖØÜ" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:67 +msgid "~I~ndy fight controls" +msgstr "ºÕàãÒÐÝÝï ÑÞïÜØ Ò Indy" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:68 +msgid "Show mouse cursor" +msgstr "¿ÞÚÐ×ãÒÐâØ ÚãàáÞà ÜØèö" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:69 +msgid "Snap to edges" +msgstr "¿àØÚàößØâØ ÔÞ ÚàÐ÷Ò" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:71 +msgid "Touch X Offset" +msgstr "·ÜöéÕÝÝï âÞàÚÐÝì ßÞ Þáö X" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:78 +msgid "Touch Y Offset" +msgstr "·ÜöéÕÝÝï âÞàÚÐÝì ßÞ Þáö Y" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:90 +msgid "Use laptop trackpad-style cursor control" +msgstr "²ØÚÞàØáâÞÒãÒÐâØ ãßàÐÒÛöÝÝï ÚãàáÞàÞÜ ïÚ ÝÐ âàÕÚßÐÔö ÛÐßâÞßöÒ" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:91 +msgid "Tap for left click, double tap right click" +msgstr "ÂÐß ÔÛï ÛöÒÞÓÞ ÚÛÐæÐÝÝï, ßÞÔÒöÙÝØÙ âÐß ÔÛï ßàÐÒÞÓÞ ÚÛÐæÐÝÝï" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:93 +msgid "Sensitivity" +msgstr "ÇãâÛØÒöáâì" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:102 +msgid "Initial top screen scale:" +msgstr "¿ÞçÐâÚÞÒØÙ ÜÐáèâÐÑ ÒÕàåÝìÞÓÞ ÕÚàÐÝã:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:108 +msgid "Main screen scaling:" +msgstr "¼ÐáèâÐÑ ÓÞÛÞÒÝÞÓÞ ÕÚàÐÝã:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:110 +msgid "Hardware scale (fast, but low quality)" +msgstr "ÅÐàÔÒÐàÝÞÕ ÜÐáèâÐÑãÒÐÝÝï (èÒØÔÚÞ, ÐÛÕ ÝØ×ìÚÞ÷ ïÚÞáâö)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:111 +msgid "Software scale (good quality, but slower)" +msgstr "¿àÞÓàÐÜÝÕ ÜÐáèâÐÑãÒÐÝÝï (åÞàÞèÐ ïÚöáâì, ÐÛÕ ßÞÒöÛìÝöèÕ)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:112 +msgid "Unscaled (you must scroll left and right)" +msgstr "±Õ× ÜÐáèâÐÑãÒÐÝÝï (âàÕÑÐ ÑãÔÕ ßàÞÚàãçãÒÐâØ ÝÐÛöÒÞ ö ÝÐßàÐÒÞ)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:114 +msgid "Brightness:" +msgstr "ÏáÚàÐÒöáâì:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:124 +msgid "High quality audio (slower) (reboot)" +msgstr "²ØáÞÚÐ ïÚöáâì ×ÒãÚã (ßÞÒöÛìÝöèÕ) (àÕÑãâ)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:125 +msgid "Disable power off" +msgstr "·ÐÑÞàÞÝØâØ ÒØÜÚÝÕÝÝï" + +#: backends/platform/iphone/osys_events.cpp:339 +msgid "Touchpad mode enabled." +msgstr "ÀÕÖØÜ âÐçßÐÔã ãÒöÜÚÝÕÝØÙ." + +#: backends/platform/iphone/osys_events.cpp:341 +msgid "Touchpad mode disabled." +msgstr "ÀÕÖØÜ âÐçßÐÔã ÒØÜÚÝÕÝØÙ." + +#: backends/platform/sdl/graphics.cpp:40 +#: backends/platform/wince/wince-sdl.cpp:111 +#: backends/platform/wince/wince-sdl.cpp:118 +msgid "Normal (no scaling)" +msgstr "±Õ× ×ÑöÛìèÕÝÝï" + +#: backends/platform/symbian/src/SymbianActions.cpp:41 +#: backends/platform/wince/CEActionsSmartphone.cpp:38 +msgid "Up" +msgstr "²ÒÕàå" + +#: backends/platform/symbian/src/SymbianActions.cpp:42 +#: backends/platform/wince/CEActionsSmartphone.cpp:39 +msgid "Down" +msgstr "²ÝØ×" + +#: backends/platform/symbian/src/SymbianActions.cpp:43 +#: backends/platform/wince/CEActionsSmartphone.cpp:40 +msgid "Left" +msgstr "²ÛöÒÞ" + +#: backends/platform/symbian/src/SymbianActions.cpp:44 +#: backends/platform/wince/CEActionsSmartphone.cpp:41 +msgid "Right" +msgstr "²ßàÐÒÞ" + +#: backends/platform/symbian/src/SymbianActions.cpp:45 +#: backends/platform/wince/CEActionsPocket.cpp:59 +#: backends/platform/wince/CEActionsSmartphone.cpp:42 +msgid "Left Click" +msgstr "»öÒØÙ ÚÛöÚ" + +#: backends/platform/symbian/src/SymbianActions.cpp:46 +#: backends/platform/wince/CEActionsSmartphone.cpp:43 +msgid "Right Click" +msgstr "¿àÐÒØÙ ÚÛöÚ" + +#: backends/platform/symbian/src/SymbianActions.cpp:49 +#: backends/platform/wince/CEActionsSmartphone.cpp:46 +msgid "Zone" +msgstr "·ÞÝÐ" + +#: backends/platform/symbian/src/SymbianActions.cpp:50 +#: backends/platform/wince/CEActionsPocket.cpp:53 +#: backends/platform/wince/CEActionsSmartphone.cpp:47 +msgid "Multi Function" +msgstr "¼ãÛìâöäãÝÚæöï" + +#: backends/platform/symbian/src/SymbianActions.cpp:51 +msgid "Swap character" +msgstr "·ÜöÝØâØ ÓÕàÞï" + +#: backends/platform/symbian/src/SymbianActions.cpp:52 +msgid "Skip text" +msgstr "¿àÞßãáâØâØ âÕÚáâ" + +#: backends/platform/symbian/src/SymbianActions.cpp:54 +msgid "Fast mode" +msgstr "ÈÒØÔÚØÙ àÕÖØÜ" + +#: backends/platform/symbian/src/SymbianActions.cpp:55 +#: backends/platform/wince/CEActionsPocket.cpp:43 +#: backends/platform/wince/CEActionsSmartphone.cpp:51 +msgid "Quit" +msgstr "²ØåöÔ" + +#: backends/platform/symbian/src/SymbianActions.cpp:56 +msgid "Debugger" +msgstr "²öÔÛÐÔçØÚ" + +#: backends/platform/symbian/src/SymbianActions.cpp:57 +msgid "Global menu" +msgstr "³ÛÞÑÐÛìÝÕ ÜÕÝî" + +#: backends/platform/symbian/src/SymbianActions.cpp:58 +msgid "Virtual keyboard" +msgstr "²öàâãÐÛìÝÐ ÚÛÐÒöÐâãàÐ" + +#: backends/platform/symbian/src/SymbianActions.cpp:59 +msgid "Key mapper" +msgstr "¿àØ×ÝÐçÕÝÝï ÚÛÐÒöè" + +#: backends/platform/symbian/src/SymbianOS.cpp:446 +msgid "Do you want to quit ?" +msgstr "²Ø åÞçØâÕ ÒØÙâØ?" + +#: backends/platform/wii/options.cpp:51 +msgid "Video" +msgstr "²öÔÕÞ" + +#: backends/platform/wii/options.cpp:54 +msgid "Current video mode:" +msgstr "ÂÕÚãçØÙ ÒöÔÕÞàÕÖØÜ:" + +#: backends/platform/wii/options.cpp:56 +msgid "Double-strike" +msgstr "¿ÞÔÒöÙÝØÙ ãÔÐà" + +#: backends/platform/wii/options.cpp:60 +msgid "Horizontal underscan:" +msgstr "³ÞàØ×ÞÝâÐÛìÝØÙ underscan:" + +#: backends/platform/wii/options.cpp:66 +msgid "Vertical underscan:" +msgstr "²ÕàâØÚÐÛìÝØÙ underscan:" + +#: backends/platform/wii/options.cpp:71 +msgid "Input" +msgstr "²ÒöÔ" + +#: backends/platform/wii/options.cpp:74 +msgid "GC Pad sensitivity:" +msgstr "ÇãâÛØÒöáâì GC ßÐÔã:" + +#: backends/platform/wii/options.cpp:80 +msgid "GC Pad acceleration:" +msgstr "¿àØáÚÞàÕÝÝï GC ßÐÔã:" + +#: backends/platform/wii/options.cpp:86 +msgid "DVD" +msgstr "DVD" + +#: backends/platform/wii/options.cpp:89 +#: backends/platform/wii/options.cpp:101 +msgid "Status:" +msgstr "ÁâÐÝ:" + +#: backends/platform/wii/options.cpp:90 +#: backends/platform/wii/options.cpp:102 +msgid "Unknown" +msgstr "½ÕÒöÔÞÜÞ" + +#: backends/platform/wii/options.cpp:93 +msgid "Mount DVD" +msgstr "¿öÔÚÛîçØâØ DVD" + +#: backends/platform/wii/options.cpp:94 +msgid "Unmount DVD" +msgstr "²öÔÚÛîçØâØ DVD" + +#: backends/platform/wii/options.cpp:98 +msgid "SMB" +msgstr "SMB" + +#: backends/platform/wii/options.cpp:106 +msgid "Server:" +msgstr "ÁÕàÒÕà:" + +#: backends/platform/wii/options.cpp:110 +msgid "Share:" +msgstr "¼ÕàÕÖÕÒÐ ßÐßÚÐ:" + +#: backends/platform/wii/options.cpp:114 +msgid "Username:" +msgstr "ºÞàØáâãÒÐç:" + +#: backends/platform/wii/options.cpp:118 +msgid "Password:" +msgstr "¿ÐàÞÛì:" + +#: backends/platform/wii/options.cpp:121 +msgid "Init network" +msgstr "¦ÝöæöÐÛö×Ðæöï ÜÕàÕÖö" + +#: backends/platform/wii/options.cpp:123 +msgid "Mount SMB" +msgstr "¿öÔÚÛîçØâØ SMB" + +#: backends/platform/wii/options.cpp:124 +msgid "Unmount SMB" +msgstr "²öÔÚÛîçâØ SMB" + +#: backends/platform/wii/options.cpp:145 +msgid "DVD Mounted successfully" +msgstr "DVD ßöÔÚÛîçÕÝØÙ ãáßöèÝÞ" + +#: backends/platform/wii/options.cpp:148 +msgid "Error while mounting the DVD" +msgstr "¿ÞÜØÛÚÐ ßöÔ çÐá ßöÔÚÛîçÕÝÝï DVD" + +#: backends/platform/wii/options.cpp:150 +msgid "DVD not mounted" +msgstr "DVD ÝÕ ßöÔÚÛîçÕÝØÙ" + +#: backends/platform/wii/options.cpp:163 +msgid "Network up, share mounted" +msgstr "¼ÕàÕÖÐ ßàÐæîô, ßÐßÚÐ ßöÔÚÛîçÕÝÐ" + +#: backends/platform/wii/options.cpp:165 +msgid "Network up" +msgstr "¼ÕàÕÖÐ ßàÐæîô" + +#: backends/platform/wii/options.cpp:168 +msgid ", error while mounting the share" +msgstr ", ßÞÜØÛÚÐ ßöÔ çÐá ßöÔÚÛîçÕÝÝï ßÐßÚØ" + +#: backends/platform/wii/options.cpp:170 +msgid ", share not mounted" +msgstr ", ßÐßÚÐ ÝÕ ßöÔÚÛîçÕÝÐ" + +#: backends/platform/wii/options.cpp:176 +msgid "Network down" +msgstr "¼ÕàÕÖÐ ÒØÜÚÝÕÝÐ" + +#: backends/platform/wii/options.cpp:180 +msgid "Initialising network" +msgstr "½ÐÛÐèâÞÒãî ÜÕàÕÖã" + +#: backends/platform/wii/options.cpp:184 +msgid "Timeout while initialising network" +msgstr "ÇÐá ßöÔÚÛîçÕÝÝï ÔÞ ÜÕàÕÖö ÒØâöÚ" + +#: backends/platform/wii/options.cpp:188 +#, c-format +msgid "Network not initialsed (%d)" +msgstr "¼ÕàÕÖÐ ÝÕ ÝÐÛÐÓÞÔÖÕÝÐ (%d)" + +#: backends/platform/wince/CEActionsPocket.cpp:45 +msgid "Hide Toolbar" +msgstr "·ÐåÞÒÐâØ ßÐÝÕÛì öÝáâàãÜÕÝâöÒ" + +#: backends/platform/wince/CEActionsPocket.cpp:46 +msgid "Show Keyboard" +msgstr "¿ÞÚÐ×ÐâØ ÚÛÐÒöÐâãàã" + +#: backends/platform/wince/CEActionsPocket.cpp:47 +msgid "Sound on/off" +msgstr "·ÒãÚ ãÒöÜ/ÒØÜÚ" + +#: backends/platform/wince/CEActionsPocket.cpp:48 +msgid "Right click" +msgstr "¿àÐÒØÙ ÚÛöÚ" + +#: backends/platform/wince/CEActionsPocket.cpp:49 +msgid "Show/Hide Cursor" +msgstr "¿ÞÚÐ×ÐâØ/ÁåÞÒÐâØ ÚãàáÞà" + +#: backends/platform/wince/CEActionsPocket.cpp:50 +msgid "Free look" +msgstr "²öÛìÝØÙ ÞÓÛïÔ" + +#: backends/platform/wince/CEActionsPocket.cpp:51 +msgid "Zoom up" +msgstr "·ÑöÛ. ÜÐèâÐÑ" + +#: backends/platform/wince/CEActionsPocket.cpp:52 +msgid "Zoom down" +msgstr "·ÜÝè. ÜÐèâÐÑ" + +#: backends/platform/wince/CEActionsPocket.cpp:54 +#: backends/platform/wince/CEActionsSmartphone.cpp:48 +msgid "Bind Keys" +msgstr "ßàØ×ÝÐçØâØ ÚÛÐÒöèö" + +#: backends/platform/wince/CEActionsPocket.cpp:55 +msgid "Cursor Up" +msgstr "ºãàáÞà ÒÒÕàå" + +#: backends/platform/wince/CEActionsPocket.cpp:56 +msgid "Cursor Down" +msgstr "ºãàáÞà ÒÝØ×" + +#: backends/platform/wince/CEActionsPocket.cpp:57 +msgid "Cursor Left" +msgstr "ºãàáÞà ÒÛöÒÞ" + +#: backends/platform/wince/CEActionsPocket.cpp:58 +msgid "Cursor Right" +msgstr "ºãàáÞà ÒßàÐÒÞ" + +#: backends/platform/wince/CEActionsPocket.cpp:263 +#: backends/platform/wince/CEActionsSmartphone.cpp:225 +msgid "Do you want to load or save the game?" +msgstr "²Ø åÞçÕâÕ ×ÐÒÐÝâÐÖØâØ ÐÑÞ ×ÑÕàÕÓâØ Óàã?" + +#: backends/platform/wince/CEActionsPocket.cpp:313 +#: backends/platform/wince/CEActionsSmartphone.cpp:272 +msgid " Are you sure you want to quit ? " +msgstr " ²Ø ãßÕÒÝÕÝö, éÞ åÞçÕâÕ ÒØÙâØ? " + +#: backends/platform/wince/CEActionsSmartphone.cpp:49 +msgid "Keyboard" +msgstr "ºÛÐÒöÐâãàÐ" + +#: backends/platform/wince/CEActionsSmartphone.cpp:50 +msgid "Rotate" +msgstr "¿ÞÒÕàÝãâØ" + +#: backends/platform/wince/CELauncherDialog.cpp:58 +msgid "Using SDL driver " +msgstr "²ØÚÞàØáâÞÒãî ÔàÐÙÒÕà SDL " + +#: backends/platform/wince/CELauncherDialog.cpp:62 +msgid "Display " +msgstr "¿ÞÚÐ×ÐâØ " + +#: backends/platform/wince/CELauncherDialog.cpp:104 +msgid "Do you want to perform an automatic scan ?" +msgstr "²Ø åÞçÕâÕ ×ÔöÙáÝØâØ ÐÒâÞÜÐâØçÝØÙ ßÞèãÚ?" + diff --git a/sound/module.mk b/sound/module.mk index a3fa4027c9..4e2f77c4df 100644 --- a/sound/module.mk +++ b/sound/module.mk @@ -35,6 +35,10 @@ MODULE_OBJS := \ softsynth/opl/dbopl.o \ softsynth/opl/dosbox.o \ softsynth/opl/mame.o \ + softsynth/fmtowns_pc98/towns_audio.o \ + softsynth/fmtowns_pc98/towns_euphony.o \ + softsynth/fmtowns_pc98/towns_pc98_driver.o \ + softsynth/fmtowns_pc98/towns_pc98_fmsynth.o \ softsynth/ym2612.o \ softsynth/fluidsynth.o \ softsynth/mt32.o \ diff --git a/sound/softsynth/fmtowns_pc98/towns_audio.cpp b/sound/softsynth/fmtowns_pc98/towns_audio.cpp new file mode 100644 index 0000000000..f09c5d8851 --- /dev/null +++ b/sound/softsynth/fmtowns_pc98/towns_audio.cpp @@ -0,0 +1,1561 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "sound/softsynth/fmtowns_pc98/towns_audio.h" +#include "common/endian.h" + + +class TownsAudio_PcmChannel { +friend class TownsAudioInterface; +public: + TownsAudio_PcmChannel(); + ~TownsAudio_PcmChannel(); + +private: + void loadExtData(uint8 *buffer, uint32 size); + void setupLoop(uint32 start, uint32 len); + void clear(); + + void envAttack(); + void envDecay(); + void envSustain(); + void envRelease(); + + uint8 *curInstrument; + uint8 note; + uint8 velo; + + int8 *data; + int8 *dataEnd; + + int8 *loopEnd; + uint32 loopLen; + + uint16 stepNote; + uint16 stepPitch; + uint16 step; + + uint8 panLeft; + uint8 panRight; + + uint32 pos; + + uint8 envTotalLevel; + uint8 envAttackRate; + uint8 envDecayRate; + uint8 envSustainLevel; + uint8 envSustainRate; + uint8 envReleaseRate; + + int16 envStep; + int16 envCurrentLevel; + + EnvelopeState envState; + + int8 *extData; +}; + +class TownsAudio_WaveTable { +friend class TownsAudioInterface; +public: + TownsAudio_WaveTable(); + ~TownsAudio_WaveTable(); + +private: + void readHeader(const uint8 *buffer); + void readData(const uint8 *buffer); + void clear(); + + char name[9]; + int32 id; + uint32 size; + uint32 loopStart; + uint32 loopLen; + uint16 rate; + uint16 rateOffs; + uint16 baseNote; + int8 *data; +}; + +TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) : TownsPC98_FmSynth(mixer, kTypeTowns), + _fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0), + _baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver), + _pcmSfxChanMask(0), _musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume), + _cdaVolFlags(0), _ready(false) { + +#define INTCB(x) &TownsAudioInterface::intf_##x + static const TownsAudioIntfCallback intfCb[] = { + // 0 + INTCB(reset), + INTCB(keyOn), + INTCB(keyOff), + INTCB(setPanPos), + // 4 + INTCB(setInstrument), + INTCB(loadInstrument), + INTCB(notImpl), + INTCB(setPitch), + // 8 + INTCB(setLevel), + INTCB(chanOff), + INTCB(notImpl), + INTCB(notImpl), + // 12 + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 16 + INTCB(notImpl), + INTCB(writeReg), + INTCB(notImpl), + INTCB(writeRegBuffer), + // 20 + INTCB(readRegBuffer), + INTCB(setTimerA), + INTCB(setTimerB), + INTCB(enableTimerA), + // 24 + INTCB(enableTimerB), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 28 + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 32 + INTCB(loadSamples), + INTCB(reserveEffectChannels), + INTCB(loadWaveTable), + INTCB(unloadWaveTable), + // 36 + INTCB(notImpl), + INTCB(pcmPlayEffect), + INTCB(notImpl), + INTCB(pcmChanOff), + // 40 + INTCB(pcmEffectPlaying), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 44 + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 48 + INTCB(notImpl), + INTCB(notImpl), + INTCB(fmKeyOn), + INTCB(fmKeyOff), + // 52 + INTCB(fmSetPanPos), + INTCB(fmSetInstrument), + INTCB(fmLoadInstrument), + INTCB(notImpl), + // 56 + INTCB(fmSetPitch), + INTCB(fmSetLevel), + INTCB(fmReset), + INTCB(notImpl), + // 60 + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 64 + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + INTCB(cdaSetVolume), + // 68 + INTCB(cdaReset), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 72 + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 76 + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + INTCB(notImpl), + // 80 + INTCB(pcmUpdateEnvelopeGenerator), + INTCB(notImpl) + + }; +#undef INTCB + + _intfOpcodes = intfCb; + + memset(_fmSaveReg, 0, sizeof(_fmSaveReg)); + _timerBase = (uint32)(_baserate * 1000000.0f); + _tickLength = 2 * _timerBase; +} + +TownsAudioInterface::~TownsAudioInterface() { + delete[] _fmSaveReg[0]; + delete[] _fmSaveReg[1]; + delete[] _fmInstruments; + delete[] _pcmInstruments; + delete[] _waveTables; + delete[] _pcmChan; +} + +bool TownsAudioInterface::init() { + if (_ready) + return true; + + if (!_drv) + return false; + + if (!TownsPC98_FmSynth::init()) + return false; + + _fmSaveReg[0] = new uint8[256]; + _fmSaveReg[1] = new uint8[256]; + _fmInstruments = new uint8[128 * 48]; + _pcmInstruments = new uint8[32 * 128]; + _waveTables = new TownsAudio_WaveTable[128]; + _pcmChan = new TownsAudio_PcmChannel[8]; + + _timer = 0; + + setVolumeChannelMasks(-1, 0); + + callback(0); + + _ready = true; + return true; +} + +int TownsAudioInterface::callback(int command, ...) { + if (!_ready) + return 1; + + va_list args; + va_start(args, command); + + if (command > 81) { + va_end(args); + return 4; + } + + int res = (this->*_intfOpcodes[command])(args); + + va_end(args); + return res; +} + +void TownsAudioInterface::setMusicVolume(int volume) { + _musicVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume); + setVolumeIntern(_musicVolume, _sfxVolume); +} + +void TownsAudioInterface::setSoundEffectVolume(int volume) { + _sfxVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume); + setVolumeIntern(_musicVolume, _sfxVolume); +} + +void TownsAudioInterface::setSoundEffectChanMask(uint32 mask) { + _pcmSfxChanMask = mask >> 6; + mask &= 0x3f; + setVolumeChannelMasks(~mask, mask); +} + +void TownsAudioInterface::nextTickEx(int32 *buffer, uint32 bufferSize) { + if (!_ready) + return; + + for (uint32 i = 0; i < bufferSize; i++) { + _timer += _tickLength; + while (_timer > 0x5B8D80) { + _timer -= 0x5B8D80; + + for (int ii = 0; ii < 8; ii++) { + if ((_pcmChanKeyPlaying & _chanFlags[ii]) || (_pcmChanEffectPlaying & _chanFlags[ii])) { + TownsAudio_PcmChannel *s = &_pcmChan[ii]; + s->pos += s->step; + + if (&s->data[s->pos >> 11] >= s->loopEnd) { + if (s->loopLen) { + s->pos -= s->loopLen; + } else { + s->pos = 0; + _pcmChanEffectPlaying &= ~_chanFlags[ii]; + _pcmChanKeyPlaying &= ~_chanFlags[ii]; + } + } + } + } + } + + int32 finOutL = 0; + int32 finOutR = 0; + + for (int ii = 0; ii < 8; ii++) { + if (_pcmChanOut & _chanFlags[ii]) { + int32 o = _pcmChan[ii].data[_pcmChan[ii].pos >> 11] * _pcmChan[ii].velo; + if ((1 << ii) & (~_pcmSfxChanMask)) + o = (o * _musicVolume) / Audio::Mixer::kMaxMixerVolume; + if ((1 << ii) & _pcmSfxChanMask) + o = (o * _sfxVolume) / Audio::Mixer::kMaxMixerVolume; + if (_pcmChan[ii].panLeft) + finOutL += ((o * _pcmChan[ii].panLeft) >> 3); + if (_pcmChan[ii].panRight) + finOutR += ((o * _pcmChan[ii].panRight) >> 3); + if (!((_pcmChanKeyPlaying & _chanFlags[ii]) || (_pcmChanEffectPlaying & _chanFlags[ii]))) + _pcmChanOut &= ~_chanFlags[ii]; + } + } + + buffer[i << 1] += finOutL; + buffer[(i << 1) + 1] += finOutR; + } +} + +void TownsAudioInterface::timerCallbackA() { + Common::StackLock lock(_mutex); + if (_drv && _ready) + _drv->timerCallback(0); +} + +void TownsAudioInterface::timerCallbackB() { + Common::StackLock lock(_mutex); + if (_drv && _ready) { + _drv->timerCallback(1); + callback(80); + } +} + +int TownsAudioInterface::intf_reset(va_list &args) { + Common::StackLock lock(_mutex); + fmReset(); + pcmReset(); + cdaReset(); + return 0; +} + +int TownsAudioInterface::intf_keyOn(va_list &args) { + int chan = va_arg(args, int); + int note = va_arg(args, int); + int velo = va_arg(args, int); + return (chan & 0x40) ? pcmKeyOn(chan, note, velo) : fmKeyOn(chan, note, velo); +} + +int TownsAudioInterface::intf_keyOff(va_list &args) { + int chan = va_arg(args, int); + return (chan & 0x40) ? pcmKeyOff(chan) : fmKeyOff(chan); +} + +int TownsAudioInterface::intf_setPanPos(va_list &args) { + int chan = va_arg(args, int); + int mode = va_arg(args, int); + return (chan & 0x40) ? pcmSetPanPos(chan, mode) : fmSetPanPos(chan, mode); +} + +int TownsAudioInterface::intf_setInstrument(va_list &args) { + int chan = va_arg(args, int); + int instrId = va_arg(args, int); + return (chan & 0x40) ? pcmSetInstrument(chan, instrId) : fmSetInstrument(chan, instrId); +} + +int TownsAudioInterface::intf_loadInstrument(va_list &args) { + int chanType = va_arg(args, int); + int instrId = va_arg(args, int); + uint8 *instrData = va_arg(args, uint8 *); + return (chanType & 0x40) ? pcmLoadInstrument(instrId, instrData) : fmLoadInstrument(instrId, instrData); +} + +int TownsAudioInterface::intf_setPitch(va_list &args) { + int chan = va_arg(args, int); + int16 pitch = (int16)(va_arg(args, int) & 0xffff); + return (chan & 0x40) ? pcmSetPitch(chan, pitch) : fmSetPitch(chan, pitch); +} + +int TownsAudioInterface::intf_setLevel(va_list &args) { + int chan = va_arg(args, int); + int lvl = va_arg(args, int); + return (chan & 0x40) ? pcmSetLevel(chan, lvl) : fmSetLevel(chan, lvl); +} + +int TownsAudioInterface::intf_chanOff(va_list &args) { + int chan = va_arg(args, int); + return (chan & 0x40) ? pcmChanOff(chan) : fmChanOff(chan); +} + +int TownsAudioInterface::intf_writeReg(va_list &args) { + int part = va_arg(args, int) ? 1 : 0; + int reg = va_arg(args, int); + int val = va_arg(args, int); + if ((!part && reg < 0x20) || (part && reg < 0x30) || (reg > 0xb6)) + return 3; + + bufferedWriteReg(part, reg, val); + return 0; +} + +int TownsAudioInterface::intf_writeRegBuffer(va_list &args) { + int part = va_arg(args, int) ? 1 : 0; + int reg = va_arg(args, int); + int val = va_arg(args, int); + + if ((!part && reg < 0x20) || (part && reg < 0x30) || (reg > 0xef)) + return 3; + + _fmSaveReg[part][reg] = val; + return 0; +} + +int TownsAudioInterface::intf_readRegBuffer(va_list &args) { + int part = va_arg(args, int) ? 1 : 0; + int reg = va_arg(args, int); + uint8 *dst = va_arg(args, uint8 *); + *dst = 0; + + if ((!part && reg < 0x20) || (part && reg < 0x30) || (reg > 0xef)) + return 3; + + *dst = _fmSaveReg[part][reg]; + return 0; +} + +int TownsAudioInterface::intf_setTimerA(va_list &args) { + int enable = va_arg(args, int); + int tempo = va_arg(args, int); + + if (enable) { + bufferedWriteReg(0, 0x25, tempo & 3); + bufferedWriteReg(0, 0x24, (tempo >> 2) & 0xff); + bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x05); + } else { + bufferedWriteReg(0, 0x27, (_fmSaveReg[0][0x27] & 0xfa) | 0x10); + } + + return 0; +} + +int TownsAudioInterface::intf_setTimerB(va_list &args) { + int enable = va_arg(args, int); + int tempo = va_arg(args, int); + + if (enable) { + bufferedWriteReg(0, 0x26, tempo & 0xff); + bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x0A); + } else { + bufferedWriteReg(0, 0x27, (_fmSaveReg[0][0x27] & 0xf5) | 0x20); + } + + return 0; +} + +int TownsAudioInterface::intf_enableTimerA(va_list &args) { + bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x15); + return 0; +} + +int TownsAudioInterface::intf_enableTimerB(va_list &args) { + bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x2a); + return 0; +} + +int TownsAudioInterface::intf_loadSamples(va_list &args) { + uint32 dest = va_arg(args, uint32); + int size = va_arg(args, int); + uint8 *src = va_arg(args, uint8*); + + if (dest >= 65536 || size == 0 || size > 65536) + return 3; + if (size + dest > 65536) + return 5; + + int dwIndex = _numWaveTables - 1; + for (uint32 t = _waveTablesTotalDataSize; dwIndex && (dest < t); dwIndex--) + t -= _waveTables[dwIndex].size; + + TownsAudio_WaveTable *s = &_waveTables[dwIndex]; + _waveTablesTotalDataSize -= s->size; + s->size = size; + s->readData(src); + _waveTablesTotalDataSize += s->size; + + return 0; +} + +int TownsAudioInterface::intf_reserveEffectChannels(va_list &args) { + int numChan = va_arg(args, int); + if (numChan > 8) + return 3; + if ((numChan << 13) + _waveTablesTotalDataSize > 65536) + return 5; + + if (numChan == _numReservedChannels) + return 0; + + if (numChan < _numReservedChannels) { + int c = 8 - _numReservedChannels; + for (int i = numChan; i; i--) { + uint8 f = ~_chanFlags[c--]; + _pcmChanEffectPlaying &= f; + } + } else { + int c = 7 - _numReservedChannels; + for (int i = numChan - _numReservedChannels; i; i--) { + uint8 f = ~_chanFlags[c--]; + _pcmChanKeyPressed &= f; + _pcmChanKeyPlaying &= f; + } + } + + static const uint8 reserveChanFlags[] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF }; + _numReservedChannels = numChan; + _pcmChanReserved = reserveChanFlags[_numReservedChannels]; + + return 0; +} + +int TownsAudioInterface::intf_loadWaveTable(va_list &args) { + uint8 *data = va_arg(args, uint8 *); + if (_numWaveTables > 127) + return 3; + + TownsAudio_WaveTable w; + w.readHeader(data); + if (!w.size) + return 6; + + if (_waveTablesTotalDataSize + w.size > 65504) + return 5; + + for (int i = 0; i < _numWaveTables; i++) { + if (_waveTables[i].id == w.id) + return 10; + } + + TownsAudio_WaveTable *s = &_waveTables[_numWaveTables++]; + s->readHeader(data); + + _waveTablesTotalDataSize += s->size; + callback(32, _waveTablesTotalDataSize, s->size, data + 32); + + return 0; +} + +int TownsAudioInterface::intf_unloadWaveTable(va_list &args) { + int id = va_arg(args, int); + + if (id == -1) { + for (int i = 0; i < 128; i++) + _waveTables[i].clear(); + _numWaveTables = 0; + _waveTablesTotalDataSize = 0; + } else { + if (_waveTables) { + for (int i = 0; i < _numWaveTables; i++) { + if (_waveTables[i].id == id) { + _numWaveTables--; + _waveTablesTotalDataSize -= _waveTables[i].size; + _waveTables[i].clear(); + for (; i < _numWaveTables; i++) + memcpy(&_waveTables[i], &_waveTables[i + 1], sizeof(TownsAudio_WaveTable)); + return 0; + } + return 9; + } + } + } + + return 0; +} + +int TownsAudioInterface::intf_pcmPlayEffect(va_list &args) { + int chan = va_arg(args, int); + int note = va_arg(args, int); + int velo = va_arg(args, int); + uint8 *data = va_arg(args, uint8 *); + + if (chan < 0x40 || chan > 0x47) + return 1; + + if (note & 0x80 || velo & 0x80) + return 3; + + chan -= 0x40; + + if (!(_pcmChanReserved & _chanFlags[chan])) + return 7; + + if ((_pcmChanEffectPlaying & _chanFlags[chan])) + return 2; + + TownsAudio_WaveTable w; + w.readHeader(data); + + if (w.size < (w.loopStart + w.loopLen)) + return 13; + + if (!w.size) + return 6; + + TownsAudio_PcmChannel *p = &_pcmChan[chan]; + + _pcmChanNote[chan] = note; + _pcmChanVelo[chan] = velo; + + p->note = note; + p->velo = velo << 1; + + p->loadExtData(data + 32, w.size); + p->setupLoop(w.loopStart, w.loopLen); + + pcmCalcPhaseStep(p, &w); + if (p->step > 2048) + p->step = 2048; + + _pcmChanEffectPlaying |= _chanFlags[chan]; + _pcmChanOut |= _chanFlags[chan]; + + return 0; +} + +int TownsAudioInterface::intf_pcmChanOff(va_list &args) { + int chan = va_arg(args, int); + pcmChanOff(chan); + return 0; +} + +int TownsAudioInterface::intf_pcmEffectPlaying(va_list &args) { + int chan = va_arg(args, int); + if (chan < 0x40 || chan > 0x47) + return 1; + chan -= 0x40; + return (_pcmChanEffectPlaying & _chanFlags[chan]) ? true : false; +} + +int TownsAudioInterface::intf_fmKeyOn(va_list &args) { + int chan = va_arg(args, int); + int note = va_arg(args, int); + int velo = va_arg(args, int); + return fmKeyOn(chan, note, velo); +} + +int TownsAudioInterface::intf_fmKeyOff(va_list &args) { + int chan = va_arg(args, int); + return fmKeyOff(chan); +} + +int TownsAudioInterface::intf_fmSetPanPos(va_list &args) { + int chan = va_arg(args, int); + int mode = va_arg(args, int); + return fmSetPanPos(chan, mode); +} + +int TownsAudioInterface::intf_fmSetInstrument(va_list &args) { + int chan = va_arg(args, int); + int instrId = va_arg(args, int); + return fmSetInstrument(chan, instrId); +} + +int TownsAudioInterface::intf_fmLoadInstrument(va_list &args) { + int instrId = va_arg(args, int); + uint8 *instrData = va_arg(args, uint8 *); + return fmLoadInstrument(instrId, instrData); +} + +int TownsAudioInterface::intf_fmSetPitch(va_list &args) { + int chan = va_arg(args, int); + uint16 freq = va_arg(args, int) & 0xffff; + return fmSetPitch(chan, freq); +} + +int TownsAudioInterface::intf_fmSetLevel(va_list &args) { + int chan = va_arg(args, int); + int lvl = va_arg(args, int); + return fmSetLevel(chan, lvl); +} + +int TownsAudioInterface::intf_fmReset(va_list &args) { + fmReset(); + return 0; +} + +int TownsAudioInterface::intf_cdaReset(va_list &args) { + cdaReset(); + return 0; +} + +int TownsAudioInterface::intf_pcmUpdateEnvelopeGenerator(va_list &args) { + for (int i = 0; i < 8; i++) + pcmUpdateEnvelopeGenerator(i); + return 0; +} + +int TownsAudioInterface::intf_cdaSetVolume(va_list &args) { + int mode = va_arg(args, int); + int left = va_arg(args, int); + int right = va_arg(args, int); + + // calculate mixer balance value + int8 balance = right - left; + + if (left & 0xff80 || right & 0xff80) + return 3; + + static const uint8 flags[] = { 0x0C, 0x30, 0x40, 0x80 }; + + //int a = (mode & 0x40) ? 4 : 0; + int b = mode & 3; + left = (left & 0x7e) >> 1; + right = (right & 0x7e) >> 1; + + if (mode & 0x40) + _cdaVolFlags |= flags[b]; + else + _cdaVolFlags &= ~flags[b]; + + if (mode > 1) { + // Unknown purpose / TODO + + } else if (mode == 1) { + // FM Towns seems to support volumes of 0 - 63 for each channel. + // We recalculate sane values for out 0 to 255 volume range. + + int vl = (int)(((float)left * 255.0f) / 63.0f); + int vr = (int)(((float)right * 255.0f) / 63.0f); + g_system->getAudioCDManager()->setVolume((vl + vr) >> 1); + g_system->getAudioCDManager()->setBalance(balance); + + } else { + // Unknown purpose / TODO + } + + return 0; +} + +int TownsAudioInterface::intf_notImpl(va_list &args) { + return 4; +} + +void TownsAudioInterface::fmReset() { + TownsPC98_FmSynth::reset(); + + _fmChanPlaying = 0; + memset(_fmChanNote, 0, sizeof(_fmChanNote)); + memset(_fmChanPitch, 0, sizeof(_fmChanPitch)); + + memset(_fmSaveReg[0], 0, 240); + memset(&_fmSaveReg[0][240], 0x7f, 16); + memset(_fmSaveReg[1], 0, 256); + memset(&_fmSaveReg[1][240], 0x7f, 16); + _fmSaveReg[0][243] = _fmSaveReg[0][247] = _fmSaveReg[0][251] = _fmSaveReg[0][255] = + _fmSaveReg[1][243] = _fmSaveReg[1][247] = _fmSaveReg[1][251] = _fmSaveReg[1][255] = 0xff; + + for (int i = 0; i < 128; i++) + fmLoadInstrument(i, _fmDefaultInstrument); + + bufferedWriteReg(0, 0x21, 0); + bufferedWriteReg(0, 0x2C, 0x80); + bufferedWriteReg(0, 0x2B, 0); + bufferedWriteReg(0, 0x27, 0x30); + + for (int i = 0; i < 6; i++) { + fmKeyOff(i); + fmSetInstrument(i, 0); + fmSetLevel(i, 127); + } +} + +int TownsAudioInterface::fmKeyOn(int chan, int note, int velo) { + if (chan > 5) + return 1; + if (note < 12 || note > 107 || (velo & 0x80)) + return 3; + if (_fmChanPlaying & _chanFlags[chan]) + return 2; + + _fmChanPlaying |= _chanFlags[chan]; + note -= 12; + + _fmChanNote[chan] = note; + int16 pitch = _fmChanPitch[chan]; + + uint8 part = chan > 2 ? 1 : 0; + if (chan > 2) + chan -= 3; + + int frq = 0; + uint8 bl = 0; + + if (note) { + frq = _frequency[(note - 1) % 12]; + bl = (note - 1) / 12; + } else { + frq = 616; + } + + frq += pitch; + + if (frq < 616) { + if (!bl) { + frq = 616; + } else { + frq += 616; + --bl; + } + } else if (frq > 1232) { + if (bl == 7) { + frq = 15500; + } else { + frq -= 616; + ++bl; + } + } + + frq |= (bl << 11); + + bufferedWriteReg(part, chan + 0xa4, (frq >> 8) & 0xff); + bufferedWriteReg(part, chan + 0xa0, frq & 0xff); + + velo = (velo >> 2) + 96; + uint16 c = _carrier[_fmSaveReg[part][0xb0 + chan] & 7]; + _fmSaveReg[part][0xe0 + chan] = velo; + + for (uint8 reg = 0x40 + chan; reg < 0x50; reg += 4) { + c += c; + if (c & 0x100) { + c &= 0xff; + bufferedWriteReg(part, reg, (((((((_fmSaveReg[part][0x80 + reg] ^ 0x7f) * velo) >> 7) + 1) * _fmSaveReg[part][0xd0 + chan]) >> 7) + 1) ^ 0x7f); + } + } + + uint8 v = chan; + if (part) + v |= 4; + + for (uint8 reg = 0x80 + chan; reg < 0x90; reg += 4) + writeReg(part, reg, _fmSaveReg[part][reg] | 0x0f); + + writeReg(0, 0x28, v); + + for (uint8 reg = 0x80 + chan; reg < 0x90; reg += 4) + writeReg(part, reg, _fmSaveReg[part][reg]); + + bufferedWriteReg(0, 0x28, v | 0xf0); + + return 0; +} + +int TownsAudioInterface::fmKeyOff(int chan) { + if (chan > 5) + return 1; + _fmChanPlaying &= ~_chanFlags[chan]; + if (chan > 2) + chan++; + bufferedWriteReg(0, 0x28, chan); + return 0; +} + +int TownsAudioInterface::fmChanOff(int chan) { + if (chan > 5) + return 1; + _fmChanPlaying &= ~_chanFlags[chan]; + + uint8 part = chan > 2 ? 1 : 0; + if (chan > 2) + chan -= 3; + + for (uint8 reg = 0x80 + chan; reg < 0x90; reg += 4) + writeReg(part, reg, _fmSaveReg[part][reg] | 0x0f); + + if (part) + chan += 4; + writeReg(0, 0x28, chan); + return 0; +} + +int TownsAudioInterface::fmSetPanPos(int chan, int value) { + if (chan > 5) + return 1; + + uint8 part = chan > 2 ? 1 : 0; + if (chan > 2) + chan -= 3; + + if (value > 0x40) + value = 0x40; + else if (value < 0x40) + value = 0x80; + else + value = 0xC0; + + bufferedWriteReg(part, 0xb4 + chan, (_fmSaveReg[part][0xb4 + chan] & 0x3f) | value); + return 0; +} + +int TownsAudioInterface::fmSetInstrument(int chan, int instrId) { + if (chan > 5) + return 1; + if (instrId > 127) + return 3; + + uint8 part = chan > 2 ? 1 : 0; + if (chan > 2) + chan -= 3; + + uint8 *src = &_fmInstruments[instrId * 48 + 8]; + + uint16 c = _carrier[src[24] & 7]; + uint8 reg = 0x30 + chan; + + for (; reg < 0x40; reg += 4) + bufferedWriteReg(part, reg, *src++); + + for (; reg < 0x50; reg += 4) { + uint8 v = *src++; + _fmSaveReg[part][0x80 + reg] = _fmSaveReg[part][reg] = v; + c += c; + if (c & 0x100) { + c &= 0xff; + v = 127; + } + writeReg(part, reg, v); + } + + for (; reg < 0x90; reg += 4) + bufferedWriteReg(part, reg, *src++); + + reg += 0x20; + bufferedWriteReg(part, reg, *src++); + + uint8 v = *src++; + reg += 4; + if (v < 64) + v |= (_fmSaveReg[part][reg] & 0xc0); + bufferedWriteReg(part, reg, v); + + return 0; +} + +int TownsAudioInterface::fmLoadInstrument(int instrId, const uint8 *data) { + if (instrId > 127) + return 3; + assert(data); + memcpy(&_fmInstruments[instrId * 48], data, 48); + return 0; +} + +int TownsAudioInterface::fmSetPitch(int chan, int pitch) { + if (chan > 5) + return 1; + + uint8 bl = _fmChanNote[chan]; + int frq = 0; + + if (pitch < 0) { + if (bl) { + if (pitch < -8008) + pitch = -8008; + pitch *= -1; + pitch /= 13; + frq = _frequency[(bl - 1) % 12] - pitch; + bl = (bl - 1) / 12; + _fmChanPitch[chan] = -pitch; + + if (frq < 616) { + if (bl) { + frq += 616; + bl--; + } else { + frq = 616; + bl = 0; + } + } + } else { + frq = 616; + bl = 0; + } + + } else if (pitch > 0) { + if (bl < 96) { + if (pitch > 8008) + pitch = 8008; + pitch /= 13; + + if (bl) { + frq = _frequency[(bl - 1) % 12] + pitch; + bl = (bl - 1) / 12; + } else { + frq = 616; + bl = 0; + } + + _fmChanPitch[chan] = pitch; + + if (frq > 1232) { + if (bl < 7) { + frq -= 616; + bl++; + } else { + frq = 1164; + bl = 7; + } + } else { + if (bl >= 7 && frq > 1164) + frq = 1164; + } + + } else { + frq = 1164; + bl = 7; + } + } else { + _fmChanPitch[chan] = 0; + if (bl) { + frq = _frequency[(bl - 1) % 12]; + bl = (bl - 1) / 12; + } else { + frq = 616; + bl = 0; + } + } + + uint8 part = chan > 2 ? 1 : 0; + if (chan > 2) + chan -= 3; + + frq |= (bl << 11); + + bufferedWriteReg(part, chan + 0xa4, (frq >> 8)); + bufferedWriteReg(part, chan + 0xa0, (frq & 0xff)); + + return 0; +} + +int TownsAudioInterface::fmSetLevel(int chan, int lvl) { + if (chan > 5) + return 1; + if (lvl > 127) + return 3; + + uint8 part = chan > 2 ? 1 : 0; + if (chan > 2) + chan -= 3; + + uint16 c = _carrier[_fmSaveReg[part][0xb0 + chan] & 7]; + _fmSaveReg[part][0xd0 + chan] = lvl; + + for (uint8 reg = 0x40 + chan; reg < 0x50; reg += 4) { + c += c; + if (c & 0x100) { + c &= 0xff; + bufferedWriteReg(part, reg, (((((((_fmSaveReg[part][0x80 + reg] ^ 0x7f) * lvl) >> 7) + 1) * _fmSaveReg[part][0xe0 + chan]) >> 7) + 1) ^ 0x7f); + } + } + return 0; +} + +void TownsAudioInterface::bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value) { + _fmSaveReg[part][regAddress] = value; + writeReg(part, regAddress, value); +} + +void TownsAudioInterface::pcmReset() { + _pcmChanOut = 0; + _pcmChanReserved = _pcmChanKeyPressed = _pcmChanEffectPlaying = _pcmChanKeyPlaying = 0; + _numReservedChannels = 0; + + memset(_pcmChanNote, 0, 8); + memset(_pcmChanVelo, 0, 8); + memset(_pcmChanLevel, 0, 8); + + for (int i = 0; i < 8; i++) + _pcmChan[i].clear(); + + memset(_pcmInstruments, 0, 128 * 32); + static uint8 name[] = { 0x4E, 0x6F, 0x20, 0x44, 0x61, 0x74, 0x61, 0x21 }; + for (int i = 0; i < 32; i++) + memcpy(_pcmInstruments + i * 128, name, 8); + + for (int i = 0; i < 128; i++) + _waveTables[i].clear(); + _numWaveTables = 0; + _waveTablesTotalDataSize = 0; + + for (int i = 0x40; i < 0x48; i++) { + pcmSetInstrument(i, 0); + pcmSetLevel(i, 127); + } +} + +int TownsAudioInterface::pcmKeyOn(int chan, int note, int velo) { + if (chan < 0x40 || chan > 0x47) + return 1; + + if (note & 0x80 || velo & 0x80) + return 3; + + chan -= 0x40; + + if ((_pcmChanReserved & _chanFlags[chan]) || (_pcmChanKeyPressed & _chanFlags[chan])) + return 2; + + _pcmChanNote[chan] = note; + _pcmChanVelo[chan] = velo; + + TownsAudio_PcmChannel *p = &_pcmChan[chan]; + p->note = note; + + uint8 *instr = _pcmChan[chan].curInstrument; + int i = 0; + for (; i < 8; i++) { + if (note <= instr[16 + 2 * i]) + break; + } + + if (i == 8) + return 8; + + int il = i << 3; + p->note += instr[il + 70]; + + p->envTotalLevel = instr[il + 64]; + p->envAttackRate = instr[il + 65]; + p->envDecayRate = instr[il + 66]; + p->envSustainLevel = instr[il + 67]; + p->envSustainRate = instr[il + 68]; + p->envReleaseRate = instr[il + 69]; + p->envStep = 0; + + int32 id = (int32)READ_LE_UINT32(&instr[i * 4 + 32]); + + for (i = 0; i < _numWaveTables; i++) { + if (id == _waveTables[i].id) + break; + } + + if (i == _numWaveTables) + return 9; + + TownsAudio_WaveTable *w = &_waveTables[i]; + + p->data = w->data; + p->dataEnd = w->data + w->size; + p->setupLoop(w->loopStart, w->loopLen); + + pcmCalcPhaseStep(p, w); + + uint32 lvl = _pcmChanLevel[chan] * _pcmChanVelo[chan]; + p->envTotalLevel = ((p->envTotalLevel * lvl) >> 14) & 0xff; + p->envSustainLevel = ((p->envSustainLevel * lvl) >> 14) & 0xff; + + p->envAttack(); + p->velo = (p->envCurrentLevel >> 8) << 1; + + _pcmChanKeyPressed |= _chanFlags[chan]; + _pcmChanKeyPlaying |= _chanFlags[chan]; + _pcmChanOut |= _chanFlags[chan]; + + return 0; +} + +int TownsAudioInterface::pcmKeyOff(int chan) { + if (chan < 0x40 || chan > 0x47) + return 1; + + chan -= 0x40; + _pcmChanKeyPressed &= ~_chanFlags[chan]; + _pcmChan[chan].envRelease(); + return 0; +} + +int TownsAudioInterface::pcmChanOff(int chan) { + if (chan < 0x40 || chan > 0x47) + return 1; + + chan -= 0x40; + + _pcmChanKeyPressed &= ~_chanFlags[chan]; + _pcmChanEffectPlaying &= ~_chanFlags[chan]; + _pcmChanKeyPlaying &= ~_chanFlags[chan]; + _pcmChanOut &= ~_chanFlags[chan]; + + return 0; +} + +int TownsAudioInterface::pcmSetPanPos(int chan, int mode) { + if (chan > 0x47) + return 1; + if (mode & 0x80) + return 3; + + chan -= 0x40; + uint8 blc = 0x77; + + if (mode > 64) { + mode -= 64; + blc = ((blc ^ (mode >> 3)) + (mode << 4)) & 0xff; + } else if (mode < 64) { + mode = (mode >> 3) ^ 7; + blc = ((119 + mode) ^ (mode << 4)) & 0xff; + } + + _pcmChan[chan].panLeft = blc & 0x0f; + _pcmChan[chan].panRight = blc >> 4; + + return 0; +} + +int TownsAudioInterface::pcmSetInstrument(int chan, int instrId) { + if (chan > 0x47) + return 1; + if (instrId > 31) + return 3; + chan -= 0x40; + _pcmChan[chan].curInstrument = &_pcmInstruments[instrId * 128]; + return 0; +} + +int TownsAudioInterface::pcmLoadInstrument(int instrId, const uint8 *data) { + if (instrId > 31) + return 3; + assert(data); + memcpy(&_pcmInstruments[instrId * 128], data, 128); + return 0; +} + +int TownsAudioInterface::pcmSetPitch(int chan, int pitch) { + if (chan > 0x47) + return 1; + + if (pitch < -8192 || pitch > 8191) + return 3; + + chan -= 0x40; + TownsAudio_PcmChannel *p = &_pcmChan[chan]; + + uint32 pts = 0x4000; + + if (pitch < 0) + pts = (0x20000000 / (-pitch + 0x2001)) >> 2; + else if (pitch > 0) + pts = (((pitch + 0x2001) << 16) / 0x2000) >> 2; + + p->stepPitch = pts & 0xffff; + p->step = (p->stepNote * p->stepPitch) >> 14; + +// if (_pcmChanUnkFlag & _chanFlags[chan]) +// unk[chan] = (((p->step * 1000) << 11) / 98) / 20833; + + /*else*/ + if ((_pcmChanEffectPlaying & _chanFlags[chan]) && (p->step > 2048)) + p->step = 2048; + + return 0; +} + +int TownsAudioInterface::pcmSetLevel(int chan, int lvl) { + if (chan > 0x47) + return 1; + + if (lvl & 0x80) + return 3; + + chan -= 0x40; + TownsAudio_PcmChannel *p = &_pcmChan[chan]; + + if (_pcmChanReserved & _chanFlags[chan]) { + _pcmChanVelo[chan] = lvl; + p->velo = lvl << 1; + } else { + int32 t = p->envStep * lvl; + if (_pcmChanLevel[chan]) + t /= _pcmChanLevel[chan]; + p->envStep = t; + t = p->envCurrentLevel * lvl; + if (_pcmChanLevel[chan]) + t /= _pcmChanLevel[chan]; + p->envCurrentLevel = t; + _pcmChanLevel[chan] = lvl; + p->velo = p->envCurrentLevel >> 8; + } + + return 0; +} + +void TownsAudioInterface::pcmUpdateEnvelopeGenerator(int chan) { + TownsAudio_PcmChannel *p = &_pcmChan[chan]; + if (!p->envCurrentLevel) { + _pcmChanKeyPlaying &= ~_chanFlags[chan]; + p->envState = kEnvReady; + } + + if (!(_pcmChanKeyPlaying & _chanFlags[chan])) + return; + + switch (p->envState) { + case kEnvAttacking: + if (((p->envCurrentLevel + p->envStep) >> 8) > p->envTotalLevel) { + p->envDecay(); + return; + } else { + p->envCurrentLevel += p->envStep; + } + break; + + case kEnvDecaying: + if (((p->envCurrentLevel - p->envStep) >> 8) < p->envSustainLevel) { + p->envSustain(); + return; + } else { + p->envCurrentLevel -= p->envStep; + } + break; + + case kEnvSustaining: + case kEnvReleasing: + p->envCurrentLevel -= p->envStep; + if (p->envCurrentLevel <= 0) + p->envCurrentLevel = 0; + break; + + default: + break; + } + p->velo = (p->envCurrentLevel >> 8) << 1; +} + +void TownsAudioInterface::pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w) { + int8 diff = p->note - w->baseNote; + uint16 r = w->rate + w->rateOffs; + uint16 bl = 0; + uint32 s = 0; + + if (diff < 0) { + diff *= -1; + bl = diff % 12; + diff /= 12; + s = (r >> diff); + if (bl) + s = (s * _pcmPhase2[bl]) >> 16; + + } else if (diff > 0) { + bl = diff % 12; + diff /= 12; + s = (r << diff); + if (bl) + s += ((s * _pcmPhase1[bl]) >> 16); + + } else { + s = r; + } + + p->stepNote = s & 0xffff; + p->step = (s * p->stepPitch) >> 14; +} + +void TownsAudioInterface::cdaReset() { + +} + +const uint8 TownsAudioInterface::_chanFlags[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 +}; + +const uint16 TownsAudioInterface::_frequency[] = { + 0x028C, 0x02B4, 0x02DC, 0x030A, 0x0338, 0x0368, 0x039C, 0x03D4, 0x040E, 0x044A, 0x048C, 0x04D0 +}; + +const uint8 TownsAudioInterface::_carrier[] = { + 0x10, 0x10, 0x10, 0x10, 0x30, 0x70, 0x70, 0xF0 +}; + +const uint8 TownsAudioInterface::_fmDefaultInstrument[] = { + 0x45, 0x4C, 0x45, 0x50, 0x49, 0x41, 0x4E, 0x4F, 0x01, 0x0A, 0x02, 0x01, + 0x1E, 0x32, 0x05, 0x00, 0x9C, 0xDC, 0x9C, 0xDC, 0x07, 0x03, 0x14, 0x08, + 0x00, 0x03, 0x05, 0x05, 0x55, 0x45, 0x27, 0xA7, 0x04, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const uint16 TownsAudioInterface::_pcmPhase1[] = { + 0x879B, 0x0F37, 0x1F58, 0x306E, 0x4288, 0x55B6, 0x6A08, 0x7F8F, 0x965E, 0xAE88, 0xC882, 0xE341 +}; + +const uint16 TownsAudioInterface::_pcmPhase2[] = { + 0xFEFE, 0xF1A0, 0xE411, 0xD744, 0xCB2F, 0xBFC7, 0xB504, 0xAAE2, 0xA144, 0x9827, 0x8FAC +}; + +TownsAudio_PcmChannel::TownsAudio_PcmChannel() { + extData = 0; + clear(); +} + +TownsAudio_PcmChannel::~TownsAudio_PcmChannel() { + clear(); +} + +void TownsAudio_PcmChannel::loadExtData(uint8 *buffer, uint32 size) { + delete[] extData; + extData = new int8[size]; + int8 *src = (int8 *)buffer; + int8 *dst = extData; + for (uint32 i = 0; i < size; i++) + *dst++ = *src & 0x80 ? (*src++ & 0x7f) : -*src++; + + data = extData; + dataEnd = extData + size; + pos = 0; +} + +void TownsAudio_PcmChannel::setupLoop(uint32 start, uint32 len) { + loopLen = len << 11; + loopEnd = loopLen ? &data[(start + loopLen) >> 11] : dataEnd; + pos = start; +} + +void TownsAudio_PcmChannel::clear() { + curInstrument = 0; + note = 0; + velo = 0; + + data = 0; + dataEnd = 0; + loopLen = 0; + + pos = 0; + loopEnd = 0; + + step = 0; + stepNote = 0x4000; + stepPitch = 0x4000; + + panLeft = panRight = 0; + + envTotalLevel = envAttackRate = envDecayRate = envSustainLevel = envSustainRate = envReleaseRate = 0; + envStep = envCurrentLevel = 0; + + envState = kEnvReady; + + delete[] extData; + extData = 0; +} + +void TownsAudio_PcmChannel::envAttack() { + envState = kEnvAttacking; + int16 t = envTotalLevel << 8; + if (envAttackRate == 127) { + envStep = 0; + } else if (envAttackRate) { + envStep = t / envAttackRate; + envCurrentLevel = 1; + } else { + envCurrentLevel = t; + envDecay(); + } +} + +void TownsAudio_PcmChannel::envDecay() { + envState = kEnvDecaying; + int16 t = envTotalLevel - envSustainLevel; + if (t < 0 || envDecayRate == 127) { + envStep = 0; + } else if (envDecayRate) { + envStep = (t << 8) / envDecayRate; + } else { + envCurrentLevel = envSustainLevel << 8; + envSustain(); + } +} + +void TownsAudio_PcmChannel::envSustain() { + envState = kEnvSustaining; + if (envSustainLevel && envSustainRate) + envStep = (envSustainRate == 127) ? 0 : (envCurrentLevel / envSustainRate) >> 1; + else + envStep = envCurrentLevel = 1; +} + +void TownsAudio_PcmChannel::envRelease() { + envState = kEnvReleasing; + if (envReleaseRate == 127) + envStep = 0; + else if (envReleaseRate) + envStep = envCurrentLevel / envReleaseRate; + else + envStep = envCurrentLevel = 1; +} + +TownsAudio_WaveTable::TownsAudio_WaveTable() { + data = 0; + clear(); +} + +TownsAudio_WaveTable::~TownsAudio_WaveTable() { + clear(); +} + +void TownsAudio_WaveTable::readHeader(const uint8 *buffer) { + memcpy(name, buffer, 8); + name[8] = 0; + id = READ_LE_UINT32(&buffer[8]); + size = READ_LE_UINT32(&buffer[12]); + loopStart = READ_LE_UINT32(&buffer[16]); + loopLen = READ_LE_UINT32(&buffer[20]); + rate = READ_LE_UINT16(&buffer[24]); + rateOffs = READ_LE_UINT16(&buffer[26]); + baseNote = READ_LE_UINT32(&buffer[28]); +} + +void TownsAudio_WaveTable::readData(const uint8 *buffer) { + if (!size) + return; + + delete[] data; + data = new int8[size]; + + const int8 *src = (const int8 *)buffer; + int8 *dst = data; + for (uint32 i = 0; i < size; i++) + *dst++ = *src & 0x80 ? (*src++ & 0x7f) : -*src++; +} + +void TownsAudio_WaveTable::clear() { + name[0] = name[8] = 0; + id = -1; + size = 0; + loopStart = 0; + loopLen = 0; + rate = 0; + rateOffs = 0; + baseNote = 0; + delete[] data; + data = 0; +} + diff --git a/sound/softsynth/fmtowns_pc98/towns_audio.h b/sound/softsynth/fmtowns_pc98/towns_audio.h new file mode 100644 index 0000000000..212c00c40f --- /dev/null +++ b/sound/softsynth/fmtowns_pc98/towns_audio.h @@ -0,0 +1,176 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef TOWNS_AUDIO_H +#define TOWNS_AUDIO_H + +#include "sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h" + +class TownsAudioInterfacePluginDriver { +public: + virtual ~TownsAudioInterfacePluginDriver() {} + virtual void timerCallback(int timerId) = 0; +}; + +class TownsAudio_PcmChannel; +class TownsAudio_WaveTable; + +class TownsAudioInterface : public TownsPC98_FmSynth { +public: + TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver); + ~TownsAudioInterface(); + + bool init(); + + int callback(int command, ...); + + void setMusicVolume(int volume); + void setSoundEffectVolume(int volume); + // Defines the channels used as sound effect channels for the purpose of ScummVM GUI volume control. + // The first 6 bits are the 6 fm channels. The next 8 bits are pcm channels. + void setSoundEffectChanMask(uint32 mask); + +private: + void nextTickEx(int32 *buffer, uint32 bufferSize); + + void timerCallbackA(); + void timerCallbackB(); + + typedef int (TownsAudioInterface::*TownsAudioIntfCallback)(va_list &); + const TownsAudioIntfCallback *_intfOpcodes; + + int intf_reset(va_list &args); + int intf_keyOn(va_list &args); + int intf_keyOff(va_list &args); + int intf_setPanPos(va_list &args); + int intf_setInstrument(va_list &args); + int intf_loadInstrument(va_list &args); + int intf_setPitch(va_list &args); + int intf_setLevel(va_list &args); + int intf_chanOff(va_list &args); + int intf_writeReg(va_list &args); + int intf_writeRegBuffer(va_list &args); + int intf_readRegBuffer(va_list &args); + int intf_setTimerA(va_list &args); + int intf_setTimerB(va_list &args); + int intf_enableTimerA(va_list &args); + int intf_enableTimerB(va_list &args); + int intf_loadSamples(va_list &args); + int intf_reserveEffectChannels(va_list &args); + int intf_loadWaveTable(va_list &args); + int intf_unloadWaveTable(va_list &args); + int intf_pcmPlayEffect(va_list &args); + int intf_pcmChanOff(va_list &args); + int intf_pcmEffectPlaying(va_list &args); + int intf_fmKeyOn(va_list &args); + int intf_fmKeyOff(va_list &args); + int intf_fmSetPanPos(va_list &args); + int intf_fmSetInstrument(va_list &args); + int intf_fmLoadInstrument(va_list &args); + int intf_fmSetPitch(va_list &args); + int intf_fmSetLevel(va_list &args); + int intf_fmReset(va_list &args); + int intf_cdaSetVolume(va_list &args); + int intf_cdaReset(va_list &args); + int intf_pcmUpdateEnvelopeGenerator(va_list &args); + + int intf_notImpl(va_list &args); + + void fmReset(); + int fmKeyOn(int chan, int note, int velo); + int fmKeyOff(int chan); + int fmChanOff(int chan); + int fmSetPanPos(int chan, int mode); + int fmSetInstrument(int chan, int instrId); + int fmLoadInstrument(int instrId, const uint8 *data); + int fmSetPitch(int chan, int pitch); + int fmSetLevel(int chan, int lvl); + + void bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value); + + uint8 _fmChanPlaying; + uint8 _fmChanNote[6]; + int16 _fmChanPitch[6]; + + uint8 *_fmSaveReg[2]; + uint8 *_fmInstruments; + + void pcmReset(); + int pcmKeyOn(int chan, int note, int velo); + int pcmKeyOff(int chan); + int pcmChanOff(int chan); + int pcmSetPanPos(int chan, int mode); + int pcmSetInstrument(int chan, int instrId); + int pcmLoadInstrument(int instrId, const uint8 *data); + int pcmSetPitch(int chan, int pitch); + int pcmSetLevel(int chan, int lvl); + void pcmUpdateEnvelopeGenerator(int chan); + + TownsAudio_PcmChannel *_pcmChan; + uint8 _pcmChanOut; + uint8 _pcmChanReserved; + uint8 _pcmChanKeyPressed; + uint8 _pcmChanEffectPlaying; + uint8 _pcmChanKeyPlaying; + + uint8 _pcmChanNote[8]; + uint8 _pcmChanVelo[8]; + uint8 _pcmChanLevel[8]; + + uint8 _numReservedChannels; + uint8 *_pcmInstruments; + + TownsAudio_WaveTable *_waveTables; + uint8 _numWaveTables; + uint32 _waveTablesTotalDataSize; + + void pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w); + + void cdaReset(); + + uint8 _cdaVolFlags; + + const float _baserate; + uint32 _timerBase; + uint32 _tickLength; + uint32 _timer; + + uint16 _musicVolume; + uint16 _sfxVolume; + uint32 _pcmSfxChanMask; + + TownsAudioInterfacePluginDriver *_drv; + bool _ready; + + static const uint8 _chanFlags[]; + static const uint16 _frequency[]; + static const uint8 _carrier[]; + static const uint8 _fmDefaultInstrument[]; + static const uint16 _pcmPhase1[]; + static const uint16 _pcmPhase2[]; +}; + +#endif + diff --git a/sound/softsynth/fmtowns_pc98/towns_euphony.cpp b/sound/softsynth/fmtowns_pc98/towns_euphony.cpp new file mode 100644 index 0000000000..e23d5bcb36 --- /dev/null +++ b/sound/softsynth/fmtowns_pc98/towns_euphony.cpp @@ -0,0 +1,903 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "sound/softsynth/fmtowns_pc98/towns_euphony.h" +#include "common/endian.h" + +TownsEuphonyDriver::TownsEuphonyDriver(Audio::Mixer *mixer) : _activeChannels(0), _sustainChannels(0), + _assignedChannels(0), _paraCount(0), _command(0), _tEnable(0), _tMode(0), _tOrdr(0), _tLevel(0), + _tTranspose(0), _musicPos(0), _musicStart(0), _playing(false), _eventBuffer(0), _bufferedEventsCount(0), + _tempoControlMode(0) { + _para[0] = _para[1] = 0; + _intf = new TownsAudioInterface(mixer, this); + resetTempo(); +} + +TownsEuphonyDriver::~TownsEuphonyDriver() { + delete[] _activeChannels; + delete[] _sustainChannels; + delete[] _assignedChannels; + + delete[] _tEnable; + delete[] _tMode; + delete[] _tOrdr; + delete[] _tLevel; + delete[] _tTranspose; + + delete _intf; +} + +bool TownsEuphonyDriver::init() { + if (!_intf->init()) + return false; + + _activeChannels = new int8[16]; + _sustainChannels = new int8[16]; + _assignedChannels = new ActiveChannel[128]; + _eventBuffer = new DlEvent[64]; + + _tEnable = new uint8[32]; + _tMode = new uint8[32]; + _tOrdr = new uint8[32]; + _tLevel = new int8[32]; + _tTranspose = new int8[32]; + + reset(); + + return true; +} + +void TownsEuphonyDriver::reset() { + _intf->callback(0); + + _intf->callback(74); + _intf->callback(70); + _intf->callback(75, 3); + + setTimerA(true, 1); + setTimerA(false, 1); + setTimerB(true, 221); + + _paraCount = _command = _para[0] = _para[1] = 0; + memset(_sustainChannels, 0, 16); + memset(_activeChannels, -1, 16); + for (int i = 0; i < 128; i++) { + _assignedChannels[i].chan = _assignedChannels[i].next = -1; + _assignedChannels[i].note = _assignedChannels[i].sub = 0; + } + + int e = 0; + for (int i = 0; i < 6; i++) + assignChannel(i, e++); + for (int i = 0x40; i < 0x48; i++) + assignChannel(i, e++); + + resetTables(); + + memset(_eventBuffer, 0, 64 * sizeof(DlEvent)); + _bufferedEventsCount = 0; + + _playing = _endOfTrack = _suspendParsing = _loop = false; + _elapsedEvents = 0; + _tempoDiff = 0; + + resetTempo(); + + if (_tempoControlMode == 1) { + //if (///) + // return; + setTempoIntern(_defaultTempo); + } else { + setTempoIntern(_defaultTempo); + } + + resetControl(); +} + +void TownsEuphonyDriver::loadInstrument(int chanType, int id, const uint8 *data) { + _intf->callback(5, chanType, id, data); +} + +void TownsEuphonyDriver::loadWaveTable(const uint8 *data) { + _intf->callback(34, data); +} + +void TownsEuphonyDriver::unloadWaveTable(int id) { + _intf->callback(35, id); +} + +void TownsEuphonyDriver::reserveSoundEffectChannels(int num) { + _intf->callback(33, num); + uint32 volMask = 0; + + if (num > 8) + return; + + for (uint32 v = 1 << 13; num; num--) { + volMask |= v; + v >>= 1; + } + + _intf->setSoundEffectChanMask(volMask); +} + +int TownsEuphonyDriver::setMusicTempo(int tempo) { + if (tempo > 250) + return 3; + _defaultTempo = tempo; + _trackTempo = tempo; + setTempoIntern(tempo); + return 0; +} + +int TownsEuphonyDriver::startMusicTrack(const uint8 *data, int trackSize, int startTick) { + if (_playing) + return 2; + + _musicPos = _musicStart = data; + _defaultBaseTickLen = _baseTickLen = startTick; + _musicTrackSize = trackSize; + _timeStampBase = _timeStampDest = 0; + _tickCounter = 0; + _playing = true; + + return 0; +} + +void TownsEuphonyDriver::setMusicLoop(bool loop) { + _loop = loop; +} + +void TownsEuphonyDriver::stopParser() { + if (_playing) { + _playing = false; + _pulseCount = 0; + _endOfTrack = false; + flushEventBuffer(); + resetControl(); + } +} + +void TownsEuphonyDriver::playSoundEffect(int chan, int note, int velo, const uint8 *data) { + _intf->callback(37, chan, note, velo, data); +} + +void TownsEuphonyDriver::stopSoundEffect(int chan) { + _intf->callback(39, chan); +} + +bool TownsEuphonyDriver::soundEffectIsPlaying(int chan) { + return _intf->callback(40, chan) ? true : false; +} + +void TownsEuphonyDriver::chanPanPos(int chan, int mode) { + _intf->callback(3, chan, mode); +} + +void TownsEuphonyDriver::chanPitch(int chan, int pitch) { + _intf->callback(7, chan, pitch); +} + +void TownsEuphonyDriver::chanVolume(int chan, int vol) { + _intf->callback(8, chan, vol); +} + +void TownsEuphonyDriver::cdaSetVolume(int mode, int volLeft, int volRight) { + _intf->callback(67, mode, volLeft, volRight); +} + +int TownsEuphonyDriver::chanEnable(int tableEntry, int val) { + if (tableEntry > 31) + return 3; + _tEnable[tableEntry] = val; + return 0; +} + +int TownsEuphonyDriver::chanMode(int tableEntry, int val) { + if (tableEntry > 31) + return 3; + _tMode[tableEntry] = val; + return 0; +} + +int TownsEuphonyDriver::chanOrdr(int tableEntry, int val) { + if (tableEntry > 31) + return 3; + if (val < 16) + _tOrdr[tableEntry] = val; + return 0; +} + +int TownsEuphonyDriver::chanLevel(int tableEntry, int val) { + if (tableEntry > 31) + return 3; + if (val <= 40) + _tLevel[tableEntry] = (int8)(val & 0xff); + return 0; +} + +int TownsEuphonyDriver::chanTranspose(int tableEntry, int val) { + if (tableEntry > 31) + return 3; + if (val <= 40) + _tTranspose[tableEntry] = (int8)(val & 0xff); + return 0; +} + +int TownsEuphonyDriver::assignChannel(int chan, int tableEntry) { + if (tableEntry > 15 || chan > 127 || chan < 0) + return 3; + + ActiveChannel *a = &_assignedChannels[chan]; + if (a->chan == tableEntry) + return 0; + + if (a->chan != -1) { + int8 *b = &_activeChannels[a->chan]; + while (*b != chan) { + b = &_assignedChannels[*b].next; + if (*b == -1 && *b != chan) + return 3; + } + + *b = a->next; + + if (a->note) + _intf->callback(2, chan); + + a->chan = a->next = -1; + a->note = 0; + } + + a->next = _activeChannels[tableEntry]; + _activeChannels[tableEntry] = chan; + a->chan = tableEntry; + a->note = a->sub = 0; + + return 0; +} + +void TownsEuphonyDriver::timerCallback(int timerId) { + switch (timerId) { + case 0: + updatePulseCount(); + while (_pulseCount > 0) { + --_pulseCount; + updateTimeStampBase(); + if (!_playing) + continue; + updateEventBuffer(); + updateParser(); + updateCheckEot(); + } + break; + default: + break; + } +} + +void TownsEuphonyDriver::setMusicVolume(int volume) { + _intf->setMusicVolume(volume); +} + +void TownsEuphonyDriver::setSoundEffectVolume(int volume) { + _intf->setSoundEffectVolume(volume); +} + +void TownsEuphonyDriver::resetTables() { + memset(_tEnable, 0xff, 32); + memset(_tMode, 0xff, 16); + memset(_tMode + 16, 0, 16); + for (int i = 0; i < 32; i++) + _tOrdr[i] = i & 0x0f; + memset(_tLevel, 0, 32); + memset(_tTranspose, 0, 32); +} + +void TownsEuphonyDriver::resetTempo() { + _defaultBaseTickLen = _baseTickLen = 0x33; + _pulseCount = 0; + _extraTimingControlRemainder = 0; + _extraTimingControl = 16; + _tempoModifier = 0; + _timeStampDest = 0; + _deltaTicks = 0; + _tickCounter = 0; + _defaultTempo = 90; + _trackTempo = 90; +} + +void TownsEuphonyDriver::setTempoIntern(int tempo) { + tempo = CLIP(tempo + _tempoModifier, 0, 500); + if (_tempoControlMode == 0) { + _timerSetting = 34750 / (tempo + 30); + _extraTimingControl = 16; + + while (_timerSetting < 126) { + _timerSetting <<= 1; + _extraTimingControl <<= 1; + } + + while (_timerSetting > 383) { + _timerSetting >>= 1; + _extraTimingControl >>= 1; + } + + setTimerA(true, -(_timerSetting - 2)); + + } else if (_tempoControlMode == 1) { + _timerSetting = 312500 / (tempo + 30); + _extraTimingControl = 16; + while (_timerSetting < 1105) { + _timerSetting <<= 1; + _extraTimingControl <<= 1; + } + + } else if (_tempoControlMode == 2) { + _timerSetting = 625000 / (tempo + 30); + _extraTimingControlRemainder = 0; + } +} + +void TownsEuphonyDriver::setTimerA(bool enable, int tempo) { + _intf->callback(21, enable ? 255 : 0, tempo); +} + +void TownsEuphonyDriver::setTimerB(bool enable, int tempo) { + _intf->callback(22, enable ? 255 : 0, tempo); +} + +void TownsEuphonyDriver::updatePulseCount() { + int tc = _extraTimingControl + _extraTimingControlRemainder; + _extraTimingControlRemainder = tc & 0x0f; + tc >>= 4; + _tempoDiff -= tc; + + while (_tempoDiff < 0) { + _elapsedEvents++; + _tempoDiff += 4; + } + + if (_playing && !_suspendParsing) + _pulseCount += tc; +} + +void TownsEuphonyDriver::updateTimeStampBase() { + static const uint16 table[] = { 0x180, 0xC0, 0x80, 0x60, 0x40, 0x30, 0x20, 0x18 }; + if ((uint32)(table[_baseTickLen >> 4] * ((_baseTickLen & 0x0f) + 1)) > ++_tickCounter) + return; + ++_timeStampDest; + _tickCounter = 0; + _deltaTicks = 0; +} + +void TownsEuphonyDriver::updateParser() { + for (bool loop = true; loop;) { + uint8 cmd = _musicPos[0]; + + if (cmd == 0xff || cmd == 0xf7) { + jumpNextLoop(); + + } else if (cmd < 0x90) { + _endOfTrack = true; + flushEventBuffer(); + loop = false; + + } else if (_timeStampBase > _timeStampDest) { + loop = false; + + } else { + if (_timeStampBase == _timeStampDest) { + uint16 timeStamp = READ_LE_UINT16(&_musicPos[2]); + uint8 l = (timeStamp & 0xff) + (timeStamp & 0xff); + timeStamp = ((timeStamp & 0xff00) | l) >> 1; + if (timeStamp > _tickCounter) + loop = false; + } + + if (loop) { + if (parseNext()) + loop = false; + } + } + } +} + +void TownsEuphonyDriver::updateCheckEot() { + if (!_endOfTrack || _bufferedEventsCount) + return; + stopParser(); +} + +bool TownsEuphonyDriver::parseNext() { +#define OPC(x) &TownsEuphonyDriver::evt##x + static const EuphonyOpcode opcodes[] = { + OPC(NotImpl), + OPC(SetupNote), + OPC(PolyphonicAftertouch), + OPC(ControlPitch), + OPC(InstrumentChanAftertouch), + OPC(InstrumentChanAftertouch), + OPC(ControlPitch) + }; +#undef OPC + + uint cmd = _musicPos[0]; + if (cmd != 0xfe && cmd != 0xfd) { + if (cmd >= 0xf0) { + cmd &= 0x0f; + if (cmd == 0) + evtLoadInstrument(); + else if (cmd == 2) + evtAdvanceTimestampOffset(); + else if (cmd == 8) + evtTempo(); + else if (cmd == 12) + evtModeOrdrChange(); + jumpNextLoop(); + return false; + + } else if (!(this->*opcodes[(cmd - 0x80) >> 4])()) { + jumpNextLoop(); + return false; + } + } + + if (cmd == 0xfd) { + _suspendParsing = true; + return true; + } + + if (!_loop) { + _endOfTrack = true; + return true; + } + + _endOfTrack = false; + _musicPos = _musicStart; + _timeStampBase = _timeStampDest = _tickCounter = 0; + _baseTickLen = _defaultBaseTickLen; + + return false; +} + +void TownsEuphonyDriver::jumpNextLoop() { + _musicPos += 6; + if (_musicPos >= _musicStart + _musicTrackSize) + _musicPos = _musicStart; +} + +void TownsEuphonyDriver::updateEventBuffer() { + DlEvent *e = _eventBuffer; + for (int i = _bufferedEventsCount; i; e++) { + if (e->evt == 0) + continue; + if (--e->len) { + --i; + continue; + } + processBufferNote(e->mode, e->evt, e->note, e->velo); + e->evt = 0; + --i; + --_bufferedEventsCount; + } +} + +void TownsEuphonyDriver::flushEventBuffer() { + DlEvent *e = _eventBuffer; + for (int i = _bufferedEventsCount; i; e++) { + if (e->evt == 0) + continue; + processBufferNote(e->mode, e->evt, e->note, e->velo); + e->evt = 0; + --i; + --_bufferedEventsCount; + } +} + +void TownsEuphonyDriver::processBufferNote(int mode, int evt, int note, int velo) { + if (!velo) + evt &= 0x8f; + sendEvent(mode, evt); + sendEvent(mode, note); + sendEvent(mode, velo); +} + +void TownsEuphonyDriver::resetControl() { + for (int i = 0; i < 32; i++) { + if (_tOrdr[i] > 15) { + for (int ii = 0; ii < 16; ii++) + resetControlIntern(_tMode[i], ii); + } else { + resetControlIntern(_tMode[i], _tOrdr[i]); + } + } +} + +void TownsEuphonyDriver::resetControlIntern(int mode, int chan) { + sendEvent(mode, 0xb0 | chan); + sendEvent(mode, 0x40); + sendEvent(mode, 0); + sendEvent(mode, 0xb0 | chan); + sendEvent(mode, 0x7b); + sendEvent(mode, 0); + sendEvent(mode, 0xb0 | chan); + sendEvent(mode, 0x79); + sendEvent(mode, 0x40); +} + +uint8 TownsEuphonyDriver::appendEvent(uint8 evt, uint8 chan) { + if (evt >= 0x80 && evt < 0xf0 && _tOrdr[chan] < 16) + return (evt & 0xf0) | _tOrdr[chan]; + return evt; +} + +void TownsEuphonyDriver::sendEvent(uint8 mode, uint8 command) { + if (mode == 0) { + warning("TownsEuphonyDriver: Mode 0 not implemented."); + + } else if (mode == 0x10) { + warning("TownsEuphonyDriver: Mode 0x10 not implemented."); + + } else if (mode == 0xff) { + if (command >= 0xf0) { + _paraCount = 1; + _command = 0; + } else if (command >= 0x80) { + _paraCount = 1; + _command = command; + } else if (_command >= 0x80) { + switch ((_command - 0x80) >> 4) { + case 0: + if (_paraCount < 2) { + _paraCount++; + _para[0] = command; + } else { + _paraCount = 1; + _para[1] = command; + sendNoteOff(); + } + break; + + case 1: + if (_paraCount < 2) { + _paraCount++; + _para[0] = command; + } else { + _paraCount = 1; + _para[1] = command; + if (command) + sendNoteOn(); + else + sendNoteOff(); + } + break; + + case 2: + if (_paraCount < 2) { + _paraCount++; + _para[0] = command; + } else { + _paraCount = 1; + } + break; + + case 3: + if (_paraCount < 2) { + _paraCount++; + _para[0] = command; + } else { + _paraCount = 1; + _para[1] = command; + + if (_para[0] == 7) + sendChanVolume(); + else if (_para[0] == 10) + sendPanPosition(); + else if (_para[0] == 64) + sendAllNotesOff(); + } + break; + + case 4: + _paraCount = 1; + _para[0] = command; + sendSetInstrument(); + break; + + case 5: + _paraCount = 1; + _para[0] = command; + break; + + case 6: + if (_paraCount < 2) { + _paraCount++; + _para[0] = command; + } else { + _paraCount = 1; + _para[1] = command; + sendPitch(); + } + break; + } + } + } +} + +bool TownsEuphonyDriver::evtSetupNote() { + if (_musicPos[1] > 31) + return false; + if (!_tEnable[_musicPos[1]]) { + jumpNextLoop(); + return (_musicPos[0] == 0xfe || _musicPos[0] == 0xfd) ? true : false; + } + uint8 evt = appendEvent(_musicPos[0], _musicPos[1]); + uint8 mode = _tMode[_musicPos[1]]; + uint8 note = _musicPos[4]; + uint8 velo = _musicPos[5]; + + sendEvent(mode, evt); + sendEvent(mode, prepTranspose(note)); + sendEvent(mode, prepVelo(velo)); + + jumpNextLoop(); + if (_musicPos[0] == 0xfe || _musicPos[0] == 0xfd) + return true; + + velo = _musicPos[5]; + uint16 len = ((((_musicPos[1] << 4) | (_musicPos[2] << 8)) >> 4) & 0xff) | ((((_musicPos[3] << 4) | (_musicPos[4] << 8)) >> 4) << 8); + + int i = 0; + for (; i < 64; i++) { + if (_eventBuffer[i].evt == 0) + break; + } + + if (i == 64) { + processBufferNote(mode, evt, note, velo); + } else { + _eventBuffer[i].evt = evt; + _eventBuffer[i].mode = mode; + _eventBuffer[i].note = note; + _eventBuffer[i].velo = velo; + _eventBuffer[i].len = len ? len : 1; + _bufferedEventsCount++; + } + + return false; +} + +bool TownsEuphonyDriver::evtPolyphonicAftertouch() { + if (_musicPos[1] > 31) + return false; + if (!_tEnable[_musicPos[1]]) + return false; + + uint8 evt = appendEvent(_musicPos[0], _musicPos[1]); + uint8 mode = _tMode[_musicPos[1]]; + + sendEvent(mode, evt); + sendEvent(mode, prepTranspose(_musicPos[4])); + sendEvent(mode, _musicPos[5]); + + return false; +} + +bool TownsEuphonyDriver::evtControlPitch() { + if (_musicPos[1] > 31) + return false; + if (!_tEnable[_musicPos[1]]) + return false; + + uint8 evt = appendEvent(_musicPos[0], _musicPos[1]); + uint8 mode = _tMode[_musicPos[1]]; + + sendEvent(mode, evt); + sendEvent(mode, _musicPos[4]); + sendEvent(mode, _musicPos[5]); + + return false; +} + +bool TownsEuphonyDriver::evtInstrumentChanAftertouch() { + if (_musicPos[1] > 31) + return false; + if (!_tEnable[_musicPos[1]]) + return false; + + uint8 evt = appendEvent(_musicPos[0], _musicPos[1]); + uint8 mode = _tMode[_musicPos[1]]; + + sendEvent(mode, evt); + sendEvent(mode, _musicPos[4]); + + return false; +} + +bool TownsEuphonyDriver::evtLoadInstrument() { + return false; +} + +bool TownsEuphonyDriver::evtAdvanceTimestampOffset() { + ++_timeStampBase; + _baseTickLen = _musicPos[1]; + return false; +} + +bool TownsEuphonyDriver::evtTempo() { + uint8 l = _musicPos[4] << 1; + _trackTempo = (l | (_musicPos[5] << 8)) >> 1; + setTempoIntern(_trackTempo); + return false; +} + +bool TownsEuphonyDriver::evtModeOrdrChange() { + if (_musicPos[1] > 31) + return false; + if (!_tEnable[_musicPos[1]]) + return false; + + if (_musicPos[4] == 1) + _tMode[_musicPos[1]] = _musicPos[5]; + else if (_musicPos[4] == 2) + _tOrdr[_musicPos[1]] = _musicPos[5]; + + return false; +} + +uint8 TownsEuphonyDriver::prepTranspose(uint8 in) { + int out = _tTranspose[_musicPos[1]]; + if (!out) + return in; + out += (in & 0x7f); + + if (out > 127) + out -= 12; + + if (out < 0) + out += 12; + + return out & 0xff; +} + +uint8 TownsEuphonyDriver::prepVelo(uint8 in) { + int out = _tLevel[_musicPos[1]]; + out += (in & 0x7f); + out = CLIP(out, 1, 127); + + return out & 0xff; +} + +void TownsEuphonyDriver::sendNoteOff() { + int8 *chan = &_activeChannels[_command & 0x0f]; + if (*chan == -1) + return; + + while (_assignedChannels[*chan].note != _para[0]) { + chan = &_assignedChannels[*chan].next; + if (*chan == -1) + return; + } + + if (_sustainChannels[_command & 0x0f]) { + _assignedChannels[*chan].note |= 0x80; + } else { + _assignedChannels[*chan].note = 0; + _intf->callback(2, *chan); + } +} + +void TownsEuphonyDriver::sendNoteOn() { + if (!_para[0]) + return; + int8 *chan = &_activeChannels[_command & 0x0f]; + if (*chan == -1) + return; + + do { + _assignedChannels[*chan].sub++; + chan = &_assignedChannels[*chan].next; + } while (*chan != -1); + + chan = &_activeChannels[_command & 0x0f]; + + int d = 0; + int c = 0; + bool found = false; + + do { + if (!_assignedChannels[*chan].note) { + found = true; + break; + } + if (d <= _assignedChannels[*chan].sub) { + c = *chan; + d = _assignedChannels[*chan].sub; + } + chan = &_assignedChannels[*chan].next; + } while (*chan != -1); + + if (found) + c = *chan; + else + _intf->callback(2, c); + + _assignedChannels[c].note = _para[0]; + _assignedChannels[c].sub = 0; + _intf->callback(1, c, _para[0], _para[1]); +} + +void TownsEuphonyDriver::sendChanVolume() { + int8 *chan = &_activeChannels[_command & 0x0f]; + while (*chan != -1) { + _intf->callback(8, *chan, _para[1] & 0x7f); + chan = &_assignedChannels[*chan].next; + }; +} + +void TownsEuphonyDriver::sendPanPosition() { + int8 *chan = &_activeChannels[_command & 0x0f]; + while (*chan != -1) { + _intf->callback(3, *chan, _para[1] & 0x7f); + chan = &_assignedChannels[*chan].next; + }; +} + +void TownsEuphonyDriver::sendAllNotesOff() { + if (_para[1] > 63) { + _sustainChannels[_command & 0x0f] = -1; + return; + } + + _sustainChannels[_command & 0x0f] = 0; + int8 *chan = &_activeChannels[_command & 0x0f]; + while (*chan != -1) { + if (_assignedChannels[*chan].note & 0x80) { + _assignedChannels[*chan].note = 0; + _intf->callback(2, *chan); + } + chan = &_assignedChannels[*chan].next; + }; +} + +void TownsEuphonyDriver::sendSetInstrument() { + int8 *chan = &_activeChannels[_command & 0x0f]; + while (*chan != -1) { + _intf->callback(4, *chan, _para[0]); + _intf->callback(7, *chan, 0); + chan = &_assignedChannels[*chan].next; + }; +} + +void TownsEuphonyDriver::sendPitch() { + int8 *chan = &_activeChannels[_command & 0x0f]; + while (*chan != -1) { + _para[0] += _para[0]; + int16 pitch = (((READ_LE_UINT16(_para)) >> 1) & 0x3fff) - 0x2000; + _intf->callback(7, *chan, pitch); + chan = &_assignedChannels[*chan].next; + }; +} diff --git a/sound/softsynth/fmtowns_pc98/towns_euphony.h b/sound/softsynth/fmtowns_pc98/towns_euphony.h new file mode 100644 index 0000000000..2026a299c1 --- /dev/null +++ b/sound/softsynth/fmtowns_pc98/towns_euphony.h @@ -0,0 +1,185 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef TOWNS_EUP_H +#define TOWNS_EUP_H + +#include "sound/softsynth/fmtowns_pc98/towns_audio.h" + +class TownsEuphonyDriver : public TownsAudioInterfacePluginDriver { +public: + TownsEuphonyDriver(Audio::Mixer *mixer); + virtual ~TownsEuphonyDriver(); + + bool init(); + void reset(); + + void loadInstrument(int chanType, int id, const uint8 *data); + void loadWaveTable(const uint8 *data); + void unloadWaveTable(int id); + void reserveSoundEffectChannels(int num); + + int setMusicTempo(int tempo); + int startMusicTrack(const uint8 *data, int trackSize, int startTick); + void setMusicLoop(bool loop); + void stopParser(); + + void playSoundEffect(int chan, int note, int velo, const uint8 *data); + void stopSoundEffect(int chan); + bool soundEffectIsPlaying(int chan); + + void chanPanPos(int chan, int mode); + void chanPitch(int chan, int pitch); + void chanVolume(int chan, int vol); + + void cdaSetVolume(int mode, int volLeft, int volRight); + + int chanEnable(int tableEntry, int val); + int chanMode(int tableEntry, int val); + int chanOrdr(int tableEntry, int val); + int chanLevel(int tableEntry, int val); + int chanTranspose(int tableEntry, int val); + + int assignChannel(int chan, int tableEntry); + + void timerCallback(int timerId); + + void setMusicVolume(int volume); + void setSoundEffectVolume(int volume); + + TownsAudioInterface *intf() { + return _intf; + } + +private: + void resetTables(); + + void resetTempo(); + void setTempoIntern(int tempo); + void setTimerA(bool enable, int tempo); + void setTimerB(bool enable, int tempo); + + void updatePulseCount(); + void updateTimeStampBase(); + void updateParser(); + void updateCheckEot(); + + bool parseNext(); + void jumpNextLoop(); + + void updateEventBuffer(); + void flushEventBuffer(); + void processBufferNote(int mode, int evt, int note, int velo); + + void resetControl(); + void resetControlIntern(int mode, int chan); + uint8 appendEvent(uint8 evt, uint8 chan); + + void sendEvent(uint8 mode, uint8 command); + + typedef bool(TownsEuphonyDriver::*EuphonyOpcode)(); + bool evtSetupNote(); + bool evtPolyphonicAftertouch(); + bool evtControlPitch(); + bool evtInstrumentChanAftertouch(); + bool evtLoadInstrument(); + bool evtAdvanceTimestampOffset(); + bool evtTempo(); + bool evtModeOrdrChange(); + bool evtNotImpl() { + return false; + } + + uint8 prepTranspose(uint8 in); + uint8 prepVelo(uint8 in); + + void sendNoteOff(); + void sendNoteOn(); + void sendChanVolume(); + void sendPanPosition(); + void sendAllNotesOff(); + void sendSetInstrument(); + void sendPitch(); + + int8 *_activeChannels; + int8 *_sustainChannels; + + struct ActiveChannel { + int8 chan; + int8 next; + uint8 note; + uint8 sub; + } *_assignedChannels; + + uint8 *_tEnable; + uint8 *_tMode; + uint8 *_tOrdr; + int8 *_tLevel; + int8 *_tTranspose; + + struct DlEvent { + uint8 evt; + uint8 mode; + uint8 note; + uint8 velo; + uint16 len; + } *_eventBuffer; + int _bufferedEventsCount; + + uint8 _para[2]; + uint8 _paraCount; + uint8 _command; + + uint8 _defaultBaseTickLen; + uint8 _baseTickLen; + uint32 _pulseCount; + int _tempoControlMode; + int _extraTimingControlRemainder; + int _extraTimingControl; + int _timerSetting; + int8 _tempoDiff; + int _tempoModifier; + uint32 _timeStampDest; + uint32 _timeStampBase; + int8 _elapsedEvents; + uint8 _deltaTicks; + uint32 _tickCounter; + uint8 _defaultTempo; + int _trackTempo; + + bool _loop; + bool _playing; + bool _endOfTrack; + bool _suspendParsing; + + const uint8 *_musicStart; + const uint8 *_musicPos; + uint32 _musicTrackSize; + + TownsAudioInterface *_intf; +}; + +#endif + diff --git a/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp new file mode 100644 index 0000000000..82d0bd0438 --- /dev/null +++ b/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp @@ -0,0 +1,1403 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "sound/softsynth/fmtowns_pc98/towns_pc98_driver.h" +#include "common/endian.h" + +class TownsPC98_MusicChannel { +public: + TownsPC98_MusicChannel(TownsPC98_AudioDriver *driver, uint8 regOffs, uint8 flgs, uint8 num, + uint8 key, uint8 prt, uint8 id); + virtual ~TownsPC98_MusicChannel(); + virtual void init(); + + typedef enum channelState { + CHS_RECALCFREQ = 0x01, + CHS_KEYOFF = 0x02, + CHS_SSGOFF = 0x04, + CHS_VBROFF = 0x08, + CHS_ALLOFF = 0x0f, + CHS_PROTECT = 0x40, + CHS_EOT = 0x80 + } ChannelState; + + virtual void loadData(uint8 *data); + virtual void processEvents(); + virtual void processFrequency(); + virtual bool processControlEvent(uint8 cmd); + + virtual void keyOn(); + void keyOff(); + + void setOutputLevel(); + virtual void fadeStep(); + virtual void reset(); + + const uint8 _idFlag; + +protected: + void setupVibrato(); + bool processVibrato(); + + bool control_dummy(uint8 para); + bool control_f0_setPatch(uint8 para); + bool control_f1_presetOutputLevel(uint8 para); + bool control_f2_setKeyOffTime(uint8 para); + bool control_f3_setFreqLSB(uint8 para); + bool control_f4_setOutputLevel(uint8 para); + bool control_f5_setTempo(uint8 para); + bool control_f6_repeatSection(uint8 para); + bool control_f7_setupVibrato(uint8 para); + bool control_f8_toggleVibrato(uint8 para); + bool control_fa_writeReg(uint8 para); + virtual bool control_fb_incOutLevel(uint8 para); + virtual bool control_fc_decOutLevel(uint8 para); + bool control_fd_jump(uint8 para); + virtual bool control_ff_endOfTrack(uint8 para); + + uint8 _ticksLeft; + uint8 _algorithm; + uint8 _instr; + uint8 _totalLevel; + uint8 _frqBlockMSB; + int8 _frqLSB; + uint8 _keyOffTime; + bool _hold; + uint8 *_dataPtr; + uint8 _vbrInitDelayHi; + uint8 _vbrInitDelayLo; + int16 _vbrModInitVal; + uint8 _vbrDuration; + uint8 _vbrCurDelay; + int16 _vbrModCurVal; + uint8 _vbrDurLeft; + uint16 _frequency; + uint8 _block; + uint8 _regOffset; + uint8 _flags; + uint8 _ssgTl; + uint8 _ssgStep; + uint8 _ssgTicksLeft; + uint8 _ssgTargetLvl; + uint8 _ssgStartLvl; + + const uint8 _chanNum; + const uint8 _keyNum; + const uint8 _part; + + TownsPC98_AudioDriver *_drv; + + typedef bool (TownsPC98_MusicChannel::*ControlEventFunc)(uint8 para); + const ControlEventFunc *controlEvents; +}; + +class TownsPC98_MusicChannelSSG : public TownsPC98_MusicChannel { +public: + TownsPC98_MusicChannelSSG(TownsPC98_AudioDriver *driver, uint8 regOffs, + uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id); + virtual ~TownsPC98_MusicChannelSSG() {} + void init(); + + virtual void loadData(uint8 *data); + void processEvents(); + void processFrequency(); + bool processControlEvent(uint8 cmd); + + void keyOn(); + void nextShape(); + + void protect(); + void restore(); + virtual void reset(); + + void fadeStep(); + +protected: + void setOutputLevel(uint8 lvl); + + bool control_f0_setPatch(uint8 para); + bool control_f1_setTotalLevel(uint8 para); + bool control_f4_setAlgorithm(uint8 para); + bool control_f9_loadCustomPatch(uint8 para); + bool control_fb_incOutLevel(uint8 para); + bool control_fc_decOutLevel(uint8 para); + bool control_ff_endOfTrack(uint8 para); + + typedef bool (TownsPC98_MusicChannelSSG::*ControlEventFunc)(uint8 para); + const ControlEventFunc *controlEvents; +}; + +class TownsPC98_SfxChannel : public TownsPC98_MusicChannelSSG { +public: + TownsPC98_SfxChannel(TownsPC98_AudioDriver *driver, uint8 regOffs, + uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id) : + TownsPC98_MusicChannelSSG(driver, regOffs, flgs, num, key, prt, id) {} + ~TownsPC98_SfxChannel() {} + + void loadData(uint8 *data); + void reset(); +}; + +class TownsPC98_MusicChannelPCM : public TownsPC98_MusicChannel { +public: + TownsPC98_MusicChannelPCM(TownsPC98_AudioDriver *driver, uint8 regOffs, + uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id); + ~TownsPC98_MusicChannelPCM() {} + void init(); + + void loadData(uint8 *data); + void processEvents(); + bool processControlEvent(uint8 cmd); + +private: + bool control_f1_prcStart(uint8 para); + bool control_ff_endOfTrack(uint8 para); + + typedef bool (TownsPC98_MusicChannelPCM::*ControlEventFunc)(uint8 para); + const ControlEventFunc *controlEvents; +}; + +TownsPC98_MusicChannel::TownsPC98_MusicChannel(TownsPC98_AudioDriver *driver, uint8 regOffs, uint8 flgs, uint8 num, + uint8 key, uint8 prt, uint8 id) : _drv(driver), _regOffset(regOffs), _flags(flgs), _chanNum(num), _keyNum(key), + _part(prt), _idFlag(id), controlEvents(0) { + + _ticksLeft = _algorithm = _instr = _totalLevel = _frqBlockMSB = _keyOffTime = 0; + _ssgStartLvl = _ssgTl = _ssgStep = _ssgTicksLeft = _ssgTargetLvl = _block = 0; + _vbrInitDelayHi = _vbrInitDelayLo = _vbrDuration = _vbrCurDelay = _vbrDurLeft = 0; + _frqLSB = 0; + _hold = false; + _dataPtr = 0; + _vbrModInitVal = _vbrModCurVal = 0; + _frequency = 0; +} + +TownsPC98_MusicChannel::~TownsPC98_MusicChannel() { +} + +void TownsPC98_MusicChannel::init() { +#define Control(x) &TownsPC98_MusicChannel::control_##x + static const ControlEventFunc ctrlEvents[] = { + Control(f0_setPatch), + Control(f1_presetOutputLevel), + Control(f2_setKeyOffTime), + Control(f3_setFreqLSB), + Control(f4_setOutputLevel), + Control(f5_setTempo), + Control(f6_repeatSection), + Control(f7_setupVibrato), + Control(f8_toggleVibrato), + Control(dummy), + Control(fa_writeReg), + Control(fb_incOutLevel), + Control(fc_decOutLevel), + Control(fd_jump), + Control(dummy), + Control(ff_endOfTrack) + }; +#undef Control + + controlEvents = ctrlEvents; +} + +void TownsPC98_MusicChannel::keyOff() { + // all operators off + uint8 value = _keyNum & 0x0f; + if (_part) + value |= 4; + uint8 regAddress = 0x28; + _drv->writeReg(0, regAddress, value); + _flags |= CHS_KEYOFF; +} + +void TownsPC98_MusicChannel::keyOn() { + // all operators on + uint8 value = _keyNum | 0xf0; + if (_part) + value |= 4; + uint8 regAddress = 0x28; + _drv->writeReg(0, regAddress, value); +} + +void TownsPC98_MusicChannel::loadData(uint8 *data) { + _flags = (_flags & ~CHS_EOT) | CHS_ALLOFF; + _ticksLeft = 1; + _dataPtr = data; + _totalLevel = 0x7F; + + uint8 *tmp = _dataPtr; + for (bool loop = true; loop;) { + uint8 cmd = *tmp++; + if (cmd < 0xf0) { + tmp++; + } else if (cmd == 0xff) { + if (READ_LE_UINT16(tmp)) { + _drv->_looping |= _idFlag; + tmp += _drv->_opnFxCmdLen[cmd - 240]; + } else + loop = false; + } else if (cmd == 0xf6) { + // reset repeat section countdown + tmp[0] = tmp[1]; + tmp += 4; + } else { + tmp += _drv->_opnFxCmdLen[cmd - 240]; + } + } +} + +void TownsPC98_MusicChannel::processEvents() { + if (_flags & CHS_EOT) + return; + + if (!_hold && _ticksLeft == _keyOffTime) + keyOff(); + + if (--_ticksLeft) + return; + + if (!_hold) + keyOff(); + + uint8 cmd = 0; + bool loop = true; + + while (loop) { + cmd = *_dataPtr++; + if (cmd < 0xf0) + loop = false; + else if (!processControlEvent(cmd)) + return; + } + + uint8 para = *_dataPtr++; + + if (cmd == 0x80) { + keyOff(); + _hold = false; + } else { + keyOn(); + + if (_hold == false || cmd != _frqBlockMSB) + _flags |= CHS_RECALCFREQ; + + _hold = (para & 0x80) ? true : false; + _frqBlockMSB = cmd; + } + + _ticksLeft = para & 0x7f; +} + +void TownsPC98_MusicChannel::processFrequency() { + if (_flags & CHS_RECALCFREQ) { + + _frequency = (((const uint16 *)_drv->_opnFreqTable)[_frqBlockMSB & 0x0f] + _frqLSB) | (((_frqBlockMSB & 0x70) >> 1) << 8); + + _drv->writeReg(_part, _regOffset + 0xa4, (_frequency >> 8)); + _drv->writeReg(_part, _regOffset + 0xa0, (_frequency & 0xff)); + + setupVibrato(); + } + + if (!(_flags & CHS_VBROFF)) { + if (!processVibrato()) + return; + + _drv->writeReg(_part, _regOffset + 0xa4, (_frequency >> 8)); + _drv->writeReg(_part, _regOffset + 0xa0, (_frequency & 0xff)); + } +} + +void TownsPC98_MusicChannel::setupVibrato() { + _vbrCurDelay = _vbrInitDelayHi; + if (_flags & CHS_KEYOFF) { + _vbrModCurVal = _vbrModInitVal; + _vbrCurDelay += _vbrInitDelayLo; + } + _vbrDurLeft = (_vbrDuration >> 1); + _flags &= ~(CHS_KEYOFF | CHS_RECALCFREQ); +} + +bool TownsPC98_MusicChannel::processVibrato() { + if (--_vbrCurDelay) + return false; + + _vbrCurDelay = _vbrInitDelayHi; + _frequency += _vbrModCurVal; + + if (!--_vbrDurLeft) { + _vbrDurLeft = _vbrDuration; + _vbrModCurVal = -_vbrModCurVal; + } + + return true; +} + +bool TownsPC98_MusicChannel::processControlEvent(uint8 cmd) { + uint8 para = *_dataPtr++; + return (this->*controlEvents[cmd & 0x0f])(para); +} + +void TownsPC98_MusicChannel::setOutputLevel() { + uint8 outopr = _drv->_opnCarrier[_algorithm]; + uint8 reg = 0x40 + _regOffset; + + for (int i = 0; i < 4; i++) { + if (outopr & 1) + _drv->writeReg(_part, reg, _totalLevel); + outopr >>= 1; + reg += 4; + } +} + +void TownsPC98_MusicChannel::fadeStep() { + _totalLevel += 3; + if (_totalLevel > 0x7f) + _totalLevel = 0x7f; + setOutputLevel(); +} + +void TownsPC98_MusicChannel::reset() { + _hold = false; + _keyOffTime = 0; + _ticksLeft = 1; + + _flags = (_flags & ~CHS_EOT) | CHS_ALLOFF; + + _totalLevel = 0; + _algorithm = 0; + _flags = CHS_EOT; + _algorithm = 0; + + _block = 0; + _frequency = 0; + _frqBlockMSB = 0; + _frqLSB = 0; + + _ssgTl = 0; + _ssgStartLvl = 0; + _ssgTargetLvl = 0; + _ssgStep = 0; + _ssgTicksLeft = 0; + + _vbrInitDelayHi = 0; + _vbrInitDelayLo = 0; + _vbrModInitVal = 0; + _vbrDuration = 0; + _vbrCurDelay = 0; + _vbrModCurVal = 0; + _vbrDurLeft = 0; +} + +bool TownsPC98_MusicChannel::control_f0_setPatch(uint8 para) { + _instr = para; + uint8 reg = _regOffset + 0x80; + + for (int i = 0; i < 4; i++) { + // set release rate for each operator + _drv->writeReg(_part, reg, 0x0f); + reg += 4; + } + + const uint8 *tptr = _drv->_patches + ((uint32)_instr << 5); + reg = _regOffset + 0x30; + + // write registers 0x30 to 0x8f + for (int i = 0; i < 6; i++) { + _drv->writeReg(_part, reg, tptr[0]); + reg += 4; + _drv->writeReg(_part, reg, tptr[2]); + reg += 4; + _drv->writeReg(_part, reg, tptr[1]); + reg += 4; + _drv->writeReg(_part, reg, tptr[3]); + reg += 4; + tptr += 4; + } + + reg = _regOffset + 0xB0; + _algorithm = tptr[0] & 7; + // set feedback and algorithm + _drv->writeReg(_part, reg, tptr[0]); + + setOutputLevel(); + return true; +} + +bool TownsPC98_MusicChannel::control_f1_presetOutputLevel(uint8 para) { + if (_drv->_fading) + return true; + + _totalLevel = _drv->_opnLvlPresets[para]; + setOutputLevel(); + return true; +} + +bool TownsPC98_MusicChannel::control_f2_setKeyOffTime(uint8 para) { + _keyOffTime = para; + return true; +} + +bool TownsPC98_MusicChannel::control_f3_setFreqLSB(uint8 para) { + _frqLSB = (int8) para; + return true; +} + +bool TownsPC98_MusicChannel::control_f4_setOutputLevel(uint8 para) { + if (_drv->_fading) + return true; + + _totalLevel = para; + setOutputLevel(); + return true; +} + +bool TownsPC98_MusicChannel::control_f5_setTempo(uint8 para) { + _drv->setMusicTempo(para); + return true; +} + +bool TownsPC98_MusicChannel::control_f6_repeatSection(uint8 para) { + _dataPtr--; + _dataPtr[0]--; + + if (*_dataPtr) { + // repeat section until counter has reached zero + _dataPtr = _drv->_trackPtr + READ_LE_UINT16(_dataPtr + 2); + } else { + // reset counter, advance to next section + _dataPtr[0] = _dataPtr[1]; + _dataPtr += 4; + } + return true; +} + +bool TownsPC98_MusicChannel::control_f7_setupVibrato(uint8 para) { + _vbrInitDelayHi = _dataPtr[0]; + _vbrInitDelayLo = para; + _vbrModInitVal = (int16) READ_LE_UINT16(_dataPtr + 1); + _vbrDuration = _dataPtr[3]; + _dataPtr += 4; + _flags = (_flags & ~CHS_VBROFF) | CHS_KEYOFF | CHS_RECALCFREQ; + return true; +} + +bool TownsPC98_MusicChannel::control_f8_toggleVibrato(uint8 para) { + if (para == 0x10) { + if (*_dataPtr++) { + _flags = (_flags & ~CHS_VBROFF) | CHS_KEYOFF; + } else { + _flags |= CHS_VBROFF; + } + } else { + /* NOT IMPLEMENTED + uint8 skipChannels = para / 36; + uint8 entry = para % 36; + TownsPC98_AudioDriver::TownsPC98_MusicChannel *t = &chan[skipChannels]; + + t->unnamedEntries[entry] = *_dataPtr++;*/ + } + return true; +} + +bool TownsPC98_MusicChannel::control_fa_writeReg(uint8 para) { + _drv->writeReg(_part, para, *_dataPtr++); + return true; +} + +bool TownsPC98_MusicChannel::control_fb_incOutLevel(uint8 para) { + _dataPtr--; + if (_drv->_fading) + return true; + + uint8 val = (_totalLevel + 3); + if (val > 0x7f) + val = 0x7f; + + _totalLevel = val; + setOutputLevel(); + return true; +} + +bool TownsPC98_MusicChannel::control_fc_decOutLevel(uint8 para) { + _dataPtr--; + if (_drv->_fading) + return true; + + int8 val = (int8)(_totalLevel - 3); + if (val < 0) + val = 0; + + _totalLevel = (uint8) val; + setOutputLevel(); + return true; +} + +bool TownsPC98_MusicChannel::control_fd_jump(uint8 para) { + uint8 *tmp = _drv->_trackPtr + READ_LE_UINT16(_dataPtr - 1); + _dataPtr = (tmp[1] == 1) ? tmp : (_dataPtr + 1); + return true; +} + +bool TownsPC98_MusicChannel::control_dummy(uint8 para) { + _dataPtr--; + return true; +} + +bool TownsPC98_MusicChannel::control_ff_endOfTrack(uint8 para) { + uint16 val = READ_LE_UINT16(--_dataPtr); + if (val) { + // loop + _dataPtr = _drv->_trackPtr + val; + return true; + } else { + // quit parsing for active channel + --_dataPtr; + _flags |= CHS_EOT; + _drv->_finishedChannelsFlag |= _idFlag; + keyOff(); + return false; + } +} + +TownsPC98_MusicChannelSSG::TownsPC98_MusicChannelSSG(TownsPC98_AudioDriver *driver, uint8 regOffs, + uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id) : + TownsPC98_MusicChannel(driver, regOffs, flgs, num, key, prt, id), controlEvents(0) { +} + +void TownsPC98_MusicChannelSSG::init() { + _algorithm = 0x80; + +#define Control(x) &TownsPC98_MusicChannelSSG::control_##x + static const ControlEventFunc ctrlEventsSSG[] = { + Control(f0_setPatch), + Control(f1_setTotalLevel), + Control(f2_setKeyOffTime), + Control(f3_setFreqLSB), + Control(f4_setAlgorithm), + Control(f5_setTempo), + Control(f6_repeatSection), + Control(f7_setupVibrato), + Control(f8_toggleVibrato), + Control(f9_loadCustomPatch), + Control(fa_writeReg), + Control(fb_incOutLevel), + Control(fc_decOutLevel), + Control(fd_jump), + Control(dummy), + Control(ff_endOfTrack) + }; +#undef Control + + controlEvents = ctrlEventsSSG; +} + +void TownsPC98_MusicChannelSSG::processEvents() { + if (_flags & CHS_EOT) + return; + + _drv->toggleRegProtection(_flags & CHS_PROTECT ? true : false); + + if (!_hold && _ticksLeft == _keyOffTime) + nextShape(); + + if (!--_ticksLeft) { + + uint8 cmd = 0; + bool loop = true; + + while (loop) { + cmd = *_dataPtr++; + if (cmd < 0xf0) + loop = false; + else if (!processControlEvent(cmd)) + return; + } + + uint8 para = *_dataPtr++; + + if (cmd == 0x80) { + nextShape(); + _hold = false; + } else { + if (!_hold) { + _instr &= 0xf0; + _ssgStep = _drv->_ssgPatches[_instr]; + _ssgTicksLeft = _drv->_ssgPatches[_instr + 1] & 0x7f; + _ssgTargetLvl = _drv->_ssgPatches[_instr + 2]; + _ssgStartLvl = _drv->_ssgPatches[_instr + 3]; + _flags = (_flags & ~CHS_SSGOFF) | CHS_KEYOFF; + } + + keyOn(); + + if (_hold == false || cmd != _frqBlockMSB) + _flags |= CHS_RECALCFREQ; + + _hold = (para & 0x80) ? true : false; + _frqBlockMSB = cmd; + } + + _ticksLeft = para & 0x7f; + } + + if (!(_flags & CHS_SSGOFF)) { + if (--_ssgTicksLeft) { + if (!_drv->_fading) + setOutputLevel(_ssgStartLvl); + return; + } + + _ssgTicksLeft = _drv->_ssgPatches[_instr + 1] & 0x7f; + + if (_drv->_ssgPatches[_instr + 1] & 0x80) { + uint8 t = _ssgStartLvl - _ssgStep; + + if (_ssgStep <= _ssgStartLvl && _ssgTargetLvl < t) { + if (!_drv->_fading) + setOutputLevel(t); + return; + } + } else { + int t = _ssgStartLvl + _ssgStep; + uint8 p = (uint8)(t & 0xff); + + if (t < 256 && _ssgTargetLvl > p) { + if (!_drv->_fading) + setOutputLevel(p); + return; + } + } + + setOutputLevel(_ssgTargetLvl); + if (_ssgStartLvl && !(_instr & 8)) { + _instr += 4; + _ssgStep = _drv->_ssgPatches[_instr]; + _ssgTicksLeft = _drv->_ssgPatches[_instr + 1] & 0x7f; + _ssgTargetLvl = _drv->_ssgPatches[_instr + 2]; + } else { + _flags |= CHS_SSGOFF; + setOutputLevel(0); + } + } +} + +void TownsPC98_MusicChannelSSG::processFrequency() { + if (_algorithm & 0x40) + return; + + if (_flags & CHS_RECALCFREQ) { + _block = _frqBlockMSB >> 4; + _frequency = ((const uint16 *)_drv->_opnFreqTableSSG)[_frqBlockMSB & 0x0f] + _frqLSB; + + uint16 f = _frequency >> _block; + _drv->writeReg(_part, _regOffset << 1, f & 0xff); + _drv->writeReg(_part, (_regOffset << 1) + 1, f >> 8); + + setupVibrato(); + } + + if (!(_flags & (CHS_EOT | CHS_VBROFF | CHS_SSGOFF))) { + if (!processVibrato()) + return; + + uint16 f = _frequency >> _block; + _drv->writeReg(_part, _regOffset << 1, f & 0xff); + _drv->writeReg(_part, (_regOffset << 1) + 1, f >> 8); + } +} + +bool TownsPC98_MusicChannelSSG::processControlEvent(uint8 cmd) { + uint8 para = *_dataPtr++; + return (this->*controlEvents[cmd & 0x0f])(para); +} + +void TownsPC98_MusicChannelSSG::nextShape() { + _instr = (_instr & 0xf0) + 0x0c; + _ssgStep = _drv->_ssgPatches[_instr]; + _ssgTicksLeft = _drv->_ssgPatches[_instr + 1] & 0x7f; + _ssgTargetLvl = _drv->_ssgPatches[_instr + 2]; +} + +void TownsPC98_MusicChannelSSG::keyOn() { + uint8 c = 0x7b; + uint8 t = (_algorithm & 0xC0) << 1; + if (_algorithm & 0x80) + t |= 4; + + c = (c << (_regOffset + 1)) | (c >> (7 - _regOffset)); + t = (t << (_regOffset + 1)) | (t >> (7 - _regOffset)); + + if (!(_algorithm & 0x80)) + _drv->writeReg(_part, 6, _algorithm & 0x7f); + + uint8 e = (_drv->readSSGStatus() & c) | t; + _drv->writeReg(_part, 7, e); +} + +void TownsPC98_MusicChannelSSG::protect() { + _flags |= CHS_PROTECT; +} + +void TownsPC98_MusicChannelSSG::restore() { + _flags &= ~CHS_PROTECT; + keyOn(); + _drv->writeReg(_part, 8 + _regOffset, _ssgTl); + uint16 f = _frequency >> _block; + _drv->writeReg(_part, _regOffset << 1, f & 0xff); + _drv->writeReg(_part, (_regOffset << 1) + 1, f >> 8); +} + +void TownsPC98_MusicChannelSSG::loadData(uint8 *data) { + _drv->toggleRegProtection(_flags & CHS_PROTECT ? true : false); + TownsPC98_MusicChannel::loadData(data); + setOutputLevel(0); + _algorithm = 0x80; +} + +void TownsPC98_MusicChannelSSG::setOutputLevel(uint8 lvl) { + _ssgStartLvl = lvl; + uint16 newTl = (((uint16)_totalLevel + 1) * (uint16)lvl) >> 8; + if (newTl == _ssgTl) + return; + _ssgTl = newTl; + _drv->writeReg(_part, 8 + _regOffset, _ssgTl); +} + +void TownsPC98_MusicChannelSSG::reset() { + TownsPC98_MusicChannel::reset(); + + // Unlike the original we restore the default patch data. This fixes a bug + // where certain sound effects would bring each other out of tune (e.g. the + // dragon's fire in Darm's house in Kyra 1 would sound different each time + // you triggered another sfx by dropping an item etc.) + uint8 i = (10 + _regOffset) << 4; + const uint8 *src = &_drv->_drvTables[156]; + _drv->_ssgPatches[i] = src[i]; + _drv->_ssgPatches[i + 3] = src[i + 3]; + _drv->_ssgPatches[i + 4] = src[i + 4]; + _drv->_ssgPatches[i + 6] = src[i + 6]; + _drv->_ssgPatches[i + 8] = src[i + 8]; + _drv->_ssgPatches[i + 12] = src[i + 12]; +} + +void TownsPC98_MusicChannelSSG::fadeStep() { + _totalLevel--; + if ((int8)_totalLevel < 0) + _totalLevel = 0; + setOutputLevel(_ssgStartLvl); +} + +bool TownsPC98_MusicChannelSSG::control_f0_setPatch(uint8 para) { + _instr = para << 4; + para = (para >> 3) & 0x1e; + if (para) + return control_f4_setAlgorithm(para | 0x40); + return true; +} + +bool TownsPC98_MusicChannelSSG::control_f1_setTotalLevel(uint8 para) { + if (!_drv->_fading) + _totalLevel = para; + return true; +} + +bool TownsPC98_MusicChannelSSG::control_f4_setAlgorithm(uint8 para) { + _algorithm = para; + return true; +} + +bool TownsPC98_MusicChannelSSG::control_f9_loadCustomPatch(uint8 para) { + _instr = (_drv->_sfxOffs + 10 + _regOffset) << 4; + _drv->_ssgPatches[_instr] = *_dataPtr++; + _drv->_ssgPatches[_instr + 3] = para; + _drv->_ssgPatches[_instr + 4] = *_dataPtr++; + _drv->_ssgPatches[_instr + 6] = *_dataPtr++; + _drv->_ssgPatches[_instr + 8] = *_dataPtr++; + _drv->_ssgPatches[_instr + 12] = *_dataPtr++; + return true; +} + +bool TownsPC98_MusicChannelSSG::control_fb_incOutLevel(uint8 para) { + _dataPtr--; + if (_drv->_fading) + return true; + + _totalLevel--; + if ((int8)_totalLevel < 0) + _totalLevel = 0; + + return true; +} + +bool TownsPC98_MusicChannelSSG::control_fc_decOutLevel(uint8 para) { + _dataPtr--; + if (_drv->_fading) + return true; + + if (_totalLevel + 1 < 0x10) + _totalLevel++; + + return true; +} + +bool TownsPC98_MusicChannelSSG::control_ff_endOfTrack(uint8 para) { + if (!_drv->_sfxOffs) { + uint16 val = READ_LE_UINT16(--_dataPtr); + if (val) { + // loop + _dataPtr = _drv->_trackPtr + val; + return true; + } else { + // stop parsing + if (!_drv->_fading) + setOutputLevel(0); + --_dataPtr; + _flags |= CHS_EOT; + _drv->_finishedSSGFlag |= _idFlag; + } + } else { + // end of sfx track - restore ssg music channel + _flags |= CHS_EOT; + _drv->_finishedSfxFlag |= _idFlag; + _drv->_ssgChannels[_chanNum]->restore(); + } + + return false; +} + +void TownsPC98_SfxChannel::loadData(uint8 *data) { + _flags = CHS_ALLOFF; + _ticksLeft = 1; + _dataPtr = data; + _ssgTl = 0xff; + _algorithm = 0x80; + + uint8 *tmp = _dataPtr; + for (bool loop = true; loop;) { + uint8 cmd = *tmp++; + if (cmd < 0xf0) { + tmp++; + } else if (cmd == 0xff) { + loop = false; + } else if (cmd == 0xf6) { + // reset repeat section countdown + tmp[0] = tmp[1]; + tmp += 4; + } else { + tmp += _drv->_opnFxCmdLen[cmd - 240]; + } + } +} + +void TownsPC98_SfxChannel::reset() { + TownsPC98_MusicChannel::reset(); + + // Unlike the original we restore the default patch data. This fixes a bug + // where certain sound effects would bring each other out of tune (e.g. the + // dragon's fire in Darm's house in Kyra 1 would sound different each time + // you triggered another sfx by dropping an item etc.) + uint8 i = (13 + _regOffset) << 4; + const uint8 *src = &_drv->_drvTables[156]; + _drv->_ssgPatches[i] = src[i]; + _drv->_ssgPatches[i + 3] = src[i + 3]; + _drv->_ssgPatches[i + 4] = src[i + 4]; + _drv->_ssgPatches[i + 6] = src[i + 6]; + _drv->_ssgPatches[i + 8] = src[i + 8]; + _drv->_ssgPatches[i + 12] = src[i + 12]; +} + +TownsPC98_MusicChannelPCM::TownsPC98_MusicChannelPCM(TownsPC98_AudioDriver *driver, uint8 regOffs, + uint8 flgs, uint8 num, uint8 key, uint8 prt, uint8 id) : + TownsPC98_MusicChannel(driver, regOffs, flgs, num, key, prt, id), controlEvents(0) { +} + +void TownsPC98_MusicChannelPCM::init() { + _algorithm = 0x80; + +#define Control(x) &TownsPC98_MusicChannelPCM::control_##x + static const ControlEventFunc ctrlEventsPCM[] = { + Control(dummy), + Control(f1_prcStart), + Control(dummy), + Control(dummy), + Control(dummy), + Control(dummy), + Control(f6_repeatSection), + Control(dummy), + Control(dummy), + Control(dummy), + Control(fa_writeReg), + Control(dummy), + Control(dummy), + Control(dummy), + Control(dummy), + Control(ff_endOfTrack) + }; +#undef Control + + controlEvents = ctrlEventsPCM; +} + +void TownsPC98_MusicChannelPCM::loadData(uint8 *data) { + _flags = (_flags & ~CHS_EOT) | CHS_ALLOFF; + _ticksLeft = 1; + _dataPtr = data; + _totalLevel = 0x7F; +} + +void TownsPC98_MusicChannelPCM::processEvents() { + if (_flags & CHS_EOT) + return; + + if (--_ticksLeft) + return; + + uint8 cmd = 0; + bool loop = true; + + while (loop) { + cmd = *_dataPtr++; + if (cmd == 0x80) { + loop = false; + } else if (cmd < 0xf0) { + _drv->writeReg(_part, 0x10, cmd); + } else if (!processControlEvent(cmd)) { + return; + } + } + + _ticksLeft = *_dataPtr++; +} + +bool TownsPC98_MusicChannelPCM::processControlEvent(uint8 cmd) { + uint8 para = *_dataPtr++; + return (this->*controlEvents[cmd & 0x0f])(para); +} + +bool TownsPC98_MusicChannelPCM::control_f1_prcStart(uint8 para) { + _totalLevel = para; + _drv->writeReg(_part, 0x11, para); + return true; +} + +bool TownsPC98_MusicChannelPCM::control_ff_endOfTrack(uint8 para) { + uint16 val = READ_LE_UINT16(--_dataPtr); + if (val) { + // loop + _dataPtr = _drv->_trackPtr + val; + return true; + } else { + // quit parsing for active channel + --_dataPtr; + _flags |= CHS_EOT; + _drv->_finishedRhythmFlag |= _idFlag; + return false; + } +} + +TownsPC98_AudioDriver::TownsPC98_AudioDriver(Audio::Mixer *mixer, EmuType type) : TownsPC98_FmSynth(mixer, type), + _channels(0), _ssgChannels(0), _sfxChannels(0), _rhythmChannel(0), + _trackPtr(0), _sfxData(0), _sfxOffs(0), _ssgPatches(0), + _patches(0), _sfxBuffer(0), _musicBuffer(0), + + _opnCarrier(_drvTables + 76), _opnFreqTable(_drvTables + 108), _opnFreqTableSSG(_drvTables + 132), + _opnFxCmdLen(_drvTables + 36), _opnLvlPresets(_drvTables + (type == kTypeTowns ? 52 : 84)), + + _updateChannelsFlag(type == kType26 ? 0x07 : 0x3F), _finishedChannelsFlag(0), + _updateSSGFlag(type == kTypeTowns ? 0x00 : 0x07), _finishedSSGFlag(0), + _updateRhythmFlag(type == kType86 ? 0x01 : 0x00), _finishedRhythmFlag(0), + _updateSfxFlag(0), _finishedSfxFlag(0), + + _musicTickCounter(0), + + _musicVolume(255), _sfxVolume(255), + + _musicPlaying(false), _sfxPlaying(false), _fading(false), _looping(0), _ready(false) { + + _sfxOffsets[0] = _sfxOffsets[1] = 0; +} + +TownsPC98_AudioDriver::~TownsPC98_AudioDriver() { + reset(); + + if (_channels) { + for (int i = 0; i < _numChan; i++) + delete _channels[i]; + delete[] _channels; + } + + if (_ssgChannels) { + for (int i = 0; i < _numSSG; i++) + delete _ssgChannels[i]; + delete[] _ssgChannels; + } + + if (_sfxChannels) { + for (int i = 0; i < 2; i++) + delete _sfxChannels[i]; + delete[] _sfxChannels; + } + + delete _rhythmChannel; + + delete[] _ssgPatches; +} + +bool TownsPC98_AudioDriver::init() { + if (_ready) { + reset(); + return true; + } + + TownsPC98_FmSynth::init(); + + setVolumeChannelMasks(-1, 0); + + _channels = new TownsPC98_MusicChannel *[_numChan]; + for (int i = 0; i < _numChan; i++) { + int ii = i * 6; + _channels[i] = new TownsPC98_MusicChannel(this, _drvTables[ii], _drvTables[ii + 1], + _drvTables[ii + 2], _drvTables[ii + 3], _drvTables[ii + 4], _drvTables[ii + 5]); + _channels[i]->init(); + } + + if (_numSSG) { + _ssgPatches = new uint8[256]; + memcpy(_ssgPatches, _drvTables + 156, 256); + + _ssgChannels = new TownsPC98_MusicChannelSSG *[_numSSG]; + for (int i = 0; i < _numSSG; i++) { + int ii = i * 6; + _ssgChannels[i] = new TownsPC98_MusicChannelSSG(this, _drvTables[ii], _drvTables[ii + 1], + _drvTables[ii + 2], _drvTables[ii + 3], _drvTables[ii + 4], _drvTables[ii + 5]); + _ssgChannels[i]->init(); + } + + _sfxChannels = new TownsPC98_SfxChannel *[2]; + for (int i = 0; i < 2; i++) { + int ii = (i + 1) * 6; + _sfxChannels[i] = new TownsPC98_SfxChannel(this, _drvTables[ii], _drvTables[ii + 1], + _drvTables[ii + 2], _drvTables[ii + 3], _drvTables[ii + 4], _drvTables[ii + 5]); + _sfxChannels[i]->init(); + } + } + + if (_hasPercussion) { + _rhythmChannel = new TownsPC98_MusicChannelPCM(this, 0, 0, 0, 0, 0, 1); + _rhythmChannel->init(); + } + + setMusicTempo(84); + setSfxTempo(654); + + _ready = true; + + return true; +} + +void TownsPC98_AudioDriver::loadMusicData(uint8 *data, bool loadPaused) { + if (!_ready) { + warning("TownsPC98_AudioDriver: Driver must be initialized before loading data"); + return; + } + + if (!data) { + warning("TownsPC98_AudioDriver: Invalid music file data"); + return; + } + + reset(); + + Common::StackLock lock(_mutex); + uint8 *src_a = _trackPtr = _musicBuffer = data; + + for (uint8 i = 0; i < 3; i++) { + _channels[i]->loadData(data + READ_LE_UINT16(src_a)); + src_a += 2; + } + + for (int i = 0; i < _numSSG; i++) { + _ssgChannels[i]->loadData(data + READ_LE_UINT16(src_a)); + src_a += 2; + } + + for (uint8 i = 3; i < _numChan; i++) { + _channels[i]->loadData(data + READ_LE_UINT16(src_a)); + src_a += 2; + } + + if (_hasPercussion) { + _rhythmChannel->loadData(data + READ_LE_UINT16(src_a)); + src_a += 2; + } + + toggleRegProtection(false); + + _patches = src_a + 4; + _finishedChannelsFlag = _finishedSSGFlag = _finishedRhythmFlag = 0; + + _musicPlaying = (loadPaused ? false : true); +} + +void TownsPC98_AudioDriver::loadSoundEffectData(uint8 *data, uint8 trackNum) { + if (!_ready) { + warning("TownsPC98_AudioDriver: Driver must be initialized before loading data"); + return; + } + + if (!_sfxChannels) { + warning("TownsPC98_AudioDriver: Sound effects not supported by this configuration"); + return; + } + + if (!data) { + warning("TownsPC98_AudioDriver: Invalid sound effects file data"); + return; + } + + Common::StackLock lock(_mutex); + _sfxData = _sfxBuffer = data; + _sfxOffsets[0] = READ_LE_UINT16(&_sfxData[(trackNum << 2)]); + _sfxOffsets[1] = READ_LE_UINT16(&_sfxData[(trackNum << 2) + 2]); + _sfxPlaying = true; + _finishedSfxFlag = 0; +} + +void TownsPC98_AudioDriver::reset() { + Common::StackLock lock(_mutex); + + _musicPlaying = false; + _sfxPlaying = false; + _fading = false; + _looping = 0; + _musicTickCounter = 0; + _sfxData = 0; + + TownsPC98_FmSynth::reset(); + + for (int i = 0; i < _numChan; i++) + _channels[i]->reset(); + for (int i = 0; i < _numSSG; i++) + _ssgChannels[i]->reset(); + + if (_numSSG) { + for (int i = 0; i < 2; i++) + _sfxChannels[i]->reset(); + + memcpy(_ssgPatches, _drvTables + 156, 256); + } + + if (_rhythmChannel) + _rhythmChannel->reset(); +} + +void TownsPC98_AudioDriver::fadeStep() { + if (!_musicPlaying) + return; + + Common::StackLock lock(_mutex); + for (int j = 0; j < _numChan; j++) { + if (_updateChannelsFlag & _channels[j]->_idFlag) + _channels[j]->fadeStep(); + } + + for (int j = 0; j < _numSSG; j++) { + if (_updateSSGFlag & _ssgChannels[j]->_idFlag) + _ssgChannels[j]->fadeStep(); + } + + if (!_fading) { + _fading = 19; + if (_hasPercussion) { + if (_updateRhythmFlag & _rhythmChannel->_idFlag) + _rhythmChannel->reset(); + } + } else { + if (!--_fading) + reset(); + } +} + +void TownsPC98_AudioDriver::timerCallbackB() { + _sfxOffs = 0; + + if (_musicPlaying) { + _musicTickCounter++; + + for (int i = 0; i < _numChan; i++) { + if (_updateChannelsFlag & _channels[i]->_idFlag) { + _channels[i]->processEvents(); + _channels[i]->processFrequency(); + } + } + + for (int i = 0; i < _numSSG; i++) { + if (_updateSSGFlag & _ssgChannels[i]->_idFlag) { + _ssgChannels[i]->processEvents(); + _ssgChannels[i]->processFrequency(); + } + } + + if (_hasPercussion) + if (_updateRhythmFlag & _rhythmChannel->_idFlag) + _rhythmChannel->processEvents(); + } + + toggleRegProtection(false); + + if (_finishedChannelsFlag == _updateChannelsFlag && _finishedSSGFlag == _updateSSGFlag && _finishedRhythmFlag == _updateRhythmFlag) + _musicPlaying = false; +} + +void TownsPC98_AudioDriver::timerCallbackA() { + if (_sfxChannels && _sfxPlaying) { + if (_sfxData) + startSoundEffect(); + + _sfxOffs = 3; + _trackPtr = _sfxBuffer; + + for (int i = 0; i < 2; i++) { + if (_updateSfxFlag & _sfxChannels[i]->_idFlag) { + _sfxChannels[i]->processEvents(); + _sfxChannels[i]->processFrequency(); + } + } + + _trackPtr = _musicBuffer; + } + + if (_updateSfxFlag && _finishedSfxFlag == _updateSfxFlag) { + _sfxPlaying = false; + _updateSfxFlag = 0; + setVolumeChannelMasks(-1, 0); + } +} + +void TownsPC98_AudioDriver::setMusicTempo(uint8 tempo) { + writeReg(0, 0x26, tempo); + writeReg(0, 0x27, 0x33); +} + +void TownsPC98_AudioDriver::setSfxTempo(uint16 tempo) { + writeReg(0, 0x24, tempo & 0xff); + writeReg(0, 0x25, tempo >> 8); + writeReg(0, 0x27, 0x33); +} + +void TownsPC98_AudioDriver::startSoundEffect() { + int volFlags = 0; + + for (int i = 0; i < 2; i++) { + if (_sfxOffsets[i]) { + _ssgChannels[i + 1]->protect(); + _sfxChannels[i]->reset(); + _sfxChannels[i]->loadData(_sfxData + _sfxOffsets[i]); + _updateSfxFlag |= _sfxChannels[i]->_idFlag; + volFlags |= (_sfxChannels[i]->_idFlag << _numChan); + } else { + _ssgChannels[i + 1]->restore(); + _updateSfxFlag &= ~_sfxChannels[i]->_idFlag; + } + } + + setVolumeChannelMasks(~volFlags, volFlags); + _sfxData = 0; +} + +const uint8 TownsPC98_AudioDriver::_drvTables[] = { + // channel presets + 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x80, 0x01, 0x01, 0x00, 0x02, + 0x02, 0x80, 0x02, 0x02, 0x00, 0x04, + 0x00, 0x80, 0x03, 0x04, 0x01, 0x08, + 0x01, 0x80, 0x04, 0x05, 0x01, 0x10, + 0x02, 0x80, 0x05, 0x06, 0x01, 0x20, + + // control event size + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x05, + 0x02, 0x06, 0x02, 0x00, 0x00, 0x02, 0x00, 0x02, + + // fmt level presets + 0x54, 0x50, 0x4C, 0x48, 0x44, 0x40, 0x3C, 0x38, + 0x34, 0x30, 0x2C, 0x28, 0x24, 0x20, 0x1C, 0x18, + 0x14, 0x10, 0x0C, 0x08, 0x04, 0x90, 0x90, 0x90, + + // carriers + 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0E, 0x0E, 0x0F, + + // pc98 level presets + 0x40, 0x3B, 0x38, 0x34, 0x30, 0x2A, 0x28, 0x25, + 0x22, 0x20, 0x1D, 0x1A, 0x18, 0x15, 0x12, 0x10, + 0x0D, 0x0A, 0x08, 0x05, 0x02, 0x90, 0x90, 0x90, + + // frequencies + 0x6A, 0x02, 0x8F, 0x02, 0xB6, 0x02, 0xDF, 0x02, + 0x0B, 0x03, 0x39, 0x03, 0x6A, 0x03, 0x9E, 0x03, + 0xD5, 0x03, 0x10, 0x04, 0x4E, 0x04, 0x8F, 0x04, + + // ssg frequencies + 0xE8, 0x0E, 0x12, 0x0E, 0x48, 0x0D, 0x89, 0x0C, + 0xD5, 0x0B, 0x2B, 0x0B, 0x8A, 0x0A, 0xF3, 0x09, + 0x64, 0x09, 0xDD, 0x08, 0x5E, 0x08, 0xE6, 0x07, + + // ssg patch data + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x37, 0x81, 0xC8, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x37, 0x81, 0xC8, 0x00, + 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00, + 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00, + 0x04, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00, + 0x0A, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0x01, 0x00, + 0xFF, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, + 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0x00, + 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + 0x64, 0x01, 0xFF, 0x64, 0xFF, 0x81, 0xFF, 0x00, + 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + + 0x02, 0x01, 0xFF, 0x28, 0xFF, 0x81, 0xF0, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xC8, 0x00, + 0x01, 0x81, 0x00, 0x00, 0x28, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0x78, 0x5F, 0x81, 0xA0, 0x00, + 0x05, 0x81, 0x00, 0x00, 0x28, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00 +}; + +#undef EUPHONY_FADEOUT_TICKS + diff --git a/sound/softsynth/fmtowns_pc98/towns_pc98_driver.h b/sound/softsynth/fmtowns_pc98/towns_pc98_driver.h new file mode 100644 index 0000000000..18daee1e72 --- /dev/null +++ b/sound/softsynth/fmtowns_pc98/towns_pc98_driver.h @@ -0,0 +1,129 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef TOWNS_PC98_AUDIODRIVER_H +#define TOWNS_PC98_AUDIODRIVER_H + +#include "sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h" + +class TownsPC98_MusicChannel; +class TownsPC98_MusicChannelSSG; +class TownsPC98_SfxChannel; +class TownsPC98_MusicChannelPCM; + +class TownsPC98_AudioDriver : public TownsPC98_FmSynth { +friend class TownsPC98_MusicChannel; +friend class TownsPC98_MusicChannelSSG; +friend class TownsPC98_SfxChannel; +friend class TownsPC98_MusicChannelPCM; +public: + TownsPC98_AudioDriver(Audio::Mixer *mixer, EmuType type); + ~TownsPC98_AudioDriver(); + + void loadMusicData(uint8 *data, bool loadPaused = false); + void loadSoundEffectData(uint8 *data, uint8 trackNum); + bool init(); + void reset(); + + void fadeStep(); + + void pause() { + _musicPlaying = false; + } + void cont() { + _musicPlaying = true; + } + + void timerCallbackB(); + void timerCallbackA(); + + bool looping() { + return _looping == _updateChannelsFlag ? true : false; + } + bool musicPlaying() { + return _musicPlaying; + } + + void setMusicVolume(int volume) { + _musicVolume = volume; + setVolumeIntern(_musicVolume, _sfxVolume); + } + void setSoundEffectVolume(int volume) { + _sfxVolume = volume; + setVolumeIntern(_musicVolume, _sfxVolume); + } + +protected: + void startSoundEffect(); + + void setMusicTempo(uint8 tempo); + void setSfxTempo(uint16 tempo); + + TownsPC98_MusicChannel **_channels; + TownsPC98_MusicChannelSSG **_ssgChannels; + TownsPC98_SfxChannel **_sfxChannels; + TownsPC98_MusicChannelPCM *_rhythmChannel; + + const uint8 *_opnCarrier; + const uint8 *_opnFreqTable; + const uint8 *_opnFreqTableSSG; + const uint8 *_opnFxCmdLen; + const uint8 *_opnLvlPresets; + + uint8 *_musicBuffer; + uint8 *_sfxBuffer; + uint8 *_trackPtr; + uint8 *_patches; + uint8 *_ssgPatches; + + uint8 _updateChannelsFlag; + uint8 _updateSSGFlag; + uint8 _updateRhythmFlag; + uint8 _updateSfxFlag; + uint8 _finishedChannelsFlag; + uint8 _finishedSSGFlag; + uint8 _finishedRhythmFlag; + uint8 _finishedSfxFlag; + + bool _musicPlaying; + bool _sfxPlaying; + uint8 _fading; + uint8 _looping; + uint32 _musicTickCounter; + + int _sfxOffs; + uint8 *_sfxData; + uint16 _sfxOffsets[2]; + + uint16 _musicVolume; + uint16 _sfxVolume; + + static const uint8 _drvTables[]; + + bool _ready; +}; + +#endif + diff --git a/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp new file mode 100644 index 0000000000..507c8e159a --- /dev/null +++ b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp @@ -0,0 +1,1510 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h" +#include "common/endian.h" + +class TownsPC98_FmSynthOperator { +public: + TownsPC98_FmSynthOperator(const uint32 timerbase, const uint8 *rateTable, + const uint8 *shiftTable, const uint8 *attackDecayTable, const uint32 *frqTable, + const uint32 *sineTable, const int32 *tlevelOut, const int32 *detuneTable); + ~TownsPC98_FmSynthOperator() {} + + void keyOn(); + void keyOff(); + void frequency(int freq); + void updatePhaseIncrement(); + void recalculateRates(); + void generateOutput(int32 phasebuf, int32 *feedbuf, int32 &out); + + void feedbackLevel(int32 level) { + _feedbackLevel = level ? level + 6 : 0; + } + void detune(int value) { + _detn = &_detnTbl[value << 5]; + } + void multiple(uint32 value) { + _multiple = value ? (value << 1) : 1; + } + void attackRate(uint32 value) { + _specifiedAttackRate = value; + } + bool scaleRate(uint8 value); + void decayRate(uint32 value) { + _specifiedDecayRate = value; + recalculateRates(); + } + void sustainRate(uint32 value) { + _specifiedSustainRate = value; + recalculateRates(); + } + void sustainLevel(uint32 value) { + _sustainLevel = (value == 0x0f) ? 0x3e0 : value << 5; + } + void releaseRate(uint32 value) { + _specifiedReleaseRate = value; + recalculateRates(); + } + void totalLevel(uint32 value) { + _totalLevel = value << 3; + } + void ampModulation(bool enable) { + _ampMod = enable; + } + void reset(); + +protected: + EnvelopeState _state; + bool _playing; + uint32 _feedbackLevel; + uint32 _multiple; + uint32 _totalLevel; + uint8 _keyScale1; + uint8 _keyScale2; + uint32 _specifiedAttackRate; + uint32 _specifiedDecayRate; + uint32 _specifiedSustainRate; + uint32 _specifiedReleaseRate; + uint32 _tickCount; + uint32 _sustainLevel; + + bool _ampMod; + uint32 _frequency; + uint8 _kcode; + uint32 _phase; + uint32 _phaseIncrement; + const int32 *_detn; + + const uint8 *_rateTbl; + const uint8 *_rshiftTbl; + const uint8 *_adTbl; + const uint32 *_fTbl; + const uint32 *_sinTbl; + const int32 *_tLvlTbl; + const int32 *_detnTbl; + + const uint32 _tickLength; + uint32 _timer; + int32 _currentLevel; + + struct EvpState { + uint8 rate; + uint8 shift; + } fs_a, fs_d, fs_s, fs_r; +}; + +TownsPC98_FmSynthOperator::TownsPC98_FmSynthOperator(const uint32 timerbase, const uint8 *rateTable, + const uint8 *shiftTable, const uint8 *attackDecayTable, const uint32 *frqTable, + const uint32 *sineTable, const int32 *tlevelOut, const int32 *detuneTable) : + _rateTbl(rateTable), _rshiftTbl(shiftTable), _adTbl(attackDecayTable), _fTbl(frqTable), + _sinTbl(sineTable), _tLvlTbl(tlevelOut), _detnTbl(detuneTable), _tickLength(timerbase * 2), + _specifiedAttackRate(0), _specifiedDecayRate(0), _specifiedReleaseRate(0), _specifiedSustainRate(0), + _phase(0), _state(kEnvReady), _playing(false), _timer(0), _keyScale1(0), + _keyScale2(0), _currentLevel(1023), _ampMod(false), _tickCount(0) { + + fs_a.rate = fs_a.shift = fs_d.rate = fs_d.shift = fs_s.rate = fs_s.shift = fs_r.rate = fs_r.shift = 0; + + reset(); +} + +void TownsPC98_FmSynthOperator::keyOn() { + if (_playing) + return; + + _playing = true; + _state = kEnvAttacking; + _phase = 0; +} + +void TownsPC98_FmSynthOperator::keyOff() { + if (!_playing) + return; + + _playing = false; + if (_state != kEnvReady) + _state = kEnvReleasing; +} + +void TownsPC98_FmSynthOperator::frequency(int freq) { + uint8 block = (freq >> 11); + uint16 pos = (freq & 0x7ff); + uint8 c = pos >> 7; + + _kcode = (block << 2) | ((c < 7) ? 0 : ((c > 8) ? 3 : c - 6)); + _frequency = _fTbl[pos << 1] >> (7 - block); +} + +void TownsPC98_FmSynthOperator::updatePhaseIncrement() { + _phaseIncrement = ((_frequency + _detn[_kcode]) * _multiple) >> 1; + uint8 keyscale = _kcode >> _keyScale1; + if (_keyScale2 != keyscale) { + _keyScale2 = keyscale; + recalculateRates(); + } +} + +void TownsPC98_FmSynthOperator::recalculateRates() { + int k = _keyScale2; + int r = _specifiedAttackRate ? (_specifiedAttackRate << 1) + 0x20 : 0; + fs_a.rate = ((r + k) < 94) ? _rateTbl[r + k] : 136; + fs_a.shift = ((r + k) < 94) ? _rshiftTbl[r + k] : 0; + + r = _specifiedDecayRate ? (_specifiedDecayRate << 1) + 0x20 : 0; + fs_d.rate = _rateTbl[r + k]; + fs_d.shift = _rshiftTbl[r + k]; + + r = _specifiedSustainRate ? (_specifiedSustainRate << 1) + 0x20 : 0; + fs_s.rate = _rateTbl[r + k]; + fs_s.shift = _rshiftTbl[r + k]; + + r = (_specifiedReleaseRate << 2) + 0x22; + fs_r.rate = _rateTbl[r + k]; + fs_r.shift = _rshiftTbl[r + k]; +} + +void TownsPC98_FmSynthOperator::generateOutput(int32 phasebuf, int32 *feed, int32 &out) { + if (_state == kEnvReady) + return; + + _timer += _tickLength; + while (_timer > 0x5B8D80) { + _timer -= 0x5B8D80; + ++_tickCount; + + int32 levelIncrement = 0; + uint32 targetTime = 0; + int32 targetLevel = 0; + EnvelopeState nextState = kEnvReady; + + switch (_state) { + case kEnvReady: + return; + case kEnvAttacking: + targetLevel = 0; + nextState = kEnvDecaying; + if ((_specifiedAttackRate << 1) + _keyScale2 < 64) { + targetTime = (1 << fs_a.shift) - 1; + levelIncrement = (~_currentLevel * _adTbl[fs_a.rate + ((_tickCount >> fs_a.shift) & 7)]) >> 4; + break; + } else { + _currentLevel = targetLevel; + _state = nextState; + } + // Fall through + case kEnvDecaying: + targetTime = (1 << fs_d.shift) - 1; + nextState = kEnvSustaining; + targetLevel = _sustainLevel; + levelIncrement = _adTbl[fs_d.rate + ((_tickCount >> fs_d.shift) & 7)]; + break; + case kEnvSustaining: + targetTime = (1 << fs_s.shift) - 1; + nextState = kEnvSustaining; + targetLevel = 1023; + levelIncrement = _adTbl[fs_s.rate + ((_tickCount >> fs_s.shift) & 7)]; + break; + case kEnvReleasing: + targetTime = (1 << fs_r.shift) - 1; + nextState = kEnvReady; + targetLevel = 1023; + levelIncrement = _adTbl[fs_r.rate + ((_tickCount >> fs_r.shift) & 7)]; + break; + } + + if (!(_tickCount & targetTime)) { + _currentLevel += levelIncrement; + if ((_state == kEnvAttacking && _currentLevel <= targetLevel) || (_state != kEnvAttacking && _currentLevel >= targetLevel)) { + if (_state != kEnvDecaying) + _currentLevel = targetLevel; + _state = nextState; + } + } + } + + uint32 lvlout = _totalLevel + (uint32) _currentLevel; + + + int32 outp = 0; + int32 *i = &outp, *o = &outp; + int phaseShift = 0; + + if (feed) { + o = &feed[0]; + i = &feed[1]; + phaseShift = _feedbackLevel ? ((*o + *i) << _feedbackLevel) : 0; + *o = *i; + } else { + phaseShift = phasebuf << 15; + } + + if (lvlout < 832) { + uint32 index = (lvlout << 3) + _sinTbl[(((int32)((_phase & 0xffff0000) + + phaseShift)) >> 16) & 0x3ff]; + *i = ((index < 6656) ? _tLvlTbl[index] : 0); + } else { + *i = 0; + } + + _phase += _phaseIncrement; + out += *o; +} + +void TownsPC98_FmSynthOperator::reset() { + keyOff(); + _timer = 0; + _keyScale2 = 0; + _currentLevel = 1023; + + frequency(0); + detune(0); + scaleRate(0); + multiple(0); + updatePhaseIncrement(); + attackRate(0); + decayRate(0); + releaseRate(0); + sustainRate(0); + feedbackLevel(0); + totalLevel(127); + ampModulation(false); +} + +bool TownsPC98_FmSynthOperator::scaleRate(uint8 value) { + value = 3 - value; + if (_keyScale1 != value) { + _keyScale1 = value; + return true; + } + + int k = _keyScale2; + int r = _specifiedAttackRate ? (_specifiedAttackRate << 1) + 0x20 : 0; + fs_a.rate = ((r + k) < 94) ? _rateTbl[r + k] : 136; + fs_a.shift = ((r + k) < 94) ? _rshiftTbl[r + k] : 0; + return false; +} + +class TownsPC98_FmSynthSquareSineSource { +public: + TownsPC98_FmSynthSquareSineSource(const uint32 timerbase); + ~TownsPC98_FmSynthSquareSineSource(); + + void init(const int *rsTable, const int *rseTable); + void reset(); + void writeReg(uint8 address, uint8 value, bool force = false); + + void nextTick(int32 *buffer, uint32 bufferSize); + + void setVolumeIntern(int volA, int volB) { + _volumeA = volA; + _volumeB = volB; + } + void setVolumeChannelMasks(int channelMaskA, int channelMaskB) { + _volMaskA = channelMaskA; + _volMaskB = channelMaskB; + } + + uint8 chanEnable() const { + return _chanEnable; + } +private: + void updateRegs(); + + uint8 _updateRequestBuf[64]; + int _updateRequest; + int _rand; + + int8 _evpTimer; + uint32 _pReslt; + uint8 _attack; + + bool _evpUpdate, _cont; + + int _evpUpdateCnt; + uint8 _outN; + int _nTick; + + int32 *_tlTable; + int32 *_tleTable; + + const uint32 _tickLength; + uint32 _timer; + + struct Channel { + int tick; + uint8 smp; + uint8 out; + + uint8 frqL; + uint8 frqH; + uint8 vol; + } _channels[3]; + + uint8 _noiseGenerator; + uint8 _chanEnable; + + uint8 **_reg; + + uint16 _volumeA; + uint16 _volumeB; + int _volMaskA; + int _volMaskB; + + bool _ready; +}; + +class TownsPC98_FmSynthPercussionSource { +public: + TownsPC98_FmSynthPercussionSource(const uint32 timerbase); + ~TownsPC98_FmSynthPercussionSource() { + delete[] _reg; + } + + void init(const uint8 *instrData = 0); + void reset(); + void writeReg(uint8 address, uint8 value); + + void nextTick(int32 *buffer, uint32 bufferSize); + + void setVolumeIntern(int volA, int volB) { + _volumeA = volA; + _volumeB = volB; + } + void setVolumeChannelMasks(int channelMaskA, int channelMaskB) { + _volMaskA = channelMaskA; + _volMaskB = channelMaskB; + } + +private: + struct RhtChannel { + const uint8 *data; + + const uint8 *start; + const uint8 *end; + const uint8 *pos; + uint32 size; + bool active; + uint8 level; + + int8 decState; + uint8 decStep; + + int16 samples[2]; + int out; + + uint8 startPosH; + uint8 startPosL; + uint8 endPosH; + uint8 endPosL; + }; + + void recalcOuput(RhtChannel *ins); + void advanceInput(RhtChannel *ins); + + RhtChannel _rhChan[6]; + + uint8 _totalLevel; + + const uint32 _tickLength; + uint32 _timer; + + uint8 **_reg; + + uint16 _volumeA; + uint16 _volumeB; + int _volMaskA; + int _volMaskB; + + bool _ready; +}; + +TownsPC98_FmSynthSquareSineSource::TownsPC98_FmSynthSquareSineSource(const uint32 timerbase) : _tlTable(0), + _tleTable(0), _updateRequest(-1), _tickLength(timerbase * 27), _ready(0), _reg(0), _rand(1), _outN(1), + _nTick(0), _evpUpdateCnt(0), _evpTimer(0x1f), _pReslt(0x1f), _attack(0), _cont(false), _evpUpdate(true), + _timer(0), _noiseGenerator(0), _chanEnable(0), + _volMaskA(0), _volMaskB(0), _volumeA(Audio::Mixer::kMaxMixerVolume), _volumeB(Audio::Mixer::kMaxMixerVolume) { + + memset(_channels, 0, sizeof(_channels)); + memset(_updateRequestBuf, 0, sizeof(_updateRequestBuf)); + _reg = new uint8 *[11]; + + _reg[0] = &_channels[0].frqL; + _reg[1] = &_channels[0].frqH; + _reg[2] = &_channels[1].frqL; + _reg[3] = &_channels[1].frqH; + _reg[4] = &_channels[2].frqL; + _reg[5] = &_channels[2].frqH; + _reg[6] = &_noiseGenerator; + _reg[7] = &_chanEnable; + _reg[8] = &_channels[0].vol; + _reg[9] = &_channels[1].vol; + _reg[10] = &_channels[2].vol; + + reset(); +} + +TownsPC98_FmSynthSquareSineSource::~TownsPC98_FmSynthSquareSineSource() { + delete[] _tlTable; + delete[] _tleTable; + delete[] _reg; +} + +void TownsPC98_FmSynthSquareSineSource::init(const int *rsTable, const int *rseTable) { + if (_ready) { + reset(); + return; + } + + delete[] _tlTable; + delete[] _tleTable; + _tlTable = new int32[16]; + _tleTable = new int32[32]; + float a, b, d; + d = 801.0f; + + for (int i = 0; i < 16; i++) { + b = 1.0f / rsTable[i]; + a = 1.0f / d + b + 1.0f / 1000.0f; + float v = (b / a) * 32767.0f; + _tlTable[i] = (int32) v; + + b = 1.0f / rseTable[i]; + a = 1.0f / d + b + 1.0f / 1000.0f; + v = (b / a) * 32767.0f; + _tleTable[i] = (int32) v; + } + + for (int i = 16; i < 32; i++) { + b = 1.0f / rseTable[i]; + a = 1.0f / d + b + 1.0f / 1000.0f; + float v = (b / a) * 32767.0f; + _tleTable[i] = (int32) v; + } + + _ready = true; +} + +void TownsPC98_FmSynthSquareSineSource::reset() { + _rand = 1; + _outN = 1; + _updateRequest = -1; + _nTick = _evpUpdateCnt = 0; + _evpTimer = 0x1f; + _pReslt = 0x1f; + _attack = 0; + _cont = false; + _evpUpdate = true; + _timer = 0; + + for (int i = 0; i < 3; i++) { + _channels[i].tick = 0; + _channels[i].smp = _channels[i].out = 0; + } + + for (int i = 0; i < 14; i++) + writeReg(i, 0, true); + + writeReg(7, 0xbf, true); +} + +void TownsPC98_FmSynthSquareSineSource::writeReg(uint8 address, uint8 value, bool force) { + if (!_ready) + return; + + if (address > 10 || *_reg[address] == value) { + if ((address == 11 || address == 12 || address == 13) && value) + warning("TownsPC98_FmSynthSquareSineSource: unsupported reg address: %d", address); + return; + } + + if (!force) { + if (_updateRequest >= 63) { + warning("TownsPC98_FmSynthSquareSineSource: event buffer overflow"); + _updateRequest = -1; + } + _updateRequestBuf[++_updateRequest] = value; + _updateRequestBuf[++_updateRequest] = address; + return; + } + + *_reg[address] = value; +} + +void TownsPC98_FmSynthSquareSineSource::nextTick(int32 *buffer, uint32 bufferSize) { + if (!_ready) + return; + + for (uint32 i = 0; i < bufferSize; i++) { + _timer += _tickLength; + while (_timer > 0x5B8D80) { + _timer -= 0x5B8D80; + + if (++_nTick >= (_noiseGenerator & 0x1f)) { + if ((_rand + 1) & 2) + _outN ^= 1; + + _rand = (((_rand & 1) ^ ((_rand >> 3) & 1)) << 16) | (_rand >> 1); + _nTick = 0; + } + + for (int ii = 0; ii < 3; ii++) { + if (++_channels[ii].tick >= (((_channels[ii].frqH & 0x0f) << 8) | _channels[ii].frqL)) { + _channels[ii].tick = 0; + _channels[ii].smp ^= 1; + } + _channels[ii].out = (_channels[ii].smp | ((_chanEnable >> ii) & 1)) & (_outN | ((_chanEnable >> (ii + 3)) & 1)); + } + + if (_evpUpdate) { + if (++_evpUpdateCnt >= 0) { + _evpUpdateCnt = 0; + + if (--_evpTimer < 0) { + if (_cont) { + _evpTimer &= 0x1f; + } else { + _evpUpdate = false; + _evpTimer = 0; + } + } + } + } + _pReslt = _evpTimer ^ _attack; + updateRegs(); + } + + int32 finOut = 0; + for (int ii = 0; ii < 3; ii++) { +int32 finOutTemp = ((_channels[ii].vol >> 4) & 1) ? _tleTable[_channels[ii].out ? _pReslt : 0] : _tlTable[_channels[ii].out ? (_channels[ii].vol & 0x0f) : 0]; + + if ((1 << ii) & _volMaskA) + finOutTemp = (finOutTemp * _volumeA) / Audio::Mixer::kMaxMixerVolume; + + if ((1 << ii) & _volMaskB) + finOutTemp = (finOutTemp * _volumeB) / Audio::Mixer::kMaxMixerVolume; + + finOut += finOutTemp; + } + + finOut /= 3; + + buffer[i << 1] += finOut; + buffer[(i << 1) + 1] += finOut; + } +} + +void TownsPC98_FmSynthSquareSineSource::updateRegs() { + for (int i = 0; i < _updateRequest;) { + uint8 b = _updateRequestBuf[i++]; + uint8 a = _updateRequestBuf[i++]; + writeReg(a, b, true); + } + _updateRequest = -1; +} + +TownsPC98_FmSynthPercussionSource::TownsPC98_FmSynthPercussionSource(const uint32 timerbase) : + _tickLength(timerbase * 2), _timer(0), _ready(false), _volMaskA(0), _volMaskB(0), _volumeA(Audio::Mixer::kMaxMixerVolume), _volumeB(Audio::Mixer::kMaxMixerVolume) { + + memset(_rhChan, 0, sizeof(RhtChannel) * 6); + _reg = new uint8 *[40]; + + _reg[0] = _reg[1] = _reg[2] = _reg[3] = _reg[4] = _reg[5] = _reg[6] = _reg[7] = _reg[8] = _reg[9] = _reg[10] = _reg[11] = _reg[12] = _reg[13] = _reg[14] = _reg[15] = 0; + _reg[16] = &_rhChan[0].startPosL; + _reg[17] = &_rhChan[1].startPosL; + _reg[18] = &_rhChan[2].startPosL; + _reg[19] = &_rhChan[3].startPosL; + _reg[20] = &_rhChan[4].startPosL; + _reg[21] = &_rhChan[5].startPosL; + _reg[22] = &_rhChan[0].startPosH; + _reg[23] = &_rhChan[1].startPosH; + _reg[24] = &_rhChan[2].startPosH; + _reg[25] = &_rhChan[3].startPosH; + _reg[26] = &_rhChan[4].startPosH; + _reg[27] = &_rhChan[5].startPosH; + _reg[28] = &_rhChan[0].endPosL; + _reg[29] = &_rhChan[1].endPosL; + _reg[30] = &_rhChan[2].endPosL; + _reg[31] = &_rhChan[3].endPosL; + _reg[32] = &_rhChan[4].endPosL; + _reg[33] = &_rhChan[5].endPosL; + _reg[34] = &_rhChan[0].endPosH; + _reg[35] = &_rhChan[1].endPosH; + _reg[36] = &_rhChan[2].endPosH; + _reg[37] = &_rhChan[3].endPosH; + _reg[38] = &_rhChan[4].endPosH; + _reg[39] = &_rhChan[5].endPosH; +} + +void TownsPC98_FmSynthPercussionSource::init(const uint8 *instrData) { + if (_ready) { + reset(); + return; + } + + const uint8 *start = instrData; + const uint8 *pos = start; + + if (instrData) { + for (int i = 0; i < 6; i++) { + _rhChan[i].data = start + READ_BE_UINT16(pos); + pos += 2; + _rhChan[i].size = READ_BE_UINT16(pos); + pos += 2; + } + reset(); + _ready = true; + } else { + memset(_rhChan, 0, sizeof(RhtChannel) * 6); + _ready = false; + } +} + +void TownsPC98_FmSynthPercussionSource::reset() { + _timer = 0; + _totalLevel = 63; + + for (int i = 0; i < 6; i++) { + RhtChannel *s = &_rhChan[i]; + s->pos = s->start = s->data; + s->end = s->data + s->size; + s->active = false; + s->level = 0; + s->out = 0; + s->decStep = 1; + s->decState = 0; + s->samples[0] = s->samples[1] = 0; + s->startPosH = s->startPosL = s->endPosH = s->endPosL = 0; + } +} + +void TownsPC98_FmSynthPercussionSource::writeReg(uint8 address, uint8 value) { + if (!_ready) + return; + + uint8 h = address >> 4; + uint8 l = address & 15; + + if (address > 15) + *_reg[address] = value; + + if (address == 0) { + if (value & 0x80) { + //key off + for (int i = 0; i < 6; i++) { + if ((value >> i) & 1) + _rhChan[i].active = false; + } + } else { + //key on + for (int i = 0; i < 6; i++) { + if ((value >> i) & 1) { + RhtChannel *s = &_rhChan[i]; + s->pos = s->start; + s->active = true; + s->out = 0; + s->samples[0] = s->samples[1] = 0; + s->decStep = 1; + s->decState = 0; + } + } + } + } else if (address == 1) { + // total level + _totalLevel = (value & 63) ^ 63; + for (int i = 0; i < 6; i++) + recalcOuput(&_rhChan[i]); + } else if (!h && l & 8) { + // instrument level + l &= 7; + _rhChan[l].level = (value & 0x1f) ^ 0x1f; + recalcOuput(&_rhChan[l]); + } else if (h & 3) { + l &= 7; + if (h == 1) { + // set start offset + _rhChan[l].start = _rhChan[l].data + ((_rhChan[l].startPosH << 8 | _rhChan[l].startPosL) << 8); + } else if (h == 2) { + // set end offset + _rhChan[l].end = _rhChan[l].data + ((_rhChan[l].endPosH << 8 | _rhChan[l].endPosL) << 8) + 255; + } + } +} + +void TownsPC98_FmSynthPercussionSource::nextTick(int32 *buffer, uint32 bufferSize) { + if (!_ready) + return; + + for (uint32 i = 0; i < bufferSize; i++) { + _timer += _tickLength; + while (_timer > 0x5B8D80) { + _timer -= 0x5B8D80; + + for (int ii = 0; ii < 6; ii++) { + RhtChannel *s = &_rhChan[ii]; + if (s->active) { + recalcOuput(s); + if (s->decStep) { + advanceInput(s); + if (s->pos == s->end) + s->active = false; + } + s->decStep ^= 1; + } + } + } + + int32 finOut = 0; + + for (int ii = 0; ii < 6; ii++) { + if (_rhChan[ii].active) + finOut += _rhChan[ii].out; + } + + finOut <<= 1; + + if (1 & _volMaskA) + finOut = (finOut * _volumeA) / Audio::Mixer::kMaxMixerVolume; + + if (1 & _volMaskB) + finOut = (finOut * _volumeB) / Audio::Mixer::kMaxMixerVolume; + + buffer[i << 1] += finOut; + buffer[(i << 1) + 1] += finOut; + } +} + +void TownsPC98_FmSynthPercussionSource::recalcOuput(RhtChannel *ins) { + uint32 s = _totalLevel + ins->level; + uint32 x = s > 62 ? 0 : (1 + (s >> 3)); + int32 y = s > 62 ? 0 : (15 - (s & 7)); + ins->out = ((ins->samples[ins->decStep] * y) >> x) & ~3; +} + +void TownsPC98_FmSynthPercussionSource::advanceInput(RhtChannel *ins) { + static const int8 adjustIndex[] = { -1, -1, -1, -1, 2, 5, 7, 9 }; + + static const int16 stepTable[] = { + 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, + 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, + 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552 + }; + + uint8 cur = (int8)*ins->pos++; + + for (int i = 0; i < 2; i++) { + int b = (2 * (cur & 7) + 1) * stepTable[ins->decState] / 8; + ins->samples[i] = CLIP<int16>(ins->samples[i ^ 1] + (cur & 8 ? b : -b), -2048, 2047); + ins->decState = CLIP<int8>(ins->decState + adjustIndex[cur & 7], 0, 48); + cur >>= 4; + } +} + +TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) : + _mixer(mixer), + _chanInternal(0), _ssg(0), _prc(0), + _numChan(type == kType26 ? 3 : 6), _numSSG(type == kTypeTowns ? 0 : 3), _hasPercussion(type == kType86 ? true : false), + _oprRates(0), _oprRateshift(0), _oprAttackDecay(0), _oprFrq(0), _oprSinTbl(0), _oprLevelOut(0), _oprDetune(0), + _baserate(55125.0f / (float)mixer->getOutputRate()), + _volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), + _regProtectionFlag(false), _ready(false) { + + memset(&_timers[0], 0, sizeof(ChipTimer)); + memset(&_timers[1], 0, sizeof(ChipTimer)); + _timers[0].cb = &TownsPC98_FmSynth::timerCallbackA; + _timers[1].cb = &TownsPC98_FmSynth::timerCallbackB; + _timerbase = (uint32)(_baserate * 1000000.0f); +} + +TownsPC98_FmSynth::~TownsPC98_FmSynth() { + Common::StackLock lock(_mutex); + _mixer->stopHandle(_soundHandle); + delete _ssg; + delete _prc; + delete[] _chanInternal; + + delete[] _oprRates; + delete[] _oprRateshift; + delete[] _oprFrq; + delete[] _oprAttackDecay; + delete[] _oprSinTbl; + delete[] _oprLevelOut; + delete[] _oprDetune; +} + +bool TownsPC98_FmSynth::init() { + if (_ready) { + reset(); + return true; + } + + generateTables(); + + _chanInternal = new ChanInternal[_numChan]; + for (int i = 0; i < _numChan; i++) { + memset(&_chanInternal[i], 0, sizeof(ChanInternal)); + for (int j = 0; j < 4; ++j) + _chanInternal[i].opr[j] = new TownsPC98_FmSynthOperator(_timerbase, _oprRates, _oprRateshift, _oprAttackDecay, _oprFrq, _oprSinTbl, _oprLevelOut, _oprDetune); + } + + if (_numSSG) { + _ssg = new TownsPC98_FmSynthSquareSineSource(_timerbase); + _ssg->init(&_ssgTables[0], &_ssgTables[16]); + } + + if (_hasPercussion) { + _prc = new TownsPC98_FmSynthPercussionSource(_timerbase); + _prc->init(_percussionData); + } + + _mixer->playStream(Audio::Mixer::kPlainSoundType, + &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + + _ready = true; + + return true; +} + +void TownsPC98_FmSynth::reset() { + for (int i = 0; i < _numChan; i++) { + for (int ii = 0; ii < 4; ii++) + _chanInternal[i].opr[ii]->reset(); + memset(_chanInternal[i].feedbuf, 0, 3); + _chanInternal[i].algorithm = 0; + _chanInternal[i].frqTemp = 0; + _chanInternal[i].enableLeft = _chanInternal[i].enableRight = true; + _chanInternal[i].updateEnvelopeParameters = false; + } + + writeReg(0, 0x27, 0x33); + + if (_ssg) + _ssg->reset(); + + if (_prc) + _prc->reset(); +} + +void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) { + if (_regProtectionFlag || !_ready) + return; + + static const uint8 oprOrdr[] = { 0, 2, 1, 3 }; + + Common::StackLock lock(_mutex); + + uint8 h = regAddress & 0xf0; + uint8 l = (regAddress & 0x0f); + + ChanInternal *c = 0; + TownsPC98_FmSynthOperator **co = 0; + TownsPC98_FmSynthOperator *o = 0; + + if (regAddress > 0x2F) { + c = &_chanInternal[(l & 3) + 3 * part]; + co = c->opr; + o = c->opr[oprOrdr[(l - (l & 3)) >> 2]]; + } else if (regAddress == 0x28) { + c = &_chanInternal[(value & 3) + ((value & 4) ? 3 : 0)]; + co = c->opr; + } + + switch (h) { + case 0x00: + // ssg + if (_ssg) + _ssg->writeReg(l, value); + break; + case 0x10: + // pcm rhythm channel + if (_prc) + _prc->writeReg(l, value); + break; + case 0x20: + if (l == 8) { + // Key on/off + for (int i = 0; i < 4; i++) { + if ((value >> (4 + i)) & 1) + co[oprOrdr[i]]->keyOn(); + else + co[oprOrdr[i]]->keyOff(); + } + } else if (l == 4) { + // Timer A + _timers[0].value = (_timers[0].value & 3) | (value << 2); + } else if (l == 5) { + // Timer A + _timers[0].value = (_timers[0].value & 0x3fc) | (value & 3); + } else if (l == 6) { + // Timer B + _timers[1].value = value & 0xff; + } else if (l == 7) { + if (value & 1) { + float spc = (float)(0x400 - _timers[0].value) / _baserate; + if (spc < 1) { + warning("TownsPC98_FmSynth: Invalid Timer A setting: %d", _timers[0].value); + spc = 1; + } + + _timers[0].smpPerCb = (int32) spc; + _timers[0].smpPerCbRem = (uint32)((spc - (float)_timers[0].smpPerCb) * 1000000.0f); + _timers[0].smpTillCb = _timers[0].smpPerCb; + _timers[0].smpTillCbRem = _timers[0].smpPerCbRem; + _timers[0].enabled = true; + } else { + _timers[0].enabled = false; + } + + if (value & 2) { + float spc = (float)(0x100 - _timers[1].value) * 16.0f / _baserate; + if (spc < 1) { + warning("TownsPC98_FmSynth: Invalid Timer B setting: %d", _timers[1].value); + spc = 1; + } + + _timers[1].smpPerCb = (int32) spc; + _timers[1].smpPerCbRem = (uint32)((spc - (float)_timers[1].smpPerCb) * 1000000.0f); + _timers[1].smpTillCb = _timers[1].smpPerCb; + _timers[1].smpTillCbRem = _timers[1].smpPerCbRem; + _timers[1].enabled = true; + } else { + _timers[1].enabled = false; + } + + if (value & 0x10) { + _timers[0].smpTillCb = _timers[0].smpPerCb; + _timers[0].smpTillCbRem = _timers[0].smpTillCbRem; + } + + if (value & 0x20) { + _timers[1].smpTillCb = _timers[1].smpPerCb; + _timers[1].smpTillCbRem = _timers[1].smpTillCbRem; + } + } else if (l == 2) { + // LFO + if (value & 8) + warning("TownsPC98_FmSynth: TRYING TO USE LFO (NOT SUPPORTED)"); + } else if (l == 10 || l == 11) { + // DAC + if (l == 11 && (value & 0x80)) + warning("TownsPC98_FmSynth: TRYING TO USE DAC (NOT SUPPORTED)"); + } + break; + + case 0x30: + // detune, multiple + o->detune((value >> 4) & 7); + o->multiple(value & 0x0f); + c->updateEnvelopeParameters = true; + break; + + case 0x40: + // total level + o->totalLevel(value & 0x7f); + break; + + case 0x50: + // rate scaling, attack rate + o->attackRate(value & 0x1f); + if (o->scaleRate(value >> 6)) + c->updateEnvelopeParameters = true; + break; + + case 0x60: + // first decay rate, amplitude modulation + o->decayRate(value & 0x1f); + o->ampModulation(value & 0x80 ? true : false); + break; + + case 0x70: + // secondary decay rate + o->sustainRate(value & 0x1f); + break; + + case 0x80: + // secondary amplitude, release rate; + o->sustainLevel(value >> 4); + o->releaseRate(value & 0x0f); + break; + + case 0x90: + warning("TownsPC98_FmSynth: TRYING TO USE SSG ENVELOPE SHAPES (NOT SUPPORTED)"); + break; + + case 0xa0: + // frequency + l &= ~3; + if (l == 0) { + c->frqTemp = (c->frqTemp & 0xff00) | value; + c->updateEnvelopeParameters = true; + for (int i = 0; i < 4; i++) + co[i]->frequency(c->frqTemp); + } else if (l == 4) { + c->frqTemp = (c->frqTemp & 0xff) | (value << 8); + } else if (l == 8) { + // Ch 3/6 special mode frq + warning("TownsPC98_FmSynth: TRYING TO USE CH 3/6 SPECIAL MODE FREQ (NOT SUPPORTED)"); + } else if (l == 12) { + // Ch 3/6 special mode frq + warning("TownsPC98_FmSynth: TRYING TO USE CH 3/6 SPECIAL MODE FREQ (NOT SUPPORTED)"); + } + break; + + case 0xb0: + l &= ~3; + if (l == 0) { + // feedback, _algorithm + co[0]->feedbackLevel((value >> 3) & 7); + c->algorithm = value & 7; + } else if (l == 4) { + // stereo, LFO sensitivity + c->enableLeft = value & 0x80 ? true : false; + c->enableRight = value & 0x40 ? true : false; + c->ampModSensitivity((value & 0x30) >> 4); + c->frqModSensitivity(value & 3); + } + break; + + default: + warning("TownsPC98_FmSynth: UNKNOWN ADDRESS %d", regAddress); + } +} + +int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) { + Common::StackLock lock(_mutex); + + memset(buffer, 0, sizeof(int16) * numSamples); + int32 *tmp = new int32[numSamples]; + int32 *tmpStart = tmp; + memset(tmp, 0, sizeof(int32) * numSamples); + int32 samplesLeft = numSamples >> 1; + + while (samplesLeft) { + int32 render = samplesLeft; + + for (int i = 0; i < 2; i++) { + if (_timers[i].enabled && _timers[i].cb) { + if (!_timers[i].smpTillCb) { + (this->*_timers[i].cb)(); + _timers[i].smpTillCb = _timers[i].smpPerCb; + + _timers[i].smpTillCbRem += _timers[i].smpPerCbRem; + if (_timers[i].smpTillCbRem >= _timerbase) { + _timers[i].smpTillCb++; + _timers[i].smpTillCbRem -= _timerbase; + } + } + render = MIN(render, _timers[i].smpTillCb); + } + } + + samplesLeft -= render; + + for (int i = 0; i < 2; i++) { + if (_timers[i].enabled && _timers[i].cb) { + _timers[i].smpTillCb -= render; + } + } + + nextTick(tmp, render); + + if (_ssg) + _ssg->nextTick(tmp, render); + if (_prc) + _prc->nextTick(tmp, render); + + nextTickEx(tmp, render); + + for (int i = 0; i < render; ++i) { + int32 l = CLIP<int32>(tmp[i << 1], -32767, 32767); + buffer[i << 1] = (int16) l; + int32 r = CLIP<int32>(tmp[(i << 1) + 1], -32767, 32767); + buffer[(i << 1) + 1] = (int16) r; + } + + buffer += (render << 1); + tmp += (render << 1); + } + + delete[] tmpStart; + return numSamples; +} + +uint8 TownsPC98_FmSynth::readSSGStatus() { + return _ssg->chanEnable(); +} + +void TownsPC98_FmSynth::setVolumeIntern(int volA, int volB) { + Common::StackLock lock(_mutex); + _volumeA = CLIP<uint16>(volA, 0, Audio::Mixer::kMaxMixerVolume); + _volumeB = CLIP<uint16>(volB, 0, Audio::Mixer::kMaxMixerVolume); + if (_ssg) + _ssg->setVolumeIntern(_volumeA, _volumeB); + if (_prc) + _prc->setVolumeIntern(_volumeA, _volumeB); +} + +void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB) { + Common::StackLock lock(_mutex); + _volMaskA = channelMaskA; + _volMaskB = channelMaskB; + if (_ssg) + _ssg->setVolumeChannelMasks(_volMaskA >> _numChan, _volMaskB >> _numChan); + if (_prc) + _prc->setVolumeChannelMasks(_volMaskA >> (_numChan + _numSSG), _volMaskB >> (_numChan + _numSSG)); +} + +void TownsPC98_FmSynth::generateTables() { + delete[] _oprRates; + _oprRates = new uint8[128]; + + WRITE_BE_UINT32(_oprRates + 32, _numChan == 6 ? 0x90900000 : 0x00081018); + WRITE_BE_UINT32(_oprRates + 36, _numChan == 6 ? 0x00001010 : 0x00081018); + memset(_oprRates, 0x90, 32); + memset(_oprRates + 96, 0x80, 32); + uint8 *dst = (uint8 *)_oprRates + 40; + for (int i = 0; i < 40; i += 4) + WRITE_BE_UINT32(dst + i, 0x00081018); + for (int i = 0; i < 48; i += 4) + WRITE_BE_UINT32(dst + i, 0x00081018); + dst += 40; + for (uint8 i = 0; i < 16; i ++) { + uint8 v = (i < 12) ? i : 12; + *dst++ = ((4 + v) << 3); + } + + delete[] _oprRateshift; + _oprRateshift = new uint8[128]; + memset(_oprRateshift, 0, 128); + dst = (uint8 *)_oprRateshift + 32; + for (int i = 11; i; i--) { + memset(dst, i, 4); + dst += 4; + } + + delete[] _oprFrq; + _oprFrq = new uint32[0x1000]; + for (uint32 i = 0; i < 0x1000; i++) + _oprFrq[i] = (uint32)(_baserate * (float)(i << 11)); + + delete[] _oprAttackDecay; + _oprAttackDecay = new uint8[152]; + memset(_oprAttackDecay, 0, 152); + for (int i = 0; i < 36; i++) + WRITE_BE_UINT32(_oprAttackDecay + (i << 2), _adtStat[i]); + + delete[] _oprSinTbl; + _oprSinTbl = new uint32[1024]; + for (int i = 0; i < 1024; i++) { + double val = sin((double)(((i << 1) + 1) * PI / 1024.0)); + double d_dcb = log(1.0 / (double)ABS(val)) / log(2.0) * 256.0; + int32 i_dcb = (int32)(2.0 * d_dcb); + i_dcb = (i_dcb & 1) ? (i_dcb >> 1) + 1 : (i_dcb >> 1); + _oprSinTbl[i] = (i_dcb << 1) + (val >= 0.0 ? 0 : 1); + } + + delete[] _oprLevelOut; + _oprLevelOut = new int32[0x1a00]; + for (int i = 0; i < 256; i++) { + double val = floor(65536.0 / pow(2.0, 0.00390625 * (double)(1 + i))); + int32 val_int = ((int32) val) >> 4; + _oprLevelOut[i << 1] = (val_int & 1) ? ((val_int >> 1) + 1) << 2 : (val_int >> 1) << 2; + _oprLevelOut[(i << 1) + 1] = -_oprLevelOut[i << 1]; + for (int ii = 1; ii < 13; ++ii) { + _oprLevelOut[(i << 1) + (ii << 9)] = _oprLevelOut[i << 1] >> ii; + _oprLevelOut[(i << 1) + (ii << 9) + 1] = -_oprLevelOut[(i << 1) + (ii << 9)]; + } + } + + uint8 *dtt = new uint8[128]; + memset(dtt, 0, 36); + memset(dtt + 36, 1, 8); + memcpy(dtt + 44, _detSrc, 84); + + delete[] _oprDetune; + _oprDetune = new int32[256]; + for (int i = 0; i < 128; i++) { + _oprDetune[i] = (int32)((float)dtt[i] * _baserate * 64.0); + _oprDetune[i + 128] = -_oprDetune[i]; + } + + delete[] dtt; +} + +void TownsPC98_FmSynth::nextTick(int32 *buffer, uint32 bufferSize) { + if (!_ready) + return; + + for (int i = 0; i < _numChan; i++) { + TownsPC98_FmSynthOperator **o = _chanInternal[i].opr; + + if (_chanInternal[i].updateEnvelopeParameters) { + _chanInternal[i].updateEnvelopeParameters = false; + for (int ii = 0; ii < 4 ; ii++) + o[ii]->updatePhaseIncrement(); + } + + for (uint32 ii = 0; ii < bufferSize ; ii++) { + int32 phbuf1, phbuf2, output; + phbuf1 = phbuf2 = output = 0; + + int32 *leftSample = &buffer[ii * 2]; + int32 *rightSample = &buffer[ii * 2 + 1]; + int32 *del = &_chanInternal[i].feedbuf[2]; + int32 *feed = _chanInternal[i].feedbuf; + + switch (_chanInternal[i].algorithm) { + case 0: + o[0]->generateOutput(0, feed, phbuf1); + o[2]->generateOutput(*del, 0, phbuf2); + *del = 0; + o[1]->generateOutput(phbuf1, 0, *del); + o[3]->generateOutput(phbuf2, 0, output); + break; + case 1: + o[0]->generateOutput(0, feed, phbuf1); + o[2]->generateOutput(*del, 0, phbuf2); + o[1]->generateOutput(0, 0, phbuf1); + o[3]->generateOutput(phbuf2, 0, output); + *del = phbuf1; + break; + case 2: + o[0]->generateOutput(0, feed, phbuf2); + o[2]->generateOutput(*del, 0, phbuf2); + o[1]->generateOutput(0, 0, phbuf1); + o[3]->generateOutput(phbuf2, 0, output); + *del = phbuf1; + break; + case 3: + o[0]->generateOutput(0, feed, phbuf2); + o[2]->generateOutput(0, 0, *del); + o[1]->generateOutput(phbuf2, 0, phbuf1); + o[3]->generateOutput(*del, 0, output); + *del = phbuf1; + break; + case 4: + o[0]->generateOutput(0, feed, phbuf1); + o[2]->generateOutput(0, 0, phbuf2); + o[1]->generateOutput(phbuf1, 0, output); + o[3]->generateOutput(phbuf2, 0, output); + *del = 0; + break; + case 5: + o[0]->generateOutput(0, feed, phbuf1); + o[2]->generateOutput(*del, 0, output); + o[1]->generateOutput(phbuf1, 0, output); + o[3]->generateOutput(phbuf1, 0, output); + *del = phbuf1; + break; + case 6: + o[0]->generateOutput(0, feed, phbuf1); + o[2]->generateOutput(0, 0, output); + o[1]->generateOutput(phbuf1, 0, output); + o[3]->generateOutput(0, 0, output); + *del = 0; + break; + case 7: + o[0]->generateOutput(0, feed, output); + o[2]->generateOutput(0, 0, output); + o[1]->generateOutput(0, 0, output); + o[3]->generateOutput(0, 0, output); + *del = 0; + break; + }; + + int32 finOut = (output << 2) / ((_numChan + _numSSG - 3) / 3); + + if ((1 << i) & _volMaskA) + finOut = (finOut * _volumeA) / Audio::Mixer::kMaxMixerVolume; + + if ((1 << i) & _volMaskB) + finOut = (finOut * _volumeB) / Audio::Mixer::kMaxMixerVolume; + + if (_chanInternal[i].enableLeft) + *leftSample += finOut; + + if (_chanInternal[i].enableRight) + *rightSample += finOut; + } + } +} + +const uint32 TownsPC98_FmSynth::_adtStat[] = { + 0x00010001, 0x00010001, 0x00010001, 0x01010001, + 0x00010101, 0x00010101, 0x00010101, 0x01010101, + 0x01010101, 0x01010101, 0x01010102, 0x01010102, + 0x01020102, 0x01020102, 0x01020202, 0x01020202, + 0x02020202, 0x02020202, 0x02020204, 0x02020204, + 0x02040204, 0x02040204, 0x02040404, 0x02040404, + 0x04040404, 0x04040404, 0x04040408, 0x04040408, + 0x04080408, 0x04080408, 0x04080808, 0x04080808, + 0x08080808, 0x08080808, 0x10101010, 0x10101010 +}; + +const uint8 TownsPC98_FmSynth::_detSrc[] = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, + 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x10, 0x10, 0x10, 0x10, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, + 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x13, 0x14, + 0x16, 0x16, 0x16, 0x16 +}; + +const int TownsPC98_FmSynth::_ssgTables[] = { + 0x01202A, 0x0092D2, 0x006B42, 0x0053CB, 0x003DF8, 0x003053, 0x0022DA, 0x001A8C, + 0x00129B, 0x000DC1, 0x000963, 0x0006C9, 0x000463, 0x0002FA, 0x0001B6, 0x0000FB, + 0x0193B6, 0x01202A, 0x00CDB1, 0x0092D2, 0x007D7D, 0x006B42, 0x005ECD, 0x0053CB, + 0x00480F, 0x003DF8, 0x0036B9, 0x003053, 0x00290A, 0x0022DA, 0x001E6B, 0x001A8C, + 0x001639, 0x00129B, 0x000FFF, 0x000DC1, 0x000B5D, 0x000963, 0x0007FB, 0x0006C9, + 0x000575, 0x000463, 0x00039D, 0x0002FA, 0x000242, 0x0001B6, 0x00014C, 0x0000FB +}; + +const uint8 TownsPC98_FmSynth::_percussionData[] = { + 0, 24, 1, 192, 1, 216, 2, 128, 4, 88, 23, 64, 27, 152, 1, 128, 29, 24, 2, 128, 31, 152, 0, 128, 136, 128, 128, 128, 0, 136, 97, 103, 153, 139, 34, 163, 72, 195, 27, 69, 1, 154, 137, 35, 8, 51, 169, 122, 164, 75, 133, 203, 81, 146, 168, 121, 185, 68, 202, 8, 33, 237, 49, 177, 12, 133, 140, 17, 160, 42, 161, 10, 0, 137, 176, 57, + 233, 41, 160, 136, 235, 65, 177, 137, 128, 26, 164, 28, 3, 157, 51, 137, 1, 152, 113, 161, 40, 146, 115, 192, 56, 5, 169, 66, 161, 56, 1, 50, 145, 59, 39, 168, 97, 1, 160, 57, 7, 153, 50, 153, 32, 2, 25, 129, 32, 20, 186, 66, 129, 24, 153, 164, 142, 130, 169, 153, 26, 242, 138, 217, 9, 128, 204, 58, 209, 172, 40, 176, 141, + 128, 155, 144, 203, 139, 0, 235, 9, 177, 172, 0, 185, 168, 138, 25, 240, 59, 211, 139, 19, 176, 90, 160, 17, 26, 132, 41, 1, 5, 25, 3, 50, 144, 115, 147, 42, 39, 152, 41, 3, 56, 193, 105, 130, 155, 66, 200, 26, 19, 218, 154, 49, 201, 171, 138, 176, 251, 139, 185, 172, 136, 189, 139, 145, 207, 41, 160, 171, 152, 186, 139, + 186, 141, 128, 218, 171, 51, 217, 170, 56, 163, 12, 4, 155, 81, 147, 42, 37, 152, 32, 54, 136, 49, 50, 48, 37, 32, 69, 0, 17, 50, 50, 83, 2, 16, 68, 20, 8, 66, 4, 154, 84, 145, 24, 33, 24, 32, 17, 18, 145, 32, 22, 168, 49, 163, 1, 33, 50, 184, 115, 129, 25, 66, 1, 24, 67, 2, 80, 35, 40, 53, 2, 65, 51, 19, 67, 37, 0, 52, 35, 49, 37, + 34, 49, 37, 17, 52, 17, 35, 35, 35, 34, 32, 49, 33, 152, 34, 145, 24, 24, 128, 138, 128, 184, 9, 177, 171, 168, 185, 155, 152, 172, 155, 186, 172, 185, 172, 155, 186, 173, 153, 202, 187, 185, 202, 170, 171, 202, 186, 169, 170, 170, 171, 139, 154, 171, 153, 154, 169, 10, 168, 154, 128, 168, 154, 0, 153, 152, 136, 137, + 128, 153, 0, 152, 8, 128, 137, 0, 136, 136, 8, 9, 8, 9, 8, 24, 153, 128, 136, 153, 144, 0, 161, 138, 1, 169, 136, 128, 160, 168, 152, 153, 138, 137, 154, 153, 153, 154, 153, 170, 168, 170, 185, 168, 169, 154, 169, 171, 153, 169, 170, 153, 152, 154, 153, 137, 169, 137, 136, 144, 152, 144, 128, 128, 144, 129, 129, 0, 33, + 0, 17, 17, 17, 33, 33, 18, 18, 34, 34, 34, 34, 34, 34, 35, 19, 35, 19, 35, 35, 18, 19, 18, 35, 18, 33, 0, 8, 8, 8, 8, 8, 8, 8, 160, 205, 65, 176, 171, 203, 16, 240, 95, 242, 120, 145, 156, 66, 177, 26, 19, 153, 9, 35, 35, 239, 56, 132, 138, 154, 50, 145, 203, 25, 32, 20, 237, 24, 130, 138, 160, 27, 39, 173, 50, 203, 64, 145, 139, + 18, 168, 48, 146, 171, 65, 18, 176, 12, 52, 128, 25, 5, 57, 240, 104, 161, 25, 129, 18, 188, 114, 160, 26, 36, 200, 154, 18, 1, 128, 186, 73, 162, 173, 32, 184, 25, 144, 137, 234, 8, 154, 32, 160, 158, 18, 187, 81, 2, 235, 41, 36, 144, 154, 17, 67, 128, 33, 160, 114, 146, 26, 37, 33, 232, 41, 130, 41, 178, 29, 50, 251, 24, + 1, 153, 138, 160, 76, 179, 155, 11, 0, 38, 252, 41, 146, 41, 178, 27, 193, 43, 39, 170, 136, 17, 129, 8, 49, 233, 48, 129, 11, 6, 26, 130, 136, 128, 64, 1, 248, 105, 145, 9, 16, 144, 140, 5, 25, 168, 16, 186, 48, 5, 171, 217, 57, 134, 171, 8, 34, 188, 20, 203, 41, 6, 155, 161, 89, 164, 140, 2, 136, 51, 202, 41, 131, 56, 144, + 8, 97, 144, 146, 13, 69, 200, 42, 130, 25, 152, 57, 6, 220, 88, 177, 26, 148, 9, 168, 8, 67, 192, 156, 65, 145, 137, 10, 4, 154, 18, 157, 67, 160, 154, 1, 50, 188, 82, 170, 82, 185, 49, 220, 97, 144, 10, 8, 16, 145, 9, 136, 18, 202, 51, 184, 141, 114, 179, 139, 24, 19, 8, 250, 121, 160, 40, 160, 10, 18, 152, 168, 42, 35, 216, + 187, 120, 145, 18, 156, 203, 84, 144, 9, 144, 26, 66, 161, 13, 1, 128, 17, 154, 18, 142, 6, 154, 65, 192, 29, 35, 186, 64, 192, 24, 9, 146, 56, 185, 16, 248, 121, 176, 40, 129, 136, 171, 96, 147, 140, 50, 203, 64, 144, 41, 128, 161, 187, 71, 200, 24, 129, 24, 217, 56, 20, 220, 24, 4, 169, 9, 1, 33, 201, 26, 134, 141, 51, 201, + 25, 16, 33, 235, 32, 144, 33, 153, 169, 99, 160, 11, 3, 136, 58, 210, 33, 203, 48, 163, 17, 219, 128, 140, 38, 8, 184, 141, 50, 131, 159, 33, 128, 153, 25, 18, 153, 88, 242, 43, 3, 9, 136, 157, 53, 202, 40, 145, 25, 2, 204, 105, 146, 156, 66, 152, 8, 153, 33, 128, 129, 136, 153, 50, 186, 55, 188, 51, 249, 64, 178, 27, 128, + 48, 177, 156, 18, 35, 175, 51, 189, 32, 51, 234, 155, 69, 184, 26, 2, 152, 9, 17, 136, 144, 137, 50, 235, 115, 216, 24, 2, 170, 67, 187, 49, 129, 155, 4, 27, 129, 56, 232, 43, 39, 203, 40, 3, 154, 169, 66, 184, 114, 224, 25, 2, 9, 128, 11, 35, 155, 18, 11, 202, 84, 169, 26, 5, 154, 8, 160, 98, 185, 17, 187, 50, 23, 188, 33, + 1, 139, 4, 154, 90, 147, 12, 3, 43, 2, 170, 171, 103, 193, 28, 132, 137, 8, 129, 24, 170, 50, 201, 42, 35, 202, 169, 52, 201, 33, 218, 40, 39, 203, 0, 40, 147, 29, 163, 139, 83, 185, 1, 4, 159, 34, 160, 12, 21, 155, 40, 129, 137, 58, 151, 13, 2, 136, 144, 16, 153, 40, 17, 131, 207, 51, 144, 140, 4, 154, 17, 146, 170, 73, 163, + 44, 164, 12, 152, 37, 203, 17, 128, 144, 139, 23, 154, 128, 138, 38, 216, 41, 1, 0, 233, 73, 131, 171, 49, 136, 9, 164, 46, 3, 171, 32, 0, 145, 157, 38, 187, 64, 176, 58, 134, 155, 18, 136, 217, 64, 1, 200, 140, 38, 153, 170, 66, 161, 8, 169, 65, 185, 98, 200, 41, 3, 155, 144, 58, 23, 187, 1, 145, 40, 147, 189, 32, 68, 249, + 1, 112, 255, 199, 195, 19, 108, 76, 187, 247, 247, 183, 40, 168, 212, 245, 199, 227, 68, 45, 59, 10, 145, 177, 198, 24, 130, 76, 26, 193, 180, 129, 0, 162, 42, 160, 199, 162, 0, 16, 152, 137, 132, 168, 195, 130, 162, 181, 227, 163, 161, 179, 211, 180, 179, 164, 128, 162, 161, 194, 164, 179, 40, 153, 195, 213, 146, 178, + 147, 176, 50, 186, 161, 196, 151, 58, 16, 28, 162, 160, 131, 122, 155, 33, 241, 146, 128, 40, 26, 128, 154, 36, 170, 89, 59, 9, 24, 144, 77, 161, 8, 177, 112, 139, 33, 232, 148, 24, 41, 61, 9, 26, 162, 32, 30, 58, 153, 32, 59, 73, 59, 11, 79, 137, 57, 9, 49, 30, 24, 153, 131, 25, 106, 61, 153, 73, 28, 56, 27, 41, 137, 148, + 76, 43, 74, 58, 13, 161, 3, 171, 149, 32, 77, 10, 74, 42, 168, 16, 0, 123, 138, 129, 162, 178, 225, 50, 140, 161, 0, 147, 10, 129, 41, 244, 210, 165, 1, 152, 24, 162, 184, 166, 32, 144, 59, 216, 132, 177, 8, 145, 67, 143, 146, 160, 183, 162, 130, 24, 192, 32, 225, 146, 144, 33, 44, 73, 30, 129, 137, 32, 76, 152, 25, 161, + 2, 154, 32, 177, 132, 232, 2, 136, 210, 128, 149, 177, 32, 58, 27, 168, 225, 133, 8, 44, 107, 136, 25, 136, 17, 26, 58, 46, 16, 11, 145, 17, 144, 79, 136, 144, 136, 145, 152, 33, 31, 162, 130, 200, 82, 153, 74, 137, 147, 26, 0, 13, 133, 170, 149, 16, 192, 0, 178, 0, 128, 152, 182, 150, 9, 16, 9, 137, 33, 59, 63, 10, 152, 32, + 179, 192, 5, 154, 228, 182, 145, 130, 144, 42, 128, 242, 2, 136, 41, 168, 17, 76, 57, 31, 129, 136, 17, 47, 8, 41, 138, 32, 138, 123, 59, 58, 10, 136, 161, 4, 46, 25, 145, 136, 129, 25, 56, 28, 91, 41, 154, 108, 9, 16, 44, 24, 137, 48, 15, 0, 194, 162, 41, 194, 56, 241, 163, 146, 0, 139, 7, 186, 150, 129, 152, 1, 208, 33, 176, + 136, 164, 163, 185, 7, 138, 130, 242, 162, 163, 177, 88, 136, 184, 166, 146, 0, 25, 25, 177, 199, 146, 16, 136, 9, 145, 178, 178, 0, 147, 138, 229, 18, 152, 25, 144, 163, 246, 162, 129, 129, 184, 5, 152, 178, 145, 148, 136, 146, 95, 152, 128, 144, 33, 170, 81, 11, 40, 202, 131, 0, 243, 24, 1, 11, 148, 42, 24, 163, 140, + 120, 9, 76, 58, 153, 145, 56, 30, 72, 46, 42, 9, 8, 57, 91, 76, 59, 26, 160, 129, 41, 76, 10, 57, 192, 163, 129, 16, 225, 2, 27, 40, 200, 48, 91, 226, 40, 145, 43, 177, 177, 182, 196, 145, 33, 184, 165, 17, 192, 163, 194, 129, 211, 128, 162, 197, 129, 0, 136, 211, 146, 8, 162, 144, 0, 167, 160, 1, 176, 150, 137, 1, 24, 243, + 0, 129, 145, 25, 123, 169, 130, 168, 132, 41, 63, 42, 136, 137, 120, 26, 136, 8, 24, 89, 29, 58, 177, 193, 147, 1, 26, 162, 176, 167, 180, 8, 49, 28, 29, 178, 162, 88, 43, 42, 57, 43, 61, 8, 29, 129, 128, 128, 123, 137, 24, 243, 16, 136, 16, 46, 0, 169, 149, 128, 1, 60, 153, 72, 154, 90, 25, 25, 25, 8, 91, 73, 12, 16, 137, 144, + 72, 11, 8, 167, 128, 129, 9, 138, 166, 193, 147, 162, 123, 137, 145, 1, 162, 26, 1, 219, 147, 129, 210, 147, 243, 1, 243, 16, 144, 145, 160, 131, 200, 4, 59, 75, 57, 218, 2, 178, 77, 24, 60, 11, 147, 10, 50, 141, 64, 27, 185, 122, 161, 41, 128, 90, 136, 24, 46, 16, 139, 16, 24, 28, 124, 9, 41, 8, 26, 121, 10, 42, 40, 139, 129, + 0, 201, 135, 137, 56, 176, 176, 35, 215, 145, 1, 26, 145, 144, 160, 135, 138, 1, 177, 146, 146, 161, 65, 242, 136, 164, 177, 1, 1, 186, 151, 208, 148, 129, 10, 32, 241, 145, 163, 178, 17, 168, 136, 151, 168, 2, 148, 185, 133, 176, 130, 129, 154, 163, 215, 0, 146, 136, 40, 211, 161, 131, 171, 81, 144, 170, 21, 184, 56, + 195, 168, 133, 177, 91, 16, 187, 5, 145, 153, 66, 172, 18, 177, 42, 120, 138, 27, 134, 26, 106, 42, 138, 146, 184, 66, 75, 46, 41, 168, 0, 145, 57, 91, 75, 27, 24, 27, 48, 169, 40, 122, 9, 109, 10, 8, 177, 146, 16, 74, 30, 129, 160, 162, 146, 41, 124, 138, 24, 145, 152, 3, 1, 14, 3, 139, 1, 192, 161, 151, 177, 122, 8, 10, 0, + 176, 130, 129, 27, 88, 225, 0, 2, 154, 129, 129, 193, 49, 203, 81, 153, 226, 33, 0, 30, 0, 176, 179, 18, 9, 96, 156, 162, 148, 160, 129, 2, 29, 195, 128, 0, 56, 156, 20, 232, 129, 128, 32, 10, 144, 74, 183, 9, 145, 162, 1, 162, 138, 23, 171, 1, 164, 224, 34, 43, 43, 177, 200, 135, 161, 91, 57, 154, 177, 148, 145, 146, 58, + 108, 136, 170, 35, 208, 177, 34, 128, 44, 129, 155, 151, 243, 16, 1, 154, 72, 193, 144, 18, 11, 122, 160, 153, 5, 192, 24, 130, 184, 132, 226, 0, 128, 153, 131, 181, 136, 65, 154, 128, 17, 170, 39, 28, 59, 144, 168, 80, 25, 47, 24, 26, 144, 32, 47, 41, 153, 161, 148, 8, 92, 9, 9, 129, 144, 33, 26, 47, 24, 137, 108, 25, 10, + 17, 10, 73, 75, 47, 24, 184, 48, 8, 45, 57, 138, 136, 150, 10, 48, 139, 136, 35, 203, 121, 8, 27, 179, 161, 106, 0, 29, 16, 176, 179, 3, 185, 19, 227, 41, 145, 168, 61, 197, 177, 20, 10, 57, 42, 250, 147, 196, 16, 41, 138, 24, 195, 208, 135, 137, 0, 145, 160, 2, 210, 146, 195, 177, 132, 136, 153, 167, 210, 146, 162, 40, 8, + 138, 148, 227, 145, 17, 137, 40, 169, 179, 130, 242, 2, 196, 9, 146, 145, 169, 167, 146, 130, 137, 136, 51, 220, 17, 163, 28, 74, 10, 76, 40, 140, 5, 137, 43, 18, 12, 107, 137, 40, 8, 201, 50, 0, 143, 3, 138, 161, 134, 138, 104, 169, 16, 162, 160, 121, 25, 28, 129, 152, 32, 56, 14, 16, 184, 146, 3, 46, 25, 176, 129, 179, + 193, 17, 130, 202, 135, 8, 57, 25, 154, 148, 184, 120, 9, 153, 211, 165, 24, 128, 26, 17, 242, 161, 18, 185, 81, 42, 11, 17, 12, 25, 181, 137, 66, 42, 47, 41, 184, 166, 129, 24, 91, 27, 136, 196, 0, 0, 74, 28, 178, 161, 149, 160, 32, 8, 225, 32, 128, 59, 8, 169, 50, 139, 47, 72, 186, 16, 132, 9, 122, 9, 160, 146, 144, 89, 153, + 10, 149, 178, 0, 121, 11, 146, 152, 162, 48, 13, 123, 177, 24, 0, 106, 27, 9, 144, 132, 12, 17, 0, 168, 0, 181, 56, 169, 129, 242, 195, 129, 17, 154, 64, 161, 244, 16, 137, 24, 144, 144, 164, 129, 75, 42, 176, 149, 9, 179, 148, 203, 4, 166, 136, 163, 128, 227, 163, 8, 57, 11, 30, 165, 0, 74, 59, 62, 9, 208, 131, 144, 40, 76, + 26, 27, 196, 129, 1, 25, 43, 49, 174, 67, 153, 136, 106, 152, 41, 25, 28, 2, 43, 44, 104, 45, 59, 8, 43, 128, 144, 120, 25, 12, 17, 152, 9, 130, 155, 151, 145, 74, 40, 13, 48, 192, 58, 90, 43, 43, 177, 146, 49, 31, 75, 24, 217, 131, 0, 76, 26, 152, 149, 161, 24, 74, 154, 193, 166, 145, 32, 27, 161, 164, 176, 135, 152, 24, 193, + 162, 146, 164, 58, 227, 193, 148, 161, 128, 18, 234, 130, 180, 145, 2, 200, 1, 163, 186, 98, 184, 129, 149, 153, 49, 42, 186, 151, 242, 129, 1, 43, 8, 177, 212, 165, 8, 40, 137, 24, 8, 144, 90, 9, 25, 48, 44, 46, 24, 138, 40, 144, 108, 58, 27, 128, 181, 128, 80, 29, 42, 152, 162, 130, 25, 106, 136, 11, 148, 8, 144, 128, 136, + 112, 139, 80, 153, 24, 136, 129, 46, 0, 60, 129, 208, 1, 3, 13, 57, 168, 144, 1, 242, 17, 9, 26, 2, 185, 27, 55, 140, 73, 137, 179, 16, 192, 3, 145, 143, 33, 9, 171, 135, 160, 17, 137, 10, 151, 168, 3, 178, 44, 17, 208, 144, 167, 0, 40, 155, 16, 167, 152, 18, 144, 26, 160, 199, 1, 136, 91, 136, 160, 178, 150, 161, 1, 10, 181, + 145, 161, 1, 145, 161, 198, 2, 9, 90, 137, 177, 160, 150, 40, 29, 129, 144, 145, 162, 57, 77, 169, 16, 148, 42, 42, 40, 141, 34, 170, 121, 154, 210, 131, 162, 107, 8, 9, 160, 195, 40, 73, 139, 18, 224, 162, 34, 139, 0, 244, 178, 163, 24, 26, 146, 194, 166, 49, 29, 42, 137, 130, 192, 16, 93, 128, 154, 19, 59, 11, 122, 11, + 146, 177, 120, 42, 26, 43, 164, 152, 17, 60, 63, 137, 128, 48, 10, 58, 92, 9, 59, 91, 75, 139, 32, 25, 25, 61, 74, 28, 177, 40, 130, 74, 29, 73, 168, 130, 128, 48, 14, 8, 77, 9, 25, 26, 179, 211, 32, 78, 26, 41, 152, 161, 180, 89, 59, 9, 153, 166, 160, 3, 26, 57, 106, 154, 88, 184, 40, 1, 27, 58, 73, 143, 131, 169, 3, 161, 184, + 122, 152, 16, 181, 145, 129, 17, 15, 129, 193, 147, 145, 192, 33, 193, 162, 183, 163, 136, 178, 129, 178, 197, 2, 41, 216, 131, 168, 163, 181, 226, 163, 178, 1, 33, 187, 166, 212, 129, 1, 27, 24, 162, 184, 151, 8, 16, 160, 144, 181, 210, 72, 168, 128, 32, 42, 25, 40, 142, 5, 185, 88, 58, 11, 58, 177, 32, 129, 63, 42, 136, + 186, 53, 29, 75, 58, 144, 144, 129, 77, 128, 11, 144, 133, 29, 40, 152, 24, 161, 129, 80, 155, 60, 3, 12, 89, 8, 60, 152, 152, 49, 136, 47, 57, 224, 129, 16, 41, 90, 139, 162, 147, 170, 51, 169, 27, 17, 95, 26, 26, 160, 5, 139, 48, 76, 10, 228, 146, 1, 136, 44, 161, 147, 209, 130, 137, 73, 224, 1, 162, 195, 32, 210, 177, 180, + 179, 148, 145, 154, 132, 242, 146, 1, 152, 32, 192, 1, 144, 155, 7, 177, 168, 5, 138, 178, 148, 152, 150, 136, 89, 152, 9, 41, 196, 145, 40, 28, 16, 8, 10, 178, 167, 24, 1, 44, 123, 137, 136, 145, 194, 48, 27, 74, 26, 192, 179, 135, 136, 88, 27, 10, 177, 163, 164, 128, 73, 24, 31, 8, 0, 192, 149, 144, 129, 9, 106, 41, 200, + 161, 151, 41, 138, 0, 24, 226, 162, 49, 42, 11, 90, 136, 136, 152, 17, 145, 10, 63, 40, 11, 56, 245, 162, 16, 26, 73, 11, 144, 135, 137, 58, 106, 10, 25, 8, 57, 137, 28, 33, 129, 156, 113, 10, 10, 161, 18, 8, 153, 77, 3, 217, 0, 1, 242, 128, 193, 18, 128, 75, 60, 178, 154, 37, 45, 58, 29, 144, 1, 184, 66, 41, 29, 8, 145, 10, + 194, 33, 148, 170, 107, 89, 139, 128, 163, 178, 16, 63, 59, 176, 144, 151, 129, 42, 74, 10, 129, 192, 2, 128, 154, 97, 192, 0, 177, 128, 178, 183, 16, 16, 155, 149, 145, 184, 84, 138, 8, 192, 161, 20, 225, 0, 130, 138, 165, 0, 28, 148, 153, 18, 209, 128, 88, 153, 89, 152, 9, 17, 9, 29, 130, 43, 122, 153, 24, 32, 202, 49, + 24, 43, 106, 154, 130, 193, 27, 51, 29, 28, 133, 138, 65, 11, 123, 25, 10, 40, 152, 44, 130, 26, 43, 148, 45, 73, 140, 33, 8, 153, 88, 128, 61, 144, 42, 59, 225, 128, 18, 155, 50, 75, 186, 20, 202, 120, 144, 42, 92, 176, 162, 165, 25, 2, 169, 152, 135, 185, 19, 152, 8, 146, 160, 123, 195, 137, 132, 209, 0, 16, 11, 2, 242, + 146, 164, 152, 73, 193, 136, 130, 178, 1, 136, 169, 23, 169, 128, 164, 242, 129, 178, 129, 32, 138, 180, 167, 153, 132, 8, 138, 2, 209, 4, 138, 1, 128, 138, 92, 136, 44, 129, 136, 162, 33, 63, 40, 141, 2, 160, 144, 106, 137, 64, 155, 17, 129, 60, 30, 146, 26, 17, 28, 48, 46, 169, 51, 154, 91, 137, 41, 26, 32, 143, 18, 138, + 1, 32, 28, 123, 177, 9, 181, 195, 56, 57, 14, 145, 161, 17, 17, 31, 41, 152, 145, 194, 194, 20, 153, 41, 9, 243, 129, 180, 0, 128, 45, 16, 43, 170, 135, 144, 16, 25, 42, 137, 242, 163, 194, 16, 0, 57, 14, 130, 194, 178, 16, 33, 30, 8, 59, 211, 163, 160, 5, 137, 44, 10, 17, 170, 3, 120, 9, 44, 146, 136, 131, 140, 91, 9, 171, + 7, 161, 32, 73, 13, 8, 161, 40, 106, 11, 25, 129, 59, 0, 49, 31, 42, 28, 40, 11, 0, 81, 176, 61, 32, 138, 25, 178, 241, 148, 136, 106, 8, 136, 128, 177, 90, 8, 155, 96, 176, 9, 18, 217, 132, 129, 10, 81, 156, 40, 178, 161, 36, 169, 76, 147, 203, 150, 0, 10, 146, 200, 147, 149, 128, 144, 148, 154, 182, 24, 0, 137, 11, 134, 211, + 24, 136, 129, 145, 209, 33, 8, 43, 163, 243, 88, 41, 13, 0, 160, 145, 33, 31, 32, 185, 145, 4, 155, 17, 32, 47, 161, 128, 73, 160, 44, 56, 176, 75, 74, 12, 35, 141, 104, 137, 9, 89, 152, 58, 56, 44, 41, 30, 41, 40, 157, 48, 128, 154, 88, 41, 42, 8, 14, 3, 184, 59, 120, 152, 9, 56, 10, 128, 41, 57, 227, 186, 52, 152, 62, 8, 56, + 242, 0, 58, 8, 156, 34, 243, 128, 24, 176, 51, 169, 58, 183, 192, 146, 164, 177, 18, 170, 7, 177, 208, 132, 161, 24, 136, 27, 147, 243, 128, 133, 10, 24, 161, 161, 178, 214, 17, 160, 25, 16, 161, 137, 165, 192, 48, 27, 72, 58, 218, 133, 162, 26, 72, 27, 10, 197, 178, 49, 138, 89, 56, 142, 1, 24, 11, 0, 44, 105, 10, 25, 0, + 194, 9, 3, 47, 8, 138, 147, 18, 28, 48, 202, 147, 199, 146, 25, 161, 0, 145, 194, 163, 57, 11, 146, 248, 130, 32, 57, 63, 154, 16, 48, 14, 128, 144, 209, 133, 26, 56, 154, 182, 162, 195, 18, 152, 44, 194, 180, 168, 5, 24, 137, 138, 35, 192, 232, 66, 176, 161, 24, 41, 26, 244, 129, 163, 160, 75, 129, 226, 147, 40, 145, 61, + 13, 130, 177, 17, 137, 112, 170, 130, 0, 136, 75, 152, 177, 241, 34, 0, 59, 156, 51, 186, 178, 91, 132, 137, 137, 122, 1, 45, 28, 50, 172, 57, 108, 8, 26, 136, 32, 152, 46, 144, 131, 171, 4, 152, 18, 141, 148, 1, 216, 32, 9, 60, 169, 66, 152, 128, 72, 90, 201, 1, 17, 201, 136, 3, 195, 26, 73, 133, 200, 176, 150, 146, 169, + 24, 33, 178, 184, 151, 73, 11, 28, 72, 44, 153, 82, 153, 17, 42, 57, 78, 153, 8, 160, 0, 1, 123, 11, 19, 171, 195, 18, 59, 31, 129, 10, 162, 2, 58, 96, 142, 130, 26, 75, 128, 176, 17, 180, 123, 9, 90, 137, 211, 145, 32, 26, 76, 43, 145, 130, 12, 90, 41, 27, 58, 160, 160, 128, 178, 7, 76, 59, 0, 203, 180, 147, 33, 62, 10, 0, 243, + 129, 146, 73, 29, 145, 144, 0, 26, 56, 153, 185, 83, 8, 76, 27, 166, 161, 193, 146, 131, 224, 145, 165, 161, 40, 168, 149, 162, 226, 2, 136, 138, 163, 131, 211, 0, 59, 146, 218, 148, 1, 192, 16, 16, 58, 248, 88, 144, 177, 136, 1, 58, 45, 9, 195, 197, 147, 48, 29, 10, 0, 162, 176, 64, 122, 9, 10, 17, 9, 153, 56, 75, 27, 31, + 72, 136, 9, 129, 129, 61, 45, 59, 10, 161, 18, 122, 43, 59, 41, 169, 34, 155, 130, 131, 219, 120, 162, 27, 49, 208, 160, 131, 156, 66, 12, 145, 50, 240, 16, 136, 12, 162, 40, 129, 130, 15, 129, 162, 146, 180, 83, 139, 58, 217, 129, 177, 4, 0, 169, 197, 163, 144, 242, 131, 168, 179, 179, 17, 197, 145, 178, 164, 128, 160, + 211, 2, 244, 163, 145, 162, 129, 212, 177, 163, 17, 208, 163, 195, 180, 57, 24, 170, 182, 164, 129, 0, 60, 60, 169, 149, 162, 177, 122, 26, 24, 136, 136, 133, 43, 27, 178, 56, 77, 24, 128, 240, 0, 2, 44, 46, 8, 128, 193, 146, 64, 27, 42, 16, 193, 25, 0, 192, 148, 11, 52, 47, 153, 147, 243, 0, 24, 73, 28, 144, 161, 150, 9, + 8, 73, 170, 2, 162, 25, 27, 147, 167, 131, 29, 1, 168, 200, 165, 16, 91, 137, 8, 162, 176, 35, 41, 31, 24, 169, 50, 168, 58, 123, 144, 48, 128, 13, 73, 169, 144, 16, 57, 123, 44, 200, 163, 56, 153, 80, 10, 176, 146, 57, 94, 8, 152, 131, 9, 168, 125, 26, 145, 177, 132, 137, 41, 60, 26, 144, 243, 32, 192, 34, 60, 43, 26, 16, + 249, 164, 16, 58, 61, 11, 130, 243, 146, 2, 42, 44, 27, 128, 165, 137, 49, 45, 28, 16, 43, 8, 211, 48, 28, 152, 105, 9, 9, 163, 161, 169, 35, 107, 42, 232, 164, 130, 168, 72, 42, 168, 210, 148, 144, 136, 129, 3, 217, 194, 50, 27, 192, 41, 210, 147, 40, 76, 226, 1, 161, 1, 155, 132, 145, 147, 171, 67, 173, 210, 132, 161, 106, + 137, 56, 169, 209, 131, 64, 13, 129, 9, 194, 17, 57, 61, 169, 17, 128, 40, 31, 16, 10, 162, 57, 61, 75, 139, 40, 242, 17, 58, 59, 138, 179, 144, 50, 105, 140, 179, 243, 57, 40, 26, 9, 243, 130, 24, 29, 57, 128, 210, 129, 25, 59, 91, 137, 162, 178, 72, 27, 181, 168, 19, 129, 8, 184, 231, 147, 178, 32, 28, 184, 198, 148, 144, + 1, 26, 128, 16, 192, 2, 26, 144, 244, 129, 0, 16, 10, 197, 177, 181, 1, 41, 9, 178, 165, 211, 129, 25, 145, 137, 210, 147, 152, 210, 163, 132, 194, 17, 91, 169, 145, 181, 130, 9, 89, 137, 152, 178, 4, 128, 9, 63, 160, 128, 106, 8, 25, 43, 10, 32, 47, 26, 123, 152, 24, 40, 25, 27, 18, 186, 35, 158, 64, 42, 216, 33, 25, 58, 58, + 45, 184, 147, 29, 72, 46, 9, 0, 178, 146, 58, 77, 26, 25, 209, 165, 128, 145, 17, 153, 128, 129, 148, 240, 129, 1, 40, 31, 0, 152, 242, 163, 16, 59, 44, 24, 243, 146, 128, 1, 26, 26, 179, 213, 145, 130, 176, 131, 40, 25, 145, 219, 179, 167, 8, 33, 59, 14, 176, 166, 16, 136, 74, 128, 176, 128, 149, 8, 8, 209, 148, 152, 0, 72, + 153, 161, 178, 35, 62, 75, 154, 163, 153, 19, 62, 170, 133, 179, 136, 89, 12, 129, 164, 144, 3, 47, 58, 193, 177, 148, 0, 61, 43, 10, 129, 17, 41, 61, 43, 25, 8, 126, 26, 25, 137, 145, 34, 44, 45, 129, 216, 179, 1, 90, 25, 137, 32, 227, 8, 16, 9, 170, 49, 31, 32, 29, 128, 145, 148, 75, 25, 75, 153, 162, 192, 35, 12, 80, 136, + 176, 8, 194, 24, 1, 176, 21, 154, 145, 80, 251, 130, 2, 30, 9, 8, 130, 145, 128, 98, 27, 26, 129, 136, 162, 15, 33, 168, 59, 65, 177, 77, 141, 1, 128, 168, 113, 10, 137, 178, 163, 146, 132, 74, 153, 224, 164, 33, 184, 19, 184, 228, 161, 17, 91, 152, 25, 146, 152, 44, 121, 9, 160, 145, 17, 25, 28, 93, 128, 152, 2, 25, 27, 161, + 210, 129, 146, 45, 179, 227, 163, 162, 9, 40, 193, 148, 179, 57, 107, 140, 196, 32, 25, 57, 47, 136, 210, 130, 24, 40, 28, 152, 210, 182, 145, 40, 8, 129, 184, 147, 147, 140, 163, 166, 160, 34, 45, 144, 194, 161, 134, 41, 46, 152, 162, 162, 3, 44, 58, 75, 209, 162, 144, 57, 129, 47, 152, 130, 59, 16, 248, 129, 17, 26, 57, + 9, 29, 167, 2, 60, 42, 138, 136, 209, 130, 90, 42, 42, 176, 146, 178, 120, 28, 8, 160, 145, 16, 33, 31, 1, 8, 160, 129, 128, 242, 164, 32, 152, 177, 146, 213, 196, 128, 40, 26, 160, 163, 180, 146, 108, 60, 144, 144, 136, 147, 137, 40, 90, 161, 3, 17, 219, 243, 33, 184, 130, 60, 136, 243, 178, 179, 132, 26, 8, 168, 212, 147, + 16, 57, 42, 31, 145, 145, 160, 32, 43, 184, 66, 45, 180, 33, 140, 226, 1, 91, 152, 16, 144, 193, 162, 48, 77, 25, 137, 153, 17, 178, 78, 0, 0, 16, 14, 90, 152, 153, 19, 129, 13, 123, 137, 129, 160, 1, 73, 44, 9, 129, 0, 153, 120, 10, 9, 162, 195, 32, 139, 28, 151, 161, 2, 128, 26, 45, 193, 146, 48, 29, 146, 153, 194, 5, 59, + 29, 128, 144, 195, 1, 64, 43, 208, 178, 149, 8, 9, 16, 240, 163, 129, 16, 42, 185, 181, 211, 24, 48, 45, 137, 149, 9, 24, 41, 75, 184, 177, 4, 43, 91, 128, 180, 16, 144, 29, 25, 184, 167, 1, 59, 60, 153, 148, 161, 146, 91, 42, 186, 4, 24, 145, 123, 11, 2, 178, 77, 136, 26, 25, 195, 40, 115, 61, 27, 168, 177, 3, 59, 79, 26, 25, + 144, 1, 48, 13, 56, 154, 248, 1, 16, 9, 129, 8, 2, 178, 31, 130, 153, 162, 20, 15, 33, 170, 56, 40, 29, 28, 128, 152, 149, 144, 56, 120, 11, 162, 212, 129, 144, 145, 59, 180, 243, 147, 145, 144, 16, 152, 48, 241, 0, 161, 176, 1, 134, 10, 129, 200, 166, 144, 128, 121, 26, 24, 177, 178, 196, 48, 75, 138, 41, 180, 195, 26, 24, + 89, 138, 24, 33, 187, 41, 84, 155, 57, 79, 136, 160, 210, 130, 0, 58, 58, 168, 243, 132, 27, 41, 75, 138, 3, 8, 61, 8, 29, 145, 179, 76, 24, 28, 146, 208, 2, 49, 140, 75, 196, 144, 0, 40, 44, 179, 208, 3, 176, 33, 15, 177, 2, 160, 106, 8, 160, 164, 164, 8, 73, 27, 226, 179, 161, 1, 57, 1, 196, 211, 128, 40, 156, 145, 166, 178, + 131, 29, 128, 145, 162, 165, 40, 27, 216, 146, 135, 144, 40, 160, 194, 177, 145, 20, 139, 200, 151, 178, 17, 136, 40, 25, 205, 130, 17, 11, 17, 129, 156, 38, 26, 25, 137, 179, 163, 11, 79, 16, 12, 146, 147, 143, 89, 25, 136, 136, 25, 48, 26, 46, 129, 40, 29, 42, 29, 8, 145, 2, 56, 27, 62, 8, 25, 212, 161, 48, 43, 144, 129, + 29, 145, 144, 41, 106, 10, 107, 43, 184, 131, 1, 36, 61, 13, 138, 2, 194, 1, 16, 27, 75, 186, 181, 151, 8, 1, 161, 138, 211, 129, 2, 59, 248, 129, 16, 0, 144, 63, 152, 150, 136, 24, 25, 128, 30, 161, 128, 17, 24, 225, 146, 10, 16, 0, 9, 227, 183, 129, 40, 60, 26, 162, 194, 181, 24, 90, 9, 24, 0, 176, 161, 193, 194, 35, 12, 63, + 8, 210, 162, 1, 32, 78, 28, 152, 164, 144, 16, 48, 45, 137, 162, 147, 168, 152, 98, 27, 43, 33, 12, 160, 165, 129, 137, 63, 41, 153, 153, 151, 16, 91, 26, 8, 8, 9, 56, 10, 46, 24, 146, 57, 168, 160, 166, 241, 129, 32, 140, 16, 145, 179, 164, 137, 113, 138, 208, 131, 26, 25, 1, 42, 178, 196, 106, 24, 171, 18, 196, 8, 18, 29, + 41, 194, 128, 3, 249, 57, 162, 152, 48, 184, 120, 160, 208, 33, 137, 74, 57, 187, 149, 129, 26, 35, 158, 72, 128, 168, 32, 26, 25, 180, 75, 2, 136, 15, 163, 161, 136, 120, 27, 41, 160, 128, 182, 56, 60, 25, 12, 178, 151, 128, 168, 72, 10, 152, 4, 177, 26, 147, 137, 113, 44, 42, 33, 220, 2, 152, 41, 82, 11, 210, 163, 184, + 133, 162, 10, 196, 128, 3, 234, 40, 149, 152, 161, 1, 44, 129, 194, 4, 225, 16, 58, 168, 24, 194, 146, 146, 154, 49, 21, 218, 33, 152, 248, 129, 194, 147, 0, 28, 1, 195, 162, 20, 140, 42, 25, 160, 198, 1, 33, 136, 142, 3, 25, 24, 141, 16, 177, 208, 112, 0, 138, 41, 160, 130, 45, 60, 32, 170, 73, 24, 75, 59, 161, 176, 49, 159, + 97, 26, 168, 149, 145, 32, 28, 25, 184, 211, 129, 179, 74, 73, 8, 153, 136, 193, 151, 160, 32, 48, 143, 9, 147, 181, 145, 32, 60, 9, 187, 133, 166, 144, 32, 152, 25, 136, 161, 150, 168, 145, 81, 10, 42, 0, 169, 182, 148, 136, 58, 41, 187, 182, 211, 131, 16, 137, 25, 243, 144, 129, 2, 9, 8, 202, 7, 25, 185, 21, 144, 136, 153, + 65, 184, 137, 56, 151, 10, 153, 49, 16, 145, 14, 56, 176, 11, 192, 19, 89, 91, 44, 168, 147, 2, 8, 147, 63, 27, 1, 136, 229, 129, 73, 26, 136, 26, 137, 81, 170, 147, 77, 72, 12, 42, 42, 192, 24, 104, 91, 26, 27, 65, 177, 27, 32, 41, 60, 14, 136, 17, 170, 150, 129, 24, 58, 11, 16, 251, 162, 19, 57, 31, 0, 152, 129, 145, 17, 61, + 14, 1, 129, 27, 129, 66, 169, 178, 74, 12, 11, 19, 198, 145, 75, 33, 138, 174, 133, 1, 184, 57, 40, 136, 169, 20, 1, 60, 174, 20, 154, 201, 67, 26, 162, 151, 42, 16, 138, 59, 130, 204, 20, 169, 59, 180, 59, 114, 184, 56, 178, 242, 128, 130, 43, 8, 194, 3, 229, 144, 33, 185, 144, 34, 181, 145, 168, 17, 149, 153, 74, 35, 220, + 129, 128, 1, 88, 59, 75, 225, 136, 130, 168, 17, 144, 12, 151, 8, 25, 179, 8, 1, 240, 16, 8, 25, 145, 211, 41, 130, 138, 115, 169, 160, 163, 168, 84, 154, 74, 0, 170, 144, 211, 149, 2, 30, 128, 137, 9, 149, 1, 144, 58, 60, 57, 153, 178, 150, 17, 29, 27, 74, 25, 195, 152, 56, 15, 1, 25, 26, 152, 149, 80, 153, 57, 73, 140, 128, + 160, 144, 113, 27, 56, 28, 25, 4, 42, 44, 137, 60, 171, 130, 50, 240, 8, 5, 139, 145, 1, 105, 137, 200, 80, 137, 145, 146, 178, 179, 160, 46, 16, 240, 195, 131, 128, 144, 24, 164, 198, 128, 0, 136, 137, 131, 194, 165, 177, 2, 161, 147, 11, 144, 188, 181, 148, 144, 23, 0, 28, 224, 128, 131, 192, 32, 1, 224, 1, 168, 132, 145, + 9, 41, 208, 58, 137, 179, 151, 145, 16, 1, 30, 8, 145, 178, 1, 47, 32, 186, 72, 169, 146, 75, 8, 41, 48, 136, 89, 13, 48, 9, 10, 124, 26, 11, 42, 32, 129, 91, 77, 16, 12, 128, 42, 57, 138, 10, 60, 2, 63, 9, 0, 93, 128, 152, 90, 8, 10, 24, 40, 44, 144, 29, 49, 188, 48, 72, 25, 30, 177, 33, 128, 186, 120, 129, 186, 133, 152, 130, + 24, 156, 51, 154, 8, 226, 2, 56, 155, 2, 179, 233, 167, 128, 24, 129, 176, 136, 151, 8, 184, 0, 33, 224, 152, 21, 177, 24, 10, 163, 16, 250, 17, 130, 171, 83, 137, 136, 37, 12, 56, 242, 154, 17, 160, 145, 82, 13, 3, 201, 128, 18, 137, 24, 162, 63, 162, 8, 107, 178, 128, 57, 158, 32, 24, 200, 18, 0, 106, 154, 73, 16, 248, 8, + 73, 137, 57, 75, 0, 128, 12, 65, 137, 59, 75, 28, 144, 129, 122, 0, 58, 140, 160, 195, 145, 105, 56, 28, 153, 145, 164, 88, 8, 28, 25, 153, 9, 162, 113, 89, 153, 136, 33, 234, 147, 128, 41, 72, 11, 138, 151, 144, 145, 16, 43, 58, 248, 130, 178, 42, 4, 40, 10, 196, 154, 147, 216, 24, 7, 136, 10, 161, 148, 210, 161, 98, 138, + 137, 128, 146, 176, 33, 105, 27, 43, 163, 49, 185, 6, 10, 136, 43, 67, 174, 161, 162, 151, 137, 1, 64, 200, 193, 24, 64, 200, 56, 145, 242, 24, 57, 137, 1, 128, 3, 162, 175, 80, 128, 162, 152, 25, 58, 175, 17, 17, 0, 200, 64, 168, 162, 91, 1, 154, 44, 211, 177, 35, 64, 160, 161, 144, 4, 241, 41, 209, 162, 25, 1, 3, 242, 176, + 134, 153, 42, 41, 136, 135, 154, 2, 130, 46, 41, 161, 153, 180, 145, 34, 26, 46, 18, 242, 137, 146, 129, 25, 128, 11, 151, 161, 40, 179, 27, 122, 168, 59, 137, 181, 50, 172, 36, 56, 15, 9, 129, 137, 128, 75, 2, 58, 12, 52, 141, 8, 24, 58, 153, 157, 122, 145, 9, 1, 80, 27, 184, 32, 74, 219, 50, 57, 168, 153, 180, 48, 28, 143, + 131, 144, 178, 65, 13, 48, 168, 162, 147, 155, 121, 9, 170, 5, 16, 153, 21, 29, 144, 161, 91, 0, 184, 57, 128, 137, 17, 159, 88, 178, 128, 105, 152, 9, 162, 33, 164, 141, 88, 178, 224, 1, 0, 16, 27, 185, 150, 161, 9, 4, 139, 16, 128, 160, 194, 144, 65, 180, 46, 40, 136, 27, 135, 160, 16, 44, 57, 145, 236, 2, 195, 40, 75, 177, + 2, 200, 179, 146, 186, 104, 50, 141, 24, 169, 165, 148, 11, 97, 10, 11, 130, 177, 49, 57, 78, 42, 154, 128, 165, 59, 33, 28, 30, 1, 136, 16, 192, 41, 128, 152, 123, 136, 24, 1, 169, 113, 10, 11, 49, 153, 14, 147, 19, 45, 43, 8, 176, 210, 148, 8, 16, 11, 96, 144, 192, 163, 150, 10, 128, 43, 26, 150, 178, 165, 24, 41, 171, 18, + 27, 215, 1, 8, 128, 136, 40, 35, 208, 11, 161, 193, 18, 73, 154, 133, 155, 165, 164, 10, 49, 154, 8, 199, 0, 2, 168, 64, 192, 0, 40, 162, 43, 202, 180, 150, 10, 106, 24, 185, 145, 131, 184, 113, 43, 24, 162, 187, 73, 146, 42, 81, 171, 121, 58, 155, 151, 16, 43, 32, 31, 9, 160, 146, 17, 136, 94, 10, 24, 145, 25, 9, 130, 59, + 65, 13, 91, 25, 169, 146, 176, 112, 42, 59, 16, 217, 130, 20, 13, 25, 9, 40, 161, 138, 68, 169, 154, 18, 62, 154, 180, 145, 135, 152, 56, 58, 155, 165, 211, 8, 40, 42, 10, 198, 1, 2, 184, 57, 184, 224, 51, 154, 27, 134, 168, 19, 202, 73, 75, 184, 35, 176, 75, 24, 25, 209, 51, 157, 19, 30, 184, 179, 3, 33, 148, 45, 232, 146, + 129, 168, 41, 32, 170, 149, 193, 35, 136, 16, 50, 191, 56, 146, 173, 149, 16, 24, 41, 30, 129, 168, 209, 3, 57, 31, 0, 16, 176, 147, 41, 152, 10, 17, 181, 14, 40, 144, 49, 170, 75, 97, 141, 25, 162, 146, 72, 177, 92, 137, 137, 19, 137, 153, 113, 154, 2, 41, 60, 129, 217, 2, 211, 152, 73, 42, 193, 197, 146, 147, 10, 59, 0, + 192, 196, 132, 41, 160, 25, 88, 169, 16, 40, 241, 1, 153, 81, 28, 10, 147, 161, 209, 88, 75, 9, 161, 162, 180, 16, 43, 57, 235, 33, 56, 156, 129, 144, 2, 135, 31, 128, 145, 136, 163, 56, 59, 154, 57, 167, 160, 105, 137, 0, 138, 163, 3, 41, 47, 185, 211, 131, 41, 41, 60, 139, 182, 146, 16, 16, 43, 242, 144, 145, 129, 16, 179, + 183, 1, 26, 9, 147, 240, 131, 160, 91, 74, 152, 184, 166, 178, 33, 140, 9, 4, 162, 233, 34, 136, 129, 144, 163, 60, 142, 144, 149, 128, 33, 73, 13, 161, 194, 131, 0, 26, 56, 142, 128, 163, 128, 1, 233, 56, 209, 41, 145, 194, 147, 179, 149, 64, 30, 8, 128, 216, 18, 24, 43, 43, 32, 153, 25, 74, 109, 137, 153, 48, 8, 137, 122, + 25, 144, 26, 43, 59, 30, 33, 41, 27, 24, 96, 153, 160, 50, 76, 27, 47, 152, 145, 163, 73, 40, 14, 152, 131, 176, 74, 90, 8, 8, 200, 67, 155, 154, 50, 49, 155, 28, 124, 177, 152, 1, 2, 17, 62, 138, 180, 176, 4, 25, 9, 177, 245, 162, 129, 40, 25, 176, 164, 130, 172, 4, 8, 181, 194, 49, 11, 168, 154, 165, 133, 152, 40, 136, 226, + 179, 19, 26, 185, 16, 167, 194, 16, 25, 57, 243, 136, 147, 1, 31, 25, 184, 132, 160, 33, 62, 138, 129, 130, 41, 121, 137, 153, 145, 26, 17, 107, 136, 179, 1, 61, 60, 26, 162, 168, 148, 64, 31, 25, 32, 168, 152, 64, 31, 137, 8, 129, 33, 62, 24, 137, 8, 16, 59, 47, 153, 33, 162, 91, 59, 41, 170, 145, 5, 43, 60, 41, 13, 178, 134, + 57, 153, 12, 194, 227, 8, 2, 128, 57, 208, 162, 19, 216, 32, 178, 25, 128, 160, 48, 194, 195, 37, 155, 10, 33, 251, 163, 146, 16, 136, 12, 166, 195, 160, 148, 129, 176, 147, 178, 150, 160, 72, 162, 162, 193, 162, 60, 200, 145, 5, 144, 25, 122, 216, 129, 161, 130, 0, 10, 73, 1, 241, 2, 9, 168, 33, 13, 161, 165, 24, 64, 203, + 50, 1, 14, 9, 9, 129, 161, 106, 33, 27, 13, 164, 128, 40, 41, 107, 169, 160, 33, 136, 60, 92, 168, 152, 2, 91, 57, 176, 129, 0, 144, 47, 136, 162, 164, 128, 80, 43, 154, 179, 213, 130, 74, 27, 0, 145, 145, 167, 58, 59, 160, 9, 26, 76, 8, 171, 5, 49, 28, 44, 169, 162, 183, 130, 72, 28, 144, 179, 228, 2, 25, 26, 129, 186, 151, + 1, 75, 128, 169, 17, 178, 15, 57, 170, 16, 166, 16, 57, 8, 139, 162, 181, 1, 8, 152, 164, 181, 41, 81, 43, 10, 242, 145, 57, 139, 89, 8, 193, 18, 154, 32, 176, 10, 165, 129, 137, 147, 177, 134, 0, 25, 25, 201, 147, 227, 129, 72, 59, 185, 167, 128, 129, 160, 91, 25, 176, 130, 147, 145, 9, 160, 5, 202, 17, 16, 186, 136, 37, + 177, 56, 76, 42, 169, 186, 48, 9, 145, 57, 24, 128, 41, 169, 134, 137, 145, 147, 28, 41, 168, 131, 228, 32, 27, 9, 60, 129, 178, 64, 60, 45, 25, 9, 24, 152, 49, 31, 136, 57, 42, 0, 25, 12, 181, 18, 153, 57, 96, 169, 177, 132, 153, 123, 9, 152, 129, 177, 17, 74, 43, 24, 169, 128, 121, 137, 25, 1, 139, 96, 42, 10, 146, 178, 18, + 44, 29, 1, 161, 164, 146, 31, 137, 146, 177, 19, 1, 10, 26, 209, 165, 146, 43, 40, 138, 240, 130, 18, 144, 25, 40, 212, 1, 58, 11, 152, 196, 147, 10, 74, 26, 152, 225, 130, 146, 58, 60, 210, 145, 16, 148, 16, 185, 192, 18, 44, 42, 57, 199, 162, 1, 9, 87, 47, 186, 215, 231, 197, 179, 180, 195, 212, 164, 32, 59, 92, 126, 62, + 41, 59, 76, 59, 60, 168, 179, 213, 197, 163, 72, 44, 25, 74, 126, 127, 127, 79, 26, 177, 148, 90, 27, 225, 247, 165, 0, 152, 147, 123, 138, 211, 164, 72, 126, 127, 46, 210, 196, 163, 228, 215, 64, 11, 210, 180, 1, 8, 58, 153, 1, 224, 149, 57, 76, 27, 24, 76, 42, 43, 136, 128, 243, 179, 130, 106, 60, 42, 42, 92, 28, 243, 231, + 147, 24, 57, 44, 58, 94, 45, 8, 57, 139, 214, 148, 40, 77, 26, 9, 16, 10, 144, 64, 62, 43, 25, 123, 59, 138, 162, 48, 63, 26, 41, 92, 60, 43, 176, 3, 59, 232, 214, 164, 16, 75, 75, 76, 60, 153, 179, 33, 62, 26, 136, 40, 75, 169, 197, 163, 129, 57, 60, 59, 75, 138, 145, 64, 63, 138, 179, 1, 42, 136, 90, 43, 176, 214, 180, 1, 25, + 152, 195, 129, 129, 106, 76, 60, 137, 145, 178, 2, 25, 10, 228, 130, 57, 59, 44, 41, 154, 165, 105, 76, 44, 144, 16, 76, 26, 41, 76, 26, 152, 1, 58, 26, 9, 193, 165, 16, 92, 26, 41, 77, 59, 76, 76, 60, 26, 136, 161, 130, 152, 195, 163, 211, 146, 0, 57, 11, 211, 130, 8, 25, 40, 62, 153, 162, 17, 109, 60, 153, 146, 40, 76, 60, + 26, 160, 179, 211, 163, 32, 60, 42, 153, 179, 194, 199, 130, 24, 58, 43, 58, 27, 128, 161, 195, 129, 226, 196, 147, 90, 59, 75, 44, 136, 128, 145, 160, 148, 123, 59, 42, 26, 41, 26, 57, 27, 192, 215, 147, 57, 59, 27, 161, 145, 213, 130, 106, 76, 43, 9, 144, 162, 129, 177, 181, 130, 136, 194, 146, 40, 10, 129, 25, 210, 146, + 178, 197, 196, 179, 196, 130, 8, 41, 9, 144, 178, 130, 209, 182, 17, 92, 43, 176, 147, 144, 212, 130, 136, 0, 177, 130, 73, 62, 10, 161, 130, 91, 75, 59, 43, 57, 46, 25, 41, 77, 10, 177, 164, 16, 26, 136, 210, 197, 179, 130, 128, 57, 77, 43, 25, 75, 10, 227, 179, 180, 179, 146, 128, 57, 185, 183, 163, 145, 0, 8, 8, 10, 119, + 114, 120, 16, 210, 244, 60, 28, 41, 25, 152, 149, 56, 161, 35, 44, 89, 27, 24, 136, 24, 164, 211, 17, 233, 176, 136, 192, 129, 179, 17, 17, 25, 0, 10, 46, 160, 132, 49, 66, 24, 132, 177, 147, 193, 56, 72, 26, 29, 232, 168, 176, 12, 137, 41, 139, 147, 9, 1, 41, 15, 91, 136, 35, 148, 21, 18, 48, 40, 1, 168, 167, 144, 0, 42, 172, + 177, 204, 193, 155, 232, 152, 152, 26, 152, 41, 146, 17, 6, 4, 65, 34, 35, 135, 4, 16, 32, 9, 24, 186, 176, 0, 250, 153, 204, 186, 173, 154, 153, 177, 3, 65, 41, 34, 145, 134, 35, 65, 98, 49, 50, 50, 2, 33, 169, 138, 155, 175, 170, 172, 204, 192, 138, 234, 136, 155, 136, 10, 32, 18, 5, 52, 48, 24, 162, 17, 67, 54, 66, 51, 34, + 131, 184, 174, 234, 153, 10, 9, 40, 0, 152, 251, 168, 142, 154, 9, 16, 33, 49, 33, 128, 154, 170, 156, 34, 54, 54, 33, 68, 0, 1, 136, 201, 137, 26, 88, 48, 35, 99, 8, 152, 189, 189, 187, 155, 171, 16, 24, 130, 145, 188, 175, 203, 144, 49, 115, 67, 67, 50, 19, 2, 1, 0, 0, 130, 131, 1, 136, 206, 216, 188, 203, 204, 187, 187, + 156, 153, 0, 0, 51, 17, 34, 24, 112, 20, 69, 67, 67, 34, 19, 0, 136, 169, 185, 137, 186, 232, 185, 219, 201, 203, 187, 173, 170, 154, 153, 129, 131, 6, 2, 19, 49, 49, 21, 65, 19, 53, 51, 83, 34, 16, 168, 201, 154, 172, 156, 138, 0, 1, 24, 201, 233, 186, 204, 186, 171, 137, 3, 37, 48, 24, 128, 201, 202, 202, 129, 17, 48, 21, + 22, 20, 19, 19, 32, 16, 2, 66, 52, 68, 4, 3, 1, 203, 235, 188, 189, 186, 171, 153, 137, 153, 170, 219, 170, 140, 9, 17, 53, 115, 50, 52, 67, 51, 51, 51, 17, 130, 0, 145, 154, 169, 188, 236, 187, 190, 203, 187, 172, 171, 138, 136, 17, 33, 18, 2, 34, 98, 98, 50, 50, 52, 66, 34, 35, 2, 19, 24, 169, 203, 203, 188, 219, 169, 154, + 9, 137, 171, 204, 188, 203, 184, 136, 34, 83, 50, 33, 153, 184, 170, 170, 152, 40, 57, 19, 36, 50, 50, 18, 35, 17, 2, 49, 49, 66, 66, 66, 34, 17, 168, 233, 202, 202, 170, 171, 170, 186, 219, 203, 188, 188, 154, 138, 25, 33, 68, 52, 68, 67, 67, 36, 51, 36, 18, 17, 17, 136, 8, 170, 176, 202, 188, 206, 202, 171, 172, 186, 169, + 153, 8, 25, 144, 128, 1, 34, 68, 52, 68, 51, 52, 34, 49, 18, 34, 2, 144, 136, 155, 140, 187, 186, 186, 154, 154, 185, 185, 153, 9, 9, 0, 24, 0, 128, 144, 168, 169, 170, 154, 154, 153, 9, 8, 16, 8, 0, 144, 19, 35, 68, 51, 52, 67, 51, 66, 34, 50, 33, 1, 144, 185, 186, 172, 204, 187, 188, 173, 172, 186, 172, 186, 154, 138, 41, + 33, 52, 53, 83, 50, 51, 52, 52, 37, 34, 34, 18, 16, 144, 152, 154, 187, 219, 203, 188, 173, 186, 186, 186, 170, 154, 153, 138, 144, 16, 17, 67, 82, 50, 51, 21, 34, 19, 33, 2, 18, 33, 1, 8, 153, 169, 153, 153, 136, 128, 0, 136, 154, 153, 153, 8, 8, 1, 16, 0, 169, 170, 187, 171, 171, 154, 153, 153, 152, 153, 153, 0, 16, 51, 83, + 66, 50, 67, 50, 51, 67, 51, 52, 35, 18, 136, 186, 219, 187, 189, 186, 171, 187, 173, 187, 188, 187, 203, 138, 9, 16, 33, 50, 52, 53, 67, 67, 147, 8, 128, 128, 128, 128, 128, 128, 128, 128, 0, 240, 255, 55, 232, 23, 220, 0, 148, 1, 9, 18, 148, 10, 189, 32, 163, 62, 160, 5, 137, 12, 149, 42, 153, 144, 34, 42, 8, 1, 138, 181, + 45, 136, 18, 144, 105, 138, 1, 160, 14, 128, 132, 145, 186, 37, 138, 41, 192, 48, 145, 46, 160, 33, 44, 24, 225, 16, 13, 132, 136, 137, 16, 148, 25, 170, 194, 82, 152, 136, 91, 24, 42, 169, 33, 233, 131, 179, 24, 185, 149, 16, 57, 172, 164, 18, 10, 211, 160, 147, 211, 33, 138, 243, 129, 16, 41, 193, 0, 43, 132, 155, 73, + 58, 145, 244, 145, 43, 35, 9, 171, 16, 110, 25, 8, 28, 74, 162, 128, 26, 27, 82, 45, 136, 153, 18, 8, 136, 8 +}; + +TownsPC98_FmSynth::ChanInternal::ChanInternal() { + memset(this, 0, sizeof(ChanInternal)); +} + +TownsPC98_FmSynth::ChanInternal::~ChanInternal() { + for (uint i = 0; i < ARRAYSIZE(opr); ++i) + delete opr[i]; +} diff --git a/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h new file mode 100644 index 0000000000..34ee2ce7b8 --- /dev/null +++ b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h @@ -0,0 +1,176 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef TOWNS_PC98_FMSYNTH_H +#define TOWNS_PC98_FMSYNTH_H + +#include "sound/audiostream.h" +#include "sound/mixer.h" +#include "common/list.h" + +class TownsPC98_FmSynthOperator; +class TownsPC98_FmSynthSquareSineSource; +class TownsPC98_FmSynthPercussionSource; + +enum EnvelopeState { + kEnvReady, + kEnvAttacking, + kEnvDecaying, + kEnvSustaining, + kEnvReleasing +}; + +class TownsPC98_FmSynth : public Audio::AudioStream { +public: + enum EmuType { + kTypeTowns, + kType26, + kType86 + }; + + TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type); + virtual ~TownsPC98_FmSynth(); + + virtual bool init(); + virtual void reset(); + + void writeReg(uint8 part, uint8 regAddress, uint8 value); + + // AudioStream interface + int readBuffer(int16 *buffer, const int numSamples); + bool isStereo() const { + return true; + } + bool endOfData() const { + return false; + } + int getRate() const { + return _mixer->getOutputRate(); + } + +protected: + // Implement this in your inherited class if your driver generates + // additional output that has to be inserted into the buffer. + virtual void nextTickEx(int32 *buffer, uint32 bufferSize) {} + + void toggleRegProtection(bool prot) { + _regProtectionFlag = prot; + } + uint8 readSSGStatus(); + + virtual void timerCallbackA() = 0; + virtual void timerCallbackB() = 0; + + // The audio driver can store and apply two different audio settings + // (usually for music and sound effects). The channel mask will determine + // which channels get effected by the setting. The first bits will be + // the normal fm channels, the next bits the ssg channels and the final + // bit the rhythm channel. + void setVolumeIntern(int volA, int volB); + void setVolumeChannelMasks(int channelMaskA, int channelMaskB); + + const int _numChan; + const int _numSSG; + const bool _hasPercussion; + + Common::Mutex _mutex; +private: + void generateTables(); + void nextTick(int32 *buffer, uint32 bufferSize); + void generateOutput(int32 &leftSample, int32 &rightSample, int32 *del, int32 *feed); + + struct ChanInternal { + ChanInternal(); + ~ChanInternal(); + + void ampModSensitivity(uint32 value) { + ampModSvty = (1 << (3 - value)) - (((value >> 1) & 1) | (value & 1)); + } + void frqModSensitivity(uint32 value) { + frqModSvty = value << 5; + } + + uint16 frqTemp; + bool enableLeft; + bool enableRight; + bool updateEnvelopeParameters; + int32 feedbuf[3]; + uint8 algorithm; + + uint32 ampModSvty; + uint32 frqModSvty; + + TownsPC98_FmSynthOperator *opr[4]; + }; + + TownsPC98_FmSynthSquareSineSource *_ssg; + TownsPC98_FmSynthPercussionSource *_prc; + ChanInternal *_chanInternal; + + uint8 *_oprRates; + uint8 *_oprRateshift; + uint8 *_oprAttackDecay; + uint32 *_oprFrq; + uint32 *_oprSinTbl; + int32 *_oprLevelOut; + int32 *_oprDetune; + + bool _regProtectionFlag; + + typedef void (TownsPC98_FmSynth::*ChipTimerProc)(); + + struct ChipTimer { + bool enabled; + uint16 value; + + int32 smpTillCb; + uint32 smpTillCbRem; + int32 smpPerCb; + uint32 smpPerCbRem; + + ChipTimerProc cb; + }; + + ChipTimer _timers[2]; + + int _volMaskA, _volMaskB; + uint16 _volumeA, _volumeB; + + const float _baserate; + uint32 _timerbase; + + Audio::Mixer *_mixer; + Audio::SoundHandle _soundHandle; + + static const uint8 _percussionData[]; + static const uint32 _adtStat[]; + static const uint8 _detSrc[]; + static const int _ssgTables[]; + + bool _ready; +}; + +#endif + diff --git a/sound/softsynth/sid.cpp b/sound/softsynth/sid.cpp index d600ac28f5..e925f4a447 100644 --- a/sound/softsynth/sid.cpp +++ b/sound/softsynth/sid.cpp @@ -46,11 +46,6 @@ const int SID::FIXP_MASK = 0xffff; WaveformGenerator::WaveformGenerator() { sync_source = this; - wave__ST = wave6581__ST; - wave_P_T = wave6581_P_T; - wave_PS_ = wave6581_PS_; - wave_PST = wave6581_PST; - reset(); } @@ -226,19 +221,19 @@ RESID_INLINE reg12 WaveformGenerator::outputN___() { // Combined waveforms: RESID_INLINE reg12 WaveformGenerator::output__ST() { - return wave__ST[output__S_()] << 4; + return wave6581__ST[output__S_()] << 4; } RESID_INLINE reg12 WaveformGenerator::output_P_T() { - return (wave_P_T[output___T() >> 1] << 4) & output_P__(); + return (wave6581_P_T[output___T() >> 1] << 4) & output_P__(); } RESID_INLINE reg12 WaveformGenerator::output_PS_() { - return (wave_PS_[output__S_()] << 4) & output_P__(); + return (wave6581_PS_[output__S_()] << 4) & output_P__(); } RESID_INLINE reg12 WaveformGenerator::output_PST() { - return (wave_PST[output__S_()] << 4) & output_P__(); + return (wave6581_PST[output__S_()] << 4) & output_P__(); } // Combined waveforms including noise: diff --git a/sound/softsynth/sid.h b/sound/softsynth/sid.h index d57ec73bad..c78f538441 100644 --- a/sound/softsynth/sid.h +++ b/sound/softsynth/sid.h @@ -118,15 +118,10 @@ protected: reg12 outputNPST(); // Sample data for combinations of waveforms. - static reg8 wave6581__ST[]; - static reg8 wave6581_P_T[]; - static reg8 wave6581_PS_[]; - static reg8 wave6581_PST[]; - - reg8* wave__ST; - reg8* wave_P_T; - reg8* wave_PS_; - reg8* wave_PST; + static const reg8 wave6581__ST[]; + static const reg8 wave6581_P_T[]; + static const reg8 wave6581_PS_[]; + static const reg8 wave6581_PST[]; friend class Voice; friend class SID; diff --git a/sound/softsynth/wave6581.cpp b/sound/softsynth/wave6581.cpp index 29998dcd0a..d1ddad1623 100644 --- a/sound/softsynth/wave6581.cpp +++ b/sound/softsynth/wave6581.cpp @@ -32,11 +32,9 @@ #include "sid.h" -namespace Resid -{ +namespace Resid { -reg8 WaveformGenerator::wave6581__ST[] = -{ +const reg8 WaveformGenerator::wave6581__ST[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -551,8 +549,7 @@ reg8 WaveformGenerator::wave6581__ST[] = /* 0xff8: */ 0x3e, 0x3e, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0x7f, }; -reg8 WaveformGenerator::wave6581_P_T[] = -{ +const reg8 WaveformGenerator::wave6581_P_T[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1067,8 +1064,7 @@ reg8 WaveformGenerator::wave6581_P_T[] = /* 0xff8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -reg8 WaveformGenerator::wave6581_PS_[] = -{ +const reg8 WaveformGenerator::wave6581_PS_[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1583,8 +1579,7 @@ reg8 WaveformGenerator::wave6581_PS_[] = /* 0xff8: */ 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, }; -reg8 WaveformGenerator::wave6581_PST[] = -{ +const reg8 WaveformGenerator::wave6581_PST[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp index c1bcbc006c..a9d1ecc721 100644 --- a/tools/create_kyradat/create_kyradat.cpp +++ b/tools/create_kyradat/create_kyradat.cpp @@ -45,7 +45,7 @@ #include <map> enum { - kKyraDatVersion = 70 + kKyraDatVersion = 71 }; const ExtractFilename extractFilenames[] = { @@ -163,6 +163,7 @@ const ExtractFilename extractFilenames[] = { { k1CreditsStrings, kTypeRawData, true }, // FM-TOWNS specific + { k1TownsMusicFadeTable, k3TypeRaw16to8, false }, { k1TownsSFXwdTable, kTypeTownsWDSfxTable, false }, { k1TownsSFXbtTable, kTypeRawData, false }, { k1TownsCDATable, kTypeRawData, false }, @@ -500,7 +501,7 @@ bool checkIndex(PAKFile &file) { void printHelp(const char *f) { printf("Usage:\n"); - printf("%s output inputfiles ...", f); + printf("%s output inputfiles ...\n", f); } bool process(PAKFile &out, const Game *g, const byte *data, const uint32 size); @@ -898,6 +899,8 @@ const char *getIdString(const int id) { return "k1GUIStrings"; case k1ConfigStrings: return "k1ConfigStrings"; + case k1TownsMusicFadeTable: + return "k1TownsMusicFadeTable"; case k1TownsSFXwdTable: return "k1TownsSFXwdTable"; case k1TownsSFXbtTable: diff --git a/tools/create_kyradat/create_kyradat.h b/tools/create_kyradat/create_kyradat.h index 435e239381..d82e16fed0 100644 --- a/tools/create_kyradat/create_kyradat.h +++ b/tools/create_kyradat/create_kyradat.h @@ -138,6 +138,7 @@ enum kExtractID { k1CreditsStrings, + k1TownsMusicFadeTable, k1TownsSFXwdTable, k1TownsSFXbtTable, k1TownsCDATable, diff --git a/tools/create_kyradat/games.cpp b/tools/create_kyradat/games.cpp index 9976451067..1bd7d31648 100644 --- a/tools/create_kyradat/games.cpp +++ b/tools/create_kyradat/games.cpp @@ -411,6 +411,8 @@ const int kyra1TownsNeed[] = { k1NewGameString, k1ConfigStrings, + k1TownsMusicFadeTable, + k1TownsMusicFadeTable, k1TownsSFXwdTable, k1TownsSFXbtTable, k1TownsCDATable, diff --git a/tools/create_kyradat/tables.cpp b/tools/create_kyradat/tables.cpp index a74f58e2c3..dc8163901d 100644 --- a/tools/create_kyradat/tables.cpp +++ b/tools/create_kyradat/tables.cpp @@ -968,6 +968,12 @@ const ExtractEntrySearchData k1ConfigStringsProvider[] = { EXTRACT_END_ENTRY }; +const ExtractEntrySearchData k1TownsMusicFadeTableProvider[] = { + { UNK_LANG, kPlatformFMTowns, { 0x00000B10, 0x000076DE, { { 0x9F, 0x08, 0x5B, 0xD6, 0x25, 0x7F, 0x11, 0x08, 0x87, 0x45, 0x92, 0xD3, 0xE5, 0xA8, 0x7C, 0x2F } } } }, + + EXTRACT_END_ENTRY +}; + const ExtractEntrySearchData k1TownsSFXwdTableProvider[] = { { UNK_LANG, kPlatformFMTowns, { 0x00012608, 0x006717A1, { { 0x34, 0xDD, 0x2D, 0xA5, 0x14, 0x05, 0xEE, 0x2F, 0x93, 0x7C, 0x78, 0x4D, 0xCA, 0x13, 0xED, 0x93 } } } }, @@ -1823,6 +1829,7 @@ const ExtractEntry extractProviders[] = { { k1SpecialPalette33, k1SpecialPalette33Provider }, { k1GUIStrings, k1GUIStringsProvider }, { k1ConfigStrings, k1ConfigStringsProvider }, + { k1TownsMusicFadeTable, k1TownsMusicFadeTableProvider }, { k1TownsSFXwdTable, k1TownsSFXwdTableProvider }, { k1TownsSFXbtTable, k1TownsSFXbtTableProvider }, { k1TownsCDATable, k1TownsCDATableProvider }, diff --git a/tools/create_msvc/create_msvc.cpp b/tools/create_msvc/create_msvc.cpp index f7dba20486..384534e547 100644 --- a/tools/create_msvc/create_msvc.cpp +++ b/tools/create_msvc/create_msvc.cpp @@ -1669,7 +1669,7 @@ void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int b "\t\tName=\"VCCLCompilerTool\"\n" "\t\tDisableLanguageExtensions=\"true\"\n" "\t\tDisableSpecificWarnings=\"" << _globalWarnings << "\"\n" - "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;%(SCUMMVM_LIBS)\\include\"\n" + "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;$(SCUMMVM_LIBS)\\include\"\n" "\t\tPreprocessorDefinitions=\"" << defines << "\"\n" "\t\tExceptionHandling=\"0\"\n" "\t\tRuntimeTypeInfo=\"false\"\n" @@ -1686,7 +1686,7 @@ void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int b "\t\tIgnoreDefaultLibraryNames=\"\"\n" "\t\tSubSystem=\"1\"\n" "\t\tEntryPointSymbol=\"WinMainCRTStartup\"\n" - "\t\tAdditionalLibraryDirectories=\"%(SCUMMVM_LIBS)\\libs\\" << (isWin32 ? "x86" : "x64") << "\"\n" + "\t\tAdditionalLibraryDirectories=\"$(SCUMMVM_LIBS)\\libs\\" << (isWin32 ? "x86" : "x64") << "\"\n" "\t/>\n" "\t<Tool\n" "\t\tName=\"VCResourceCompilerTool\"\n" diff --git a/tools/credits.pl b/tools/credits.pl index cf9becc9b5..f59c68021a 100755 --- a/tools/credits.pl +++ b/tools/credits.pl @@ -875,6 +875,12 @@ begin_credits("Credits"); begin_section("Russian"); add_person("Eugene Sandulenko", "sev", ""); end_section(); + begin_section("Spanish"); + add_person("Tomás Maidagan", "Truido", ""); + end_section(); + begin_section("Ukrainian"); + add_person("Lubomyr Lisen", "", ""); + end_section(); end_section(); begin_section("Websites (design)"); diff --git a/tools/po2c b/tools/po2c index 9dbc5e0fb7..10e15338c7 100755 --- a/tools/po2c +++ b/tools/po2c @@ -161,19 +161,29 @@ foreach my $l (keys(%msgs)) print "struct PoLangEntry {\n"; print "\tconst char *lang;\n"; print "\tconst char *charset;\n"; +print "\tconst char *langname;\n"; print "\tconst PoMessageEntry *msgs;\n"; print "};\n\n"; print "const PoLangEntry _translations[] = {\n"; foreach my $l (keys(%msgs)) { + # charset $header = $msgs{$l}->{""}; $header =~ /charset=([^\\]+)/; $charset = $1; - print "\t{ \"" . $l . "\", \"" . $charset . "\", _translation_${l} },\n"; + # user readable language name + $lang = "NULL"; + $header = $msgs{$l}->{""}; + $header =~ /Language:[\s]*([^\\]*)/; + unless ($1 eq "") + { + $lang = "\"" . $1 . "\""; + } + print "\t{ \"" . $l . "\", \"" . $charset . "\", " . $lang . ", _translation_${l} },\n"; } -print "\t{ NULL, NULL, NULL }\n};\n\n"; +print "\t{ NULL, NULL, NULL, NULL }\n};\n\n"; print "// code\n"; print << 'EOF'; @@ -255,6 +265,13 @@ const char *po2c_getlang(const int num) { assert(num < ARRAYSIZE(_translations)); return _translations[num].lang; } + +const char *po2c_getlangname(const int num) { + assert(num < ARRAYSIZE(_translations)); + if (_translations[num].langname != NULL) + return _translations[num].langname; + return _translations[num].lang; +} EOF exit 0; |