diff options
349 files changed, 11860 insertions, 5624 deletions
diff --git a/.gitignore b/.gitignore index b834214a00..a74f45bec0 100644 --- a/.gitignore +++ b/.gitignore @@ -93,6 +93,7 @@ project.xcworkspace /dists/msvc*/*.SAV /dists/msvc*/*.dat /dists/msvc*/*.dll +/dists/msvc*/test_runner.cpp /doc/*.aux /doc/*.dvi @@ -161,6 +162,10 @@ ipch/ #Ignore default Visual Studio build folders [Dd]ebug/ [Rr]elease/ +[Dd]ebug32/ +[Rr]elease32/ +[Dd]ebug64/ +[Rr]elease64/ #Ignore Qt Creator project files ScummVM.config @@ -238,9 +238,6 @@ ScummVM Team Andre Heider Angus Lees - BADA: - Chris Warren-Smith - Dreamcast: Marcus Comstedt @@ -288,6 +285,9 @@ ScummVM Team Jurgen Braam Lars Persson + Tizen / BADA: + Chris Warren-Smith + WebOS: Klaus Reimer @@ -32,8 +32,10 @@ ifeq "$(HAVE_GCC)" "1" # being helpful. #CXXFLAGS+= -Wmissing-format-attribute - # Disable RTTI and exceptions +ifneq "$(BACKEND)" "tizen" + # Disable RTTI and exceptions. These settings cause tizen apps to crash CXXFLAGS+= -fno-rtti -fno-exceptions +endif ifneq "$(HAVE_CLANG)" "1" # enable checking of pointers returned by "new", but only when we do not @@ -44,6 +46,11 @@ endif ifeq "$(HAVE_CLANG)" "1" CXXFLAGS+= -Wno-conversion -Wno-shorten-64-to-32 -Wno-sign-compare -Wno-four-char-constants + # We use a anonymous nested type declaration in an anonymous union in + # common/str.h. This is no standard construct and clang warns about it. + # It works for all our target systems though, thus we simply disable that + # warning. + CXXFLAGS+= -Wno-nested-anon-types endif ifeq "$(HAVE_ICC)" "1" @@ -2,7 +2,14 @@ For a more comprehensive changelog of the latest experimental code, see: https://github.com/scummvm/scummvm/commits/ 1.7.0 (????-??-??) + Gob: + - Improved video quality in Urban Runner + + Broken Sword 1: + - Added back support for MPEG-2 videos + Broken Sword 2: + - Added back support for MPEG-2 videos 1.6.0 (2013-05-31) New Games: diff --git a/audio/mixer.cpp b/audio/mixer.cpp index 8ff364b98d..9e6e4596e2 100644 --- a/audio/mixer.cpp +++ b/audio/mixer.cpp @@ -20,6 +20,8 @@ * */ +#include "gui/EventRecorder.h" + #include "common/util.h" #include "common/system.h" #include "common/textconsole.h" @@ -427,6 +429,11 @@ void MixerImpl::pauseHandle(SoundHandle handle, bool paused) { bool MixerImpl::isSoundIDActive(int id) { Common::StackLock lock(_mutex); + +#ifdef ENABLE_EVENTRECORDER + g_eventRec.updateSubsystems(); +#endif + for (int i = 0; i != NUM_CHANNELS; i++) if (_channels[i] && _channels[i]->getId() == id) return true; @@ -443,6 +450,11 @@ int MixerImpl::getSoundID(SoundHandle handle) { bool MixerImpl::isSoundHandleActive(SoundHandle handle) { Common::StackLock lock(_mutex); + +#ifdef ENABLE_EVENTRECORDER + g_eventRec.updateSubsystems(); +#endif + const int index = handle._val % NUM_CHANNELS; return _channels[index] && _channels[index]->getHandle()._val == handle._val; } @@ -556,12 +568,12 @@ void Channel::pause(bool paused) { _pauseLevel++; if (_pauseLevel == 1) - _pauseStartTime = g_system->getMillis(); + _pauseStartTime = g_system->getMillis(true); } else if (_pauseLevel > 0) { _pauseLevel--; if (!_pauseLevel) { - _pauseTime = (g_system->getMillis() - _pauseStartTime); + _pauseTime = (g_system->getMillis(true) - _pauseStartTime); _pauseStartTime = 0; } } @@ -579,7 +591,7 @@ Timestamp Channel::getElapsedTime() { if (isPaused()) delta = _pauseStartTime - _mixerTimeStamp; else - delta = g_system->getMillis() - _mixerTimeStamp - _pauseTime; + delta = g_system->getMillis(true) - _mixerTimeStamp - _pauseTime; // Convert the number of samples into a time duration. @@ -599,13 +611,12 @@ int Channel::mix(int16 *data, uint len) { assert(_stream); int res = 0; - if (_stream->endOfData()) { // TODO: call drain method } else { assert(_converter); _samplesConsumed = _samplesDecoded; - _mixerTimeStamp = g_system->getMillis(); + _mixerTimeStamp = g_system->getMillis(true); _pauseTime = 0; res = _converter->flow(*_stream, data, len, _volL, _volR); _samplesDecoded += res; diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp index 518e260175..efcf1be615 100644 --- a/audio/softsynth/fluidsynth.cpp +++ b/audio/softsynth/fluidsynth.cpp @@ -163,7 +163,7 @@ int MidiDriver_FluidSynth::open() { Common::String interpolation = ConfMan.get("fluidsynth_misc_interpolation"); int interpMethod = FLUID_INTERP_4THORDER; - + if (interpolation == "none") { interpMethod = FLUID_INTERP_NONE; } else if (interpolation == "linear") { diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp index 00d0469356..29f5e3577c 100644 --- a/audio/softsynth/mt32.cpp +++ b/audio/softsynth/mt32.cpp @@ -62,7 +62,8 @@ protected: // Callback for debug messages, in vprintf() format void printDebug(const char *fmt, va_list list) { - debug(4, fmt, list); + Common::String out = Common::String::vformat(fmt, list); + debug(4, "%s", out.c_str()); } // Callbacks for reporting various errors and information diff --git a/audio/softsynth/mt32/Part.cpp b/audio/softsynth/mt32/Part.cpp index 62ba346c35..88404316eb 100644 --- a/audio/softsynth/mt32/Part.cpp +++ b/audio/softsynth/mt32/Part.cpp @@ -175,6 +175,7 @@ void Part::refresh() { patchCache[t].reverb = patchTemp->patch.reverbSwitch > 0; } memcpy(currentInstr, timbreTemp->common.name, 10); + synth->newTimbreSet(partNum, patchTemp->patch.timbreGroup, currentInstr); updatePitchBenderRange(); } @@ -207,7 +208,6 @@ void RhythmPart::setTimbre(TimbreParam * /*timbre*/) { void Part::setTimbre(TimbreParam *timbre) { *timbreTemp = *timbre; - synth->newTimbreSet(partNum, timbre->common.name); } unsigned int RhythmPart::getAbsTimbreNum() const { @@ -533,7 +533,6 @@ void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhyt #if MT32EMU_MONITOR_PARTIALS > 1 synth->printPartialUsage(); #endif - synth->partStateChanged(partNum, true); synth->polyStateChanged(partNum); } @@ -614,9 +613,6 @@ void Part::partialDeactivated(Poly *poly) { freePolys.prepend(poly); synth->polyStateChanged(partNum); } - if (activePartialCount == 0) { - synth->partStateChanged(partNum, false); - } } //#define POLY_LIST_DEBUG diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp index a0aec90ec4..b80a028515 100644 --- a/audio/softsynth/mt32/Partial.cpp +++ b/audio/softsynth/mt32/Partial.cpp @@ -87,7 +87,6 @@ void Partial::deactivate() { if (poly != NULL) { poly->partialDeactivated(this); } - synth->partialStateChanged(this, tva->getPhase(), TVA_PHASE_DEAD); #if MT32EMU_MONITOR_PARTIALS > 2 synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, debugPartialNum); synth->printPartialUsage(sampleNum); diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp index b7af992b99..1e1be06bc9 100644 --- a/audio/softsynth/mt32/Synth.cpp +++ b/audio/softsynth/mt32/Synth.cpp @@ -201,25 +201,12 @@ void ReportHandler::printDebug(const char *fmt, va_list list) { printf("\n"); } -void Synth::partStateChanged(int partNum, bool isPartActive) { - reportHandler->onPartStateChanged(partNum, isPartActive); -} - void Synth::polyStateChanged(int partNum) { reportHandler->onPolyStateChanged(partNum); } -void Synth::partialStateChanged(const Partial * const partial, int oldPartialPhase, int newPartialPhase) { - for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) { - if (getPartial(i) == partial) { - reportHandler->onPartialStateChanged(i, oldPartialPhase, newPartialPhase); - break; - } - } -} - -void Synth::newTimbreSet(int partNum, char patchName[]) { - reportHandler->onProgramChanged(partNum, patchName); +void Synth::newTimbreSet(int partNum, Bit8u timbreGroup, const char patchName[]) { + reportHandler->onProgramChanged(partNum, timbreGroup, patchName); } void Synth::printDebug(const char *fmt, ...) { diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h index 56e88e6156..b85e7ae507 100644 --- a/audio/softsynth/mt32/Synth.h +++ b/audio/softsynth/mt32/Synth.h @@ -249,10 +249,10 @@ protected: virtual void onNewReverbMode(Bit8u /* mode */) {} virtual void onNewReverbTime(Bit8u /* time */) {} virtual void onNewReverbLevel(Bit8u /* level */) {} - virtual void onPartStateChanged(int /* partNum */, bool /* isActive */) {} + virtual void onPartStateChanged(int /* partNum */, bool /* hasActiveNonReleasingPolys */) {} virtual void onPolyStateChanged(int /* partNum */) {} virtual void onPartialStateChanged(int /* partialNum */, int /* oldPartialPhase */, int /* newPartialPhase */) {} - virtual void onProgramChanged(int /* partNum */, char * /* patchName */) {} + virtual void onProgramChanged(int /* partNum */, int /* bankNum */, const char * /* patchName */) {} }; class Synth { @@ -370,10 +370,8 @@ private: void printPartialUsage(unsigned long sampleOffset = 0); - void partStateChanged(int partNum, bool isPartActive); void polyStateChanged(int partNum); - void partialStateChanged(const Partial * const partial, int oldPartialPhase, int newPartialPhase); - void newTimbreSet(int partNum, char patchName[]); + void newTimbreSet(int partNum, Bit8u timbreGroup, const char patchName[]); void printDebug(const char *fmt, ...); public: diff --git a/audio/softsynth/mt32/TVA.cpp b/audio/softsynth/mt32/TVA.cpp index 65e5256048..5438471fa4 100644 --- a/audio/softsynth/mt32/TVA.cpp +++ b/audio/softsynth/mt32/TVA.cpp @@ -34,9 +34,6 @@ TVA::TVA(const Partial *usePartial, LA32Ramp *useAmpRamp) : } void TVA::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) { - if (newPhase != phase) { - partial->getSynth()->partialStateChanged(partial, phase, newPhase); - } target = newTarget; phase = newPhase; ampRamp->startRamp(newTarget, newIncrement); @@ -46,9 +43,6 @@ void TVA::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) { } void TVA::end(int newPhase) { - if (newPhase != phase) { - partial->getSynth()->partialStateChanged(partial, phase, newPhase); - } phase = newPhase; playing = false; #if MT32EMU_MONITOR_TVA >= 1 diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp index 38a0c8d46f..bf76bbc1cb 100644 --- a/backends/events/default/default-events.cpp +++ b/backends/events/default/default-events.cpp @@ -84,7 +84,8 @@ void DefaultEventManager::init() { } bool DefaultEventManager::pollEvent(Common::Event &event) { - uint32 time = g_system->getMillis(); + // Skip recording of these events + uint32 time = g_system->getMillis(true); bool result = false; _dispatcher.dispatch(); diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp index 0ca5bbb059..e2ef7f6bf6 100644 --- a/backends/events/sdl/sdl-events.cpp +++ b/backends/events/sdl/sdl-events.cpp @@ -106,7 +106,9 @@ void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) { } void SdlEventSource::handleKbdMouse() { - uint32 curTime = g_system->getMillis(); + // Skip recording of these events + uint32 curTime = g_system->getMillis(true); + if (curTime >= _km.last_time + _km.delay_time) { _km.last_time = curTime; if (_km.x_down_count == 1) { diff --git a/backends/graphics/opengl/gltexture.h b/backends/graphics/opengl/gltexture.h index 8ff9838ff7..6ef80923ae 100644 --- a/backends/graphics/opengl/gltexture.h +++ b/backends/graphics/opengl/gltexture.h @@ -44,9 +44,9 @@ #define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0]))) #endif -#if defined(BADA) +#if defined(TIZEN) #include <FGraphicsOpengl.h> -using namespace Osp::Graphics::Opengl; +using namespace Tizen::Graphics::Opengl; #elif defined(USE_GLES) #include <GLES/gl.h> #elif defined(SDL_BACKEND) diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 02e58ab319..a2e1981e79 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -40,6 +40,7 @@ #include "graphics/scaler.h" #include "graphics/scaler/aspect.h" #include "graphics/surface.h" +#include "gui/EventRecorder.h" static const OSystem::GraphicsMode s_supportedGraphicsModes[] = { {"1x", _s("Normal (no scaling)"), GFX_NORMAL}, @@ -135,6 +136,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou _paletteDirtyStart(0), _paletteDirtyEnd(0), _screenIsLocked(false), _graphicsMutex(0), + _displayDisabled(false), #ifdef USE_SDL_DEBUG_FOCUSRECT _enableFocusRectDebugCode(false), _enableFocusRect(false), _focusRect(), #endif @@ -765,9 +767,20 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() { fixupResolutionForAspectRatio(_videoMode.desiredAspectRatio, _videoMode.hardwareWidth, _videoMode.hardwareHeight); } - _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16, - _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE - ); + +#ifdef ENABLE_EVENTRECORDER + _displayDisabled = ConfMan.getBool("disable_display"); + + if (_displayDisabled) { + _hwscreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight); + } else +#endif + { + _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16, + _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE + ); + } + #ifdef USE_RGB_COLOR detectSupportedFormats(); #endif @@ -1188,7 +1201,9 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() { #endif // Finally, blit all our changes to the screen - SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); + if (!_displayDisabled) { + SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); + } } _numDirtyRects = 0; diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index 21444cc25d..97de0f9c97 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -232,6 +232,9 @@ protected: int _scalerType; int _transactionMode; + // Indicates whether it is needed to free _hwsurface in destructor + bool _displayDisabled; + bool _screenIsLocked; Graphics::Surface _framebuffer; diff --git a/backends/mixer/nullmixer/nullsdl-mixer.cpp b/backends/mixer/nullmixer/nullsdl-mixer.cpp new file mode 100644 index 0000000000..2fd652e19f --- /dev/null +++ b/backends/mixer/nullmixer/nullsdl-mixer.cpp @@ -0,0 +1,75 @@ +/* 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. + * + */ + +#include "backends/mixer/nullmixer/nullsdl-mixer.h" +#include "common/savefile.h" + +NullSdlMixerManager::NullSdlMixerManager() : SdlMixerManager() { + _outputRate = 22050; + _callsCounter = 0; + _callbackPeriod = 10; + _samples = 8192; + while (_samples * 16 > _outputRate * 2) + _samples >>= 1; + _samplesBuf = new uint8[_samples * 4]; +} + +NullSdlMixerManager::~NullSdlMixerManager() { + delete _samplesBuf; +} + +void NullSdlMixerManager::init() { + _mixer = new Audio::MixerImpl(g_system, _outputRate); + assert(_mixer); + _mixer->setReady(true); +} + +void NullSdlMixerManager::suspendAudio() { + _audioSuspended = true; +} + +int NullSdlMixerManager::resumeAudio() { + if (!_audioSuspended) { + return -2; + } + _audioSuspended = false; + return 0; +} + + +void NullSdlMixerManager::startAudio() { +} + +void NullSdlMixerManager::callbackHandler(byte *samples, int len) { + assert(_mixer); + _mixer->mixCallback(samples, len); +} + +void NullSdlMixerManager::update() { + if (_audioSuspended) { + return; + } + _callsCounter++; + if ((_callsCounter % _callbackPeriod) == 0) { + callbackHandler(_samplesBuf, _samples); + } +} diff --git a/backends/mixer/nullmixer/nullsdl-mixer.h b/backends/mixer/nullmixer/nullsdl-mixer.h new file mode 100644 index 0000000000..94248ced66 --- /dev/null +++ b/backends/mixer/nullmixer/nullsdl-mixer.h @@ -0,0 +1,62 @@ +/* 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. + * + */ + +#ifndef BACKENDS_MIXER_NULLSDL_H +#define BACKENDS_MIXER_NULLSDL_H + +#include "backends/mixer/sdl/sdl-mixer.h" +#include "common/str.h" + +/** Audio mixer which in fact does not output audio. + * + * It is used by events recorder since the recorder is intentionally + * turning sound off to avoid stuttering. + * + * It returns correct output and shoots callbacks, so all OSystem + * users could work without modifications. + */ + +class NullSdlMixerManager : public SdlMixerManager { +public: + NullSdlMixerManager(); + virtual ~NullSdlMixerManager(); + + virtual void init(); + void update(); + + virtual void suspendAudio(); + virtual int resumeAudio(); + +protected: + + virtual void startAudio(); + virtual void callbackHandler(byte *samples, int len); + +private: + uint32 _outputRate; + uint32 _callsCounter; + uint8 _callbackPeriod; + uint32 _samples; + uint8 *_samplesBuf; +}; + +#endif diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp index b46f33a2bc..6afe06aeca 100644 --- a/backends/modular-backend.cpp +++ b/backends/modular-backend.cpp @@ -26,6 +26,7 @@ #include "backends/graphics/graphics.h" #include "backends/mutex/mutex.h" +#include "gui/EventRecorder.h" #include "audio/mixer.h" #include "graphics/pixelformat.h" @@ -52,7 +53,7 @@ bool ModularBackend::hasFeature(Feature f) { } void ModularBackend::setFeatureState(Feature f, bool enable) { - return _graphicsManager->setFeatureState(f, enable); + _graphicsManager->setFeatureState(f, enable); } bool ModularBackend::getFeatureState(Feature f) { @@ -141,7 +142,15 @@ void ModularBackend::fillScreen(uint32 col) { } void ModularBackend::updateScreen() { +#ifdef ENABLE_EVENTRECORDER + g_eventRec.preDrawOverlayGui(); +#endif + _graphicsManager->updateScreen(); + +#ifdef ENABLE_EVENTRECORDER + g_eventRec.postDrawOverlayGui(); +#endif } void ModularBackend::setShakePos(int shakeOffset) { diff --git a/backends/module.mk b/backends/module.mk index a4f525d21d..31ac444750 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -70,7 +70,7 @@ MODULE_OBJS += \ mutex/sdl/sdl-mutex.o \ plugins/sdl/sdl-provider.o \ timer/sdl/sdl-timer.o - + # SDL 1.3 removed audio CD support ifndef USE_SDL13 MODULE_OBJS += \ @@ -120,9 +120,9 @@ MODULE_OBJS += \ mixer/sdl13/sdl13-mixer.o endif -ifeq ($(BACKEND),bada) +ifeq ($(BACKEND),tizen) MODULE_OBJS += \ - timer/bada/timer.o + timer/tizen/timer.o endif ifeq ($(BACKEND),ds) @@ -214,5 +214,11 @@ MODULE_OBJS += \ plugins/wii/wii-provider.o endif +ifdef ENABLE_EVENTRECORDER +MODULE_OBJS += \ + mixer/nullmixer/nullsdl-mixer.o \ + saves/recorder/recorder-saves.o +endif + # Include common rules include $(srcdir)/rules.mk diff --git a/backends/mutex/sdl/sdl-mutex.cpp b/backends/mutex/sdl/sdl-mutex.cpp index 8491ae468c..a51e6f0e38 100644 --- a/backends/mutex/sdl/sdl-mutex.cpp +++ b/backends/mutex/sdl/sdl-mutex.cpp @@ -33,15 +33,15 @@ OSystem::MutexRef SdlMutexManager::createMutex() { } void SdlMutexManager::lockMutex(OSystem::MutexRef mutex) { - SDL_mutexP((SDL_mutex *) mutex); + SDL_mutexP((SDL_mutex *)mutex); } void SdlMutexManager::unlockMutex(OSystem::MutexRef mutex) { - SDL_mutexV((SDL_mutex *) mutex); + SDL_mutexV((SDL_mutex *)mutex); } void SdlMutexManager::deleteMutex(OSystem::MutexRef mutex) { - SDL_DestroyMutex((SDL_mutex *) mutex); + SDL_DestroyMutex((SDL_mutex *)mutex); } #endif diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp index f06e4be19e..ad80ea7f8c 100644 --- a/backends/platform/android/android.cpp +++ b/backends/platform/android/android.cpp @@ -450,7 +450,7 @@ bool OSystem_Android::getFeatureState(Feature f) { } } -uint32 OSystem_Android::getMillis() { +uint32 OSystem_Android::getMillis(bool skipRecord) { timeval curTime; gettimeofday(&curTime, 0); diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h index 5f2f40b726..b4813b3bdf 100644 --- a/backends/platform/android/android.h +++ b/backends/platform/android/android.h @@ -274,7 +274,7 @@ public: virtual void setCursorPalette(const byte *colors, uint start, uint num); virtual bool pollEvent(Common::Event &event); - virtual uint32 getMillis(); + virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); virtual MutexRef createMutex(void); diff --git a/backends/platform/bada/bada.mk b/backends/platform/bada/bada.mk deleted file mode 100644 index 7c72d7752b..0000000000 --- a/backends/platform/bada/bada.mk +++ /dev/null @@ -1,5 +0,0 @@ -# Bada specific modules are built under eclipse - -$(EXECUTABLE): $(OBJS) - rm -f $@ - ar Tru $@ $(OBJS) diff --git a/backends/platform/bada/form.cpp b/backends/platform/bada/form.cpp deleted file mode 100644 index dfa72bce08..0000000000 --- a/backends/platform/bada/form.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/* 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. - * - */ - -#include <FAppApplication.h> - -#include "common/translation.h" -#include "base/main.h" - -#include "backends/platform/bada/form.h" -#include "backends/platform/bada/system.h" - -using namespace Osp::Base::Runtime; -using namespace Osp::Ui; -using namespace Osp::Ui::Controls; - -// number of volume levels -#define LEVEL_RANGE 5 - -// round down small Y touch values to 1 to allow the -// cursor to be positioned at the top of the screen -#define MIN_TOUCH_Y 10 - -// block for up to 2.5 seconds during shutdown to -// allow the game thread to exit gracefully. -#define EXIT_SLEEP_STEP 10 -#define EXIT_SLEEP 250 - -// -// BadaAppForm -// -BadaAppForm::BadaAppForm() : - _gameThread(0), - _state(kInitState), - _buttonState(kLeftButton), - _shortcut(kSetVolume) { - _eventQueueLock = new Mutex(); - _eventQueueLock->Create(); -} - -result BadaAppForm::Construct() { - result r = Form::Construct(Controls::FORM_STYLE_NORMAL); - if (IsFailed(r)) { - return r; - } - - BadaSystem *badaSystem = NULL; - _gameThread = NULL; - - badaSystem = new BadaSystem(this); - r = badaSystem != NULL ? E_SUCCESS : E_OUT_OF_MEMORY; - - if (!IsFailed(r)) { - r = badaSystem->Construct(); - } - - if (!IsFailed(r)) { - _gameThread = new Thread(); - r = _gameThread != NULL ? E_SUCCESS : E_OUT_OF_MEMORY; - } - - if (!IsFailed(r)) { - r = _gameThread->Construct(*this); - } - - if (IsFailed(r)) { - if (badaSystem != NULL) { - delete badaSystem; - } - if (_gameThread != NULL) { - delete _gameThread; - _gameThread = NULL; - } - } else { - g_system = badaSystem; - } - - return r; -} - -BadaAppForm::~BadaAppForm() { - logEntered(); - - if (_gameThread && _state != kErrorState) { - terminate(); - - _gameThread->Stop(); - if (_state != kErrorState) { - _gameThread->Join(); - } - - delete _gameThread; - _gameThread = NULL; - } - - if (_eventQueueLock) { - delete _eventQueueLock; - _eventQueueLock = NULL; - } - - logLeaving(); -} - -// -// abort the game thread -// -void BadaAppForm::terminate() { - if (_state == kActiveState) { - ((BadaSystem *)g_system)->setMute(true); - - _eventQueueLock->Acquire(); - - Common::Event e; - e.type = Common::EVENT_QUIT; - _eventQueue.push(e); - _state = kClosingState; - - _eventQueueLock->Release(); - - // block while thread ends - AppLog("waiting for shutdown"); - for (int i = 0; i < EXIT_SLEEP_STEP && _state == kClosingState; i++) { - Thread::Sleep(EXIT_SLEEP); - } - - if (_state == kClosingState) { - // failed to terminate - Join() will freeze - _state = kErrorState; - } - } -} - -void BadaAppForm::exitSystem() { - _state = kErrorState; - - if (_gameThread) { - _gameThread->Stop(); - delete _gameThread; - _gameThread = NULL; - } -} - -result BadaAppForm::OnInitializing(void) { - logEntered(); - - SetOrientation(ORIENTATION_LANDSCAPE); - AddOrientationEventListener(*this); - AddTouchEventListener(*this); - AddKeyEventListener(*this); - - // set focus to enable receiving key events - SetFocusable(true); - SetFocus(); - - return E_SUCCESS; -} - -result BadaAppForm::OnDraw(void) { - logEntered(); - - if (g_system) { - BadaSystem *system = (BadaSystem *)g_system; - BadaGraphicsManager *graphics = system->getGraphics(); - if (graphics && graphics->isReady()) { - g_system->updateScreen(); - } - } - - return E_SUCCESS; -} - -bool BadaAppForm::pollEvent(Common::Event &event) { - bool result = false; - - _eventQueueLock->Acquire(); - if (!_eventQueue.empty()) { - event = _eventQueue.pop(); - result = true; - } - _eventQueueLock->Release(); - - return result; -} - -void BadaAppForm::pushEvent(Common::EventType type, const Point ¤tPosition) { - BadaSystem *system = (BadaSystem *)g_system; - BadaGraphicsManager *graphics = system->getGraphics(); - if (graphics) { - // graphics could be NULL at startup or when - // displaying the system error screen - Common::Event e; - e.type = type; - e.mouse.x = currentPosition.x; - e.mouse.y = currentPosition.y > MIN_TOUCH_Y ? currentPosition.y : 1; - - bool moved = graphics->moveMouse(e.mouse.x, e.mouse.y); - - _eventQueueLock->Acquire(); - - if (moved && type != Common::EVENT_MOUSEMOVE) { - Common::Event moveEvent; - moveEvent.type = Common::EVENT_MOUSEMOVE; - moveEvent.mouse = e.mouse; - _eventQueue.push(moveEvent); - } - - _eventQueue.push(e); - _eventQueueLock->Release(); - } -} - -void BadaAppForm::pushKey(Common::KeyCode keycode) { - Common::Event e; - e.synthetic = false; - e.kbd.keycode = keycode; - e.kbd.ascii = keycode; - e.kbd.flags = 0; - - _eventQueueLock->Acquire(); - - e.type = Common::EVENT_KEYDOWN; - _eventQueue.push(e); - e.type = Common::EVENT_KEYUP; - _eventQueue.push(e); - - _eventQueueLock->Release(); -} - -void BadaAppForm::OnOrientationChanged(const Control &source, - OrientationStatus orientationStatus) { - logEntered(); - if (_state == kInitState) { - _state = kActiveState; - _gameThread->Start(); - } -} - -Object *BadaAppForm::Run(void) { - scummvm_main(0, 0); - - if (_state == kActiveState) { - Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT, NULL); - } - _state = kDoneState; - return NULL; -} - -void BadaAppForm::setButtonShortcut() { - switch (_buttonState) { - case kLeftButton: - g_system->displayMessageOnOSD(_("Right Click Once")); - _buttonState = kRightButtonOnce; - break; - case kRightButtonOnce: - g_system->displayMessageOnOSD(_("Right Click")); - _buttonState = kRightButton; - break; - case kRightButton: - g_system->displayMessageOnOSD(_("Move Only")); - _buttonState = kMoveOnly; - break; - case kMoveOnly: - g_system->displayMessageOnOSD(_("Left Click")); - _buttonState = kLeftButton; - break; - } -} - -void BadaAppForm::setShortcut() { - // cycle to the next shortcut - switch (_shortcut) { - case kControlMouse: - g_system->displayMessageOnOSD(_("Escape Key")); - _shortcut = kEscapeKey; - break; - - case kEscapeKey: - g_system->displayMessageOnOSD(_("Game Menu")); - _shortcut = kGameMenu; - break; - - case kGameMenu: - g_system->displayMessageOnOSD(_("Show Keypad")); - _shortcut = kShowKeypad; - break; - - case kSetVolume: - // fallthru - - case kShowKeypad: - g_system->displayMessageOnOSD(_("Control Mouse")); - _shortcut = kControlMouse; - break; - } -} - -void BadaAppForm::setVolume(bool up, bool minMax) { - int level = ((BadaSystem *)g_system)->setVolume(up, minMax); - if (level != -1) { - char message[32]; - char ind[LEVEL_RANGE]; // 1..5 (0=off) - int j = LEVEL_RANGE - 1; // 0..4 - for (int i = 1; i <= LEVEL_RANGE; i++) { - ind[j--] = level >= i ? '|' : ' '; - } - snprintf(message, sizeof(message), "Volume: [ %c%c%c%c%c ]", - ind[0], ind[1], ind[2], ind[3], ind[4]); - g_system->displayMessageOnOSD(message); - } -} - -void BadaAppForm::showKeypad() { - // display the soft keyboard - _buttonState = kLeftButton; - pushKey(Common::KEYCODE_F7); -} - -void BadaAppForm::OnTouchDoublePressed(const Control &source, - const Point ¤tPosition, - const TouchEventInfo &touchInfo) { - if (_buttonState != kMoveOnly) { - pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN, - currentPosition); - pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN, - currentPosition); - } -} - -void BadaAppForm::OnTouchFocusIn(const Control &source, - const Point ¤tPosition, - const TouchEventInfo &touchInfo) { -} - -void BadaAppForm::OnTouchFocusOut(const Control &source, - const Point ¤tPosition, - const TouchEventInfo &touchInfo) { -} - -void BadaAppForm::OnTouchLongPressed(const Control &source, - const Point ¤tPosition, - const TouchEventInfo &touchInfo) { - if (_buttonState != kLeftButton) { - pushKey(Common::KEYCODE_RETURN); - } -} - -void BadaAppForm::OnTouchMoved(const Control &source, - const Point ¤tPosition, - const TouchEventInfo &touchInfo) { - pushEvent(Common::EVENT_MOUSEMOVE, currentPosition); -} - -void BadaAppForm::OnTouchPressed(const Control &source, - const Point ¤tPosition, - const TouchEventInfo &touchInfo) { - if (_buttonState != kMoveOnly) { - pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN, - currentPosition); - } -} - -void BadaAppForm::OnTouchReleased(const Control &source, - const Point ¤tPosition, - const TouchEventInfo &touchInfo) { - if (_buttonState != kMoveOnly) { - pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONUP : Common::EVENT_RBUTTONUP, - currentPosition); - if (_buttonState == kRightButtonOnce) { - _buttonState = kLeftButton; - } - // flick to skip dialog - if (touchInfo.IsFlicked()) { - pushKey(Common::KEYCODE_PERIOD); - } - } -} - -void BadaAppForm::OnKeyLongPressed(const Control &source, KeyCode keyCode) { - logEntered(); - switch (keyCode) { - case KEY_SIDE_UP: - _shortcut = kSetVolume; - setVolume(true, true); - return; - - case KEY_SIDE_DOWN: - _shortcut = kSetVolume; - setVolume(false, true); - return; - - case KEY_CAMERA: - _shortcut = kShowKeypad; - showKeypad(); - return; - - default: - break; - } -} - -void BadaAppForm::OnKeyPressed(const Control &source, KeyCode keyCode) { - switch (keyCode) { - case KEY_SIDE_UP: - if (_shortcut != kSetVolume) { - _shortcut = kSetVolume; - } else { - setVolume(true, false); - } - return; - - case KEY_SIDE_DOWN: - switch (_shortcut) { - case kControlMouse: - setButtonShortcut(); - break; - - case kEscapeKey: - pushKey(Common::KEYCODE_ESCAPE); - break; - - case kGameMenu: - _buttonState = kLeftButton; - pushKey(Common::KEYCODE_F5); - break; - - case kShowKeypad: - showKeypad(); - break; - - default: - setVolume(false, false); - break; - } - break; - - case KEY_CAMERA: - setShortcut(); - break; - - default: - break; - } -} - -void BadaAppForm::OnKeyReleased(const Control &source, KeyCode keyCode) { -} diff --git a/backends/platform/bada/form.h b/backends/platform/bada/form.h deleted file mode 100644 index 3340e2216b..0000000000 --- a/backends/platform/bada/form.h +++ /dev/null @@ -1,108 +0,0 @@ -/* 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. - * - */ - -#ifndef BADA_FORM_H -#define BADA_FORM_H - -#include <FApp.h> -#include <FUi.h> -#include <FSystem.h> -#include <FBase.h> -#include <FUiITouchEventListener.h> -#include <FUiITextEventListener.h> - -#include "config.h" -#include "common/scummsys.h" -#include "common/events.h" -#include "common/queue.h" -#include "common/mutex.h" - -// -// BadaAppForm -// -class BadaAppForm : public Osp::Ui::Controls::Form, - public Osp::Ui::IOrientationEventListener, - public Osp::Ui::ITouchEventListener, - public Osp::Ui::IKeyEventListener, - public Osp::Base::Runtime::IRunnable { -public: - BadaAppForm(); - ~BadaAppForm(); - - result Construct(); - bool pollEvent(Common::Event &event); - bool isClosing() { return _state == kClosingState; } - void pushKey(Common::KeyCode keycode); - void exitSystem(); - -private: - Object *Run(); - result OnInitializing(void); - result OnDraw(void); - void OnOrientationChanged(const Osp::Ui::Control &source, - Osp::Ui::OrientationStatus orientationStatus); - void OnTouchDoublePressed(const Osp::Ui::Control &source, - const Osp::Graphics::Point ¤tPosition, - const Osp::Ui::TouchEventInfo &touchInfo); - void OnTouchFocusIn(const Osp::Ui::Control &source, - const Osp::Graphics::Point ¤tPosition, - const Osp::Ui::TouchEventInfo &touchInfo); - void OnTouchFocusOut(const Osp::Ui::Control &source, - const Osp::Graphics::Point ¤tPosition, - const Osp::Ui::TouchEventInfo &touchInfo); - void OnTouchLongPressed(const Osp::Ui::Control &source, - const Osp::Graphics::Point ¤tPosition, - const Osp::Ui::TouchEventInfo &touchInfo); - void OnTouchMoved(const Osp::Ui::Control &source, - const Osp::Graphics::Point ¤tPosition, - const Osp::Ui::TouchEventInfo &touchInfo); - void OnTouchPressed(const Osp::Ui::Control &source, - const Osp::Graphics::Point ¤tPosition, - const Osp::Ui::TouchEventInfo &touchInfo); - void OnTouchReleased(const Osp::Ui::Control &source, - const Osp::Graphics::Point ¤tPosition, - const Osp::Ui::TouchEventInfo &touchInfo); - void OnKeyLongPressed(const Osp::Ui::Control &source, - Osp::Ui::KeyCode keyCode); - void OnKeyPressed(const Osp::Ui::Control &source, - Osp::Ui::KeyCode keyCode); - void OnKeyReleased(const Osp::Ui::Control &source, - Osp::Ui::KeyCode keyCode); - - void pushEvent(Common::EventType type, - const Osp::Graphics::Point ¤tPosition); - void terminate(); - void setButtonShortcut(); - void setShortcut(); - void setVolume(bool up, bool minMax); - void showKeypad(); - - // event handling - Osp::Base::Runtime::Thread *_gameThread; - Osp::Base::Runtime::Mutex *_eventQueueLock; - Common::Queue<Common::Event> _eventQueue; - enum { kInitState, kActiveState, kClosingState, kDoneState, kErrorState } _state; - enum { kLeftButton, kRightButtonOnce, kRightButton, kMoveOnly } _buttonState; - enum { kControlMouse, kEscapeKey, kGameMenu, kShowKeypad, kSetVolume } _shortcut; -}; - -#endif diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h index d41839d961..d62ced02e1 100644 --- a/backends/platform/dc/dc.h +++ b/backends/platform/dc/dc.h @@ -151,7 +151,7 @@ public: void setShakePos(int shake_pos); // Get the number of milliseconds since the program was started. - uint32 getMillis(); + uint32 getMillis(bool skipRecord = false); // Delay for a specified amount of milliseconds void delayMillis(uint msecs); diff --git a/backends/platform/dc/time.cpp b/backends/platform/dc/time.cpp index 8cc3a71e8d..1e5f44ec85 100644 --- a/backends/platform/dc/time.cpp +++ b/backends/platform/dc/time.cpp @@ -26,7 +26,7 @@ #include "dc.h" -uint32 OSystem_Dreamcast::getMillis() +uint32 OSystem_Dreamcast::getMillis(bool skipRecord) { static uint32 msecs=0; static unsigned int t0=0; diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index 830c782b90..9dc66e80d7 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -2280,7 +2280,7 @@ void VBlankHandler(void) { //REG_IF = IRQ_VBLANK; } -int getMillis() { +int getMillis(bool skipRecord) { return currentTimeMillis; // return frameCount * FRAME_TIME; } diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h index ad49ae276d..5e91fae13a 100644 --- a/backends/platform/ds/arm9/source/dsmain.h +++ b/backends/platform/ds/arm9/source/dsmain.h @@ -88,7 +88,7 @@ void setGamma(int gamma); // Timers void setTimerCallback(OSystem_DS::TimerProc proc, int interval); // Setup a callback function at a regular interval -int getMillis(); // Return the current runtime in milliseconds +int getMillis(bool skipRecord = false); // Return the current runtime in milliseconds void doTimerCallback(); // Call callback function if required // Sound diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp index a4b9c842fc..2f6358d8ee 100644 --- a/backends/platform/ds/arm9/source/osystem_ds.cpp +++ b/backends/platform/ds/arm9/source/osystem_ds.cpp @@ -656,7 +656,7 @@ bool OSystem_DS::pollEvent(Common::Event &event) { return false; } -uint32 OSystem_DS::getMillis() { +uint32 OSystem_DS::getMillis(bool skipRecord) { return DS::getMillis(); } diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h index a6001da764..4550e22b2c 100644 --- a/backends/platform/ds/arm9/source/osystem_ds.h +++ b/backends/platform/ds/arm9/source/osystem_ds.h @@ -117,7 +117,7 @@ public: virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format); virtual bool pollEvent(Common::Event &event); - virtual uint32 getMillis(); + virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); virtual void getTimeAndDate(TimeDate &t) const; diff --git a/backends/platform/iphone/osys_main.cpp b/backends/platform/iphone/osys_main.cpp index ed2c886213..460d3fd2ac 100644 --- a/backends/platform/iphone/osys_main.cpp +++ b/backends/platform/iphone/osys_main.cpp @@ -166,7 +166,7 @@ void OSystem_IPHONE::suspendLoop() { _timeSuspended += getMillis() - startTime; } -uint32 OSystem_IPHONE::getMillis() { +uint32 OSystem_IPHONE::getMillis(bool skipRecord) { //printf("getMillis()\n"); struct timeval currentTime; diff --git a/backends/platform/iphone/osys_main.h b/backends/platform/iphone/osys_main.h index 037125490d..811a8ddb2e 100644 --- a/backends/platform/iphone/osys_main.h +++ b/backends/platform/iphone/osys_main.h @@ -165,7 +165,7 @@ public: virtual void setCursorPalette(const byte *colors, uint start, uint num); virtual bool pollEvent(Common::Event &event); - virtual uint32 getMillis(); + virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); virtual MutexRef createMutex(void); diff --git a/backends/platform/n64/osys_n64.h b/backends/platform/n64/osys_n64.h index bc6b3cb1a5..10138b230a 100644 --- a/backends/platform/n64/osys_n64.h +++ b/backends/platform/n64/osys_n64.h @@ -184,7 +184,7 @@ public: virtual void setCursorPalette(const byte *colors, uint start, uint num); virtual bool pollEvent(Common::Event &event); - virtual uint32 getMillis(); + virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); virtual MutexRef createMutex(void); diff --git a/backends/platform/n64/osys_n64_base.cpp b/backends/platform/n64/osys_n64_base.cpp index 1e2aca9e51..afd93f5e09 100644 --- a/backends/platform/n64/osys_n64_base.cpp +++ b/backends/platform/n64/osys_n64_base.cpp @@ -810,7 +810,7 @@ void OSystem_N64::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, return; } -uint32 OSystem_N64::getMillis() { +uint32 OSystem_N64::getMillis(bool skipRecord) { return getMilliTick(); } diff --git a/backends/platform/null/null.cpp b/backends/platform/null/null.cpp index 4690a67c55..9e05539799 100644 --- a/backends/platform/null/null.cpp +++ b/backends/platform/null/null.cpp @@ -49,7 +49,7 @@ public: virtual bool pollEvent(Common::Event &event); - virtual uint32 getMillis(); + virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); virtual void getTimeAndDate(TimeDate &t) const {} diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index 5628658381..a7d782b07c 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -571,7 +571,7 @@ void OSystem_PS2::displayMessageOnOSD(const char *msg) { printf("displayMessageOnOSD: %s\n", msg); } -uint32 OSystem_PS2::getMillis(void) { +uint32 OSystem_PS2::getMillis(bool skipRecord) { return msecCount; } diff --git a/backends/platform/ps2/systemps2.h b/backends/platform/ps2/systemps2.h index 99482d4da4..3ba40a70f9 100644 --- a/backends/platform/ps2/systemps2.h +++ b/backends/platform/ps2/systemps2.h @@ -82,7 +82,7 @@ public: virtual void warpMouse(int x, int y); virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = 0); - virtual uint32 getMillis(); + virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); virtual bool pollEvent(Common::Event &event); diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp index fb8c1c60bf..8559066e53 100644 --- a/backends/platform/psp/osys_psp.cpp +++ b/backends/platform/psp/osys_psp.cpp @@ -349,7 +349,7 @@ bool OSystem_PSP::pollEvent(Common::Event &event) { return _inputHandler.getAllInputs(event); } -uint32 OSystem_PSP::getMillis() { +uint32 OSystem_PSP::getMillis(bool skipRecord) { return PspRtc::instance().getMillis(); } diff --git a/backends/platform/psp/osys_psp.h b/backends/platform/psp/osys_psp.h index 2afdabd0fc..f4591e476d 100644 --- a/backends/platform/psp/osys_psp.h +++ b/backends/platform/psp/osys_psp.h @@ -125,7 +125,7 @@ public: bool processInput(Common::Event &event); // Time - uint32 getMillis(); + uint32 getMillis(bool skipRecord = false); void delayMillis(uint msecs); // Timer diff --git a/backends/platform/psp/rtc.cpp b/backends/platform/psp/rtc.cpp index cbbb7d3f80..4f15e45535 100644 --- a/backends/platform/psp/rtc.cpp +++ b/backends/platform/psp/rtc.cpp @@ -52,7 +52,7 @@ void PspRtc::init() { // init our starting ticks // Note that after we fill up 32 bits ie 50 days we'll loop back to 0, which may cause // unpredictable results -uint32 PspRtc::getMillis() { +uint32 PspRtc::getMillis(bool skipRecord) { uint32 ticks[2]; sceRtcGetCurrentTick((u64 *)ticks); // can introduce weird thread delays diff --git a/backends/platform/psp/rtc.h b/backends/platform/psp/rtc.h index 45885c3e66..d2689681dd 100644 --- a/backends/platform/psp/rtc.h +++ b/backends/platform/psp/rtc.h @@ -40,7 +40,7 @@ public: init(); } void init(); - uint32 getMillis(); + uint32 getMillis(bool skipRecord = false); uint32 getMicros(); }; diff --git a/backends/platform/sdl/sdl-sys.h b/backends/platform/sdl/sdl-sys.h index ca3c586e03..eccf73815d 100644 --- a/backends/platform/sdl/sdl-sys.h +++ b/backends/platform/sdl/sdl-sys.h @@ -35,8 +35,11 @@ // it with an alternate slightly less unfriendly override. #if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_FILE) #undef FILE +// Solaris has typedef __FILE FILE in several places already +#if !defined(__sun) typedef struct { int FAKE; } FAKE_FILE; #define FILE FAKE_FILE +#endif // (__sun) #endif #if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_strcasecmp) diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index d54854352d..7ab367d4a4 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -30,7 +30,7 @@ #include "backends/platform/sdl/sdl.h" #include "common/config-manager.h" -#include "common/EventRecorder.h" +#include "gui/EventRecorder.h" #include "common/taskbar.h" #include "common/textconsole.h" @@ -97,7 +97,15 @@ OSystem_SDL::~OSystem_SDL() { _audiocdManager = 0; delete _mixerManager; _mixerManager = 0; + +#ifdef ENABLE_EVENTRECORDER + // HACK HACK HACK + // This is nasty. + delete g_eventRec.getTimerManager(); +#else delete _timerManager; +#endif + _timerManager = 0; delete _mutexManager; _mutexManager = 0; @@ -131,9 +139,6 @@ void OSystem_SDL::init() { if (_mutexManager == 0) _mutexManager = new SdlMutexManager(); - if (_timerManager == 0) - _timerManager = new SdlTimerManager(); - #if defined(USE_TASKBAR) if (_taskbarManager == 0) _taskbarManager = new Common::TaskbarManager(); @@ -191,11 +196,19 @@ void OSystem_SDL::initBackend() { if (_mixerManager == 0) { _mixerManager = new SdlMixerManager(); - // Setup and start mixer _mixerManager->init(); } +#ifdef ENABLE_EVENTRECORDER + g_eventRec.registerMixerManager(_mixerManager); + + g_eventRec.registerTimerManager(new SdlTimerManager()); +#else + if (_timerManager == 0) + _timerManager = new SdlTimerManager(); +#endif + if (_audiocdManager == 0) { // Audio CD support was removed with SDL 1.3 #if SDL_VERSION_ATLEAST(1, 3, 0) @@ -466,14 +479,21 @@ void OSystem_SDL::setupIcon() { free(icon); } -uint32 OSystem_SDL::getMillis() { + +uint32 OSystem_SDL::getMillis(bool skipRecord) { uint32 millis = SDL_GetTicks(); - g_eventRec.processMillis(millis); + +#ifdef ENABLE_EVENTRECORDER + g_eventRec.processMillis(millis, skipRecord); +#endif + return millis; } void OSystem_SDL::delayMillis(uint msecs) { - if (!g_eventRec.processDelayMillis(msecs)) +#ifdef ENABLE_EVENTRECORDER + if (!g_eventRec.processDelayMillis()) +#endif SDL_Delay(msecs); } @@ -491,12 +511,25 @@ void OSystem_SDL::getTimeAndDate(TimeDate &td) const { Audio::Mixer *OSystem_SDL::getMixer() { assert(_mixerManager); - return _mixerManager->getMixer(); + return getMixerManager()->getMixer(); } SdlMixerManager *OSystem_SDL::getMixerManager() { assert(_mixerManager); + +#ifdef ENABLE_EVENTRECORDER + return g_eventRec.getMixerManager(); +#else return _mixerManager; +#endif +} + +Common::TimerManager *OSystem_SDL::getTimerManager() { +#ifdef ENABLE_EVENTRECORDER + return g_eventRec.getTimerManager(); +#else + return _timerManager; +#endif } #ifdef USE_OPENGL diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index f05207b482..840e73ff09 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -68,10 +68,11 @@ public: virtual void setWindowCaption(const char *caption); virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); - virtual uint32 getMillis(); + virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); virtual void getTimeAndDate(TimeDate &td) const; virtual Audio::Mixer *getMixer(); + virtual Common::TimerManager *getTimerManager(); protected: bool _inited; diff --git a/backends/platform/bada/README.TXT b/backends/platform/tizen/README.TXT index c4a04d5450..def3da2cce 100644 --- a/backends/platform/bada/README.TXT +++ b/backends/platform/tizen/README.TXT @@ -1,77 +1,58 @@ -Build instructions: +Build instructions (using linux) -1. Install BADA SDK (requires free registration): - - http://developer.bada.com/apis/index.do - -2. Install Cygwin: - - http://www.cygwin.com/ +1. Install the Tizen SDK - Add the following to your cygwin .bash_profile: +http://www.tizen.org - alias mmake=/cygdrive/c/MinGW/bin/mingw32-make.exe - export BADA_SDK=/cygdrive/c/bada/1.2.1 - export ARM_BIN=c:/bada/1.2.1/Tools/Toolchains/ARM/bin - export CPPFLAGS="-fpic -fshort-wchar -mcpu=cortex-a8 -mfpu=vfpv3 \ - -mfloat-abi=hard -mlittle-endian -mthumb-interwork -Wno-psabi \ - -fno-strict-aliasing -fno-short-enums" - export LDFLAGS="-nostdlib -lc-newlib -lm-newlib -LC:/bada/1.2.1/Model/Wave_LP1/Target" - #export PATH=${BADA_SDK}/Tools/Toolchains/Win32/bin:${PATH} - export PATH=${BADA_SDK}/Tools/Toolchains/ARM/bin:~/utils:${PATH} - alias gcc=${ARM_BIN}/arm-samsung-nucleuseabi-gcc.exe - alias ar=${ARM_BIN}/arm-samsung-nucleuseabi-ar.exe +To use an alternative Java SDK to run the Tizen IDE (eclipse), edit ~/.profile - The following were added to ~/utils for zlib: +export JAVA_HOME=/opt/jdk1.6.0_45 +export PATH=${PATH}:${JAVA_HOME}/bin - ar: - #!/bin/sh - ${ARM_BIN}/arm-samsung-nucleuseabi-ar.exe $* +2. Add the following to your ~/.bashrc file - gcc: - #!/bin/sh - ${ARM_BIN}/arm-samsung-nucleuseabi-gcc.exe $* +export TIZEN_SDK=${HOME}/tizen-sdk +export TIZEN_ROOTSTRAP=${TIZEN_SDK}/platforms/tizen2.1/rootstraps/tizen-device-2.1.native +export TIZEN_BIN=${TIZEN_SDK}/tools/arm-linux-gnueabi-gcc-4.5/bin +export TIZEN_LIBS=${HOME}/tizen-lib +export PATH=${PATH}:${TIZEN_BIN}:~/bin +export CHOST=arm-linux-gnueabi +export LDFLAGS="--sysroot=${TIZEN_ROOTSTRAP} -L${TIZEN_LIBS}/lib" +export CPPFLAGS="--sysroot=${TIZEN_ROOTSTRAP} -fmessage-length=0 -fPIC\ + -I${TIZEN_ROOTSTRAP}/usr/include -I${TIZEN_LIBS}/include" +export CFLAGS=${CPPFLAGS} 3. Build dependencies - zlib, libogg, libvorbis, libmad, FLAC - - see: "Building the libraries" under: + See: "Building the libraries" under: http://wiki.scummvm.org/index.php/Compiling_ScummVM/MinGW#Building_the_libraries for instructions on how to obtain these modules - 3.1 For Target-Release configure ogg and mad with: - - ./configure --host=arm-samsung-nucleuseabi --disable-shared + 3.1 zlib - when building vorbis and flac: + $ ./configure --static --prefix=${TIZEN_LIBS} + $ make && make install - ./configure --host=arm-samsung-nucleuseabi --disable-shared --with-ogg=c:/cygwin/usr/local + 3.2 freetype, libtheora, libogg, libvorbis, libmad, FLAC - 3.2 for each module, after a successful configure, add the following - to the generated config.h (gzguts.h for zlib) + $ ./configure --host=arm-linux-gnueabi --prefix=${TIZEN_LIBS} --disable-shared + $ make && make install - #undef __MINGW32__ - #undef _WIN32 - #include "c:/src/scummvm/backends/platform/bada/portdefs.h" - - 3.3 Additional post configure edits: + Note: you can ignore the ranlib errors when doing make install. - - removed -fforce-mem from the libMAD Makefile - - in libvorbis/lib/Makefile comment lines with vorbis_selftests - - edit libFLAC/Makefile ... CFLAGS = $(OGG_CFLAGS) + Modify the resulting ~/tizen-lib/bin/freetype-config file to include -lz when printing libs - Note: you can ignore the ranlib errors when doing make install. + 3.3 Linker ordering: scummvm, freetype, theoradec, vorbis, vorbisfile, mad, FLAC, ogg, z 4. Build the ScummVM base library: - ./configure --host=bada --enable-release + ./configure --host=tizen --enable-release --with-freetype2-prefix=${TIZEN_LIBS}/bin - To target the Win32 simulator: + For development: - ./configure --host=bada --enable-debug + ./configure --host=tizen --enable-verbose-build --enable-debug -5. Build the front end application using BADA-Ide: +5. Build the front end application using Tizen IDE Copy the scummvm/dists/bada folder into a clean directory outside of the scummvm package. Start the BADA IDE then @@ -90,3 +71,38 @@ HelvB14 font files: Then run the following command: $ ./ucs2any.pl 100dpi/helvB14.bdf MAPPINGS/8859-1.TXT iso8859-1 \ MAPPINGS/8859-2.TXT iso8859-2 MAPPINGS/8859-3.TXT iso8859-3 + +===================================================================== +Archived build instruction for BADA/cygwin + +1. Install BADA SDK (requires free registration): + + http://developer.bada.com/apis/index.do + +2. Install Cygwin: + + http://www.cygwin.com/ + + Add the following to your cygwin .bash_profile: + + alias mmake=/cygdrive/c/MinGW/bin/mingw32-make.exe + export BADA_SDK=/cygdrive/c/bada/1.2.1 + export ARM_BIN=c:/bada/1.2.1/Tools/Toolchains/ARM/bin + export CPPFLAGS="-fpic -fshort-wchar -mcpu=cortex-a8 -mfpu=vfpv3 \ + -mfloat-abi=hard -mlittle-endian -mthumb-interwork -Wno-psabi \ + -fno-strict-aliasing -fno-short-enums" + export LDFLAGS="-nostdlib -lc-newlib -lm-newlib -LC:/bada/1.2.1/Model/Wave_LP1/Target" + #export PATH=${BADA_SDK}/Tools/Toolchains/Win32/bin:${PATH} + export PATH=${BADA_SDK}/Tools/Toolchains/ARM/bin:~/utils:${PATH} + alias gcc=${ARM_BIN}/arm-samsung-nucleuseabi-gcc.exe + alias ar=${ARM_BIN}/arm-samsung-nucleuseabi-ar.exe + + The following were added to ~/utils for zlib: + + ar: + #!/bin/sh + ${ARM_BIN}/arm-samsung-nucleuseabi-ar.exe $* + + gcc: + #!/bin/sh + ${ARM_BIN}/arm-samsung-nucleuseabi-gcc.exe $* diff --git a/backends/platform/bada/application.cpp b/backends/platform/tizen/application.cpp index e761649245..8236ebef67 100644 --- a/backends/platform/bada/application.cpp +++ b/backends/platform/tizen/application.cpp @@ -22,43 +22,55 @@ #include "engines/engine.h" -#include "backends/platform/bada/form.h" -#include "backends/platform/bada/system.h" -#include "backends/platform/bada/application.h" +#include "backends/platform/tizen/form.h" +#include "backends/platform/tizen/system.h" +#include "backends/platform/tizen/application.h" -using namespace Osp::System; -using namespace Osp::Ui::Controls; - -Application *BadaScummVM::createInstance() { - return new BadaScummVM(); +Application *TizenScummVM::createInstance() { + logEntered(); + return new TizenScummVM(); } -BadaScummVM::BadaScummVM() : _appForm(0) { +TizenScummVM::TizenScummVM() : _appForm(0) { + logEntered(); } -BadaScummVM::~BadaScummVM() { +TizenScummVM::~TizenScummVM() { logEntered(); if (g_system) { - BadaSystem *system = (BadaSystem *)g_system; + TizenSystem *system = (TizenSystem *)g_system; system->destroyBackend(); delete system; g_system = 0; } } -bool BadaScummVM::OnAppInitializing(AppRegistry &appRegistry) { +bool TizenScummVM::OnAppInitialized(void) { + logEntered(); + _appForm->SetOrientation(Tizen::Ui::ORIENTATION_LANDSCAPE); + return true; +} + +bool TizenScummVM::OnAppWillTerminate(void) { + logEntered(); + return true; +} + +bool TizenScummVM::OnAppInitializing(AppRegistry &appRegistry) { + logEntered(); _appForm = systemStart(this); return (_appForm != NULL); } -bool BadaScummVM::OnAppTerminating(AppRegistry &appRegistry, - bool forcedTermination) { +bool TizenScummVM::OnAppTerminating(AppRegistry &appRegistry, bool forcedTermination) { logEntered(); return true; } -void BadaScummVM::OnUserEventReceivedN(RequestId requestId, - Osp::Base::Collection::IList *args) { +void TizenScummVM::OnUserEventReceivedN(RequestId requestId, IList *args) { + MessageBox messageBox; + int modalResult; + logEntered(); if (requestId == USER_MESSAGE_EXIT) { @@ -73,39 +85,56 @@ void BadaScummVM::OnUserEventReceivedN(RequestId requestId, if (!message) { message = new String("Unknown error"); } - - MessageBox messageBox; messageBox.Construct(L"Oops...", *message, MSGBOX_STYLE_OK); - int modalResult; + messageBox.ShowAndWait(modalResult); + Terminate(); + } else if (requestId == USER_MESSAGE_EXIT_ERR_CONFIG) { + // the config file was corrupted + messageBox.Construct(L"Config file corrupted", + L"Settings have been reverted, please restart.", MSGBOX_STYLE_OK); messageBox.ShowAndWait(modalResult); Terminate(); } } -void BadaScummVM::OnForeground(void) { +void TizenScummVM::OnForeground(void) { logEntered(); pauseGame(false); } -void BadaScummVM::OnBackground(void) { +void TizenScummVM::OnBackground(void) { logEntered(); pauseGame(true); } -void BadaScummVM::OnBatteryLevelChanged(BatteryLevel batteryLevel) { +void TizenScummVM::OnBatteryLevelChanged(BatteryLevel batteryLevel) { + logEntered(); } -void BadaScummVM::OnLowMemory(void) { +void TizenScummVM::OnLowMemory(void) { + logEntered(); +} + +void TizenScummVM::OnScreenOn(void) { + logEntered(); +} + +void TizenScummVM::OnScreenOff(void) { + logEntered(); +} + +void TizenScummVM::OnScreenBrightnessChanged(int brightness) { + logEntered(); } -void BadaScummVM::pauseGame(bool pause) { +void TizenScummVM::pauseGame(bool pause) { if (_appForm) { if (pause && g_engine && !g_engine->isPaused()) { _appForm->pushKey(Common::KEYCODE_SPACE); } if (g_system) { - ((BadaSystem *)g_system)->setMute(pause); + ((TizenSystem *)g_system)->setMute(pause); } } } diff --git a/backends/platform/tizen/application.h b/backends/platform/tizen/application.h new file mode 100644 index 0000000000..f18ccb175b --- /dev/null +++ b/backends/platform/tizen/application.h @@ -0,0 +1,69 @@ +/* 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. + * + */ + +#ifndef TIZEN_APPLICATION_H +#define TIZEN_APPLICATION_H + +#include <FBase.h> +#include <FApp.h> +#include <FGraphics.h> +#include <FUi.h> +#include <FSystem.h> + +#include "backends/platform/tizen/system.h" +#include "backends/platform/tizen/form.h" + +using namespace Tizen::App; +using namespace Tizen::System; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Controls; +using namespace Tizen::Base::Collection; + +class TizenScummVM : + public UiApp, + public IScreenEventListener { + +public: + TizenScummVM(); + virtual ~TizenScummVM(); + + static UiApp *createInstance(void); + + virtual bool OnAppInitializing(AppRegistry &appRegistry); + virtual bool OnAppInitialized(void); + virtual bool OnAppWillTerminate(void); + virtual bool OnAppTerminating(AppRegistry &appRegistry, bool forcedTermination = false); + virtual void OnLowMemory(void); + virtual void OnBatteryLevelChanged(BatteryLevel batteryLevel); + virtual void OnUserEventReceivedN(RequestId requestId, IList *pArgs); + virtual void OnForeground(void); + virtual void OnBackground(void); + virtual void OnScreenOn(void); + virtual void OnScreenOff(void); + virtual void OnScreenBrightnessChanged(int brightness); + +private: + void pauseGame(bool pause); + TizenAppForm *_appForm; +}; + +#endif diff --git a/backends/platform/bada/audio.cpp b/backends/platform/tizen/audio.cpp index 65a5a80fa5..313a10eaa8 100644 --- a/backends/platform/bada/audio.cpp +++ b/backends/platform/tizen/audio.cpp @@ -23,18 +23,11 @@ #include <FSysSettingInfo.h> #include <FAppAppRegistry.h> -#include "backends/platform/bada/audio.h" -#include "backends/platform/bada/system.h" +#include "backends/platform/tizen/audio.h" +#include "backends/platform/tizen/system.h" -#define TIMER_INCREMENT 10 -#define TIMER_INTERVAL 40 -#define MIN_TIMER_INTERVAL 10 -#define MAX_TIMER_INTERVAL 160 -#define INIT_LEVEL 3 -#define CONFIG_KEY L"audiovol" - -// sound level pre-sets -const int levels[] = {0, 1, 10, 45, 70, 99}; +#define TIMER_INTERVAL 10 +#define VOLUME 99 AudioThread::AudioThread() : _mixer(0), @@ -51,9 +44,7 @@ AudioThread::AudioThread() : Audio::MixerImpl *AudioThread::Construct(OSystem *system) { logEntered(); - if (IsFailed(Thread::Construct(THREAD_TYPE_EVENT_DRIVEN, - DEFAULT_STACK_SIZE, - THREAD_PRIORITY_HIGH))) { + if (IsFailed(EventDrivenThread::Construct(DEFAULT_STACK_SIZE, THREAD_PRIORITY_HIGH))) { AppLog("Failed to create AudioThread"); return NULL; } @@ -69,7 +60,7 @@ AudioThread::~AudioThread() { bool AudioThread::isSilentMode() { bool silentMode; String key(L"SilentMode"); - Osp::System::SettingInfo::GetValue(key, silentMode); + Tizen::System::SettingInfo::GetValue(key, silentMode); return silentMode; } @@ -79,59 +70,16 @@ void AudioThread::setMute(bool on) { if (on) { _timer->Cancel(); } else { - _timer->Start(_interval); - } - } -} - -int AudioThread::setVolume(bool up, bool minMax) { - int level = -1; - int numLevels = sizeof(levels) / sizeof(levels[0]); - - if (_audioOut) { - int volume = _audioOut->GetVolume(); - if (minMax) { - level = up ? numLevels - 1 : 0; - volume = levels[level]; - } else { - // adjust volume to be one of the preset values - for (int i = 0; i < numLevels && level == -1; i++) { - if (volume == levels[i]) { - level = i; - if (up) { - if (i + 1 < numLevels) { - level = i + 1; - } - } else if (i > 0) { - level = i - 1; - } - } - } - - // default to INIT_LEVEL when current not preset value - if (level == -1) { - level = INIT_LEVEL; - } - volume = levels[level]; - } - - _audioOut->SetVolume(volume); - - // remember the chosen setting - AppRegistry *registry = Application::GetInstance()->GetAppRegistry(); - if (registry) { - registry->Set(CONFIG_KEY, volume); + _timer->StartAsRepeatable(_interval); } } - return level; } bool AudioThread::OnStart(void) { logEntered(); - _audioOut = new Osp::Media::AudioOut(); - if (!_audioOut || - IsFailed(_audioOut->Construct(*this))) { + _audioOut = new Tizen::Media::AudioOut(); + if (!_audioOut || IsFailed(_audioOut->Construct(*this))) { AppLog("Failed to create AudioOut"); return false; } @@ -144,8 +92,7 @@ bool AudioThread::OnStart(void) { } if (IsFailed(_audioOut->Prepare(AUDIO_TYPE_PCM_S16_LE, - AUDIO_CHANNEL_TYPE_STEREO, - sampleRate))) { + AUDIO_CHANNEL_TYPE_STEREO, sampleRate))) { AppLog("Failed to prepare AudioOut %d", sampleRate); return false; } @@ -164,26 +111,14 @@ bool AudioThread::OnStart(void) { return false; } - if (IsFailed(_timer->Start(_interval))) { + if (IsFailed(_timer->StartAsRepeatable(_interval))) { AppLog("failed to start audio timer"); return false; } - // get the volume from the app-registry - int volume = levels[INIT_LEVEL]; - AppRegistry *registry = Application::GetInstance()->GetAppRegistry(); - if (registry) { - if (E_KEY_NOT_FOUND == registry->Get(CONFIG_KEY, volume)) { - registry->Add(CONFIG_KEY, volume); - volume = levels[INIT_LEVEL]; - } else { - AppLog("Setting volume: %d", volume); - } - } - _muted = false; _mixer->setReady(true); - _audioOut->SetVolume(isSilentMode() ? 0 : volume); + _audioOut->SetVolume(isSilentMode() ? 0 : VOLUME); _audioOut->Start(); return true; } @@ -206,20 +141,20 @@ void AudioThread::OnStop(void) { } } -void AudioThread::OnAudioOutErrorOccurred(Osp::Media::AudioOut &src, result r) { +void AudioThread::OnAudioOutErrorOccurred(Tizen::Media::AudioOut &src, result r) { logEntered(); } -void AudioThread::OnAudioOutInterrupted(Osp::Media::AudioOut &src) { +void AudioThread::OnAudioOutInterrupted(Tizen::Media::AudioOut &src) { logEntered(); } -void AudioThread::OnAudioOutReleased(Osp::Media::AudioOut &src) { +void AudioThread::OnAudioOutReleased(Tizen::Media::AudioOut &src) { logEntered(); _audioOut->Start(); } -void AudioThread::OnAudioOutBufferEndReached(Osp::Media::AudioOut &src) { +void AudioThread::OnAudioOutBufferEndReached(Tizen::Media::AudioOut &src) { if (_ready > 0) { _playing = _tail; _audioOut->WriteBuffer(_audioBuffer[_tail]); @@ -228,10 +163,6 @@ void AudioThread::OnAudioOutBufferEndReached(Osp::Media::AudioOut &src) { } else { // audio buffer empty: decrease timer inverval _playing = -1; - _interval -= TIMER_INCREMENT; - if (_interval < MIN_TIMER_INTERVAL) { - _interval = MIN_TIMER_INTERVAL; - } } } @@ -243,18 +174,8 @@ void AudioThread::OnTimerExpired(Timer &timer) { _head = (_head + 1) % NUM_AUDIO_BUFFERS; _ready++; } - } else { - // audio buffer full: increase timer inverval - _interval += TIMER_INCREMENT; - if (_interval > MAX_TIMER_INTERVAL) { - _interval = MAX_TIMER_INTERVAL; - } } - if (_ready && _playing == -1) { OnAudioOutBufferEndReached(*_audioOut); } - - _timer->Start(_interval); } - diff --git a/backends/platform/bada/audio.h b/backends/platform/tizen/audio.h index 72c537a942..8d7835042d 100644 --- a/backends/platform/bada/audio.h +++ b/backends/platform/tizen/audio.h @@ -20,8 +20,8 @@ * */ -#ifndef BADA_AUDIO_H -#define BADA_AUDIO_H +#ifndef TIZEN_AUDIO_H +#define TIZEN_AUDIO_H #include <FBase.h> #include <FMedia.h> @@ -33,17 +33,19 @@ #include "common/system.h" #include "audio/mixer_intern.h" -using namespace Osp::Base; -using namespace Osp::Base::Collection; -using namespace Osp::Base::Runtime; -using namespace Osp::Media; -using namespace Osp::Io; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Base::Runtime; +using namespace Tizen::Media; +using namespace Tizen::Io; #define NUM_AUDIO_BUFFERS 2 -class AudioThread: public Osp::Media::IAudioOutEventListener, - public Osp::Base::Runtime::ITimerEventListener, - public Osp::Base::Runtime::Thread { +class AudioThread: + public Tizen::Media::IAudioOutEventListener, + public Tizen::Base::Runtime::ITimerEventListener, + public Tizen::Base::Runtime::EventDrivenThread { + public: AudioThread(void); ~AudioThread(void); @@ -51,21 +53,20 @@ public: Audio::MixerImpl *Construct(OSystem *system); bool isSilentMode(); void setMute(bool on); - int setVolume(bool up, bool minMax); bool OnStart(void); void OnStop(void); - void OnAudioOutErrorOccurred(Osp::Media::AudioOut &src, result r); - void OnAudioOutInterrupted(Osp::Media::AudioOut &src); - void OnAudioOutReleased(Osp::Media::AudioOut &src); - void OnAudioOutBufferEndReached(Osp::Media::AudioOut &src); + void OnAudioOutErrorOccurred(Tizen::Media::AudioOut &src, result r); + void OnAudioOutInterrupted(Tizen::Media::AudioOut &src); + void OnAudioOutReleased(Tizen::Media::AudioOut &src); + void OnAudioOutBufferEndReached(Tizen::Media::AudioOut &src); void OnTimerExpired(Timer &timer); private: Audio::MixerImpl *_mixer; - Osp::Base::Runtime::Timer *_timer; - Osp::Media::AudioOut *_audioOut; - Osp::Base::ByteBuffer _audioBuffer[NUM_AUDIO_BUFFERS]; + Tizen::Base::Runtime::Timer *_timer; + Tizen::Media::AudioOut *_audioOut; + Tizen::Base::ByteBuffer _audioBuffer[NUM_AUDIO_BUFFERS]; int _head, _tail, _ready, _interval, _playing; bool _muted; }; diff --git a/backends/platform/tizen/form.cpp b/backends/platform/tizen/form.cpp new file mode 100644 index 0000000000..5050699ca9 --- /dev/null +++ b/backends/platform/tizen/form.cpp @@ -0,0 +1,419 @@ +/* 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. + * + */ + +#include <FApp.h> +#include <FSysSystemTime.h> + +#include "common/translation.h" +#include "base/main.h" + +#include "backends/platform/tizen/form.h" +#include "backends/platform/tizen/system.h" + +using namespace Tizen::Base::Collection; +using namespace Tizen::Base::Runtime; +using namespace Tizen::Ui::Controls; + +// round down small Y touch values to 1 to allow the +// cursor to be positioned at the top of the screen +#define MIN_TOUCH_Y 20 + +// block for up to 2.5 seconds during shutdown to +// allow the game thread to exit gracefully. +#define EXIT_SLEEP_STEP 10 +#define EXIT_SLEEP 250 + +// +// TizenAppForm +// +TizenAppForm::TizenAppForm() : + _gestureMode(false), + _osdMessage(NULL), + _gameThread(NULL), + _eventQueueLock(NULL), + _state(kInitState), + _buttonState(kLeftButton), + _shortcut(kShowKeypad) { +} + +result TizenAppForm::Construct() { + TizenSystem *tizenSystem = NULL; + result r = Form::Construct(FORM_STYLE_NORMAL); + if (!IsFailed(r)) { + tizenSystem = new TizenSystem(this); + r = tizenSystem != NULL ? E_SUCCESS : E_OUT_OF_MEMORY; + } + if (!IsFailed(r)) { + r = tizenSystem->Construct(); + } + if (!IsFailed(r)) { + _gameThread = new Thread(); + r = _gameThread != NULL ? E_SUCCESS : E_OUT_OF_MEMORY; + } + if (!IsFailed(r)) { + r = _gameThread->Construct(*this); + } + if (!IsFailed(r)) { + _eventQueueLock = new Mutex(); + r = _eventQueueLock != NULL ? E_SUCCESS : E_OUT_OF_MEMORY; + } + if (!IsFailed(r)) { + r = _eventQueueLock->Create(); + } + + if (!IsFailed(r)) { + g_system = tizenSystem; + } else { + AppLog("Form startup failed"); + delete tizenSystem; + delete _gameThread; + _gameThread = NULL; + } + return r; +} + +TizenAppForm::~TizenAppForm() { + logEntered(); + + if (_gameThread && _state != kErrorState) { + terminate(); + + _gameThread->Stop(); + if (_state != kErrorState) { + _gameThread->Join(); + } + + delete _gameThread; + _gameThread = NULL; + } + + delete _eventQueueLock; + _eventQueueLock = NULL; + + logLeaving(); +} + +// +// abort the game thread +// +void TizenAppForm::terminate() { + if (_state == kActiveState) { + ((TizenSystem *)g_system)->setMute(true); + + _eventQueueLock->Acquire(); + + Common::Event e; + e.type = Common::EVENT_QUIT; + _eventQueue.push(e); + _state = kClosingState; + + _eventQueueLock->Release(); + + // block while thread ends + AppLog("waiting for shutdown"); + for (int i = 0; i < EXIT_SLEEP_STEP && _state == kClosingState; i++) { + Thread::Sleep(EXIT_SLEEP); + } + + if (_state == kClosingState) { + // failed to terminate - Join() will freeze + _state = kErrorState; + } + } +} + +void TizenAppForm::exitSystem() { + _state = kErrorState; + + if (_gameThread) { + _gameThread->Stop(); + delete _gameThread; + _gameThread = NULL; + } +} + +result TizenAppForm::OnInitializing(void) { + logEntered(); + + AddOrientationEventListener(*this); + AddTouchEventListener(*this); + SetMultipointTouchEnabled(true); + + // set focus to enable receiving key events + SetEnabled(true); + SetFocusable(true); + SetFocus(); + + return E_SUCCESS; +} + +result TizenAppForm::OnDraw(void) { + logEntered(); + return E_SUCCESS; +} + +void TizenAppForm::OnOrientationChanged(const Control &source, OrientationStatus orientationStatus) { + logEntered(); + if (_state == kInitState) { + _state = kActiveState; + _gameThread->Start(); + } +} + +Tizen::Base::Object *TizenAppForm::Run() { + logEntered(); + + scummvm_main(0, 0); + if (_state == kActiveState) { + Tizen::App::Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT, NULL); + } + _state = kDoneState; + return NULL; +} + +bool TizenAppForm::pollEvent(Common::Event &event) { + bool result = false; + + _eventQueueLock->Acquire(); + if (!_eventQueue.empty()) { + event = _eventQueue.pop(); + result = true; + } + if (_osdMessage) { + TizenSystem *system = (TizenSystem *)g_system; + TizenGraphicsManager *graphics = system->getGraphics(); + if (graphics) { + graphics->displayMessageOnOSD(_osdMessage); + _osdMessage = NULL; + } + } + _eventQueueLock->Release(); + + return result; +} + +void TizenAppForm::pushEvent(Common::EventType type, const Point ¤tPosition) { + TizenSystem *system = (TizenSystem *)g_system; + TizenGraphicsManager *graphics = system->getGraphics(); + if (graphics) { + // graphics could be NULL at startup or when + // displaying the system error screen + Common::Event e; + e.type = type; + e.mouse.x = currentPosition.x; + e.mouse.y = currentPosition.y > MIN_TOUCH_Y ? currentPosition.y : 1; + + bool moved = graphics->moveMouse(e.mouse.x, e.mouse.y); + + _eventQueueLock->Acquire(); + + if (moved && type != Common::EVENT_MOUSEMOVE) { + Common::Event moveEvent; + moveEvent.type = Common::EVENT_MOUSEMOVE; + moveEvent.mouse = e.mouse; + _eventQueue.push(moveEvent); + } + + _eventQueue.push(e); + _eventQueueLock->Release(); + } +} + +void TizenAppForm::pushKey(Common::KeyCode keycode) { + if (_eventQueueLock) { + Common::Event e; + e.synthetic = false; + e.kbd.keycode = keycode; + e.kbd.ascii = keycode; + e.kbd.flags = 0; + + _eventQueueLock->Acquire(); + e.type = Common::EVENT_KEYDOWN; + _eventQueue.push(e); + e.type = Common::EVENT_KEYUP; + _eventQueue.push(e); + _eventQueueLock->Release(); + } +} + +void TizenAppForm::setButtonShortcut() { + switch (_buttonState) { + case kLeftButton: + setMessage(_s("Right Click Once")); + _buttonState = kRightButtonOnce; + break; + case kRightButtonOnce: + setMessage(_s("Right Click")); + _buttonState = kRightButton; + break; + case kRightButton: + setMessage(_s("Move Only")); + _buttonState = kMoveOnly; + break; + case kMoveOnly: + setMessage(_s("Left Click")); + _buttonState = kLeftButton; + break; + } +} + +void TizenAppForm::setMessage(const char *message) { + if (_eventQueueLock) { + _eventQueueLock->Acquire(); + _osdMessage = message; + _eventQueueLock->Release(); + } +} + +void TizenAppForm::setShortcut() { + logEntered(); + // cycle to the next shortcut + switch (_shortcut) { + case kControlMouse: + setMessage(_s("Escape Key")); + _shortcut = kEscapeKey; + break; + + case kEscapeKey: + setMessage(_s("Game Menu")); + _shortcut = kGameMenu; + break; + + case kGameMenu: + setMessage(_s("Show Keypad")); + _shortcut = kShowKeypad; + break; + + case kShowKeypad: + setMessage(_s("Control Mouse")); + _shortcut = kControlMouse; + break; + } +} + +void TizenAppForm::invokeShortcut() { + logEntered(); + switch (_shortcut) { + case kControlMouse: + setButtonShortcut(); + break; + + case kEscapeKey: + pushKey(Common::KEYCODE_ESCAPE); + break; + + case kGameMenu: + _buttonState = kLeftButton; + pushKey(Common::KEYCODE_F5); + break; + + case kShowKeypad: + showKeypad(); + break; + } +} + +void TizenAppForm::showKeypad() { + // display the soft keyboard + if (_state == kActiveState) { + _buttonState = kLeftButton; + pushKey(Common::KEYCODE_F7); + } +} + +int TizenAppForm::getTouchCount() { + Tizen::Ui::TouchEventManager *touch = Tizen::Ui::TouchEventManager::GetInstance(); + IListT<TouchEventInfo *> *touchList = touch->GetTouchInfoListN(); + int touchCount = touchList->GetCount(); + touchList->RemoveAll(); + delete touchList; + return touchCount; +} + +void TizenAppForm::OnTouchDoublePressed(const Control &source, + const Point ¤tPosition, const TouchEventInfo &touchInfo) { + if (_buttonState != kMoveOnly) { + pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN, + currentPosition); + pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN, + currentPosition); + } +} + +void TizenAppForm::OnTouchFocusIn(const Control &source, + const Point ¤tPosition, const TouchEventInfo &touchInfo) { +} + +void TizenAppForm::OnTouchFocusOut(const Control &source, + const Point ¤tPosition, const TouchEventInfo &touchInfo) { +} + +void TizenAppForm::OnTouchLongPressed(const Control &source, + const Point ¤tPosition, const TouchEventInfo &touchInfo) { + logEntered(); + if (_buttonState != kLeftButton) { + pushKey(Common::KEYCODE_RETURN); + } +} + +void TizenAppForm::OnTouchMoved(const Control &source, + const Point ¤tPosition, const TouchEventInfo &touchInfo) { + if (!_gestureMode) { + pushEvent(Common::EVENT_MOUSEMOVE, currentPosition); + } +} + +void TizenAppForm::OnTouchPressed(const Control &source, + const Point ¤tPosition, const TouchEventInfo &touchInfo) { + if (getTouchCount() > 1) { + _gestureMode = true; + } else if (_buttonState != kMoveOnly) { + pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN, + currentPosition); + } +} + +void TizenAppForm::OnTouchReleased(const Control &source, + const Point ¤tPosition, const TouchEventInfo &touchInfo) { + if (_gestureMode) { + int touchCount = getTouchCount(); + if (touchCount == 1) { + setShortcut(); + } else { + if (touchCount == 2) { + invokeShortcut(); + } + _gestureMode = false; + } + } else if (_buttonState != kMoveOnly) { + pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONUP : Common::EVENT_RBUTTONUP, + currentPosition); + if (_buttonState == kRightButtonOnce) { + _buttonState = kLeftButton; + } + // flick to skip dialog + if (touchInfo.IsFlicked()) { + pushKey(Common::KEYCODE_PERIOD); + } + } +} + diff --git a/backends/platform/tizen/form.h b/backends/platform/tizen/form.h new file mode 100644 index 0000000000..64c447d409 --- /dev/null +++ b/backends/platform/tizen/form.h @@ -0,0 +1,113 @@ +/* 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. + * + */ + +#ifndef TIZEN_FORM_H +#define TIZEN_FORM_H + +#include <FApp.h> +#include <FUi.h> +#include <FSystem.h> +#include <FBase.h> +#include <FUiITouchEventListener.h> +#include <FUiITextEventListener.h> + +#include "config.h" +#include "common/scummsys.h" +#include "common/events.h" +#include "common/queue.h" +#include "common/mutex.h" +#include "engines/engine.h" + +using namespace Tizen::Ui; +using namespace Tizen::Graphics; +using namespace Tizen::Base::Runtime; + +// +// TizenAppForm +// +class TizenAppForm : + public Controls::Form, + public IRunnable, + public IOrientationEventListener, + public ITouchEventListener { + +public: + TizenAppForm(); + virtual ~TizenAppForm(); + + result Construct(); + bool pollEvent(Common::Event &event); + bool isClosing() { return _state == kClosingState; } + bool isStarting() { return _state == kInitState; } + void pushKey(Common::KeyCode keycode); + void exitSystem(); + void showKeypad(); + +private: + Tizen::Base::Object *Run(); + result OnInitializing(void); + result OnDraw(void); + void OnOrientationChanged(const Control &source, + OrientationStatus orientationStatus); + void OnTouchDoublePressed(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + void OnTouchFocusIn(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + void OnTouchFocusOut(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + void OnTouchLongPressed(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + void OnTouchMoved(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + void OnTouchPressed(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + void OnTouchReleased(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + + void pushEvent(Common::EventType type, const Point ¤tPosition); + void terminate(); + void setButtonShortcut(); + void setMessage(const char *message); + void setShortcut(); + void invokeShortcut(); + int getTouchCount(); + bool gameActive() { return _state == kActiveState && g_engine != NULL && !g_engine->isPaused(); } + + // event handling + bool _gestureMode; + const char *_osdMessage; + Tizen::Base::Runtime::Thread *_gameThread; + Tizen::Base::Runtime::Mutex *_eventQueueLock; + Common::Queue<Common::Event> _eventQueue; + enum { kInitState, kActiveState, kClosingState, kDoneState, kErrorState } _state; + enum { kLeftButton, kRightButtonOnce, kRightButton, kMoveOnly } _buttonState; + enum { kControlMouse, kEscapeKey, kGameMenu, kShowKeypad } _shortcut; +}; + +#endif diff --git a/backends/platform/bada/fs.cpp b/backends/platform/tizen/fs.cpp index 37ca496d18..f8b32f4239 100644 --- a/backends/platform/bada/fs.cpp +++ b/backends/platform/tizen/fs.cpp @@ -20,33 +20,38 @@ */ #include "config.h" -#include "backends/platform/bada/system.h" -#include "backends/platform/bada/fs.h" +#include "common/translation.h" +#include "backends/platform/tizen/system.h" +#include "backends/platform/tizen/fs.h" + +#include <FAppApp.h> #define BUFFER_SIZE 1024 -// internal BADA paths -#define PATH_ROOT "/" -#define PATH_HOME "/Home" -#define PATH_HOME_SHARE "/Home/Share" -#define PATH_HOME_SHARE2 "/Home/Share2" -#define PATH_HOME_X "/Home/" -#define PATH_HOME_EXT "/HomeExt" -#define PATH_MEDIA "/Media" -#define PATH_CARD "/Storagecard" -#define PATH_CARD_MEDIA "/Storagecard/Media" +using namespace Tizen::App; + +// +// converts a Tizen (wchar) String into a scummVM (char) string +// +Common::String fromString(const Tizen::Base::String &in) { + ByteBuffer *buf = StringUtil::StringToUtf8N(in); + Common::String result((const char*)buf->GetPointer()); + delete buf; + return result; +} // -// BadaFileStream +// TizenFileStream // -class BadaFileStream : public Common::SeekableReadStream, - public Common::WriteStream, - public Common::NonCopyable { +class TizenFileStream : + public Common::SeekableReadStream, + public Common::WriteStream, + public Common::NonCopyable { public: - static BadaFileStream *makeFromPath(const String &path, bool writeMode); + static TizenFileStream *makeFromPath(const String &path, bool writeMode); - BadaFileStream(File *file, bool writeMode); - ~BadaFileStream(); + TizenFileStream(File *file, bool writeMode); + ~TizenFileStream(); bool err() const; void clearErr(); @@ -61,81 +66,81 @@ public: uint32 read(void *dataPtr, uint32 dataSize); private: - byte buffer[BUFFER_SIZE]; - uint32 bufferIndex; - uint32 bufferLength; - bool writeMode; - File *file; + byte _buffer[BUFFER_SIZE]; + uint32 _bufferIndex; + uint32 _bufferLength; + bool _writeMode; + File *_file; }; -BadaFileStream::BadaFileStream(File *ioFile, bool writeMode) : - bufferIndex(0), - bufferLength(0), - writeMode(writeMode), - file(ioFile) { +TizenFileStream::TizenFileStream(File *ioFile, bool writeMode) : + _bufferIndex(0), + _bufferLength(0), + _writeMode(writeMode), + _file(ioFile) { AppAssert(ioFile != 0); } -BadaFileStream::~BadaFileStream() { - if (file) { - if (writeMode) { +TizenFileStream::~TizenFileStream() { + if (_file) { + if (_writeMode) { flush(); } - delete file; + delete _file; } } -bool BadaFileStream::err() const { +bool TizenFileStream::err() const { result r = GetLastResult(); return (r != E_SUCCESS && r != E_END_OF_FILE); } -void BadaFileStream::clearErr() { +void TizenFileStream::clearErr() { SetLastResult(E_SUCCESS); } -bool BadaFileStream::eos() const { - return (bufferLength - bufferIndex == 0) && (GetLastResult() == E_END_OF_FILE); +bool TizenFileStream::eos() const { + return (_bufferLength - _bufferIndex == 0) && (GetLastResult() == E_END_OF_FILE); } -int32 BadaFileStream::pos() const { - return file->Tell() - (bufferLength - bufferIndex); +int32 TizenFileStream::pos() const { + return _file->Tell() - (_bufferLength - _bufferIndex); } -int32 BadaFileStream::size() const { - int32 oldPos = file->Tell(); - file->Seek(FILESEEKPOSITION_END, 0); +int32 TizenFileStream::size() const { + int32 oldPos = _file->Tell(); + _file->Seek(FILESEEKPOSITION_END, 0); - int32 length = file->Tell(); - SetLastResult(file->Seek(FILESEEKPOSITION_BEGIN, oldPos)); + int32 length = _file->Tell(); + SetLastResult(_file->Seek(FILESEEKPOSITION_BEGIN, oldPos)); return length; } -bool BadaFileStream::seek(int32 offs, int whence) { +bool TizenFileStream::seek(int32 offs, int whence) { bool result = false; switch (whence) { case SEEK_SET: // set from start of file - SetLastResult(file->Seek(FILESEEKPOSITION_BEGIN, offs)); + SetLastResult(_file->Seek(FILESEEKPOSITION_BEGIN, offs)); result = (E_SUCCESS == GetLastResult()); break; case SEEK_CUR: // set relative to offs - if (bufferIndex < bufferLength && bufferIndex > (uint32)-offs) { + if (_bufferIndex < _bufferLength && _bufferIndex > (uint32)-offs) { // re-position within the buffer SetLastResult(E_SUCCESS); - bufferIndex += offs; + _bufferIndex += offs; return true; } else { - offs -= (bufferLength - bufferIndex); - if (offs < 0 && file->Tell() + offs < 0) { + offs -= (_bufferLength - _bufferIndex); + if (offs < 0 && _file->Tell() + offs < 0) { // avoid negative positioning offs = 0; } if (offs != 0) { - SetLastResult(file->Seek(FILESEEKPOSITION_CURRENT, offs)); + SetLastResult(_file->Seek(FILESEEKPOSITION_CURRENT, offs)); result = (E_SUCCESS == GetLastResult()); } else { result = true; @@ -145,7 +150,7 @@ bool BadaFileStream::seek(int32 offs, int whence) { case SEEK_END: // set relative to end - positive will increase the file size - SetLastResult(file->Seek(FILESEEKPOSITION_END, offs)); + SetLastResult(_file->Seek(FILESEEKPOSITION_END, offs)); result = (E_SUCCESS == GetLastResult()); break; @@ -158,46 +163,46 @@ bool BadaFileStream::seek(int32 offs, int whence) { AppLog("seek failed"); } - bufferIndex = bufferLength = 0; + _bufferIndex = _bufferLength = 0; return result; } -uint32 BadaFileStream::read(void *ptr, uint32 len) { +uint32 TizenFileStream::read(void *ptr, uint32 len) { uint32 result = 0; if (!eos()) { - if (bufferIndex < bufferLength) { + if (_bufferIndex < _bufferLength) { // use existing buffer - uint32 available = bufferLength - bufferIndex; + uint32 available = _bufferLength - _bufferIndex; if (len <= available) { // use allocation - memcpy((byte *)ptr, &buffer[bufferIndex], len); - bufferIndex += len; + memcpy((byte *)ptr, &_buffer[_bufferIndex], len); + _bufferIndex += len; result = len; } else { // use remaining allocation - memcpy((byte *)ptr, &buffer[bufferIndex], available); + memcpy((byte *)ptr, &_buffer[_bufferIndex], available); uint32 remaining = len - available; result = available; if (remaining) { - result += file->Read(((byte *)ptr) + available, remaining); + result += _file->Read(((byte *)ptr) + available, remaining); } - bufferIndex = bufferLength = 0; + _bufferIndex = _bufferLength = 0; } } else if (len < BUFFER_SIZE) { // allocate and use buffer - bufferIndex = 0; - bufferLength = file->Read(buffer, BUFFER_SIZE); - if (bufferLength) { - if (bufferLength < len) { - len = bufferLength; + _bufferIndex = 0; + _bufferLength = _file->Read(_buffer, BUFFER_SIZE); + if (_bufferLength) { + if (_bufferLength < len) { + len = _bufferLength; } - memcpy((byte *)ptr, buffer, len); - result = bufferIndex = len; + memcpy((byte *)ptr, _buffer, len); + result = _bufferIndex = len; } } else { - result = file->Read((byte *)ptr, len); - bufferIndex = bufferLength = 0; + result = _file->Read((byte *)ptr, len); + _bufferIndex = _bufferLength = 0; } } else { AppLog("Attempted to read past EOS"); @@ -205,59 +210,77 @@ uint32 BadaFileStream::read(void *ptr, uint32 len) { return result; } -uint32 BadaFileStream::write(const void *ptr, uint32 len) { - result r = file->Write(ptr, len); +uint32 TizenFileStream::write(const void *ptr, uint32 len) { + result r = _file->Write(ptr, len); SetLastResult(r); return (r == E_SUCCESS ? len : 0); } -bool BadaFileStream::flush() { +bool TizenFileStream::flush() { logEntered(); - SetLastResult(file->Flush()); + SetLastResult(_file->Flush()); return (E_SUCCESS == GetLastResult()); } -BadaFileStream *BadaFileStream::makeFromPath(const String &path, bool writeMode) { +TizenFileStream *TizenFileStream::makeFromPath(const String &path, bool writeMode) { File *ioFile = new File(); String filePath = path; if (writeMode && (path[0] != '.' && path[0] != '/')) { - filePath.Insert(PATH_HOME_X, 0); + filePath.Insert(App::GetInstance()->GetAppDataPath() + L"/", 0); } AppLog("Open file %S", filePath.GetPointer()); - + TizenFileStream *stream; result r = ioFile->Construct(filePath, writeMode ? L"w" : L"r", writeMode); if (r == E_SUCCESS) { - return new BadaFileStream(ioFile, writeMode); + stream = new TizenFileStream(ioFile, writeMode); + } else { + AppLog("Failed to open file"); + delete ioFile; + stream = NULL; } - - AppLog("Failed to open file"); - delete ioFile; - return 0; -} - -// -// converts a bada (wchar) String into a scummVM (char) string -// -Common::String fromString(const Osp::Base::String &in) { - ByteBuffer *buf = StringUtil::StringToUtf8N(in); - Common::String result((const char*)buf->GetPointer()); - delete buf; - - return result; + return stream; } // -// BadaFilesystemNode +// TizenFilesystemNode // -BadaFilesystemNode::BadaFilesystemNode(const Common::String &nodePath) { +TizenFilesystemNode::TizenFilesystemNode(const Common::String &nodePath) { AppAssert(nodePath.size() > 0); init(nodePath); } -BadaFilesystemNode::BadaFilesystemNode(const Common::String &root, - const Common::String &nodePath) { +TizenFilesystemNode::TizenFilesystemNode(SystemPath systemPath) { + switch (systemPath) { + case kData: + _unicodePath = App::GetInstance()->GetAppDataPath(); + _displayName = _s("[ Data ]"); + break; + case kResource: + _unicodePath = App::GetInstance()->GetAppResourcePath(); + _displayName = _s("[ Resources ]"); + break; + case kSdCard: + _unicodePath = Tizen::System::Environment::GetExternalStoragePath(); + _displayName = _s("[ SDCard ]"); + break; + case kMedia: + _unicodePath = Tizen::System::Environment::GetMediaPath(); + _displayName = _s("[ Media ]"); + break; + case kShared: + _unicodePath = App::GetInstance()->GetAppSharedPath(); + _displayName = _s("[ Shared ]"); + break; + } + _path = ::fromString(_unicodePath); + _isValid = _isVirtualDir = !IsFailed(File::GetAttributes(_unicodePath, _attr)); +} + +TizenFilesystemNode::TizenFilesystemNode(const Common::String &root, const Common::String &nodePath) { + AppLog("TizenFilesystemNode '%s' '%s'", root.c_str(), nodePath.c_str()); + // Make sure the string contains no slashes AppAssert(!nodePath.contains('/')); @@ -272,71 +295,54 @@ BadaFilesystemNode::BadaFilesystemNode(const Common::String &root, init(newPath); } -void BadaFilesystemNode::init(const Common::String &nodePath) { +void TizenFilesystemNode::init(const Common::String &nodePath) { // Normalize the path (that is, remove unneeded slashes etc.) _path = Common::normalizePath(nodePath, '/'); _displayName = Common::lastPathComponent(_path, '/'); StringUtil::Utf8ToString(_path.c_str(), _unicodePath); - _isVirtualDir = (_path == PATH_ROOT || - _path == PATH_HOME || - _path == PATH_HOME_SHARE || - _path == PATH_HOME_SHARE2 || - _path == PATH_CARD); + _isVirtualDir = (_path == "/"); _isValid = _isVirtualDir || !IsFailed(File::GetAttributes(_unicodePath, _attr)); } -bool BadaFilesystemNode::exists() const { +bool TizenFilesystemNode::exists() const { return _isValid; } -bool BadaFilesystemNode::isReadable() const { +bool TizenFilesystemNode::isReadable() const { return _isVirtualDir || _isValid; } -bool BadaFilesystemNode::isDirectory() const { +bool TizenFilesystemNode::isDirectory() const { return _isVirtualDir || (_isValid && _attr.IsDirectory()); } -bool BadaFilesystemNode::isWritable() const { - bool result = (_isValid && !_isVirtualDir && !_attr.IsDirectory() && !_attr.IsReadOnly()); - if (_path == PATH_HOME || - _path == PATH_HOME_EXT || - _path == PATH_HOME_SHARE || - _path == PATH_HOME_SHARE2) { - result = true; +bool TizenFilesystemNode::isWritable() const { + bool result = (_isValid && !_attr.IsReadOnly()); + if (_unicodePath == App::GetInstance()->GetAppResourcePath()) { + result = false; } return result; } -AbstractFSNode *BadaFilesystemNode::getChild(const Common::String &n) const { +AbstractFSNode *TizenFilesystemNode::getChild(const Common::String &n) const { AppAssert(!_path.empty()); AppAssert(isDirectory()); - return new BadaFilesystemNode(_path, n); + return new TizenFilesystemNode(_path, n); } -bool BadaFilesystemNode::getChildren(AbstractFSList &myList, - ListMode mode, bool hidden) const { +bool TizenFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { AppAssert(isDirectory()); bool result = false; - if (_isVirtualDir && mode != Common::FSNode::kListFilesOnly) { - // present well known BADA file system areas - if (_path == PATH_ROOT) { - myList.push_back(new BadaFilesystemNode(PATH_HOME)); - myList.push_back(new BadaFilesystemNode(PATH_HOME_EXT)); - myList.push_back(new BadaFilesystemNode(PATH_MEDIA)); - myList.push_back(new BadaFilesystemNode(PATH_CARD)); - result = true; // no more entries - } else if (_path == PATH_CARD) { - myList.push_back(new BadaFilesystemNode(PATH_CARD_MEDIA)); - result = true; // no more entries - } else if (_path == PATH_HOME) { - // ensure share path is always included - myList.push_back(new BadaFilesystemNode(PATH_HOME_SHARE)); - myList.push_back(new BadaFilesystemNode(PATH_HOME_SHARE2)); - } + if (_isVirtualDir && mode != Common::FSNode::kListFilesOnly && _path == "/") { + // present well known TIZEN file system areas + myList.push_back(new TizenFilesystemNode(kData)); + myList.push_back(new TizenFilesystemNode(kResource)); + myList.push_back(new TizenFilesystemNode(kSdCard)); + myList.push_back(new TizenFilesystemNode(kMedia)); + myList.push_back(new TizenFilesystemNode(kShared)); } if (!result) { @@ -358,7 +364,7 @@ bool BadaFilesystemNode::getChildren(AbstractFSList &myList, DirEntry dirEntry = pDirEnum->GetCurrentDirEntry(); // skip 'invisible' files if necessary - Osp::Base::String fileName = dirEntry.GetName(); + Tizen::Base::String fileName = dirEntry.GetName(); if (fileName[0] == '.' && !hidden) { continue; @@ -374,7 +380,7 @@ bool BadaFilesystemNode::getChildren(AbstractFSList &myList, (mode == Common::FSNode::kListDirectoriesOnly && !dirEntry.IsDirectory())) { continue; } - myList.push_back(new BadaFilesystemNode(_path, fromString(fileName))); + myList.push_back(new TizenFilesystemNode(_path, ::fromString(fileName))); } } @@ -392,9 +398,9 @@ bool BadaFilesystemNode::getChildren(AbstractFSList &myList, return result; } -AbstractFSNode *BadaFilesystemNode::getParent() const { - logEntered(); - if (_path == PATH_ROOT) { +AbstractFSNode *TizenFilesystemNode::getParent() const { + logEntered(); + if (_path == "/") { return 0; // The filesystem root has no parent } @@ -412,22 +418,22 @@ AbstractFSNode *BadaFilesystemNode::getParent() const { // there simply is no parent. // TODO: We could also resolve this by assuming that the parent is the // current working directory, and returning a node referring to that. - return 0; + return NULL; } - return new BadaFilesystemNode(Common::String(start, end)); + return new TizenFilesystemNode(Common::String(start, end)); } -Common::SeekableReadStream *BadaFilesystemNode::createReadStream() { - Common::SeekableReadStream *result = BadaFileStream::makeFromPath(_unicodePath, false); +Common::SeekableReadStream *TizenFilesystemNode::createReadStream() { + Common::SeekableReadStream *result = TizenFileStream::makeFromPath(_unicodePath, false); if (result != NULL) { _isValid = !IsFailed(File::GetAttributes(_unicodePath, _attr)); } return result; } -Common::WriteStream *BadaFilesystemNode::createWriteStream() { - Common::WriteStream *result = BadaFileStream::makeFromPath(_unicodePath, true); +Common::WriteStream *TizenFilesystemNode::createWriteStream() { + Common::WriteStream *result = TizenFileStream::makeFromPath(_unicodePath, true); if (result != NULL) { _isValid = !IsFailed(File::GetAttributes(_unicodePath, _attr)); } diff --git a/backends/platform/bada/fs.h b/backends/platform/tizen/fs.h index d7d368ac20..0356aaad33 100644 --- a/backends/platform/bada/fs.h +++ b/backends/platform/tizen/fs.h @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef BADA_FILESYSTEM_H -#define BADA_FILESYSTEM_H +#ifndef TIZEN_FILESYSTEM_H +#define TIZEN_FILESYSTEM_H #include <FBaseString.h> #include <FBaseUtilStringUtil.h> @@ -32,23 +32,40 @@ #include "common/stream.h" #include "backends/fs/abstract-fs.h" -using namespace Osp::Io; -using namespace Osp::Base; -using namespace Osp::Base::Utility; +using namespace Tizen::Io; +using namespace Tizen::Base; +using namespace Tizen::Base::Utility; + +// +// converts a Tizen (wchar) String into a scummVM (char) string +// +Common::String fromString(const Tizen::Base::String &in); + +// +// Enumerates the possible system paths +// +enum SystemPath { kData, kResource, kSdCard, kMedia, kShared }; /** - * Implementation of the ScummVM file system API based on BADA. + * Implementation of the ScummVM file system API based on TIZEN. * * Parts of this class are documented in the base interface class, AbstractFSNode. */ -class BadaFilesystemNode : public AbstractFSNode { +class TizenFilesystemNode : public AbstractFSNode { public: /** - * Creates a BadaFilesystemNode for a given path. + * Creates a TizenFilesystemNode for a given path. + * + * @param path the path the new node should point to. + */ + TizenFilesystemNode(const Common::String &path); + + /** + * Creates a TizenFilesystemNode from the given Tizen internal path * * @param path the path the new node should point to. */ - BadaFilesystemNode(const Common::String &path); + TizenFilesystemNode(SystemPath systemPath); Common::String getDisplayName() const { return _displayName; } Common::String getName() const { return _displayName; } @@ -67,8 +84,7 @@ public: Common::WriteStream *createWriteStream(); protected: - BadaFilesystemNode(const Common::String &root, - const Common::String &p); + TizenFilesystemNode(const Common::String &root, const Common::String &p); void init(const Common::String &nodePath); Common::String _displayName; diff --git a/backends/platform/bada/graphics.cpp b/backends/platform/tizen/graphics.cpp index bd65c597c6..bf255cd264 100644 --- a/backends/platform/bada/graphics.cpp +++ b/backends/platform/tizen/graphics.cpp @@ -22,29 +22,40 @@ #include "graphics/fontman.h" -#include "backends/platform/bada/form.h" -#include "backends/platform/bada/system.h" -#include "backends/platform/bada/graphics.h" +#include "backends/platform/tizen/form.h" +#include "backends/platform/tizen/system.h" +#include "backends/platform/tizen/graphics.h" // -// BadaGraphicsManager +// TizenGraphicsManager // -BadaGraphicsManager::BadaGraphicsManager(BadaAppForm *appForm) : +TizenGraphicsManager::TizenGraphicsManager(TizenAppForm *appForm) : _appForm(appForm), _eglDisplay(EGL_DEFAULT_DISPLAY), _eglSurface(EGL_NO_SURFACE), - _eglConfig(0), + _eglConfig(NULL), _eglContext(EGL_NO_CONTEXT), _initState(true) { assert(appForm != NULL); _videoMode.fullscreen = true; } -const Graphics::Font *BadaGraphicsManager::getFontOSD() { +TizenGraphicsManager::~TizenGraphicsManager() { + logEntered(); + + if (_eglDisplay != EGL_NO_DISPLAY) { + eglMakeCurrent(_eglDisplay, NULL, NULL, NULL); + if (_eglContext != EGL_NO_CONTEXT) { + eglDestroyContext(_eglDisplay, _eglContext); + } + } +} + +const Graphics::Font *TizenGraphicsManager::getFontOSD() { return FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont); } -bool BadaGraphicsManager::moveMouse(int16 &x, int16 &y) { +bool TizenGraphicsManager::moveMouse(int16 &x, int16 &y) { int16 currentX = _cursorState.x; int16 currentY = _cursorState.y; @@ -62,7 +73,7 @@ bool BadaGraphicsManager::moveMouse(int16 &x, int16 &y) { return (currentX != x || currentY != y); } -Common::List<Graphics::PixelFormat> BadaGraphicsManager::getSupportedFormats() const { +Common::List<Graphics::PixelFormat> TizenGraphicsManager::getSupportedFormats() const { logEntered(); Common::List<Graphics::PixelFormat> res; @@ -73,33 +84,37 @@ Common::List<Graphics::PixelFormat> BadaGraphicsManager::getSupportedFormats() c return res; } -bool BadaGraphicsManager::hasFeature(OSystem::Feature f) { +bool TizenGraphicsManager::hasFeature(OSystem::Feature f) { bool result = (f == OSystem::kFeatureFullscreenMode || - f == OSystem::kFeatureVirtualKeyboard || - OpenGLGraphicsManager::hasFeature(f)); + f == OSystem::kFeatureVirtualKeyboard || + OpenGLGraphicsManager::hasFeature(f)); return result; } -void BadaGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) { - OpenGLGraphicsManager::setFeatureState(f, enable); +void TizenGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) { + if (f == OSystem::kFeatureVirtualKeyboard && enable) { + _appForm->showKeypad(); + } else { + OpenGLGraphicsManager::setFeatureState(f, enable); + } } -void BadaGraphicsManager::setReady() { +void TizenGraphicsManager::setReady() { _initState = false; } -void BadaGraphicsManager::updateScreen() { +void TizenGraphicsManager::updateScreen() { if (_transactionMode == kTransactionNone) { internUpdateScreen(); } } -bool BadaGraphicsManager::loadEgl() { +bool TizenGraphicsManager::loadEgl() { logEntered(); EGLint numConfigs = 1; EGLint eglConfigList[] = { - EGL_RED_SIZE, 5, + EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, @@ -132,8 +147,7 @@ bool BadaGraphicsManager::loadEgl() { return false; } - if (EGL_FALSE == eglChooseConfig(_eglDisplay, eglConfigList, - &_eglConfig, 1, &numConfigs) || + if (EGL_FALSE == eglChooseConfig(_eglDisplay, eglConfigList, &_eglConfig, 1, &numConfigs) || EGL_SUCCESS != eglGetError()) { systemError("eglChooseConfig() failed"); return false; @@ -144,15 +158,13 @@ bool BadaGraphicsManager::loadEgl() { return false; } - _eglSurface = eglCreateWindowSurface(_eglDisplay, _eglConfig, - (EGLNativeWindowType)_appForm, NULL); + _eglSurface = eglCreateWindowSurface(_eglDisplay, _eglConfig, (EGLNativeWindowType)_appForm, NULL); if (EGL_NO_SURFACE == _eglSurface || EGL_SUCCESS != eglGetError()) { systemError("eglCreateWindowSurface() failed. EGL_NO_SURFACE"); return false; } - _eglContext = eglCreateContext(_eglDisplay, _eglConfig, - EGL_NO_CONTEXT, eglContextList); + _eglContext = eglCreateContext(_eglDisplay, _eglConfig, EGL_NO_CONTEXT, eglContextList); if (EGL_NO_CONTEXT == _eglContext || EGL_SUCCESS != eglGetError()) { systemError("eglCreateContext() failed"); @@ -169,7 +181,7 @@ bool BadaGraphicsManager::loadEgl() { return true; } -bool BadaGraphicsManager::loadGFXMode() { +bool TizenGraphicsManager::loadGFXMode() { logEntered(); if (!loadEgl()) { @@ -181,35 +193,28 @@ bool BadaGraphicsManager::loadGFXMode() { _appForm->GetBounds(x, y, width, height); _videoMode.overlayWidth = _videoMode.hardwareWidth = width; _videoMode.overlayHeight = _videoMode.hardwareHeight = height; - _videoMode.scaleFactor = 3; // for proportional sized cursor in the launcher + _videoMode.scaleFactor = 4; // for proportional sized cursor in the launcher AppLog("screen size: %dx%d", _videoMode.hardwareWidth, _videoMode.hardwareHeight); return OpenGLGraphicsManager::loadGFXMode(); } -void BadaGraphicsManager::loadTextures() { +void TizenGraphicsManager::loadTextures() { logEntered(); - OpenGLGraphicsManager::loadTextures(); - - // prevent image skew in some games, see: - // http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } -void BadaGraphicsManager::internUpdateScreen() { +void TizenGraphicsManager::internUpdateScreen() { if (!_initState) { OpenGLGraphicsManager::internUpdateScreen(); eglSwapBuffers(_eglDisplay, _eglSurface); - } else { - showSplash(); } } -void BadaGraphicsManager::unloadGFXMode() { +void TizenGraphicsManager::unloadGFXMode() { logEntered(); - if (EGL_NO_DISPLAY != _eglDisplay) { + if (_eglDisplay != EGL_NO_DISPLAY) { eglMakeCurrent(_eglDisplay, NULL, NULL, NULL); if (_eglContext != EGL_NO_CONTEXT) { @@ -227,35 +232,6 @@ void BadaGraphicsManager::unloadGFXMode() { } _eglConfig = NULL; - OpenGLGraphicsManager::unloadGFXMode(); logLeaving(); } - -// display a simple splash screen until launcher is ready -void BadaGraphicsManager::showSplash() { - Canvas canvas; - canvas.Construct(); - canvas.SetBackgroundColor(Color::COLOR_BLACK); - canvas.Clear(); - - int x = _videoMode.hardwareWidth / 3; - int y = _videoMode.hardwareHeight / 3; - - Font *pFont = new Font(); - pFont->Construct(FONT_STYLE_ITALIC | FONT_STYLE_BOLD, 55); - canvas.SetFont(*pFont); - canvas.SetForegroundColor(Color::COLOR_GREEN); - canvas.DrawText(Point(x, y), L"ScummVM"); - delete pFont; - - pFont = new Font(); - pFont->Construct(FONT_STYLE_ITALIC | FONT_STYLE_BOLD, 35); - canvas.SetFont(*pFont); - canvas.SetForegroundColor(Color::COLOR_WHITE); - canvas.DrawText(Point(x + 70, y + 50), L"Loading ..."); - delete pFont; - - canvas.Show(); - -} diff --git a/backends/platform/bada/graphics.h b/backends/platform/tizen/graphics.h index b2aaca43bc..27e5a6aaeb 100644 --- a/backends/platform/bada/graphics.h +++ b/backends/platform/tizen/graphics.h @@ -20,8 +20,8 @@ * */ -#ifndef BADA_GRAPHICS_H -#define BADA_GRAPHICS_H +#ifndef TIZEN_GRAPHICS_H +#define TIZEN_GRAPHICS_H #include <FBase.h> #include <FGraphics.h> @@ -33,15 +33,16 @@ #include "config.h" #include "backends/graphics/opengl/opengl-graphics.h" #include "graphics/font.h" -#include "backends/platform/bada/form.h" +#include "backends/platform/tizen/form.h" -using namespace Osp::Graphics; -using namespace Osp::Graphics::Opengl; -using namespace Osp::App; +using namespace Tizen::Graphics; +using namespace Tizen::Graphics::Opengl; +using namespace Tizen::App; -class BadaGraphicsManager : public OpenGLGraphicsManager { +class TizenGraphicsManager : public OpenGLGraphicsManager { public: - BadaGraphicsManager(BadaAppForm *appForm); + TizenGraphicsManager(TizenAppForm *appForm); + virtual ~TizenGraphicsManager(); Common::List<Graphics::PixelFormat> getSupportedFormats() const; bool hasFeature(OSystem::Feature f); @@ -61,7 +62,7 @@ private: void showSplash(); bool loadEgl(); - BadaAppForm *_appForm; + TizenAppForm *_appForm; EGLDisplay _eglDisplay; EGLSurface _eglSurface; EGLConfig _eglConfig; diff --git a/backends/platform/bada/main.cpp b/backends/platform/tizen/main.cpp index 8c40f24dd1..b12cc3adc9 100644 --- a/backends/platform/bada/main.cpp +++ b/backends/platform/tizen/main.cpp @@ -24,44 +24,28 @@ #include <FApp.h> #include <FSystem.h> -#include "backends/platform/bada/portdefs.h" -#include "backends/platform/bada/form.h" -#include "backends/platform/bada/system.h" -#include "backends/platform/bada/application.h" +#include "backends/platform/tizen/application.h" -using namespace Osp::Base; -using namespace Osp::Base::Collection; - -C_LINKAGE_BEGIN - -_EXPORT_ int OspMain(int argc, char *pArgv[]); +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; /** - * The entry function of bada application called by the operating system. + * The entry function of tizen application called by the operating system. */ -int OspMain(int argc, char *pArgv[]) { +extern "C" _EXPORT_ int OspMain(int argc, char *pArgv[]) { result r = E_SUCCESS; AppLog("Application started."); - ArrayList *pArgs = new ArrayList(); - pArgs->Construct(); - + ArrayList args(SingleObjectDeleter); + args.Construct(); for (int i = 0; i < argc; i++) { - pArgs->Add(*(new String(pArgv[i]))); + args.Add(new (std::nothrow) String(pArgv[i])); } - r = Osp::App::Application::Execute(BadaScummVM::createInstance, pArgs); - if (IsFailed(r)) { - r &= 0x0000FFFF; - } - - pArgs->RemoveAll(true); - delete pArgs; + r = Tizen::App::UiApp::Execute(TizenScummVM::createInstance, &args); + TryLog(r == E_SUCCESS, "[%s] Application execution failed", GetErrorMessage(r)); AppLog("Application finished."); return static_cast<int>(r); } -C_LINKAGE_END - - diff --git a/backends/platform/bada/missing.cpp b/backends/platform/tizen/missing.cpp index 10d45ca4b5..5ac55d0f6c 100644 --- a/backends/platform/bada/missing.cpp +++ b/backends/platform/tizen/missing.cpp @@ -26,7 +26,7 @@ #include <FSystem.h> #include <FBase.h> -#include "backends/platform/bada/portdefs.h" +#include "backends/platform/tizen/portdefs.h" #include <stdio.h> #include <string.h> @@ -48,7 +48,7 @@ void __assert_func(const char *file, int line, systemError(buffer); } -void stderr_fprintf(void*, const char *format, ...) { +void stderr_fprintf(void *, const char *format, ...) { va_list ap; char buffer[BUF_SIZE]; @@ -59,7 +59,7 @@ void stderr_fprintf(void*, const char *format, ...) { AppLog(buffer); } -void stderr_vfprintf(void*, const char *format, va_list ap) { +void stderr_vfprintf(void *, const char *format, va_list ap) { char buffer[BUF_SIZE]; vsnprintf(buffer, sizeof(buffer), format, ap); AppLog(buffer); @@ -79,35 +79,4 @@ int printf(const char *format, ...) { return result; } -int sprintf(char *str, const char *format, ...) { - va_list ap; - int result; - char buffer[BUF_SIZE]; - - va_start(ap, format); - result = vsnprintf(buffer, sizeof(buffer), format, ap); - va_end(ap); - - strcpy(str, buffer); - - return result; -} - -char *strdup(const char *strSource) { - char *buffer; - int len = strlen(strSource) + 1; - buffer = (char *)malloc(len); - if (buffer) { - memcpy(buffer, strSource, len); - } - return buffer; -} - -int vsprintf(char *str, const char *format, va_list ap) { - char buffer[BUF_SIZE]; - int result = vsnprintf(buffer, sizeof(buffer), format, ap); - strcpy(str, buffer); - return result; -} - C_LINKAGE_END diff --git a/backends/platform/bada/portdefs.h b/backends/platform/tizen/portdefs.h index 813c5acde3..050ce7d1e0 100644 --- a/backends/platform/bada/portdefs.h +++ b/backends/platform/tizen/portdefs.h @@ -43,6 +43,9 @@ #define C_LINKAGE_END #endif +// value missing from osp gl headers +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 + C_LINKAGE_BEGIN // for libFLAC @@ -51,11 +54,11 @@ C_LINKAGE_BEGIN #define fseeko fseek #define ftello ftell -// overcome use of fprintf since bada/newlib (1.2) does not +// overcome use of fprintf since newlib (1.2) does not // support stderr/stdout (undefined reference to `_impure_ptr'). -void stderr_fprintf(void*, const char *format, ...); -void stderr_vfprintf(void*, const char *format, va_list ap); +void stderr_fprintf(void *, const char *format, ...); +void stderr_vfprintf(void *, const char *format, va_list ap); #undef fprintf #undef vfprintf @@ -75,10 +78,7 @@ void stderr_vfprintf(void*, const char *format, va_list ap); #define vfprintf stderr_vfprintf int printf(const char *format, ...); -int sprintf(char *str, const char *format, ...); int simple_sscanf(const char *buffer, const char *format, ...); -char *strdup(const char *s1); -int vsprintf(char *str, const char *format, va_list ap); C_LINKAGE_END diff --git a/backends/platform/bada/sscanf.cpp b/backends/platform/tizen/sscanf.cpp index aa846698f6..aa846698f6 100644 --- a/backends/platform/bada/sscanf.cpp +++ b/backends/platform/tizen/sscanf.cpp diff --git a/backends/platform/bada/system.cpp b/backends/platform/tizen/system.cpp index 3f862c2571..54d92146e5 100644 --- a/backends/platform/bada/system.cpp +++ b/backends/platform/tizen/system.cpp @@ -34,53 +34,53 @@ #include "backends/audiocd/default/default-audiocd.h" #include "backends/mutex/mutex.h" #include "backends/fs/fs-factory.h" -#include "backends/timer/bada/timer.h" +#include "backends/timer/tizen/timer.h" -#include "backends/platform/bada/form.h" -#include "backends/platform/bada/system.h" -#include "backends/platform/bada/graphics.h" -#include "backends/platform/bada/audio.h" +#include "backends/platform/tizen/form.h" +#include "backends/platform/tizen/system.h" +#include "backends/platform/tizen/graphics.h" +#include "backends/platform/tizen/audio.h" -using namespace Osp::Base; -using namespace Osp::Base::Runtime; -using namespace Osp::Locales; -using namespace Osp::Ui::Controls; -using namespace Osp::System; +using namespace Tizen::Base; +using namespace Tizen::Base::Runtime; +using namespace Tizen::Locales; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Controls; +using namespace Tizen::System; -#define DEFAULT_CONFIG_FILE "/Home/scummvm.ini" -#define RESOURCE_PATH "/Res" +#define DEFAULT_CONFIG_FILE "scummvm.ini" #define MUTEX_BUFFER_SIZE 5 // -// BadaFilesystemFactory +// TizenFilesystemFactory // -class BadaFilesystemFactory : public FilesystemFactory { +class TizenFilesystemFactory : public FilesystemFactory { AbstractFSNode *makeRootFileNode() const; AbstractFSNode *makeCurrentDirectoryFileNode() const; AbstractFSNode *makeFileNodePath(const Common::String &path) const; }; -AbstractFSNode *BadaFilesystemFactory::makeRootFileNode() const { - return new BadaFilesystemNode("/"); +AbstractFSNode *TizenFilesystemFactory::makeRootFileNode() const { + return new TizenFilesystemNode("/"); } -AbstractFSNode *BadaFilesystemFactory::makeCurrentDirectoryFileNode() const { - return new BadaFilesystemNode("/Home"); +AbstractFSNode *TizenFilesystemFactory::makeCurrentDirectoryFileNode() const { + return new TizenFilesystemNode("/"); } -AbstractFSNode *BadaFilesystemFactory::makeFileNodePath(const Common::String &path) const { +AbstractFSNode *TizenFilesystemFactory::makeFileNodePath(const Common::String &path) const { AppAssert(!path.empty()); - return new BadaFilesystemNode(path); + return new TizenFilesystemNode(path); } // -// BadaSaveFileManager +// TizenSaveFileManager // -struct BadaSaveFileManager : public DefaultSaveFileManager { +struct TizenSaveFileManager : public DefaultSaveFileManager { bool removeSavefile(const Common::String &filename); }; -bool BadaSaveFileManager::removeSavefile(const Common::String &filename) { +bool TizenSaveFileManager::removeSavefile(const Common::String &filename) { Common::String savePathName = getSavePath(); checkPath(Common::FSNode(savePathName)); @@ -95,18 +95,18 @@ bool BadaSaveFileManager::removeSavefile(const Common::String &filename) { String unicodeFileName; StringUtil::Utf8ToString(file.getPath().c_str(), unicodeFileName); - switch (Osp::Io::File::Remove(unicodeFileName)) { + switch (Tizen::Io::File::Remove(unicodeFileName)) { case E_SUCCESS: return true; case E_ILLEGAL_ACCESS: setError(Common::kWritePermissionDenied, "Search or write permission denied: " + - file.getName()); + file.getName()); break; default: setError(Common::kPathDoesNotExist, "removeSavefile: '" + file.getName() + - "' does not exist or path is invalid"); + "' does not exist or path is invalid"); break; } @@ -114,40 +114,40 @@ bool BadaSaveFileManager::removeSavefile(const Common::String &filename) { } // -// BadaMutexManager +// TizenMutexManager // -struct BadaMutexManager : public MutexManager { - BadaMutexManager(); - ~BadaMutexManager(); +struct TizenMutexManager : public MutexManager { + TizenMutexManager(); + ~TizenMutexManager(); OSystem::MutexRef createMutex(); void lockMutex(OSystem::MutexRef mutex); void unlockMutex(OSystem::MutexRef mutex); void deleteMutex(OSystem::MutexRef mutex); private: - Mutex *buffer[MUTEX_BUFFER_SIZE]; + Mutex *_buffer[MUTEX_BUFFER_SIZE]; }; -BadaMutexManager::BadaMutexManager() { +TizenMutexManager::TizenMutexManager() { for (int i = 0; i < MUTEX_BUFFER_SIZE; i++) { - buffer[i] = NULL; + _buffer[i] = NULL; } } -BadaMutexManager::~BadaMutexManager() { +TizenMutexManager::~TizenMutexManager() { for (int i = 0; i < MUTEX_BUFFER_SIZE; i++) { - if (buffer[i] != NULL) { - delete buffer[i]; + if (_buffer[i] != NULL) { + delete _buffer[i]; } } } -OSystem::MutexRef BadaMutexManager::createMutex() { +OSystem::MutexRef TizenMutexManager::createMutex() { Mutex *mutex = new Mutex(); mutex->Create(); for (int i = 0; i < MUTEX_BUFFER_SIZE; i++) { - if (buffer[i] == NULL) { - buffer[i] = mutex; + if (_buffer[i] == NULL) { + _buffer[i] = mutex; break; } } @@ -155,22 +155,22 @@ OSystem::MutexRef BadaMutexManager::createMutex() { return (OSystem::MutexRef) mutex; } -void BadaMutexManager::lockMutex(OSystem::MutexRef mutex) { +void TizenMutexManager::lockMutex(OSystem::MutexRef mutex) { Mutex *m = (Mutex *)mutex; m->Acquire(); } -void BadaMutexManager::unlockMutex(OSystem::MutexRef mutex) { +void TizenMutexManager::unlockMutex(OSystem::MutexRef mutex) { Mutex *m = (Mutex *)mutex; m->Release(); } -void BadaMutexManager::deleteMutex(OSystem::MutexRef mutex) { +void TizenMutexManager::deleteMutex(OSystem::MutexRef mutex) { Mutex *m = (Mutex *)mutex; for (int i = 0; i < MUTEX_BUFFER_SIZE; i++) { - if (buffer[i] == m) { - buffer[i] = NULL; + if (_buffer[i] == m) { + _buffer[i] = NULL; } } @@ -178,84 +178,101 @@ void BadaMutexManager::deleteMutex(OSystem::MutexRef mutex) { } // -// BadaEventManager +// TizenEventManager // -struct BadaEventManager : public DefaultEventManager { - BadaEventManager(Common::EventSource *boss); +struct TizenEventManager : public DefaultEventManager { + TizenEventManager(Common::EventSource *boss); void init(); int shouldQuit() const; }; -BadaEventManager::BadaEventManager(Common::EventSource *boss) : +TizenEventManager::TizenEventManager(Common::EventSource *boss) : DefaultEventManager(boss) { } -void BadaEventManager::init() { +void TizenEventManager::init() { DefaultEventManager::init(); // theme and vkbd should have now loaded - clear the splash screen - BadaSystem *system = (BadaSystem *)g_system; - BadaGraphicsManager *graphics = system->getGraphics(); + TizenSystem *system = (TizenSystem *)g_system; + TizenGraphicsManager *graphics = system->getGraphics(); if (graphics) { graphics->setReady(); - graphics->updateScreen(); } } -int BadaEventManager::shouldQuit() const { - BadaSystem *system = (BadaSystem *)g_system; +int TizenEventManager::shouldQuit() const { + TizenSystem *system = (TizenSystem *)g_system; return DefaultEventManager::shouldQuit() || system->isClosing(); } // -// BadaSystem +// TizenAppFrame - avoid drawing the misplaced UiTheme at startup // -BadaSystem::BadaSystem(BadaAppForm *appForm) : +struct TizenAppFrame : Frame { + result OnDraw(void) { + logEntered(); + TizenAppForm *form = (TizenAppForm *)GetCurrentForm(); + if (form->isStarting()) { + Canvas *canvas = GetCanvasN(); + canvas->SetBackgroundColor(Color::GetColor(COLOR_ID_BLACK)); + canvas->Clear(); + delete canvas; + } + return E_SUCCESS; + } +}; + +// +// TizenSystem +// +TizenSystem::TizenSystem(TizenAppForm *appForm) : _appForm(appForm), _audioThread(0), _epoch(0) { } -result BadaSystem::Construct(void) { +result TizenSystem::Construct(void) { logEntered(); - _fsFactory = new BadaFilesystemFactory(); + _fsFactory = new TizenFilesystemFactory(); if (!_fsFactory) { return E_OUT_OF_MEMORY; } + _resourcePath = fromString(App::GetInstance()->GetAppResourcePath()); return E_SUCCESS; } -BadaSystem::~BadaSystem() { +TizenSystem::~TizenSystem() { logEntered(); } -result BadaSystem::initModules() { +result TizenSystem::initModules() { logEntered(); - _mutexManager = new BadaMutexManager(); + _mutexManager = new TizenMutexManager(); if (!_mutexManager) { return E_OUT_OF_MEMORY; } - _timerManager = new BadaTimerManager(); + _timerManager = new TizenTimerManager(); if (!_timerManager) { return E_OUT_OF_MEMORY; } - _savefileManager = new BadaSaveFileManager(); + _savefileManager = new TizenSaveFileManager(); if (!_savefileManager) { return E_OUT_OF_MEMORY; } - _graphicsManager = (GraphicsManager *)new BadaGraphicsManager(_appForm); + _graphicsManager = (GraphicsManager *)new TizenGraphicsManager(_appForm); if (!_graphicsManager) { return E_OUT_OF_MEMORY; } // depends on _graphicsManager when ENABLE_VKEYBD enabled - _eventManager = new BadaEventManager(this); + _eventManager = new TizenEventManager(this); if (!_eventManager) { return E_OUT_OF_MEMORY; } @@ -284,19 +301,21 @@ result BadaSystem::initModules() { return E_SUCCESS; } -void BadaSystem::initBackend() { +void TizenSystem::initBackend() { logEntered(); + Common::String dataPath = fromString(App::GetInstance()->GetAppDataPath()); + // use the mobile device theme - ConfMan.set("gui_theme", "/Res/scummmobile"); + ConfMan.set("gui_theme", _resourcePath + "scummmodern"); - // allow bada virtual keypad pack to be found - ConfMan.set("vkeybdpath", "/Res/vkeybd_bada"); + // allow tizen virtual keypad pack to be found + ConfMan.set("vkeybdpath", _resourcePath + "vkeybd_bada"); ConfMan.set("vkeybd_pack_name", "vkeybd_bada"); // set default save path to writable area if (!ConfMan.hasKey("savepath")) { - ConfMan.set("savepath", "/Home/Share"); + ConfMan.set("savepath", dataPath); } // default to no auto-save @@ -314,85 +333,93 @@ void BadaSystem::initBackend() { AppLog("initModules failed"); } else { OSystem::initBackend(); - } - // replace kBigGUIFont using the large font from the scummmobile theme - Common::File fontFile; - Common::String fileName = "/Res/scummmobile/helvB14-iso-8859-1.fcc"; - BadaFilesystemNode file(fileName); - if (file.exists()) { - Common::SeekableReadStream *stream = file.createReadStream(); - if (stream) { - if (fontFile.open(stream, fileName)) { + // replace kBigGUIFont for the vkbd and on-screen messages + Common::String fontCacheFile = dataPath + "helvR24.fcc"; + TizenFilesystemNode file(fontCacheFile); + if (!file.exists()) { + Common::String bdfFile = _resourcePath + "fonts/helvR24.bdf"; + TizenFilesystemNode file(bdfFile); + if (file.exists()) { + Common::SeekableReadStream *stream = file.createReadStream(); + Common::File fontFile; + if (stream && fontFile.open(stream, bdfFile)) { + Graphics::BdfFont *font = Graphics::BdfFont::loadFont(fontFile); + Graphics::BdfFont::cacheFontData(*font, fontCacheFile); + FontMan.setFont(Graphics::FontManager::kBigGUIFont, font); + } + } + } else { + Common::SeekableReadStream *stream = file.createReadStream(); + Common::File fontFile; + if (stream && fontFile.open(stream, fontCacheFile)) { Graphics::BdfFont *font = Graphics::BdfFont::loadFromCache(fontFile); if (font) { - // use this font for the vkbd and on-screen messages FontMan.setFont(Graphics::FontManager::kBigGUIFont, font); } } } } - logLeaving(); } -void BadaSystem::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { +void TizenSystem::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { // allow translations.dat and game .DAT files to be found - s.addDirectory(RESOURCE_PATH, RESOURCE_PATH, priority); + s.addDirectory(_resourcePath, _resourcePath, priority); } -void BadaSystem::destroyBackend() { +void TizenSystem::destroyBackend() { closeAudio(); delete _graphicsManager; - _graphicsManager = 0; + _graphicsManager = NULL; delete _savefileManager; - _savefileManager = 0; + _savefileManager = NULL; delete _fsFactory; - _fsFactory = 0; + _fsFactory = NULL; delete _mixer; - _mixer = 0; + _mixer = NULL; delete _audiocdManager; - _audiocdManager = 0; + _audiocdManager = NULL; delete _timerManager; - _timerManager = 0; + _timerManager = NULL; delete _eventManager; - _eventManager = 0; + _eventManager = NULL; delete _mutexManager; - _mutexManager = 0; + _mutexManager = NULL; } -bool BadaSystem::pollEvent(Common::Event &event) { +bool TizenSystem::pollEvent(Common::Event &event) { return _appForm->pollEvent(event); } -uint32 BadaSystem::getMillis() { +uint32 TizenSystem::getMillis(bool skipRecord) { long long result, ticks = 0; SystemTime::GetTicks(ticks); result = ticks - _epoch; return result; } -void BadaSystem::delayMillis(uint msecs) { +void TizenSystem::delayMillis(uint msecs) { if (!_appForm->isClosing()) { Thread::Sleep(msecs); } } -void BadaSystem::updateScreen() { +void TizenSystem::updateScreen() { if (_graphicsManager != NULL) { _graphicsManager->updateScreen(); } } -void BadaSystem::getTimeAndDate(TimeDate &td) const { +void TizenSystem::getTimeAndDate(TimeDate &td) const { DateTime currentTime; if (E_SUCCESS == SystemTime::GetCurrentTime(WALL_TIME, currentTime)) { @@ -410,11 +437,11 @@ void BadaSystem::getTimeAndDate(TimeDate &td) const { } } -void BadaSystem::fatalError() { +void TizenSystem::fatalError() { systemError("ScummVM: Fatal internal error."); } -void BadaSystem::exitSystem() { +void TizenSystem::exitSystem() { if (_appForm) { closeAudio(); closeGraphics(); @@ -422,7 +449,7 @@ void BadaSystem::exitSystem() { } } -void BadaSystem::logMessage(LogMessageType::Type type, const char *message) { +void TizenSystem::logMessage(LogMessageType::Type type, const char *message) { if (type == LogMessageType::kError) { systemError(message); } else { @@ -430,69 +457,70 @@ void BadaSystem::logMessage(LogMessageType::Type type, const char *message) { } } -Common::SeekableReadStream *BadaSystem::createConfigReadStream() { - BadaFilesystemNode file(DEFAULT_CONFIG_FILE); +Common::SeekableReadStream *TizenSystem::createConfigReadStream() { + TizenFilesystemNode file(fromString(App::GetInstance()->GetAppDataPath()) + DEFAULT_CONFIG_FILE); return file.createReadStream(); } -Common::WriteStream *BadaSystem::createConfigWriteStream() { - BadaFilesystemNode file(DEFAULT_CONFIG_FILE); +Common::WriteStream *TizenSystem::createConfigWriteStream() { + TizenFilesystemNode file(fromString(App::GetInstance()->GetAppDataPath()) + DEFAULT_CONFIG_FILE); return file.createWriteStream(); } -void BadaSystem::closeAudio() { +void TizenSystem::closeAudio() { if (_audioThread) { - _audioThread->Stop(); + _audioThread->Quit(); _audioThread->Join(); delete _audioThread; - _audioThread = 0; + _audioThread = NULL; } } -void BadaSystem::closeGraphics() { +void TizenSystem::closeGraphics() { if (_graphicsManager) { delete _graphicsManager; - _graphicsManager = 0; + _graphicsManager = NULL; } } -void BadaSystem::setMute(bool on) { +void TizenSystem::setMute(bool on) { // only change mute after eventManager init() has completed if (_audioThread) { - BadaGraphicsManager *graphics = getGraphics(); + TizenGraphicsManager *graphics = getGraphics(); if (graphics && graphics->isReady()) { _audioThread->setMute(on); } } } -int BadaSystem::setVolume(bool up, bool minMax) { - int level = -1; - if (_audioThread) { - level = _audioThread->setVolume(up, minMax); - } - return level; -} - // // create the ScummVM system // -BadaAppForm *systemStart(Osp::App::Application *app) { +TizenAppForm *systemStart(Tizen::App::Application *app) { logEntered(); - BadaAppForm *appForm = new BadaAppForm(); + Frame *appFrame = new (std::nothrow) TizenAppFrame(); + if (!appFrame || appFrame->Construct() == E_FAILURE) { + AppLog("Failed to create appFrame"); + return NULL; + } + app->AddFrame(*appFrame); + + TizenAppForm *appForm = new TizenAppForm(); if (!appForm) { AppLog("Failed to create appForm"); return NULL; } if (E_SUCCESS != appForm->Construct() || - E_SUCCESS != app->GetAppFrame()->GetFrame()->AddControl(*appForm)) { + E_SUCCESS != appFrame->AddControl(*appForm)) { delete appForm; AppLog("Failed to construct appForm"); return NULL; } + appFrame->SetCurrentForm(appForm); + logLeaving(); return appForm; } @@ -502,13 +530,18 @@ BadaAppForm *systemStart(Osp::App::Application *app) { void systemError(const char *message) { AppLog("Fatal system error: %s", message); - ArrayList *args = new ArrayList(); - args->Construct(); - args->Add(*(new String(message))); - Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT_ERR, args); + if (strspn(message, "Config file buggy:") > 0) { + Tizen::Io::File::Remove(DEFAULT_CONFIG_FILE); + Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT_ERR_CONFIG, NULL); + } else { + ArrayList *args = new ArrayList(); + args->Construct(); + args->Add(*(new String(message))); + Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT_ERR, args); + } if (g_system) { - BadaSystem *system = (BadaSystem *)g_system; + TizenSystem *system = (TizenSystem *)g_system; system->exitSystem(); } } diff --git a/backends/platform/bada/system.h b/backends/platform/tizen/system.h index c28686cb3d..b38940cc95 100644 --- a/backends/platform/bada/system.h +++ b/backends/platform/tizen/system.h @@ -20,8 +20,8 @@ * */ -#ifndef BADA_SYSTEM_H -#define BADA_SYSTEM_H +#ifndef TIZEN_SYSTEM_H +#define TIZEN_SYSTEM_H #include <FApp.h> #include <FGraphics.h> @@ -34,47 +34,46 @@ #include "common/scummsys.h" #include "backends/modular-backend.h" -#include "backends/platform/bada/fs.h" -#include "backends/platform/bada/form.h" -#include "backends/platform/bada/audio.h" -#include "backends/platform/bada/graphics.h" +#include "backends/platform/tizen/fs.h" +#include "backends/platform/tizen/form.h" +#include "backends/platform/tizen/audio.h" +#include "backends/platform/tizen/graphics.h" #if defined(_DEBUG) -#define logEntered() AppLog("%s entered (%s %d)", \ - __FUNCTION__, __FILE__, __LINE__); -#define logLeaving() AppLog("%s leaving (%s %d)", \ - __FUNCTION__, __FILE__, __LINE__); +#define logEntered() AppLog("%s entered (%s %d)", __FUNCTION__, __FILE__, __LINE__); +#define logLeaving() AppLog("%s leaving (%s %d)", __FUNCTION__, __FILE__, __LINE__); #else #define logEntered() #define logLeaving() #endif -BadaAppForm *systemStart(Osp::App::Application *app); +TizenAppForm *systemStart(Tizen::App::Application *app); void systemError(const char *message); -#define USER_MESSAGE_EXIT 1000 -#define USER_MESSAGE_EXIT_ERR 1001 +#define USER_MESSAGE_EXIT 1000 +#define USER_MESSAGE_EXIT_ERR 1001 +#define USER_MESSAGE_EXIT_ERR_CONFIG 1002 // -// BadaSystem +// TizenSystem // -class BadaSystem : public ModularBackend, - Common::EventSource { +class TizenSystem : + public ModularBackend, + Common::EventSource { public: - BadaSystem(BadaAppForm *appForm); - ~BadaSystem(); + TizenSystem(TizenAppForm *appForm); + ~TizenSystem(); result Construct(); void closeAudio(); void closeGraphics(); void destroyBackend(); void setMute(bool on); - int setVolume(bool up, bool minMax); void exitSystem(); bool isClosing() { return _appForm->isClosing(); } - BadaGraphicsManager *getGraphics() { - return (BadaGraphicsManager *)_graphicsManager; + TizenGraphicsManager *getGraphics() { + return (TizenGraphicsManager *)_graphicsManager; } private: @@ -83,7 +82,7 @@ private: void updateScreen(); bool pollEvent(Common::Event &event); - uint32 getMillis(); + uint32 getMillis(bool skipRecord = false); void delayMillis(uint msecs); void getTimeAndDate(TimeDate &t) const; void fatalError(); @@ -94,9 +93,10 @@ private: Common::SeekableReadStream *createConfigReadStream(); Common::WriteStream *createConfigWriteStream(); - BadaAppForm *_appForm; + TizenAppForm *_appForm; AudioThread *_audioThread; long long _epoch; + Common::String _resourcePath; }; #endif diff --git a/backends/platform/tizen/tizen.mk b/backends/platform/tizen/tizen.mk new file mode 100644 index 0000000000..d8925b62dc --- /dev/null +++ b/backends/platform/tizen/tizen.mk @@ -0,0 +1,7 @@ +# port files built under eclipse + +MODULE := backends/platform/tizen + +$(EXECUTABLE): $(OBJS) + rm -f $@ + arm-linux-gnueabi-ar Tru $@ $(OBJS) diff --git a/backends/platform/wii/osystem.cpp b/backends/platform/wii/osystem.cpp index 22a6495f8f..9d3a7473e3 100644 --- a/backends/platform/wii/osystem.cpp +++ b/backends/platform/wii/osystem.cpp @@ -203,7 +203,7 @@ bool OSystem_Wii::getFeatureState(Feature f) { } } -uint32 OSystem_Wii::getMillis() { +uint32 OSystem_Wii::getMillis(bool skipRecord) { return ticks_to_millisecs(diff_ticks(_startup_time, gettime())); } diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h index 5d6998d0b6..287c70ad6b 100644 --- a/backends/platform/wii/osystem.h +++ b/backends/platform/wii/osystem.h @@ -193,7 +193,7 @@ public: const Graphics::PixelFormat *format); virtual bool pollEvent(Common::Event &event); - virtual uint32 getMillis(); + virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); virtual MutexRef createMutex(); diff --git a/backends/saves/recorder/recorder-saves.cpp b/backends/saves/recorder/recorder-saves.cpp new file mode 100644 index 0000000000..49b4672913 --- /dev/null +++ b/backends/saves/recorder/recorder-saves.cpp @@ -0,0 +1,35 @@ +/* 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. + * + */ + +#include "backends/saves/recorder/recorder-saves.h" +#include "gui/EventRecorder.h" +#include "common/savefile.h" + +Common::InSaveFile *RecorderSaveFileManager::openForLoading(const Common::String &filename) { + Common::InSaveFile *result = g_eventRec.processSaveStream(filename); + return result; +} + +Common::StringArray RecorderSaveFileManager::listSaveFiles(const Common::String &pattern) { + return g_eventRec.listSaveFiles(pattern); +} + diff --git a/backends/saves/recorder/recorder-saves.h b/backends/saves/recorder/recorder-saves.h new file mode 100644 index 0000000000..692aeca329 --- /dev/null +++ b/backends/saves/recorder/recorder-saves.h @@ -0,0 +1,36 @@ +/* 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. + * + */ + +#ifndef BACKEND_SAVES_RECORDER_H +#define BACKEND_SAVES_RECORDER_H + +#include "backends/saves/default/default-saves.h" + +/** + * Provides a savefile manager implementation for event recorder. + */ +class RecorderSaveFileManager : public DefaultSaveFileManager { + virtual Common::StringArray listSaveFiles(const Common::String &pattern); + virtual Common::InSaveFile *openForLoading(const Common::String &filename); +}; + +#endif diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp index 9f56d58b12..ce93320f3d 100644 --- a/backends/timer/default/default-timer.cpp +++ b/backends/timer/default/default-timer.cpp @@ -80,7 +80,7 @@ DefaultTimerManager::~DefaultTimerManager() { void DefaultTimerManager::handler() { Common::StackLock lock(_mutex); - const uint32 curTime = g_system->getMillis(); + uint32 curTime = g_system->getMillis(true); // Repeat as long as there is a TimerSlot that is scheduled to fire. TimerSlot *slot = _head->next; diff --git a/backends/timer/bada/timer.cpp b/backends/timer/tizen/timer.cpp index e41ecd4864..fa226ce747 100644 --- a/backends/timer/bada/timer.cpp +++ b/backends/timer/tizen/timer.cpp @@ -20,15 +20,14 @@ * */ -#if defined(BADA) +#if defined(TIZEN) -#include "backends/timer/bada/timer.h" +#include "backends/timer/tizen/timer.h" // -// TimerSlot +// TimerSlot - an event driven thread // -TimerSlot::TimerSlot(Common::TimerManager::TimerProc callback, - uint32 interval, void *refCon) : +TimerSlot::TimerSlot(Common::TimerManager::TimerProc callback, uint32 interval, void *refCon) : _timer(0), _callback(callback), _interval(interval), @@ -36,16 +35,17 @@ TimerSlot::TimerSlot(Common::TimerManager::TimerProc callback, } TimerSlot::~TimerSlot() { + delete _timer; } bool TimerSlot::OnStart() { - _timer = new Osp::Base::Runtime::Timer(); + _timer = new Tizen::Base::Runtime::Timer(); if (!_timer || IsFailed(_timer->Construct(*this))) { AppLog("Failed to create timer"); return false; } - if (IsFailed(_timer->Start(_interval))) { + if (IsFailed(_timer->StartAsRepeatable(_interval))) { AppLog("failed to start timer"); return false; } @@ -65,28 +65,28 @@ void TimerSlot::OnStop() { void TimerSlot::OnTimerExpired(Timer &timer) { _callback(_refCon); - timer.Start(_interval); } // -// BadaTimerManager +// TizenTimerManager // -BadaTimerManager::BadaTimerManager() { +TizenTimerManager::TizenTimerManager() { } -BadaTimerManager::~BadaTimerManager() { - for (Common::List<TimerSlot>::iterator slot = _timers.begin(); - slot != _timers.end(); ) { - slot->Stop(); - slot = _timers.erase(slot); +TizenTimerManager::~TizenTimerManager() { + for (Common::List<TimerSlot *>::iterator it = _timers.begin(); it != _timers.end(); ) { + TimerSlot *slot = (*it); + slot->Quit(); + slot->Join(); + delete slot; + it = _timers.erase(it); } } -bool BadaTimerManager::installTimerProc(TimerProc proc, int32 interval, void *refCon, - const Common::String &id) { +bool TizenTimerManager::installTimerProc(TimerProc proc, int32 interval, void *refCon, const Common::String &id) { TimerSlot *slot = new TimerSlot(proc, interval / 1000, refCon); - if (IsFailed(slot->Construct(THREAD_TYPE_EVENT_DRIVEN))) { + if (IsFailed(slot->Construct())) { AppLog("Failed to create timer thread"); delete slot; return false; @@ -98,16 +98,18 @@ bool BadaTimerManager::installTimerProc(TimerProc proc, int32 interval, void *re return false; } - _timers.push_back(*slot); + _timers.push_back(slot); return true; } -void BadaTimerManager::removeTimerProc(TimerProc proc) { - for (Common::List<TimerSlot>::iterator slot = _timers.begin(); - slot != _timers.end(); ++slot) { +void TizenTimerManager::removeTimerProc(TimerProc proc) { + for (Common::List<TimerSlot *>::iterator it = _timers.begin(); it != _timers.end(); ++it) { + TimerSlot *slot = (*it); if (slot->_callback == proc) { - slot->Stop(); - slot = _timers.erase(slot); + slot->Quit(); + slot->Join(); + delete slot; + it = _timers.erase(it); } } } diff --git a/backends/timer/bada/timer.h b/backends/timer/tizen/timer.h index 826064d7ff..4b2596401a 100644 --- a/backends/timer/bada/timer.h +++ b/backends/timer/tizen/timer.h @@ -20,20 +20,18 @@ * */ -#ifndef BADA_TIMER_H -#define BADA_TIMER_H +#ifndef TIZEN_TIMER_H +#define TIZEN_TIMER_H #include <FBase.h> #include "common/timer.h" #include "common/list.h" -using namespace Osp::Base::Runtime; +using namespace Tizen::Base::Runtime; -struct TimerSlot: public ITimerEventListener, public Thread { - TimerSlot(Common::TimerManager::TimerProc callback, - uint32 interval, - void *refCon); +struct TimerSlot: public EventDrivenThread, public ITimerEventListener { + TimerSlot(Common::TimerManager::TimerProc callback, uint32 interval, void *refCon); ~TimerSlot(); bool OnStart(void); @@ -46,17 +44,16 @@ struct TimerSlot: public ITimerEventListener, public Thread { void *_refCon; }; -class BadaTimerManager : public Common::TimerManager { +class TizenTimerManager : public Common::TimerManager { public: - BadaTimerManager(); - ~BadaTimerManager(); + TizenTimerManager(); + ~TizenTimerManager(); - bool installTimerProc(TimerProc proc, int32 interval, void *refCon, - const Common::String &id); + bool installTimerProc(TimerProc proc, int32 interval, void *refCon, const Common::String &id); void removeTimerProc(TimerProc proc); private: - Common::List<TimerSlot> _timers; + Common::List<TimerSlot *> _timers; }; #endif diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 42a3a64d34..a39c748adc 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -118,6 +118,13 @@ static const char HELP_STRING[] = " --aspect-ratio Enable aspect ratio correction\n" " --render-mode=MODE Enable additional render modes (cga, ega, hercGreen,\n" " hercAmber, amiga)\n" +#ifdef ENABLE_EVENTRECORDER + " --record-mode=MODE Specify record mode for event recorder (record, playback,\n" + " passthrough [default])\n" + " --record-file-name=FILE Specify record file name\n" + " --disable-display Disable any gfx output. Used for headless events\n" + " playback by Event Recorder\n" +#endif "\n" #if defined(ENABLE_SKY) || defined(ENABLE_QUEEN) " --alt-intro Use alternative intro for CD versions of Beneath a\n" @@ -232,10 +239,9 @@ void registerDefaults() { ConfMan.registerDefault("confirm_exit", false); ConfMan.registerDefault("disable_sdl_parachute", false); + ConfMan.registerDefault("disable_display", false); ConfMan.registerDefault("record_mode", "none"); ConfMan.registerDefault("record_file_name", "record.bin"); - ConfMan.registerDefault("record_temp_file_name", "record.tmp"); - ConfMan.registerDefault("record_time_file_name", "record.time"); ConfMan.registerDefault("gui_saveload_chooser", "grid"); ConfMan.registerDefault("gui_saveload_last_pos", "0"); @@ -424,6 +430,17 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha DO_OPTION_BOOL('f', "fullscreen") END_OPTION +#ifdef ENABLE_EVENTRECORDER + DO_LONG_OPTION_INT("disable-display") + END_OPTION + + DO_LONG_OPTION("record-mode") + END_OPTION + + DO_LONG_OPTION("record-file-name") + END_OPTION +#endif + DO_LONG_OPTION("opl-driver") END_OPTION @@ -569,18 +586,6 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha END_OPTION #endif - DO_LONG_OPTION("record-mode") - END_OPTION - - DO_LONG_OPTION("record-file-name") - END_OPTION - - DO_LONG_OPTION("record-temp-file-name") - END_OPTION - - DO_LONG_OPTION("record-time-file-name") - END_OPTION - #ifdef IPHONE // This is automatically set when launched from the Springboard. DO_LONG_OPTION_OPT("launchedFromSB", 0) diff --git a/base/main.cpp b/base/main.cpp index 355a65f883..103d743bbc 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -42,8 +42,11 @@ #include "common/debug.h" #include "common/debug-channels.h" /* for debug manager */ #include "common/events.h" -#include "common/EventRecorder.h" +#include "gui/EventRecorder.h" #include "common/fs.h" +#ifdef ENABLE_EVENTRECORDER +#include "common/recorderfile.h" +#endif #include "common/system.h" #include "common/textconsole.h" #include "common/tokenizer.h" @@ -409,7 +412,9 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { settings["gfx-mode"] = "default"; } } - + if (settings.contains("disable-display")) { + ConfMan.setInt("disable-display", 1, Common::ConfigManager::kTransientDomain); + } setupGraphics(system); // Init the different managers that are used by the engines. @@ -422,13 +427,15 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { // take place after the backend is initiated and the screen has been setup system.getEventManager()->init(); +#ifdef ENABLE_EVENTRECORDER // Directly after initializing the event manager, we will initialize our // event recorder. // // TODO: This is just to match the current behavior, when we further extend // our event recorder, we might do this at another place. Or even change // the whole API for that ;-). - g_eventRec.init(); + g_eventRec.RegisterEventSource(); +#endif // Now as the event manager is created, setup the keymapper setupKeymapper(system); @@ -448,12 +455,29 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { // to save memory PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, plugin); +#ifdef ENABLE_EVENTRECORDER + Common::String recordMode = ConfMan.get("record_mode"); + Common::String recordFileName = ConfMan.get("record_file_name"); + + if (recordMode == "record") { + g_eventRec.init(g_eventRec.generateRecordFileName(ConfMan.getActiveDomainName()), GUI::EventRecorder::kRecorderRecord); + } else if (recordMode == "playback") { + g_eventRec.init(recordFileName, GUI::EventRecorder::kRecorderPlayback); + } else if ((recordMode == "info") && (!recordFileName.empty())) { + Common::PlaybackFile record; + record.openRead(recordFileName); + debug("info:author=%s name=%s description=%s", record.getHeader().author.c_str(), record.getHeader().name.c_str(), record.getHeader().description.c_str()); + break; + } +#endif // Try to run the game Common::Error result = runGame(plugin, system, specialDebug); +#ifdef ENABLE_EVENTRECORDER // Flush Event recorder file. The recorder does not get reinitialized for next game // which is intentional. Only single game per session is allowed. g_eventRec.deinit(); +#endif #if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES) // do our best to prevent fragmentation by unloading as soon as we can @@ -478,6 +502,11 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { #ifdef FORCE_RTL g_system->getEventManager()->resetQuit(); #endif + #ifdef ENABLE_EVENTRECORDER + if (g_eventRec.checkForContinueGame()) { + continue; + } + #endif // Discard any command line options. It's unlikely that the user // wanted to apply them to *all* games ever launched. @@ -501,7 +530,9 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { GUI::GuiManager::destroy(); Common::ConfigManager::destroy(); Common::DebugManager::destroy(); - Common::EventRecorder::destroy(); +#ifdef ENABLE_EVENTRECORDER + GUI::EventRecorder::destroy(); +#endif Common::SearchManager::destroy(); #ifdef USE_TRANSLATION Common::TranslationManager::destroy(); diff --git a/common/EventDispatcher.cpp b/common/EventDispatcher.cpp index 012a2dfce5..e60c1aa7ff 100644 --- a/common/EventDispatcher.cpp +++ b/common/EventDispatcher.cpp @@ -24,7 +24,7 @@ namespace Common { -EventDispatcher::EventDispatcher() : _mapper(0) { +EventDispatcher::EventDispatcher() : _autoFreeMapper(false), _mapper(0) { } EventDispatcher::~EventDispatcher() { @@ -38,7 +38,9 @@ EventDispatcher::~EventDispatcher() { delete i->observer; } - delete _mapper; + if (_autoFreeMapper) { + delete _mapper; + } _mapper = 0; } @@ -68,11 +70,15 @@ void EventDispatcher::dispatch() { } } -void EventDispatcher::registerMapper(EventMapper *mapper) { - delete _mapper; +void EventDispatcher::registerMapper(EventMapper *mapper, bool autoFree) { + if (_autoFreeMapper) { + delete _mapper; + } _mapper = mapper; + _autoFreeMapper = autoFree; } + void EventDispatcher::registerSource(EventSource *source, bool autoFree) { SourceEntry newEntry; diff --git a/common/EventRecorder.cpp b/common/EventRecorder.cpp deleted file mode 100644 index 5e24f128c3..0000000000 --- a/common/EventRecorder.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* 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. - * - */ - -#include "common/EventRecorder.h" - -#include "common/bufferedstream.h" -#include "common/config-manager.h" -#include "common/random.h" -#include "common/savefile.h" -#include "common/textconsole.h" - -namespace Common { - -DECLARE_SINGLETON(EventRecorder); - -#define RECORD_SIGNATURE 0x54455354 -#define RECORD_VERSION 1 - -uint32 readTime(ReadStream *inFile) { - uint32 d = inFile->readByte(); - if (d == 0xff) { - d = inFile->readUint32LE(); - } - - return d; -} - -void writeTime(WriteStream *outFile, uint32 d) { - //Simple RLE compression - if (d >= 0xff) { - outFile->writeByte(0xff); - outFile->writeUint32LE(d); - } else { - outFile->writeByte(d); - } -} - -void readRecord(SeekableReadStream *inFile, uint32 &diff, Event &event, uint32 &millis) { - millis = readTime(inFile); - - diff = inFile->readUint32LE(); - - event.type = (EventType)inFile->readUint32LE(); - - switch (event.type) { - case EVENT_KEYDOWN: - case EVENT_KEYUP: - event.kbd.keycode = (KeyCode)inFile->readSint32LE(); - event.kbd.ascii = inFile->readUint16LE(); - event.kbd.flags = inFile->readByte(); - break; - case EVENT_MOUSEMOVE: - case EVENT_LBUTTONDOWN: - case EVENT_LBUTTONUP: - case EVENT_RBUTTONDOWN: - case EVENT_RBUTTONUP: - case EVENT_WHEELUP: - case EVENT_WHEELDOWN: - case EVENT_MBUTTONDOWN: - case EVENT_MBUTTONUP: - event.mouse.x = inFile->readSint16LE(); - event.mouse.y = inFile->readSint16LE(); - break; - default: - break; - } -} - -void writeRecord(WriteStream *outFile, uint32 diff, const Event &event, uint32 millis) { - writeTime(outFile, millis); - - outFile->writeUint32LE(diff); - - outFile->writeUint32LE((uint32)event.type); - - switch (event.type) { - case EVENT_KEYDOWN: - case EVENT_KEYUP: - outFile->writeSint32LE(event.kbd.keycode); - outFile->writeUint16LE(event.kbd.ascii); - outFile->writeByte(event.kbd.flags); - break; - case EVENT_MOUSEMOVE: - case EVENT_LBUTTONDOWN: - case EVENT_LBUTTONUP: - case EVENT_RBUTTONDOWN: - case EVENT_RBUTTONUP: - case EVENT_WHEELUP: - case EVENT_WHEELDOWN: - case EVENT_MBUTTONDOWN: - case EVENT_MBUTTONUP: - outFile->writeSint16LE(event.mouse.x); - outFile->writeSint16LE(event.mouse.y); - break; - default: - break; - } -} - -EventRecorder::EventRecorder() { - _recordFile = NULL; - _recordTimeFile = NULL; - _playbackFile = NULL; - _playbackTimeFile = NULL; - _timeMutex = g_system->createMutex(); - _recorderMutex = g_system->createMutex(); - - _eventCount = 0; - _lastEventCount = 0; - _lastMillis = 0; - _lastEventMillis = 0; - - _recordMode = kPassthrough; -} - -EventRecorder::~EventRecorder() { - deinit(); - - g_system->deleteMutex(_timeMutex); - g_system->deleteMutex(_recorderMutex); -} - -void EventRecorder::init() { - String recordModeString = ConfMan.get("record_mode"); - if (recordModeString.compareToIgnoreCase("record") == 0) { - _recordMode = kRecorderRecord; - - debug(3, "EventRecorder: record"); - } else { - if (recordModeString.compareToIgnoreCase("playback") == 0) { - _recordMode = kRecorderPlayback; - debug(3, "EventRecorder: playback"); - } else { - _recordMode = kPassthrough; - debug(3, "EventRecorder: passthrough"); - } - } - - _recordFileName = ConfMan.get("record_file_name"); - if (_recordFileName.empty()) { - _recordFileName = "record.bin"; - } - _recordTempFileName = ConfMan.get("record_temp_file_name"); - if (_recordTempFileName.empty()) { - _recordTempFileName = "record.tmp"; - } - _recordTimeFileName = ConfMan.get("record_time_file_name"); - if (_recordTimeFileName.empty()) { - _recordTimeFileName = "record.time"; - } - - // recorder stuff - if (_recordMode == kRecorderRecord) { - _recordCount = 0; - _recordTimeCount = 0; - _recordFile = wrapBufferedWriteStream(g_system->getSavefileManager()->openForSaving(_recordTempFileName), 128 * 1024); - _recordTimeFile = wrapBufferedWriteStream(g_system->getSavefileManager()->openForSaving(_recordTimeFileName), 128 * 1024); - _recordSubtitles = ConfMan.getBool("subtitles"); - } - - uint32 sign; - uint32 randomSourceCount; - if (_recordMode == kRecorderPlayback) { - _playbackCount = 0; - _playbackTimeCount = 0; - _playbackFile = wrapBufferedSeekableReadStream(g_system->getSavefileManager()->openForLoading(_recordFileName), 128 * 1024, DisposeAfterUse::YES); - _playbackTimeFile = wrapBufferedSeekableReadStream(g_system->getSavefileManager()->openForLoading(_recordTimeFileName), 128 * 1024, DisposeAfterUse::YES); - - if (!_playbackFile) { - warning("Cannot open playback file %s. Playback was switched off", _recordFileName.c_str()); - _recordMode = kPassthrough; - } - - if (!_playbackTimeFile) { - warning("Cannot open playback time file %s. Playback was switched off", _recordTimeFileName.c_str()); - _recordMode = kPassthrough; - } - } - - if (_recordMode == kRecorderPlayback) { - sign = _playbackFile->readUint32LE(); - if (sign != RECORD_SIGNATURE) { - error("Unknown record file signature"); - } - - _playbackFile->readUint32LE(); // version - - // conf vars - ConfMan.setBool("subtitles", _playbackFile->readByte() != 0); - - _recordCount = _playbackFile->readUint32LE(); - _recordTimeCount = _playbackFile->readUint32LE(); - - randomSourceCount = _playbackFile->readUint32LE(); - for (uint i = 0; i < randomSourceCount; ++i) { - RandomSourceRecord rec; - rec.name = ""; - uint32 sLen = _playbackFile->readUint32LE(); - for (uint j = 0; j < sLen; ++j) { - char c = _playbackFile->readSByte(); - rec.name += c; - } - rec.seed = _playbackFile->readUint32LE(); - _randomSourceRecords.push_back(rec); - } - - _hasPlaybackEvent = false; - } - - g_system->getEventManager()->getEventDispatcher()->registerSource(this, false); - g_system->getEventManager()->getEventDispatcher()->registerObserver(this, EventManager::kEventRecorderPriority, false, true); -} - -void EventRecorder::deinit() { - debug(3, "EventRecorder: deinit"); - - g_system->getEventManager()->getEventDispatcher()->unregisterSource(this); - g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this); - - g_system->lockMutex(_timeMutex); - g_system->lockMutex(_recorderMutex); - _recordMode = kPassthrough; - g_system->unlockMutex(_timeMutex); - g_system->unlockMutex(_recorderMutex); - - delete _playbackFile; - delete _playbackTimeFile; - - if (_recordFile != NULL) { - _recordFile->finalize(); - delete _recordFile; - _recordTimeFile->finalize(); - delete _recordTimeFile; - - _playbackFile = g_system->getSavefileManager()->openForLoading(_recordTempFileName); - - assert(_playbackFile); - - _recordFile = g_system->getSavefileManager()->openForSaving(_recordFileName); - _recordFile->writeUint32LE(RECORD_SIGNATURE); - _recordFile->writeUint32LE(RECORD_VERSION); - - // conf vars - _recordFile->writeByte(_recordSubtitles ? 1 : 0); - - _recordFile->writeUint32LE(_recordCount); - _recordFile->writeUint32LE(_recordTimeCount); - - _recordFile->writeUint32LE(_randomSourceRecords.size()); - for (uint i = 0; i < _randomSourceRecords.size(); ++i) { - _recordFile->writeUint32LE(_randomSourceRecords[i].name.size()); - _recordFile->writeString(_randomSourceRecords[i].name); - _recordFile->writeUint32LE(_randomSourceRecords[i].seed); - } - - for (uint i = 0; i < _recordCount; ++i) { - uint32 tempDiff; - Event tempEvent; - uint32 millis; - readRecord(_playbackFile, tempDiff, tempEvent, millis); - writeRecord(_recordFile, tempDiff, tempEvent, millis); - } - - _recordFile->finalize(); - delete _recordFile; - delete _playbackFile; - - //TODO: remove recordTempFileName'ed file - } -} - -void EventRecorder::registerRandomSource(RandomSource &rnd, const String &name) { - if (_recordMode == kRecorderRecord) { - RandomSourceRecord rec; - rec.name = name; - rec.seed = rnd.getSeed(); - _randomSourceRecords.push_back(rec); - } - - if (_recordMode == kRecorderPlayback) { - for (uint i = 0; i < _randomSourceRecords.size(); ++i) { - if (_randomSourceRecords[i].name == name) { - rnd.setSeed(_randomSourceRecords[i].seed); - _randomSourceRecords.remove_at(i); - break; - } - } - } -} - -void EventRecorder::processMillis(uint32 &millis) { - uint32 d; - if (_recordMode == kPassthrough) { - return; - } - - g_system->lockMutex(_timeMutex); - if (_recordMode == kRecorderRecord) { - d = millis - _lastMillis; - writeTime(_recordTimeFile, d); - - _recordTimeCount++; - } - - if (_recordMode == kRecorderPlayback) { - if (_recordTimeCount > _playbackTimeCount) { - d = readTime(_playbackTimeFile); - - while ((_lastMillis + d > millis) && (_lastMillis + d - millis > 50)) { - _recordMode = kPassthrough; - g_system->delayMillis(50); - millis = g_system->getMillis(); - _recordMode = kRecorderPlayback; - } - - millis = _lastMillis + d; - _playbackTimeCount++; - } - } - - _lastMillis = millis; - g_system->unlockMutex(_timeMutex); -} - -bool EventRecorder::processDelayMillis(uint &msecs) { - if (_recordMode == kRecorderPlayback) { - _recordMode = kPassthrough; - - uint32 millis = g_system->getMillis(); - - _recordMode = kRecorderPlayback; - - if (_lastMillis > millis) { - // Skip delay if we're getting late - return true; - } - } - - return false; -} - -bool EventRecorder::notifyEvent(const Event &ev) { - if (_recordMode != kRecorderRecord) - return false; - - StackLock lock(_recorderMutex); - ++_eventCount; - - writeRecord(_recordFile, _eventCount - _lastEventCount, ev, _lastMillis - _lastEventMillis); - - _recordCount++; - _lastEventCount = _eventCount; - _lastEventMillis = _lastMillis; - - return false; -} - -bool EventRecorder::notifyPoll() { - if (_recordMode != kRecorderRecord) - return false; - - ++_eventCount; - - return false; -} - -bool EventRecorder::pollEvent(Event &ev) { - uint32 millis; - - if (_recordMode != kRecorderPlayback) - return false; - - StackLock lock(_recorderMutex); - ++_eventCount; - - if (!_hasPlaybackEvent) { - if (_recordCount > _playbackCount) { - readRecord(_playbackFile, const_cast<uint32&>(_playbackDiff), _playbackEvent, millis); - _playbackCount++; - _hasPlaybackEvent = true; - } - } - - if (_hasPlaybackEvent) { - if (_playbackDiff <= (_eventCount - _lastEventCount)) { - switch (_playbackEvent.type) { - case EVENT_MOUSEMOVE: - case EVENT_LBUTTONDOWN: - case EVENT_LBUTTONUP: - case EVENT_RBUTTONDOWN: - case EVENT_RBUTTONUP: - case EVENT_WHEELUP: - case EVENT_WHEELDOWN: - g_system->warpMouse(_playbackEvent.mouse.x, _playbackEvent.mouse.y); - break; - default: - break; - } - ev = _playbackEvent; - _hasPlaybackEvent = false; - _lastEventCount = _eventCount; - return true; - } - } - - return false; -} - -} // End of namespace Common diff --git a/common/EventRecorder.h b/common/EventRecorder.h deleted file mode 100644 index 43a08b08cd..0000000000 --- a/common/EventRecorder.h +++ /dev/null @@ -1,110 +0,0 @@ -/* 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. - * - */ - -#ifndef COMMON_EVENTRECORDER_H -#define COMMON_EVENTRECORDER_H - -#include "common/scummsys.h" -#include "common/events.h" -#include "common/singleton.h" -#include "common/mutex.h" -#include "common/array.h" - -#define g_eventRec (Common::EventRecorder::instance()) - -namespace Common { - -class RandomSource; -class SeekableReadStream; -class WriteStream; - -/** - * Our generic event recorder. - * - * TODO: Add more documentation. - */ -class EventRecorder : private EventSource, private EventObserver, public Singleton<EventRecorder> { - friend class Singleton<SingletonBaseType>; - EventRecorder(); - ~EventRecorder(); -public: - void init(); - void deinit(); - - /** Register random source so it can be serialized in game test purposes */ - void registerRandomSource(RandomSource &rnd, const String &name); - - /** TODO: Add documentation, this is only used by the backend */ - void processMillis(uint32 &millis); - - /** TODO: Add documentation, this is only used by the backend */ - bool processDelayMillis(uint &msecs); - -private: - bool notifyEvent(const Event &ev); - bool notifyPoll(); - bool pollEvent(Event &ev); - bool allowMapping() const { return false; } - - class RandomSourceRecord { - public: - String name; - uint32 seed; - }; - Array<RandomSourceRecord> _randomSourceRecords; - - bool _recordSubtitles; - volatile uint32 _recordCount; - volatile uint32 _lastRecordEvent; - volatile uint32 _recordTimeCount; - volatile uint32 _lastEventMillis; - WriteStream *_recordFile; - WriteStream *_recordTimeFile; - MutexRef _timeMutex; - MutexRef _recorderMutex; - volatile uint32 _lastMillis; - - volatile uint32 _playbackCount; - volatile uint32 _playbackDiff; - volatile bool _hasPlaybackEvent; - volatile uint32 _playbackTimeCount; - Event _playbackEvent; - SeekableReadStream *_playbackFile; - SeekableReadStream *_playbackTimeFile; - - volatile uint32 _eventCount; - volatile uint32 _lastEventCount; - - enum RecordMode { - kPassthrough = 0, - kRecorderRecord = 1, - kRecorderPlayback = 2 - }; - volatile RecordMode _recordMode; - String _recordFileName; - String _recordTempFileName; - String _recordTimeFileName; -}; - -} // End of namespace Common - -#endif diff --git a/common/debug.h b/common/debug.h index dc94839082..859f3c41b3 100644 --- a/common/debug.h +++ b/common/debug.h @@ -117,5 +117,9 @@ void debugCN(uint32 debugChannels, const char *s, ...) GCC_PRINTF(2, 3); */ extern int gDebugLevel; +//Global constant for EventRecorder debug channel +enum GlobalDebugLevels { + kDebugLevelEventRec = 1 << 30 +}; #endif diff --git a/common/events.h b/common/events.h index 7366c51d36..9029a4096a 100644 --- a/common/events.h +++ b/common/events.h @@ -288,11 +288,14 @@ public: * to the EventDispatcher, thus it will be deleted * with "delete", when EventDispatcher is destroyed. * - * Note there is only one mapper per EventDispatcher - * possible, thus when this method is called twice, - * the former mapper will be destroied. + * @param autoFree Destroy previous mapper [default] + * Normally we allow only one event mapper to exists, + * However Event Recorder must intervent into normal + * event flow without altering its semantics. Thus during + * Event Recorder playback and recording we allow + * two mappers. */ - void registerMapper(EventMapper *mapper); + void registerMapper(EventMapper *mapper, bool autoFree = true); /** * Queries the setup event mapper. @@ -326,6 +329,7 @@ public: */ void unregisterObserver(EventObserver *obs); private: + bool _autoFreeMapper; EventMapper *_mapper; struct Entry { diff --git a/common/macresman.cpp b/common/macresman.cpp index 00562f746a..ba44caafd9 100644 --- a/common/macresman.cpp +++ b/common/macresman.cpp @@ -102,18 +102,18 @@ String MacResManager::computeResForkMD5AsString(uint32 length) const { return computeStreamMD5AsString(resForkStream, MIN<uint32>(length, _resForkSize)); } -bool MacResManager::open(String filename) { +bool MacResManager::open(const String &fileName) { close(); #ifdef MACOSX // Check the actual fork on a Mac computer - String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc"; + String fullPath = ConfMan.get("path") + "/" + fileName + "/..namedfork/rsrc"; FSNode resFsNode = FSNode(fullPath); if (resFsNode.exists()) { SeekableReadStream *macResForkRawStream = resFsNode.createReadStream(); if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) { - _baseFileName = filename; + _baseFileName = fileName; return true; } @@ -123,38 +123,39 @@ bool MacResManager::open(String filename) { File *file = new File(); - // First, let's try to see if the Mac converted name exists - if (file->open(constructAppleDoubleName(filename)) && loadFromAppleDouble(*file)) { - _baseFileName = filename; + // Prefer standalone files first, starting with raw forks + if (file->open(fileName + ".rsrc") && loadFromRawFork(*file)) { + _baseFileName = fileName; return true; } file->close(); - // Check .bin too - if (file->open(filename + ".bin") && loadFromMacBinary(*file)) { - _baseFileName = filename; + // Then try for AppleDouble using Apple's naming + if (file->open(constructAppleDoubleName(fileName)) && loadFromAppleDouble(*file)) { + _baseFileName = fileName; return true; } file->close(); - // Maybe we have a dumped fork? - if (file->open(filename + ".rsrc") && loadFromRawFork(*file)) { - _baseFileName = filename; + // Check .bin for MacBinary next + if (file->open(fileName + ".bin") && loadFromMacBinary(*file)) { + _baseFileName = fileName; return true; } file->close(); - // Fine, what about just the data fork? - if (file->open(filename)) { - _baseFileName = filename; + // As a last resort, see if just the data fork exists + if (file->open(fileName)) { + _baseFileName = fileName; + // FIXME: Is this really needed? if (isMacBinary(*file)) { - file->seek(0, SEEK_SET); + file->seek(0); if (loadFromMacBinary(*file)) return true; } - file->seek(0, SEEK_SET); + file->seek(0); _stream = file; return true; } @@ -165,18 +166,18 @@ bool MacResManager::open(String filename) { return false; } -bool MacResManager::open(FSNode path, String filename) { +bool MacResManager::open(const FSNode &path, const String &fileName) { close(); #ifdef MACOSX // Check the actual fork on a Mac computer - String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc"; + String fullPath = path.getPath() + "/" + fileName + "/..namedfork/rsrc"; FSNode resFsNode = FSNode(fullPath); if (resFsNode.exists()) { SeekableReadStream *macResForkRawStream = resFsNode.createReadStream(); if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) { - _baseFileName = filename; + _baseFileName = fileName; return true; } @@ -184,52 +185,53 @@ bool MacResManager::open(FSNode path, String filename) { } #endif - // First, let's try to see if the Mac converted name exists - FSNode fsNode = path.getChild(constructAppleDoubleName(filename)); + // Prefer standalone files first, starting with raw forks + FSNode fsNode = path.getChild(fileName + ".rsrc"); if (fsNode.exists() && !fsNode.isDirectory()) { SeekableReadStream *stream = fsNode.createReadStream(); - if (loadFromAppleDouble(*stream)) { - _baseFileName = filename; + if (loadFromRawFork(*stream)) { + _baseFileName = fileName; return true; } delete stream; } - // Check .bin too - fsNode = path.getChild(filename + ".bin"); + // Then try for AppleDouble using Apple's naming + fsNode = path.getChild(constructAppleDoubleName(fileName)); if (fsNode.exists() && !fsNode.isDirectory()) { SeekableReadStream *stream = fsNode.createReadStream(); - if (loadFromMacBinary(*stream)) { - _baseFileName = filename; + if (loadFromAppleDouble(*stream)) { + _baseFileName = fileName; return true; } delete stream; } - // Maybe we have a dumped fork? - fsNode = path.getChild(filename + ".rsrc"); + // Check .bin for MacBinary next + fsNode = path.getChild(fileName + ".bin"); if (fsNode.exists() && !fsNode.isDirectory()) { SeekableReadStream *stream = fsNode.createReadStream(); - if (loadFromRawFork(*stream)) { - _baseFileName = filename; + if (loadFromMacBinary(*stream)) { + _baseFileName = fileName; return true; } delete stream; } - // Fine, what about just the data fork? - fsNode = path.getChild(filename); + // As a last resort, see if just the data fork exists + fsNode = path.getChild(fileName); if (fsNode.exists() && !fsNode.isDirectory()) { SeekableReadStream *stream = fsNode.createReadStream(); - _baseFileName = filename; + _baseFileName = fileName; + // FIXME: Is this really needed? if (isMacBinary(*stream)) { - stream->seek(0, SEEK_SET); + stream->seek(0); if (loadFromMacBinary(*stream)) return true; } - stream->seek(0, SEEK_SET); + stream->seek(0); _stream = stream; return true; } @@ -238,22 +240,22 @@ bool MacResManager::open(FSNode path, String filename) { return false; } -bool MacResManager::exists(const String &filename) { +bool MacResManager::exists(const String &fileName) { // Try the file name by itself - if (Common::File::exists(filename)) + if (File::exists(fileName)) return true; // Try the .rsrc extension - if (Common::File::exists(filename + ".rsrc")) + if (File::exists(fileName + ".rsrc")) return true; // Check if we have a MacBinary file - Common::File tempFile; - if (tempFile.open(filename + ".bin") && isMacBinary(tempFile)) + File tempFile; + if (tempFile.open(fileName + ".bin") && isMacBinary(tempFile)) return true; // Check if we have an AppleDouble file - if (tempFile.open(constructAppleDoubleName(filename)) && tempFile.readUint32BE() == 0x00051607) + if (tempFile.open(constructAppleDoubleName(fileName)) && tempFile.readUint32BE() == 0x00051607) return true; return false; @@ -480,10 +482,10 @@ SeekableReadStream *MacResManager::getResource(uint32 typeID, uint16 resID) { return _stream->readStream(len); } -SeekableReadStream *MacResManager::getResource(const String &filename) { +SeekableReadStream *MacResManager::getResource(const String &fileName) { for (uint32 i = 0; i < _resMap.numTypes; i++) { for (uint32 j = 0; j < _resTypes[i].items; j++) { - if (_resLists[i][j].nameOffset != -1 && filename.equalsIgnoreCase(_resLists[i][j].name)) { + if (_resLists[i][j].nameOffset != -1 && fileName.equalsIgnoreCase(_resLists[i][j].name)) { _stream->seek(_dataOffset + _resLists[i][j].dataOffset); uint32 len = _stream->readUint32BE(); @@ -499,13 +501,13 @@ SeekableReadStream *MacResManager::getResource(const String &filename) { return 0; } -SeekableReadStream *MacResManager::getResource(uint32 typeID, const String &filename) { +SeekableReadStream *MacResManager::getResource(uint32 typeID, const String &fileName) { for (uint32 i = 0; i < _resMap.numTypes; i++) { if (_resTypes[i].id != typeID) continue; for (uint32 j = 0; j < _resTypes[i].items; j++) { - if (_resLists[i][j].nameOffset != -1 && filename.equalsIgnoreCase(_resLists[i][j].name)) { + if (_resLists[i][j].nameOffset != -1 && fileName.equalsIgnoreCase(_resLists[i][j].name)) { _stream->seek(_dataOffset + _resLists[i][j].dataOffset); uint32 len = _stream->readUint32BE(); @@ -574,7 +576,7 @@ void MacResManager::readMap() { } } -Common::String MacResManager::constructAppleDoubleName(Common::String name) { +String MacResManager::constructAppleDoubleName(String name) { // Insert "._" before the last portion of a path name for (int i = name.size() - 1; i >= 0; i--) { if (i == 0) { diff --git a/common/macresman.h b/common/macresman.h index ed74da9cc6..cca6592f21 100644 --- a/common/macresman.h +++ b/common/macresman.h @@ -54,27 +54,32 @@ public: /** * Open a Mac data/resource fork pair. + * + * This uses SearchMan to find the data/resource forks. This should only be used + * from inside an engine. + * * @param filename The base file name of the file * @note This will check for the raw resource fork, MacBinary, and AppleDouble formats. * @return True on success */ - bool open(String filename); + bool open(const String &fileName); /** * Open a Mac data/resource fork pair. + * * @param path The path that holds the forks * @param filename The base file name of the file * @note This will check for the raw resource fork, MacBinary, and AppleDouble formats. * @return True on success */ - bool open(FSNode path, String filename); + bool open(const FSNode &path, const String &fileName); /** * See if a Mac data/resource fork pair exists. * @param filename The base file name of the file * @return True if either a data fork or resource fork with this name exists */ - static bool exists(const String &filename); + static bool exists(const String &fileName); /** * Close the Mac data/resource fork pair. @@ -94,12 +99,6 @@ public: bool hasResFork() const; /** - * Check if the given stream is in the MacBinary format. - * @param stream The stream we're checking - */ - static bool isMacBinary(SeekableReadStream &stream); - - /** * Read resource from the MacBinary file * @param typeID FourCC of the type * @param resID Resource ID to fetch @@ -176,7 +175,13 @@ private: bool loadFromMacBinary(SeekableReadStream &stream); bool loadFromAppleDouble(SeekableReadStream &stream); - static Common::String constructAppleDoubleName(Common::String name); + static String constructAppleDoubleName(String name); + + /** + * Check if the given stream is in the MacBinary format. + * @param stream The stream we're checking + */ + static bool isMacBinary(SeekableReadStream &stream); enum { kResForkNone = 0, diff --git a/common/memstream.h b/common/memstream.h index 260fb64d84..7fa6500753 100644 --- a/common/memstream.h +++ b/common/memstream.h @@ -89,8 +89,9 @@ public: */ class MemoryWriteStream : public WriteStream { private: - byte *_ptr; const uint32 _bufSize; +protected: + byte *_ptr; uint32 _pos; bool _err; public: @@ -117,6 +118,40 @@ public: }; /** + * MemoryWriteStream subclass with ability to set stream position indicator. + */ +class SeekableMemoryWriteStream : public MemoryWriteStream { +private: + byte *_ptrOrig; +public: + SeekableMemoryWriteStream(byte *buf, uint32 len) : MemoryWriteStream(buf, len), _ptrOrig(buf) {} + uint32 seek(uint32 offset, int whence = SEEK_SET) { + switch (whence) { + case SEEK_END: + // SEEK_END works just like SEEK_SET, only 'reversed', + // i.e. from the end. + offset = size() + offset; + // Fall through + case SEEK_SET: + _ptr = _ptrOrig + offset; + _pos = offset; + break; + case SEEK_CUR: + _ptr += offset; + _pos += offset; + break; + } + // Post-Condition + if (_pos > size()) { + _pos = size(); + _ptr = _ptrOrig + _pos; + } + return _pos; + } +}; + + +/** * A sort of hybrid between MemoryWriteStream and Array classes. A stream * that grows as it's written to. */ diff --git a/common/module.mk b/common/module.mk index d96b11ee40..9f9126c8ef 100644 --- a/common/module.mk +++ b/common/module.mk @@ -10,7 +10,6 @@ MODULE_OBJS := \ error.o \ EventDispatcher.o \ EventMapper.o \ - EventRecorder.o \ file.o \ fs.o \ gui_options.o \ @@ -51,5 +50,10 @@ MODULE_OBJS += \ rdft.o \ sinetables.o +ifdef ENABLE_EVENTRECORDER +MODULE_OBJS += \ + recorderfile.o +endif + # Include common rules include $(srcdir)/rules.mk diff --git a/common/random.cpp b/common/random.cpp index fd75534c44..de1269b485 100644 --- a/common/random.cpp +++ b/common/random.cpp @@ -21,7 +21,7 @@ #include "common/random.h" #include "common/system.h" -#include "common/EventRecorder.h" +#include "gui/EventRecorder.h" namespace Common { @@ -30,13 +30,12 @@ RandomSource::RandomSource(const String &name) { // Use system time as RNG seed. Normally not a good idea, if you are using // a RNG for security purposes, but good enough for our purposes. assert(g_system); - uint32 seed = g_system->getMillis(); - setSeed(seed); - // Register this random source with the event recorder. This may end - // up querying or resetting the current seed, so we must call it - // *after* the initial seed has been set. - g_eventRec.registerRandomSource(*this, name); +#ifdef ENABLE_EVENTRECORDER + setSeed(g_eventRec.getRandomSeed(name)); +#else + setSeed(g_system->getMillis()); +#endif } void RandomSource::setSeed(uint32 seed) { diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp new file mode 100644 index 0000000000..d08bc599f1 --- /dev/null +++ b/common/recorderfile.cpp @@ -0,0 +1,714 @@ +/* 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. + * + */ + +#include "common/system.h" +#include "gui/EventRecorder.h" +#include "common/md5.h" +#include "common/recorderfile.h" +#include "common/savefile.h" +#include "common/bufferedstream.h" +#include "graphics/thumbnail.h" +#include "graphics/surface.h" +#include "graphics/scaler.h" + +#define RECORD_VERSION 1 + +namespace Common { + +PlaybackFile::PlaybackFile() : _tmpRecordFile(_tmpBuffer, kRecordBuffSize), _tmpPlaybackFile(_tmpBuffer, kRecordBuffSize) { + _readStream = NULL; + _writeStream = NULL; + _screenshotsFile = NULL; + _mode = kClosed; + + _recordFile = 0; + _headerDumped = false; + _recordCount = 0; + _eventsSize = 0; + memset(_tmpBuffer, 1, kRecordBuffSize); +} + +PlaybackFile::~PlaybackFile() { + close(); +} + +bool PlaybackFile::openWrite(const String &fileName) { + close(); + _header.fileName = fileName; + _writeStream = wrapBufferedWriteStream(g_system->getSavefileManager()->openForSaving(fileName), 128 * 1024); + _headerDumped = false; + _recordCount = 0; + if (_writeStream == NULL) { + return false; + } + _mode = kWrite; + return true; +} + +bool PlaybackFile::openRead(const String &fileName) { + close(); + _header.fileName = fileName; + _eventsSize = 0; + _tmpPlaybackFile.seek(0); + _readStream = wrapBufferedSeekableReadStream(g_system->getSavefileManager()->openForLoading(fileName), 128 * 1024, DisposeAfterUse::YES); + if (_readStream == NULL) { + debugC(1, kDebugLevelEventRec, "playback:action=\"Load File\" result=fail reason=\"file %s not found\"", fileName.c_str()); + return false; + } + if (!parseHeader()) { + debugC(1, kDebugLevelEventRec, "playback:action=\"Load File\" result=fail reason=\"header parsing failed\""); + return false; + } + _screenshotsFile = wrapBufferedWriteStream(g_system->getSavefileManager()->openForSaving("screenshots.bin"), 128 * 1024); + debugC(1, kDebugLevelEventRec, "playback:action=\"Load File\" result=success"); + _mode = kRead; + return true; +} + +void PlaybackFile::close() { + delete _readStream; + _readStream = NULL; + if (_writeStream != NULL) { + dumpRecordsToFile(); + _writeStream->finalize(); + delete _writeStream; + _writeStream = NULL; + updateHeader(); + } + if (_screenshotsFile != NULL) { + _screenshotsFile->finalize(); + delete _screenshotsFile; + _screenshotsFile = NULL; + } + for (HashMap<String, SaveFileBuffer>::iterator i = _header.saveFiles.begin(); i != _header.saveFiles.end(); ++i) { + free(i->_value.buffer); + } + _header.saveFiles.clear(); + _mode = kClosed; +} + +bool PlaybackFile::parseHeader() { + PlaybackFileHeader result; + ChunkHeader nextChunk; + _playbackParseState = kFileStateCheckFormat; + if (!readChunkHeader(nextChunk)) { + _playbackParseState = kFileStateError; + return false; + } + while ((_playbackParseState != kFileStateDone) && (_playbackParseState != kFileStateError)) { + if (processChunk(nextChunk)) { + if (!readChunkHeader(nextChunk)) { + warning("Error in header parsing"); + _playbackParseState = kFileStateError; + } + } + } + return _playbackParseState == kFileStateDone; +} + +bool PlaybackFile::checkPlaybackFileVersion() { + uint32 version; + version = _readStream->readUint32LE(); + if (version != RECORD_VERSION) { + warning("Incorrect playback file version. Expected version %d, but got %d.", RECORD_VERSION, version); + return false; + } + return true; +} + + +String PlaybackFile::readString(int len) { + String result; + char buf[50]; + int readSize = 49; + while (len > 0) { + if (len <= 49) { + readSize = len; + } + _readStream->read(buf, readSize); + buf[readSize] = 0; + result += buf; + len -= readSize; + } + return result; +} + +bool PlaybackFile::readChunkHeader(PlaybackFile::ChunkHeader &nextChunk) { + nextChunk.id = (FileTag)_readStream->readUint32LE(); + nextChunk.len = _readStream->readUint32LE(); + return !_readStream->err() && !_readStream->eos(); +} + +bool PlaybackFile::processChunk(ChunkHeader &nextChunk) { + switch (_playbackParseState) { + case kFileStateCheckFormat: + if (nextChunk.id == kFormatIdTag) { + _playbackParseState = kFileStateCheckVersion; + } else { + warning("Unknown playback file signature"); + _playbackParseState = kFileStateError; + } + break; + case kFileStateCheckVersion: + if ((nextChunk.id == kVersionTag) && checkPlaybackFileVersion()) { + _playbackParseState = kFileStateSelectSection; + } else { + _playbackParseState = kFileStateError; + } + break; + case kFileStateSelectSection: + switch (nextChunk.id) { + case kHeaderSectionTag: + _playbackParseState = kFileStateProcessHeader; + break; + case kHashSectionTag: + _playbackParseState = kFileStateProcessHash; + break; + case kRandomSectionTag: + _playbackParseState = kFileStateProcessRandom; + break; + case kEventTag: + case kScreenShotTag: + _readStream->seek(-8, SEEK_CUR); + _playbackParseState = kFileStateDone; + return false; + case kSaveTag: + _playbackParseState = kFileStateProcessSave; + break; + case kSettingsSectionTag: + _playbackParseState = kFileStateProcessSettings; + warning("Loading record header"); + break; + default: + _readStream->skip(nextChunk.len); + break; + } + break; + case kFileStateProcessSave: + if (nextChunk.id == kSaveRecordTag) { + readSaveRecord(); + } else { + _playbackParseState = kFileStateSelectSection; + return false; + } + break; + case kFileStateProcessHeader: + switch (nextChunk.id) { + case kAuthorTag: + _header.author = readString(nextChunk.len); + break; + case kCommentsTag: + _header.notes = readString(nextChunk.len); + break; + case kNameTag: + _header.name = readString(nextChunk.len); + break; + default: + _playbackParseState = kFileStateSelectSection; + return false; + } + break; + case kFileStateProcessHash: + if (nextChunk.id == kHashRecordTag) { + readHashMap(nextChunk); + } else { + _playbackParseState = kFileStateSelectSection; + return false; + } + break; + case kFileStateProcessRandom: + if (nextChunk.id == kRandomRecordTag) { + processRndSeedRecord(nextChunk); + } else { + _playbackParseState = kFileStateSelectSection; + return false; + } + break; + case kFileStateProcessSettings: + if (nextChunk.id == kSettingsRecordTag) { + if (!processSettingsRecord()) { + _playbackParseState = kFileStateError; + return false; + } + } else { + _playbackParseState = kFileStateSelectSection; + return false; + } + break; + default: + return false; + } + return true; +} + +void PlaybackFile::returnToChunkHeader() { + _readStream->seek(-8, SEEK_CUR); +} + +void PlaybackFile::readHashMap(ChunkHeader chunk) { + String hashName = readString(chunk.len - 32); + String hashMd5 = readString(32); + _header.hashRecords[hashName] = hashMd5; +} + +void PlaybackFile::processRndSeedRecord(ChunkHeader chunk) { + String randomSourceName = readString(chunk.len - 4); + uint32 randomSourceSeed = _readStream->readUint32LE(); + _header.randomSourceRecords[randomSourceName] = randomSourceSeed; +} + +bool PlaybackFile::processSettingsRecord() { + ChunkHeader keyChunk; + if (!readChunkHeader(keyChunk) || (keyChunk.id != kSettingsRecordKeyTag)) { + warning("Invalid format of settings section"); + return false; + } + String key = readString(keyChunk.len); + ChunkHeader valueChunk; + if (!readChunkHeader(valueChunk) || (valueChunk.id != kSettingsRecordValueTag)) { + warning("Invalid format of settings section"); + return false; + } + String value = readString(valueChunk.len); + _header.settingsRecords[key] = value; + return true; +} + + +bool PlaybackFile::readSaveRecord() { + ChunkHeader fileNameChunk; + if (!readChunkHeader(fileNameChunk) || (fileNameChunk.id != kSaveRecordNameTag)) { + warning("Invalid format of save section"); + return false; + } + String fileName = readString(fileNameChunk.len); + ChunkHeader saveBufferChunk; + if (!readChunkHeader(saveBufferChunk) || (saveBufferChunk.id != kSaveRecordBufferTag)) { + warning("Invalid format of save section"); + return false; + } + SaveFileBuffer buf; + buf.size = saveBufferChunk.len; + buf.buffer = (byte *)malloc(saveBufferChunk.len); + _readStream->read(buf.buffer, buf.size); + _header.saveFiles[fileName] = buf; + debugC(1, kDebugLevelEventRec, "playback:action=\"Load save file\" filename=%s len=%d", fileName.c_str(), buf.size); + return true; +} + + + +RecorderEvent PlaybackFile::getNextEvent() { + assert(_mode == kRead); + if (isEventsBufferEmpty()) { + PlaybackFile::ChunkHeader header; + header.id = kFormatIdTag; + while (header.id != kEventTag) { + if (!readChunkHeader(header) || _readStream->eos()) { + break; + } + switch (header.id) { + case kEventTag: + readEventsToBuffer(header.len); + break; + case kScreenShotTag: + _readStream->seek(-4, SEEK_CUR); + header.len = _readStream->readUint32BE(); + _readStream->skip(header.len-8); + break; + case kMD5Tag: + checkRecordedMD5(); + break; + default: + _readStream->skip(header.len); + break; + } + } + } + RecorderEvent result; + readEvent(result); + return result; +} + +bool PlaybackFile::isEventsBufferEmpty() { + return (uint32)_tmpPlaybackFile.pos() == _eventsSize; +} + +void PlaybackFile::readEvent(RecorderEvent& event) { + event.recordedtype = (RecorderEventType)_tmpPlaybackFile.readByte(); + switch (event.recordedtype) { + case kRecorderEventTypeTimer: + event.time = _tmpPlaybackFile.readUint32LE(); + break; + case kRecorderEventTypeNormal: + event.type = (EventType)_tmpPlaybackFile.readUint32LE(); + switch (event.type) { + case EVENT_KEYDOWN: + case EVENT_KEYUP: + event.time = _tmpPlaybackFile.readUint32LE(); + event.kbd.keycode = (KeyCode)_tmpPlaybackFile.readSint32LE(); + event.kbd.ascii = _tmpPlaybackFile.readUint16LE(); + event.kbd.flags = _tmpPlaybackFile.readByte(); + break; + case EVENT_MOUSEMOVE: + case EVENT_LBUTTONDOWN: + case EVENT_LBUTTONUP: + case EVENT_RBUTTONDOWN: + case EVENT_RBUTTONUP: + case EVENT_WHEELUP: + case EVENT_WHEELDOWN: + case EVENT_MBUTTONDOWN: + case EVENT_MBUTTONUP: + event.time = _tmpPlaybackFile.readUint32LE(); + event.mouse.x = _tmpPlaybackFile.readSint16LE(); + event.mouse.y = _tmpPlaybackFile.readSint16LE(); + break; + default: + event.time = _tmpPlaybackFile.readUint32LE(); + break; + } + break; + } + event.synthetic = true; +} + +void PlaybackFile::readEventsToBuffer(uint32 size) { + _readStream->read(_tmpBuffer, size); + _tmpPlaybackFile.seek(0); + _eventsSize = size; +} + +void PlaybackFile::saveScreenShot(Graphics::Surface &screen, byte md5[16]) { + dumpRecordsToFile(); + _writeStream->writeUint32LE(kMD5Tag); + _writeStream->writeUint32LE(16); + _writeStream->write(md5, 16); + Graphics::saveThumbnail(*_writeStream, screen); +} + +void PlaybackFile::dumpRecordsToFile() { + if (!_headerDumped) { + dumpHeaderToFile(); + _headerDumped = true; + } + if (_recordCount == 0) { + return; + } + _writeStream->writeUint32LE(kEventTag); + _writeStream->writeUint32LE(_tmpRecordFile.pos()); + _writeStream->write(_tmpBuffer, _tmpRecordFile.pos()); + _tmpRecordFile.seek(0); + _recordCount = 0; +} + +void PlaybackFile::dumpHeaderToFile() { + _writeStream->writeUint32LE(kFormatIdTag); + // Specify size for first tag as NULL since we cannot calculate + // size of the file at time of the header dumping + _writeStream->writeUint32LE(0); + _writeStream->writeUint32LE(kVersionTag); + _writeStream->writeUint32LE(4); + _writeStream->writeUint32LE(RECORD_VERSION); + writeHeaderSection(); + writeGameHash(); + writeRandomRecords(); + writeGameSettings(); + writeSaveFilesSection(); +} + +void PlaybackFile::writeHeaderSection() { + uint32 headerSize = 0; + if (!_header.author.empty()) { + headerSize = _header.author.size() + 8; + } + if (!_header.notes.empty()) { + headerSize += _header.notes.size() + 8; + } + if (!_header.name.empty()) { + headerSize += _header.name.size() + 8; + } + if (headerSize == 0) { + return; + } + _writeStream->writeUint32LE(kHeaderSectionTag); + _writeStream->writeUint32LE(headerSize); + if (!_header.author.empty()) { + _writeStream->writeUint32LE(kAuthorTag); + _writeStream->writeUint32LE(_header.author.size()); + _writeStream->writeString(_header.author); + } + if (!_header.notes.empty()) { + _writeStream->writeUint32LE(kCommentsTag); + _writeStream->writeUint32LE(_header.notes.size()); + _writeStream->writeString(_header.notes); + } + if (!_header.name.empty()) { + _writeStream->writeUint32LE(kNameTag); + _writeStream->writeUint32LE(_header.name.size()); + _writeStream->writeString(_header.name); + } +} + +void PlaybackFile::writeGameHash() { + uint32 hashSectionSize = 0; + for (StringMap::iterator i = _header.hashRecords.begin(); i != _header.hashRecords.end(); ++i) { + hashSectionSize = hashSectionSize + i->_key.size() + i->_value.size() + 8; + } + if (_header.hashRecords.size() == 0) { + return; + } + _writeStream->writeUint32LE(kHashSectionTag); + _writeStream->writeUint32LE(hashSectionSize); + for (StringMap::iterator i = _header.hashRecords.begin(); i != _header.hashRecords.end(); ++i) { + _writeStream->writeUint32LE(kHashRecordTag); + _writeStream->writeUint32LE(i->_key.size() + i->_value.size()); + _writeStream->writeString(i->_key); + _writeStream->writeString(i->_value); + } +} + +void PlaybackFile::writeRandomRecords() { + uint32 randomSectionSize = 0; + for (RandomSeedsDictionary::iterator i = _header.randomSourceRecords.begin(); i != _header.randomSourceRecords.end(); ++i) { + randomSectionSize = randomSectionSize + i->_key.size() + 12; + } + if (_header.randomSourceRecords.size() == 0) { + return; + } + _writeStream->writeUint32LE(kRandomSectionTag); + _writeStream->writeUint32LE(randomSectionSize); + for (RandomSeedsDictionary::iterator i = _header.randomSourceRecords.begin(); i != _header.randomSourceRecords.end(); ++i) { + _writeStream->writeUint32LE(kRandomRecordTag); + _writeStream->writeUint32LE(i->_key.size() + 4); + _writeStream->writeString(i->_key); + _writeStream->writeUint32LE(i->_value); + } +} + +void PlaybackFile::writeEvent(const RecorderEvent &event) { + assert(_mode == kWrite); + _recordCount++; + _tmpRecordFile.writeByte(event.recordedtype); + switch (event.recordedtype) { + case kRecorderEventTypeTimer: + _tmpRecordFile.writeUint32LE(event.time); + break; + case kRecorderEventTypeNormal: + _tmpRecordFile.writeUint32LE((uint32)event.type); + switch(event.type) { + case EVENT_KEYDOWN: + case EVENT_KEYUP: + _tmpRecordFile.writeUint32LE(event.time); + _tmpRecordFile.writeSint32LE(event.kbd.keycode); + _tmpRecordFile.writeUint16LE(event.kbd.ascii); + _tmpRecordFile.writeByte(event.kbd.flags); + break; + case EVENT_MOUSEMOVE: + case EVENT_LBUTTONDOWN: + case EVENT_LBUTTONUP: + case EVENT_RBUTTONDOWN: + case EVENT_RBUTTONUP: + case EVENT_WHEELUP: + case EVENT_WHEELDOWN: + case EVENT_MBUTTONDOWN: + case EVENT_MBUTTONUP: + _tmpRecordFile.writeUint32LE(event.time); + _tmpRecordFile.writeSint16LE(event.mouse.x); + _tmpRecordFile.writeSint16LE(event.mouse.y); + break; + default: + _tmpRecordFile.writeUint32LE(event.time); + break; + } + break; + } + if (_recordCount == kMaxBufferedRecords) { + dumpRecordsToFile(); + } +} + +void PlaybackFile::writeGameSettings() { + _writeStream->writeUint32LE(kSettingsSectionTag); + uint32 settingsSectionSize = 0; + for (StringMap::iterator i = _header.settingsRecords.begin(); i != _header.settingsRecords.end(); ++i) { + settingsSectionSize += i->_key.size() + i->_value.size() + 24; + } + _writeStream->writeUint32LE(settingsSectionSize); + for (StringMap::iterator i = _header.settingsRecords.begin(); i != _header.settingsRecords.end(); ++i) { + _writeStream->writeUint32LE(kSettingsRecordTag); + _writeStream->writeUint32LE(i->_key.size() + i->_value.size() + 16); + _writeStream->writeUint32LE(kSettingsRecordKeyTag); + _writeStream->writeUint32LE(i->_key.size()); + _writeStream->writeString(i->_key); + _writeStream->writeUint32LE(kSettingsRecordValueTag); + _writeStream->writeUint32LE(i->_value.size()); + _writeStream->writeString(i->_value); + } +} + +int PlaybackFile::getScreensCount() { + if (_mode != kRead) { + return 0; + } + _readStream->seek(0); + int result = 0; + while (skipToNextScreenshot()) { + uint32 size = _readStream->readUint32BE(); + _readStream->skip(size-8); + ++result; + } + return result; +} + +bool PlaybackFile::skipToNextScreenshot() { + while (true) { + FileTag id = (FileTag)_readStream->readUint32LE(); + if (_readStream->eos()) { + break; + } + if (id == kScreenShotTag) { + return true; + } + else { + uint32 size = _readStream->readUint32LE(); + _readStream->skip(size); + } + } + return false; +} + +Graphics::Surface *PlaybackFile::getScreenShot(int number) { + if (_mode != kRead) { + return NULL; + } + _readStream->seek(0); + int screenCount = 1; + while (skipToNextScreenshot()) { + if (screenCount == number) { + screenCount++; + _readStream->seek(-4, SEEK_CUR); + return Graphics::loadThumbnail(*_readStream); + } else { + uint32 size = _readStream->readUint32BE(); + _readStream->skip(size-8); + screenCount++; + } + } + return NULL; +} + +void PlaybackFile::updateHeader() { + if (_mode == kWrite) { + _readStream = g_system->getSavefileManager()->openForLoading(_header.fileName); + } + _readStream->seek(0); + skipHeader(); + String tmpFilename = "_" + _header.fileName; + _writeStream = g_system->getSavefileManager()->openForSaving(tmpFilename); + dumpHeaderToFile(); + uint32 readedSize = 0; + do { + readedSize = _readStream->read(_tmpBuffer, kRecordBuffSize); + _writeStream->write(_tmpBuffer, readedSize); + } while (readedSize != 0); + delete _writeStream; + _writeStream = NULL; + delete _readStream; + _readStream = NULL; + g_system->getSavefileManager()->removeSavefile(_header.fileName); + g_system->getSavefileManager()->renameSavefile(tmpFilename, _header.fileName); + if (_mode == kRead) { + openRead(_header.fileName); + } +} + +void PlaybackFile::skipHeader() { + while (true) { + uint32 id = _readStream->readUint32LE(); + if (_readStream->eos()) { + break; + } + if ((id == kScreenShotTag) || (id == kEventTag) || (id == kMD5Tag)) { + _readStream->seek(-4, SEEK_CUR); + return; + } + else { + uint32 size = _readStream->readUint32LE(); + _readStream->skip(size); + } + } +} + +void PlaybackFile::addSaveFile(const String &fileName, InSaveFile *saveStream) { + uint oldPos = saveStream->pos(); + saveStream->seek(0); + _header.saveFiles[fileName].buffer = (byte *)malloc(saveStream->size()); + _header.saveFiles[fileName].size = saveStream->size(); + saveStream->read(_header.saveFiles[fileName].buffer, saveStream->size()); + saveStream->seek(oldPos); +} + +void PlaybackFile::writeSaveFilesSection() { + uint size = 0; + for (HashMap<String, SaveFileBuffer>::iterator i = _header.saveFiles.begin(); i != _header.saveFiles.end(); ++i) { + size += i->_value.size + i->_key.size() + 24; + } + if (size == 0) { + return; + } + _writeStream->writeSint32LE(kSaveTag); + _writeStream->writeSint32LE(size); + for (HashMap<String, SaveFileBuffer>::iterator i = _header.saveFiles.begin(); i != _header.saveFiles.end(); ++i) { + _writeStream->writeSint32LE(kSaveRecordTag); + _writeStream->writeSint32LE(i->_key.size() + i->_value.size + 16); + _writeStream->writeSint32LE(kSaveRecordNameTag); + _writeStream->writeSint32LE(i->_key.size()); + _writeStream->writeString(i->_key); + _writeStream->writeSint32LE(kSaveRecordBufferTag); + _writeStream->writeSint32LE(i->_value.size); + _writeStream->write(i->_value.buffer, i->_value.size); + } +} + + +void PlaybackFile::checkRecordedMD5() { + uint8 currentMD5[16]; + uint8 savedMD5[16]; + Graphics::Surface screen; + _readStream->read(savedMD5, 16); + if (!g_eventRec.grabScreenAndComputeMD5(screen, currentMD5)) { + return; + } + uint32 seconds = g_system->getMillis(true) / 1000; + String screenTime = String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60); + if (memcmp(savedMD5, currentMD5, 16) != 0) { + debugC(1, kDebugLevelEventRec, "playback:action=\"Check screenshot\" time=%s result = fail", screenTime.c_str()); + warning("Recorded and current screenshots are different"); + } else { + debugC(1, kDebugLevelEventRec, "playback:action=\"Check screenshot\" time=%s result = success", screenTime.c_str()); + } + Graphics::saveThumbnail(*_screenshotsFile, screen); + screen.free(); +} + + +} diff --git a/common/recorderfile.h b/common/recorderfile.h new file mode 100644 index 0000000000..1c95e5a915 --- /dev/null +++ b/common/recorderfile.h @@ -0,0 +1,180 @@ +/* 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. + * + */ + +#ifndef COMMON_RECORDERFILE_H +#define COMMON_RECORDERFILE_H + +#include "common/scummsys.h" +#include "common/events.h" +#include "common/mutex.h" +#include "common/memstream.h" +#include "common/config-manager.h" +#include "common/savefile.h" + +//capacity of records buffer +#define kMaxBufferedRecords 10000 +#define kRecordBuffSize sizeof(RecorderEvent) * kMaxBufferedRecords + +namespace Common { + +enum RecorderEventType { + kRecorderEventTypeNormal = 0, + kRecorderEventTypeTimer = 1 +}; + +struct RecorderEvent : Event { + RecorderEventType recordedtype; + uint32 time; +}; + + + +class PlaybackFile { + typedef HashMap<String, uint32, IgnoreCase_Hash, IgnoreCase_EqualTo> RandomSeedsDictionary; + enum fileMode { + kRead = 0, + kWrite = 1, + kClosed = 2 + }; + enum PlaybackFileState { + kFileStateCheckFormat, + kFileStateCheckVersion, + kFileStateProcessHash, + kFileStateProcessHeader, + kFileStateProcessRandom, + kFileStateSelectSection, + kFileStateProcessSettings, + kFileStateProcessSave, + kFileStateDone, + kFileStateError + }; + enum FileTag { + kFormatIdTag = MKTAG('P','B','C','K'), + kVersionTag = MKTAG('V','E','R','S'), + kHeaderSectionTag = MKTAG('H','E','A','D'), + kHashSectionTag = MKTAG('H','A','S','H'), + kRandomSectionTag = MKTAG('R','A','N','D'), + kEventTag = MKTAG('E','V','N','T'), + kScreenShotTag = MKTAG('B','M','H','T'), + kSettingsSectionTag = MKTAG('S','E','T','T'), + kAuthorTag = MKTAG('H','A','U','T'), + kCommentsTag = MKTAG('H','C','M','T'), + kNameTag = MKTAG('H','N','A','M'), + kHashRecordTag = MKTAG('H','R','C','D'), + kRandomRecordTag = MKTAG('R','R','C','D'), + kSettingsRecordTag = MKTAG('S','R','E','C'), + kSettingsRecordKeyTag = MKTAG('S','K','E','Y'), + kSettingsRecordValueTag = MKTAG('S','V','A','L'), + kSaveTag = MKTAG('S','A','V','E'), + kSaveRecordTag = MKTAG('R','S','A','V'), + kSaveRecordNameTag = MKTAG('S','N','A','M'), + kSaveRecordBufferTag = MKTAG('S','B','U','F'), + kMD5Tag = MKTAG('M','D','5',' ') + }; + struct ChunkHeader { + FileTag id; + uint32 len; + }; +public: + struct SaveFileBuffer { + byte *buffer; + uint32 size; + }; + struct PlaybackFileHeader { + String fileName; + String author; + String name; + String notes; + String description; + StringMap hashRecords; + StringMap settingsRecords; + HashMap<String, SaveFileBuffer> saveFiles; + RandomSeedsDictionary randomSourceRecords; + }; + PlaybackFile(); + ~PlaybackFile(); + + bool openWrite(const String &fileName); + bool openRead(const String &fileName); + void close(); + + RecorderEvent getNextEvent(); + void writeEvent(const RecorderEvent &event); + + void saveScreenShot(Graphics::Surface &screen, byte md5[16]); + Graphics::Surface *getScreenShot(int number); + int getScreensCount(); + + bool isEventsBufferEmpty(); + PlaybackFileHeader &getHeader() {return _header;} + void updateHeader(); + void addSaveFile(const String &fileName, InSaveFile *saveStream); +private: + WriteStream *_recordFile; + WriteStream *_writeStream; + WriteStream *_screenshotsFile; + MemoryReadStream _tmpPlaybackFile; + SeekableReadStream *_readStream; + SeekableMemoryWriteStream _tmpRecordFile; + + fileMode _mode; + bool _headerDumped; + int _recordCount; + uint32 _eventsSize; + byte _tmpBuffer[kRecordBuffSize]; + PlaybackFileHeader _header; + PlaybackFileState _playbackParseState; + + void skipHeader(); + bool parseHeader(); + bool processChunk(ChunkHeader &nextChunk); + void returnToChunkHeader(); + + bool readSaveRecord(); + void checkRecordedMD5(); + bool readChunkHeader(ChunkHeader &nextChunk); + void processRndSeedRecord(ChunkHeader chunk); + bool processSettingsRecord(); + + bool checkPlaybackFileVersion(); + + void dumpHeaderToFile(); + void writeSaveFilesSection(); + void writeGameSettings(); + void writeHeaderSection(); + void writeGameHash(); + void writeRandomRecords(); + + void dumpRecordsToFile(); + + String readString(int len); + void readHashMap(ChunkHeader chunk); + + bool skipToNextScreenshot(); + void readEvent(RecorderEvent& event); + void readEventsToBuffer(uint32 size); + bool grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5[16]); +}; + +} // End of namespace Common + +#endif diff --git a/common/str.cpp b/common/str.cpp index 5d647ee4f0..4a10792373 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -361,6 +361,25 @@ void String::deleteChar(uint32 p) { _size--; } +void String::erase(uint32 p, uint32 len) { + assert(p < _size); + + makeUnique(); + // If len == npos or p + len is over the end, remove all the way to the end + if (len == npos || p + len >= _size) { + // Delete char at p as well. So _size = (p - 1) + 1 + _size = p; + // Null terminate + _str[_size] = 0; + return; + } + + for ( ; p + len <= _size; p++) { + _str[p] = _str[p + len]; + } + _size -= len; +} + void String::clear() { decRefCount(_extern._refCount); diff --git a/common/str.h b/common/str.h index 5039130707..6b4475e1c4 100644 --- a/common/str.h +++ b/common/str.h @@ -43,6 +43,8 @@ namespace Common { * behavior in some operations. */ class String { +public: + static const uint32 npos = 0xFFFFFFFF; protected: /** * The size of the internal storage. Increasing this means less heap @@ -191,6 +193,9 @@ public: /** Remove the character at position p from the string. */ void deleteChar(uint32 p); + /** Remove all characters from position p to the p + len. If len = String::npos, removes all characters to the end */ + void erase(uint32 p, uint32 len = npos); + /** Set character c at position p, replacing the previous character there. */ void setChar(char c, uint32 p); diff --git a/common/system.cpp b/common/system.cpp index 59210544ab..d86b5b2b81 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -30,6 +30,9 @@ #include "common/taskbar.h" #include "common/updates.h" #include "common/textconsole.h" +#ifdef ENABLE_EVENTRECORDER +#include "gui/EventRecorder.h" +#endif #include "backends/audiocd/default/default-audiocd.h" #include "backends/fs/fs-factory.h" @@ -84,7 +87,7 @@ void OSystem::initBackend() { error("Backend failed to instantiate audio CD manager"); if (!_eventManager) error("Backend failed to instantiate event manager"); - if (!_timerManager) + if (!getTimerManager()) error("Backend failed to instantiate timer manager"); // TODO: We currently don't check _savefileManager, because at least @@ -152,3 +155,15 @@ Common::String OSystem::getDefaultConfigFileName() { Common::String OSystem::getSystemLanguage() const { return "en_US"; } + +Common::TimerManager *OSystem::getTimerManager() { + return _timerManager; +} + +Common::SaveFileManager *OSystem::getSavefileManager() { +#ifdef ENABLE_EVENTRECORDER + return g_eventRec.getSaveManager(_savefileManager); +#else + return _savefileManager; +#endif +} diff --git a/common/system.h b/common/system.h index 99b947d7f3..81c4bdf34e 100644 --- a/common/system.h +++ b/common/system.h @@ -890,8 +890,14 @@ public: /** @name Events and Time */ //@{ - /** Get the number of milliseconds since the program was started. */ - virtual uint32 getMillis() = 0; + /** Get the number of milliseconds since the program was started. + + @param skipRecord Skip recording of this value by event recorder. + This could be needed particularly when we are in + an on-screen GUI loop where player can pause + the recording. + */ + virtual uint32 getMillis(bool skipRecord = false) = 0; /** Delay/sleep for the specified amount of milliseconds. */ virtual void delayMillis(uint msecs) = 0; @@ -907,9 +913,7 @@ public: * Return the timer manager singleton. For more information, refer * to the TimerManager documentation. */ - inline Common::TimerManager *getTimerManager() { - return _timerManager; - } + virtual Common::TimerManager *getTimerManager(); /** * Return the event manager singleton. For more information, refer @@ -1086,9 +1090,7 @@ public: * and other modifiable persistent game data. For more information, * refer to the SaveFileManager documentation. */ - inline Common::SaveFileManager *getSavefileManager() { - return _savefileManager; - } + Common::SaveFileManager *getSavefileManager(); #if defined(USE_TASKBAR) /** diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp index 6bb40e0980..c3698d5fce 100644 --- a/common/winexe_ne.cpp +++ b/common/winexe_ne.cpp @@ -231,7 +231,7 @@ bool NEResources::readResourceTable(uint32 offset) { if (id & 0x8000) res.id = id & 0x7FFF; else - res.id = getResourceString(*_exe, offset + id); + res.id = getResourceString(*_exe, offset + id); if (typeID & 0x8000 && ((typeID & 0x7FFF) < ARRAYSIZE(s_resTypeNames)) && s_resTypeNames[typeID & 0x7FFF][0] != 0) debug(2, "Found resource %s %s", s_resTypeNames[typeID & 0x7FFF], res.id.toString().c_str()); @@ -113,6 +113,7 @@ _seq_midi=auto _sndio=auto _timidity=auto _zlib=auto +_mpeg2=auto _sparkle=auto _png=auto _theoradec=auto @@ -138,9 +139,10 @@ _build_hq_scalers=yes _enable_prof=no _global_constructors=no _bink=yes -# Default vkeybd/keymapper options +# Default vkeybd/keymapper/eventrec options _vkeybd=no _keymapper=no +_eventrec=auto # GUI translation options _translation=yes # Default platform settings @@ -816,7 +818,7 @@ Usage: $0 [OPTIONS]... Configuration: -h, --help display this help and exit - --backend=BACKEND backend to build (android, bada, dc, dingux, ds, gph, + --backend=BACKEND backend to build (android, tizen, dc, dingux, ds, gph, iphone, linuxmoto, maemo, n64, null, openpandora, ps2, psp, samsungtv, sdl, webos, wii, wince) [sdl] @@ -845,7 +847,7 @@ Fine tuning of the installation directories: Special configuration feature: --host=HOST cross-compile to target HOST (arm-linux, ...) special targets: android for Android - bada for Samsung BADA + tizen for Samsung Tizen caanoo for Caanoo dingux for Dingux dreamcast for Sega Dreamcast @@ -898,6 +900,10 @@ Optional Features: --disable-hq-scalers exclude HQ2x and HQ3x scalers --disable-translation don't build support for translated messages --disable-taskbar don't build support for taskbar and launcher integration + --enable-vkeybd build virtual keyboard support + --enable-keymapper build key mapper support + --enable-eventrecorder enable event recording functionality + --disable-eventrecorder disable event recording functionality --enable-updates build support for updates --enable-text-console use text console instead of graphical console --enable-verbose-build enable regular echoing of commands during build @@ -924,6 +930,9 @@ Optional Libraries: --with-zlib-prefix=DIR Prefix where zlib is installed (optional) --disable-zlib disable zlib (compression) support [autodetect] + --with-mpeg2-prefix=DIR Prefix where libmpeg2 is installed (optional) + --enable-mpeg2 enable mpeg2 codec for cutscenes [autodetect] + --with-opengl-prefix=DIR Prefix where OpenGL (ES) is installed (optional) --disable-opengl disable OpenGL (ES) support [autodetect] @@ -1004,6 +1013,8 @@ for ac_option in $@; do --disable-sparkle) _sparkle=no ;; --enable-nasm) _nasm=yes ;; --disable-nasm) _nasm=no ;; + --enable-mpeg2) _mpeg2=yes ;; + --disable-mpeg2) _mpeg2=no ;; --disable-png) _png=no ;; --enable-png) _png=yes ;; --disable-theoradec) _theoradec=no ;; @@ -1036,6 +1047,8 @@ for ac_option in $@; do --disable-vkeybd) _vkeybd=no ;; --enable-keymapper) _keymapper=yes ;; --disable-keymapper) _keymapper=no ;; + --enable-eventrecorder) _eventrec=yes ;; + --disable-eventrecorder) _eventrec=no ;; --enable-text-console) _text_console=yes ;; --disable-text-console) _text_console=no ;; --with-fluidsynth-prefix=*) @@ -1043,6 +1056,11 @@ for ac_option in $@; do FLUIDSYNTH_CFLAGS="-I$arg/include" FLUIDSYNTH_LIBS="-L$arg/lib" ;; + --with-mpeg2-prefix=*) + arg=`echo $ac_option | cut -d '=' -f 2` + MPEG2_CFLAGS="-I$arg/include" + MPEG2_LIBS="-L$arg/lib" + ;; --with-alsa-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` ALSA_CFLAGS="-I$arg/include" @@ -1247,16 +1265,6 @@ arm-riscos) _host_os=riscos _host_cpu=arm ;; -bada) - _host_os=bada - if test "$_debug_build" = yes; then - _host_cpu=i686 - _host_alias=i686-mingw32 - else - _host_cpu=arm - _host_alias=arm-samsung-nucleuseabi - fi - ;; caanoo) _host_os=gph-linux _host_cpu=arm @@ -1382,6 +1390,11 @@ samsungtv) _host_cpu=arm _host_alias=arm-linux-gnueabi ;; +tizen) + _host_os=tizen + _host_cpu=arm + _host_alias=arm-linux-gnueabi + ;; webos) _host_os=webos _host_cpu=arm @@ -1491,12 +1504,6 @@ android) exit 1 fi ;; -bada) - if test -z "$BADA_SDK"; then - echo "Please set BADA_SDK in your environment. export BADA_SDK=<path to Bada SDK>" - exit 1 - fi - ;; ds | gamecube | wii) if test -z "$DEVKITPRO"; then echo "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to devkitPRO>" @@ -1538,6 +1545,12 @@ psp) exit 1 fi ;; +tizen) + if test -z "$TIZEN_ROOTSTRAP"; then + echo "Please set TIZEN_ROOTSTRAP in your environment. export TIZEN_ROOTSTRAP=<path to Tizen SDK device profile>" + exit 1 + fi + ;; webos) if test -z "$WEBOS_SDK"; then echo "Please set WEBOS_SDK in your environment. export WEBOS_SDK=<path to WebOS SDK>" @@ -1731,7 +1744,7 @@ if test "$have_gcc" = yes ; then case $_host_os in # newlib-based system include files suppress non-C89 function # declarations under __STRICT_ANSI__ - amigaos* | android | bada | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | ps3 | wii | wince ) + amigaos* | android | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | ps3 | tizen | wii | wince ) ;; *) CXXFLAGS="$CXXFLAGS -ansi" @@ -1767,12 +1780,13 @@ echo $_use_cxx11 # However, some platforms use GNU extensions in system header files, so # for these we must not use -pedantic. case $_host_os in -android | gamecube | psp | wii | webos) +android | gamecube | psp | tizen | wii | webos) ;; *) # ICC does not support pedantic, while GCC and clang do. if test "$have_icc" = no ; then - CXXFLAGS="$CXXFLAGS -pedantic" + # We *do* want the 'long long' extension. + CXXFLAGS="$CXXFLAGS -pedantic -Wno-long-long" fi ;; esac @@ -1830,7 +1844,7 @@ esac # Determine a data type with the given length # find_type_with_size() { - for datatype in int short char long "long long" unknown; do + for datatype in int short char long "long long" __int64 "long long int" unknown; do cat > tmp_find_type_with_size.cpp << EOF typedef $datatype ac__type_sizeof_; int main() { @@ -2051,16 +2065,6 @@ case $_host_os in add_line_to_config_mk "ANDROID_SDK = $ANDROID_SDK" _seq_midi=no ;; - bada) - BADA_SDK_ROOT="`cygpath -m ${BADA_SDK}`" - add_line_to_config_mk "BADA_SDK = $BADA_SDK" - add_line_to_config_mk "BADA_SDK_ROOT = $BADA_SDK_ROOT" - - # assume dependencies have been installed in cygwin's /usr/local - CYGWIN_USR_LOCAL="`cygpath -m /usr/local`" - LDFLAGS="$LDFLAGS -L${CYGWIN_USR_LOCAL}/lib" - CXXFLAGS="$CXXFLAGS -I${CYGWIN_USR_LOCAL}/include" - ;; beos*) DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" # Needs -lbind -lsocket for the timidity MIDI driver @@ -2176,7 +2180,7 @@ case $_host_os in # When not cross-compiling, enable large file support, but don't # care if getconf doesn't exist or doesn't recognize LFS_CFLAGS. if test -z "$_host"; then - CXXFLAGS="$CXXFLAGS $(getconf LFS_CFLAGS 2>/dev/null)" + CXXFLAGS="$CXXFLAGS `getconf LFS_CFLAGS 2>/dev/null`" fi ;; maemo) @@ -2238,6 +2242,12 @@ case $_host_os in # Needs -lbind -lsocket for the timidity MIDI driver LIBS="$LIBS -lnsl -lsocket" ;; + tizen) + add_line_to_config_mk "TIZEN_ROOTSTRAP = $TIZEN_ROOTSTRAP" + LDFLAGS="$LDFLAGS --sysroot=${TIZEN_ROOTSTRAP}" + LDFLAGS="$LDFLAGS -L${TIZEN_LIBS}/lib" + CXXFLAGS="$CXXFLAGS -I${TIZEN_LIBS}/include" + ;; webos) CXXFLAGS="$CXXFLAGS --sysroot=$WEBOS_PDK/arm-gcc/sysroot" CXXFLAGS="$CXXFLAGS -I$WEBOS_PDK/include" @@ -2316,22 +2326,6 @@ if test -n "$_host"; then arm-riscos|linupy) DEFINES="$DEFINES -DLINUPY" ;; - bada) - _unix=yes - _backend="bada" - _port_mk="backends/platform/bada/bada.mk" - if test "$_debug_build" = yes; then - _arm_asm=no - else - _arm_asm=yes - fi - _taskbar=no - _build_scalers=no - _seq_midi=no - _mt32emu=no - _timidity=no - _vkeybd=yes - ;; bfin*) ;; caanoo) @@ -2381,7 +2375,8 @@ if test -n "$_host"; then DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER" DEFINES="$DEFINES -DDISABLE_TEXT_CONSOLE" DEFINES="$DEFINES -DDISABLE_COMMAND_LINE" - if test "$_release_build" = yes; then + # Enable serial debugging output only when --enable-debug is passed + if test "$_release_build" = yes -o "$_debug_build" != yes; then DEFINES="$DEFINES -DNOSERIAL" fi _optimization_level=-O3 @@ -2644,6 +2639,18 @@ if test -n "$_host"; then _mt32emu=no _vkeybd=yes ;; + tizen) + _unix=yes + _backend="tizen" + _port_mk="backends/platform/tizen/tizen.mk" + _arm_asm=yes + _taskbar=no + _build_scalers=no + _seq_midi=no + _mt32emu=no + _timidity=no + _vkeybd=yes + ;; webos) _backend="webos" _port_mk="backends/platform/webos/webos.mk" @@ -2694,34 +2701,6 @@ case $_backend in LDFLAGS="$LDFLAGS -Wl,-z,noexecstack" INCLUDES="$INCLUDES -I$ANDROID_NDK/sources/cxx-stl/system/include" ;; - bada) - # dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included - DEFINES="$DEFINES -DBADA -DDISABLE_STDIO_FILESTREAM -DNONSTANDARD_PORT" - DEFINES="$DEFINES -DNO_STDERR_STDOUT" - DEFINES="$DEFINES -DDISABLE_COMMAND_LINE" - INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/bada ' - INCLUDES="$INCLUDES "'-I$(BADA_SDK)/include' - INCLUDES="$INCLUDES "'-I$(BADA_SDK_ROOT)/Include' - if test "$_debug_build" = yes; then - # debug using with the simulator - CXXFLAGS="$CXXFLAGS -D_DEBUG -DSHP -DBUILD_DLL -fmessage-length=0" - else - # created a shared library for inclusion via the eclipse build - CXXFLAGS="$CXXFLAGS -DSHP" - CXXFLAGS="$CXXFLAGS -fpic" - CXXFLAGS="$CXXFLAGS -fshort-wchar" - CXXFLAGS="$CXXFLAGS -mcpu=cortex-a8" - CXXFLAGS="$CXXFLAGS -mfpu=vfpv3" - CXXFLAGS="$CXXFLAGS -mfloat-abi=hard" - CXXFLAGS="$CXXFLAGS -mlittle-endian" - CXXFLAGS="$CXXFLAGS -mthumb-interwork" - CXXFLAGS="$CXXFLAGS -Wno-psabi" - CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" - CXXFLAGS="$CXXFLAGS -fno-short-enums" - fi - HOSTEXEPRE=lib - HOSTEXEEXT=.a - ;; dc) INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/dc' INCLUDES="$INCLUDES "'-isystem $(ronindir)/include' @@ -2729,7 +2708,8 @@ case $_backend in LDFLAGS="$LDFLAGS -nostartfiles" LDFLAGS="$LDFLAGS "'$(ronindir)/lib/crt0.o' LDFLAGS="$LDFLAGS "'-L$(ronindir)/lib' - if test "$_release_build" = yes; then + # Enable serial debugging output only when --enable-debug is passed + if test "$_release_build" = yes -o "$_debug_build" != yes; then LIBS="$LIBS -lronin-noserial -lm" else LIBS="$LIBS -lronin -lm" @@ -2804,6 +2784,25 @@ case $_backend in LDFLAGS="$LDFLAGS -shared" LDFLAGS="$LDFLAGS -fpic" ;; + tizen) + # dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included + DEFINES="$DEFINES -DTIZEN -DDISABLE_STDIO_FILESTREAM -DNONSTANDARD_PORT" + DEFINES="$DEFINES -DNO_STDERR_STDOUT" + DEFINES="$DEFINES -DDISABLE_COMMAND_LINE" + INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/tizen' + INCLUDES="$INCLUDES "'-I$(TIZEN_ROOTSTRAP)/usr/include' + INCLUDES="$INCLUDES "'-I$(TIZEN_ROOTSTRAP)/usr/include/osp' + if test "$_debug_build" = yes; then + CXXFLAGS="$CXXFLAGS -D_DEBUG -DBUILD_DLL -O0 -g3" + fi + # created a shared library for inclusion via the eclipse build + CXXFLAGS="$CXXFLAGS -Wno-psabi" + CXXFLAGS="$CXXFLAGS --sysroot=${TIZEN_ROOTSTRAP}" + CXXFLAGS="$CXXFLAGS -fmessage-length=0" + CXXFLAGS="$CXXFLAGS -fPIC" + HOSTEXEPRE=lib + HOSTEXEEXT=.a + ;; webos) # There is no sdl-config in the WebOS PDK so we don't use find_sdlconfig here. # The PDL library acts as the WebOS device toolchain, and is required to control the virtual keyboard among other OS-level events. @@ -2869,7 +2868,7 @@ esac # Enable 16bit support only for backends which support it # case $_backend in - android | bada | dingux | dc | gph | iphone | maemo | openpandora | psp | samsungtv | sdl | webos | wii) + android | dingux | dc | gph | iphone | maemo | openpandora | psp | samsungtv | sdl | tizen | webos | wii) if test "$_16bit" = auto ; then _16bit=yes else @@ -2882,6 +2881,20 @@ case $_backend in esac # +# Enable Event Recorder only for backends that support it +# +case $_backend in + sdl) + if test "$_eventrec" = auto ; then + _eventrec=yes + fi + ;; + *) + _eventrec=no + ;; +esac + +# # Disable savegame timestamp support for backends which don't have a reliable real time clock # case $_backend in @@ -3461,6 +3474,52 @@ define_in_config_if_yes "$_zlib" 'USE_ZLIB' echo "$_zlib" # +# Check for LibMPEG2 +# +echocheck "libmpeg2 >= 0.4.0" +if test "$_mpeg2" = auto ; then + _mpeg2=no + cat > $TMPC << EOF +typedef signed $type_1_byte int8_t; +typedef signed $type_2_byte int16_t; +typedef signed $type_4_byte int32_t; + +typedef unsigned $type_1_byte uint8_t; +typedef unsigned $type_2_byte uint16_t; +typedef unsigned $type_4_byte uint32_t; + +extern "C" { +#include <mpeg2dec/mpeg2.h> +} + +int main(void) { + #if MPEG2_RELEASE < MPEG2_VERSION(0, 4, 0) + #error libmpeg2 version too low + #endif + + /* mpeg2_state_t first appears in 0.4.0 */ + mpeg2_state_t state; + + return 0; +} +EOF + + if test -n "$_host"; then + # don't execute while cross compiling + cc_check $MPEG2_CFLAGS $MPEG2_LIBS -lmpeg2 && _mpeg2=yes + else + cc_check_no_clean $MPEG2_CFLAGS $MPEG2_LIBS -lmpeg2 && $TMPO$HOSTEXEEXT && _mpeg2=yes + cc_check_clean + fi +fi +if test "$_mpeg2" = yes ; then + INCLUDES="$INCLUDES $MPEG2_CFLAGS" + LIBS="$LIBS $MPEG2_LIBS -lmpeg2" +fi +define_in_config_if_yes "$_mpeg2" 'USE_MPEG2' +echo "$_mpeg2" + +# # Check for Sparkle if updates support is enabled # echocheck "Sparkle" @@ -3563,8 +3622,8 @@ if test "$_libunity" = auto ; then ;; *) # Unity has a lots of dependencies, update the libs and cflags var with them - LIBUNITY_LIBS="$LIBUNITY_LIBS $(pkg-config --libs unity = 3.8.4 2>> "$TMPLOG")" - LIBUNITY_CFLAGS="$LIBUNITY_CFLAGS $(pkg-config --cflags unity = 3.8.4 2>> "$TMPLOG")" + LIBUNITY_LIBS="$LIBUNITY_LIBS `pkg-config --libs unity = 3.8.4 2>> "$TMPLOG"`" + LIBUNITY_CFLAGS="$LIBUNITY_CFLAGS `pkg-config --cflags unity = 3.8.4 2>> "$TMPLOG"`" _libunity=no cat > $TMPC << EOF #include <unity.h> @@ -3721,7 +3780,7 @@ EOF fi case $_host_os in - bada) + tizen) # components live in non-standard locations so just assume sane SDK _opengl=yes _opengles=yes @@ -3797,10 +3856,21 @@ fi define_in_config_if_yes $_nasm 'USE_NASM' # -# Enable vkeybd / keymapper +# Enable vkeybd / keymapper / event recorder # define_in_config_if_yes $_vkeybd 'ENABLE_VKEYBD' define_in_config_if_yes $_keymapper 'ENABLE_KEYMAPPER' +define_in_config_if_yes $_eventrec 'ENABLE_EVENTRECORDER' + +# +# Check if the keymapper and the event recorder are enabled simultaneously +# +if test "$_keymapper" = yes ; then + if test "$_eventrec" = yes ; then + echo "ERROR: The keymapper and the event recorder cannot be enabled simultaneously currently, please disable one of the two" + exit 1 + fi +fi # Check whether to build translation support # @@ -3879,7 +3949,14 @@ fi test "x$prefix" = xNONE && prefix=/usr/local test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -DEFINES="$DEFINES -DDATA_PATH=\\\"$datadir\\\"" +case $_host_os in + mingw*) + # Windows stores all the external data files in executable file. + ;; + *) + DEFINES="$DEFINES -DDATA_PATH=\\\"$datadir\\\"" + ;; +esac case $_backend in openpandora) @@ -3946,7 +4023,11 @@ if test "$_vkeybd" = yes ; then fi if test "$_keymapper" = yes ; then - echo ", keymapper" + echo_n ", keymapper" +fi + +if test "$_eventrec" = yes ; then + echo ", event recorder" else echo fi diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp index ca809e0aac..01cde620e7 100644 --- a/devtools/create_kyradat/create_kyradat.cpp +++ b/devtools/create_kyradat/create_kyradat.cpp @@ -2350,8 +2350,10 @@ bool createIDMap(PAKFile &out, const ExtractInformation *eI, const int *needList for (const int *id = needList; *id != -1; ++id) { WRITE_BE_UINT16(dst, *id); dst += 2; const ExtractFilename *fDesc = getFilenameDesc(*id); - if (!fDesc) + if (!fDesc) { + delete[] map; return false; + } *dst++ = getTypeID(fDesc->type); WRITE_BE_UINT32(dst, getFilename(eI, *id)); dst += 4; } @@ -2359,15 +2361,18 @@ bool createIDMap(PAKFile &out, const ExtractInformation *eI, const int *needList char filename[12]; if (!getFilename(filename, eI, 0)) { fprintf(stderr, "ERROR: Could not create ID map for game\n"); + delete[] map; return false; } out.removeFile(filename); if (!out.addFile(filename, map, mapSize)) { fprintf(stderr, "ERROR: Could not add ID map \"%s\" to kyra.dat\n", filename); + delete[] map; return false; } + delete[] map; return true; } diff --git a/devtools/create_kyradat/pak.cpp b/devtools/create_kyradat/pak.cpp index 0203285a8f..0d085f563c 100644 --- a/devtools/create_kyradat/pak.cpp +++ b/devtools/create_kyradat/pak.cpp @@ -142,6 +142,7 @@ bool PAKFile::outputAllFiles() { printf("OK\n"); } else { printf("FAILED\n"); + fclose(file); return false; } fclose(file); @@ -168,6 +169,7 @@ bool PAKFile::outputFileAs(const char *f, const char *fn) { printf("OK\n"); } else { printf("FAILED\n"); + fclose(file); return false; } fclose(file); diff --git a/devtools/create_lure/process_actions.cpp b/devtools/create_lure/process_actions.cpp index db965730cb..d1ddbf03f2 100644 --- a/devtools/create_lure/process_actions.cpp +++ b/devtools/create_lure/process_actions.cpp @@ -149,6 +149,7 @@ uint16 process_action_sequence_entry(int supportIndex, byte *data, uint16 remain if (startOffset == 0x7328) { startOffset = 0x72ae; maxOffset = 0x7382; } if (startOffset == 0x702f) { startOffset = 0x6f3d; maxOffset = 0x70a3; } if (startOffset == 0x7886) { startOffset = 0x742a; maxOffset = 0x7896; } + break; case DE_DEU: if (startOffset == 0x7edb) { startOffset = 0x7ead; maxOffset = 0x7f05; } if (startOffset == 0x7ab8) { startOffset = 0x796c; maxOffset = 0x7ae2; } diff --git a/devtools/create_neverhood/create_neverhood.cpp b/devtools/create_neverhood/create_neverhood.cpp index f34f20882c..446ee5ec3b 100644 --- a/devtools/create_neverhood/create_neverhood.cpp +++ b/devtools/create_neverhood/create_neverhood.cpp @@ -69,13 +69,13 @@ bool loadExe(const char *filename) { bool validateMd5() { uint8 digest[16]; - + md5_buffer(data, dataSize, digest); - + printf("MD5 of nhc.exe is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", - digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], + digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]); - + if (memcmp(kNhcExeMd5, digest, 16)) { printf("MD5 hash of nhc.exe doesn't match the expected value! Quitting...\n"); return false; @@ -112,7 +112,7 @@ uint32 calcHash(const char *value) { struct HitRect { int16 x1, y1, x2, y2; uint16 messageNum; - + void load(uint32 offset) { byte *item = getData(offset); x1 = READ_LE_UINT16(item + 0); @@ -120,7 +120,7 @@ struct HitRect { x2 = READ_LE_UINT16(item + 4); y2 = READ_LE_UINT16(item + 6); messageNum = READ_LE_UINT16(item + 8); - } + } void save(FILE *fd) { writeUint16LE(fd, x1); @@ -129,11 +129,11 @@ struct HitRect { writeUint16LE(fd, y2); writeUint16LE(fd, messageNum); } - + int getItemSize() const { return 10; } - + }; struct MessageItem { @@ -141,22 +141,22 @@ struct MessageItem { uint32 messageParam; MessageItem() {} MessageItem(uint16 msgNum, uint32 msgParam) : messageNum(msgNum), messageParam(msgParam) {} - + void load(uint32 offset) { byte *item = getData(offset); messageNum = READ_LE_UINT16(item + 0); messageParam = READ_LE_UINT32(item + 4); - } + } void save(FILE *fd) { writeUint16LE(fd, messageNum); writeUint32LE(fd, messageParam); } - + int getItemSize() const { return 8; } - + }; struct SubRectItem { @@ -175,7 +175,7 @@ struct SubRectItem { // Add the message to the message list addMessageList(messageListCount, messageListOffset); } - + void save(FILE *fd) { writeUint16LE(fd, x1); writeUint16LE(fd, y1); @@ -183,11 +183,11 @@ struct SubRectItem { writeUint16LE(fd, y2); writeUint32LE(fd, messageListOffset); } - + int getItemSize() const { return 16; } - + }; struct RectItem { @@ -212,7 +212,7 @@ struct RectItem { subItemOffset += 16; subRectItems.push_back(subRectItem); } - } + } void save(FILE *fd) { writeUint16LE(fd, x1); @@ -223,11 +223,11 @@ struct RectItem { for (uint32 j = 0; j < subRectItems.size(); j++) subRectItems[j].save(fd); } - + int getItemSize() const { return 16; } - + }; struct NavigationItem { @@ -238,10 +238,10 @@ struct NavigationItem { byte interactive; byte middleFlag; uint32 mouseCursorFileHash; - + void load(uint32 offset) { byte *item = getData(offset); - fileHash = READ_LE_UINT32(item + 0); + fileHash = READ_LE_UINT32(item + 0); leftSmackerFileHash = READ_LE_UINT32(item + 4); rightSmackerFileHash = READ_LE_UINT32(item + 8); middleSmackerFileHash = READ_LE_UINT32(item + 12); @@ -263,7 +263,7 @@ struct NavigationItem { int getItemSize() const { return 24; } - + }; struct SceneInfo140Item { @@ -347,24 +347,24 @@ struct SceneInfo2700Item { template<class ITEMCLASS> class StaticDataList { public: - uint32 id; + uint32 id; std::vector<ITEMCLASS> items; - + virtual ~StaticDataList() { } - + void add(ITEMCLASS item) { items.push_back(item); } - + int getCount() const { return items.size(); } - + ITEMCLASS *getListItem(int index) { return &items[index]; } - + virtual bool specialLoadList(uint32 count, uint32 offset) { return false; } @@ -398,7 +398,7 @@ class RectList : public StaticDataList<RectItem> { }; class MessageList : public StaticDataList<MessageItem> { -public: +public: virtual bool specialLoadList(uint32 count, uint32 offset) { // Special code for message lists which are set at runtime (but otherwise constant) @@ -455,7 +455,7 @@ public: } return false; } - + }; class NavigationList : public StaticDataList<NavigationItem> { @@ -465,11 +465,11 @@ template<class LISTCLASS> class StaticDataListVector { public: std::vector<LISTCLASS*> lists; - + void add(LISTCLASS *list) { lists.push_back(list); } - + void loadListVector(const uint32 *offsets) { for (int i = 0; offsets[i] != 0; i += 2) { LISTCLASS *list = new LISTCLASS(); @@ -486,7 +486,7 @@ public: lists.push_back(list); } } - + void saveListVector(FILE *fd) { writeUint32LE(fd, lists.size()); for (typename std::vector<LISTCLASS*>::iterator it = lists.begin(); it != lists.end(); it++) { @@ -500,7 +500,7 @@ template<class ITEMCLASS> class StaticDataVector { public: std::vector<ITEMCLASS> items; - + void loadVector(const uint32 *offsets) { for (int i = 0; offsets[i] != 0; i++) { ITEMCLASS item; @@ -508,7 +508,7 @@ public: items.push_back(item); } } - + void saveVector(FILE *fd) { writeUint32LE(fd, items.size()); for (typename std::vector<ITEMCLASS>::iterator it = items.begin(); it != items.end(); it++) { @@ -522,8 +522,8 @@ StaticDataListVector<HitRectList> hitRectLists; StaticDataListVector<RectList> rectLists; StaticDataListVector<MessageList> messageLists; StaticDataListVector<NavigationList> navigationLists; -StaticDataVector<SceneInfo140Item> sceneInfo140Items; -StaticDataVector<SceneInfo2700Item> sceneInfo2700Items; +StaticDataVector<SceneInfo140Item> sceneInfo140Items; +StaticDataVector<SceneInfo2700Item> sceneInfo2700Items; void addMessageList(uint32 messageListCount, uint32 messageListOffset) { MessageList *messageList = new MessageList(); @@ -550,7 +550,7 @@ int main(int argc, char *argv[]) { writeUint32LE(datFile, 0x11223344); // Some magic writeUint32LE(datFile, DAT_VERSION); - + messageLists.saveListVector(datFile); rectLists.saveListVector(datFile); hitRectLists.saveListVector(datFile); diff --git a/devtools/create_neverhood/tables.h b/devtools/create_neverhood/tables.h index ea39aa807d..eb136491db 100644 --- a/devtools/create_neverhood/tables.h +++ b/devtools/create_neverhood/tables.h @@ -122,7 +122,7 @@ static const uint32 rectListOffsets[] = { // Scene2406 1, 0x004B78C8, 1, 0x004B78D8, - // Scene2501 + // Scene2501 1, 0x004B2608, // Scene2732 1, 0x004AE360, diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp index a8e09ff5eb..3ee5fc4f97 100644 --- a/devtools/create_project/create_project.cpp +++ b/devtools/create_project/create_project.cpp @@ -109,7 +109,7 @@ enum ProjectType { int main(int argc, char *argv[]) { #ifndef USE_WIN32_API // Initialize random number generator for UUID creation - std::srand((uint)std::time(0)); + std::srand((unsigned int)std::time(0)); #endif if (argc < 2) { @@ -189,7 +189,7 @@ int main(int argc, char *argv[]) { msvcVersion = atoi(argv[++i]); - if (msvcVersion != 8 && msvcVersion != 9 && msvcVersion != 10 && msvcVersion != 11) { + if (msvcVersion != 8 && msvcVersion != 9 && msvcVersion != 10 && msvcVersion != 11 && msvcVersion != 12) { std::cerr << "ERROR: Unsupported version: \"" << msvcVersion << "\" passed to \"--msvc-version\"!\n"; return -1; } @@ -264,7 +264,7 @@ int main(int argc, char *argv[]) { setup.filePrefix.erase(setup.filePrefix.size() - 1); } else if (!std::strcmp(argv[i], "--output-dir")) { if (i + 1 >= argc) { - std::cerr << "ERROR: Missing \"path\" parameter for \"--output-dirx\"!\n"; + std::cerr << "ERROR: Missing \"path\" parameter for \"--output-dir\"!\n"; return -1; } @@ -279,12 +279,23 @@ int main(int argc, char *argv[]) { setup.createInstaller = true; } else if (!std::strcmp(argv[i], "--tools")) { setup.devTools = true; + } else if (!std::strcmp(argv[i], "--tests")) { + setup.tests = true; } else { std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n"; return -1; } } + // When building tests, disable some features + if (setup.tests) { + setFeatureBuildState("mt32emu", setup.features, false); + setFeatureBuildState("eventrecorder", setup.features, false); + + for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j) + j->enable = false; + } + // Print status cout << "Enabled engines:\n\n"; for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) { @@ -310,6 +321,23 @@ int main(int argc, char *argv[]) { cout << " " << i->description << '\n'; } + // Check if the keymapper and the event recorder are enabled simultaneously + bool keymapperEnabled = false; + for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) { + if (i->enable && !strcmp(i->name, "keymapper")) + keymapperEnabled = true; + if (i->enable && !strcmp(i->name, "eventrecorder") && keymapperEnabled) { + std::cerr << "ERROR: The keymapper and the event recorder cannot be enabled simultaneously currently, please disable one of the two\n"; + return -1; + } + } + + // Check if tools and tests are enabled simultaneously + if (setup.devTools && setup.tests) { + std::cerr << "ERROR: The tools and tests projects cannot be created simultaneously\n"; + return -1; + } + // Setup defines and libraries setup.defines = getEngineDefines(setup.engines); setup.libraries = getFeatureLibraries(setup.features); @@ -347,8 +375,8 @@ int main(int argc, char *argv[]) { return -1; case kProjectCodeBlocks: - if (setup.devTools) { - std::cerr << "ERROR: Building tools is not supported for the CodeBlocks project type!\n"; + if (setup.devTools || setup.tests) { + std::cerr << "ERROR: Building tools or tests is not supported for the CodeBlocks project type!\n"; return -1; } @@ -520,8 +548,8 @@ int main(int argc, char *argv[]) { break; case kProjectXcode: - if (setup.devTools) { - std::cerr << "ERROR: Building tools is not supported for the XCode project type!\n"; + if (setup.devTools || setup.tests) { + std::cerr << "ERROR: Building tools or tests is not supported for the XCode project type!\n"; return -1; } @@ -562,6 +590,11 @@ int main(int argc, char *argv[]) { setup.projectDescription += "Tools"; } + if (setup.tests) { + setup.projectName += "-tests"; + setup.projectDescription += "Tests"; + } + provider->createProject(setup); delete provider; @@ -588,7 +621,7 @@ void displayHelp(const char *exe) { " Additionally there are the following switches for changing various settings:\n" "\n" "Project specific settings:\n" - " --codeblock build Code::Blocks project files\n" + " --codeblocks build Code::Blocks project files\n" " --msvc build Visual Studio project files\n" " --xcode build XCode project files\n" " --file-prefix prefix allow overwriting of relative file prefix in the\n" @@ -609,9 +642,12 @@ void displayHelp(const char *exe) { " (default: false)\n" " --installer Create NSIS installer after the build (implies --build-events)\n" " (default: false)\n" - " --tools Create project files for the devtools\n" - " (ignores --build-events and --installer, as well as engine settings)\n" - " (default: false)\n" + " --tools Create project files for the devtools\n" + " (ignores --build-events and --installer, as well as engine settings)\n" + " (default: false)\n" + " --tests Create project files for the tests\n" + " (ignores --build-events and --installer, as well as engine settings)\n" + " (default: false)\n" "\n" "Engines settings:\n" " --list-engines list all available engines and their default state\n" @@ -805,23 +841,26 @@ const Feature s_features[] = { { "vorbis", "USE_VORBIS", "libvorbisfile_static libvorbis_static libogg_static", true, "Ogg Vorbis support" }, { "flac", "USE_FLAC", "libFLAC_static", true, "FLAC support" }, { "png", "USE_PNG", "libpng", true, "libpng support" }, + { "faad", "USE_FAAD", "libfaad", false, "AAC support" }, + { "mpeg2", "USE_MPEG2", "libmpeg2", false, "MPEG-2 support" }, { "theora", "USE_THEORADEC", "libtheora_static", true, "Theora decoding support" }, {"freetype", "USE_FREETYPE2", "freetype", true, "FreeType support" }, // Feature flags - { "bink", "USE_BINK", "", true, "Bink video support" }, - { "scalers", "USE_SCALERS", "", true, "Scalers" }, - { "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" }, - { "16bit", "USE_RGB_COLOR", "", true, "16bit color support" }, - { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, - { "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling. - { "opengl", "USE_OPENGL", "opengl32", true, "OpenGL support" }, - { "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" }, - { "translation", "USE_TRANSLATION", "", true, "Translation support" }, - { "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"}, - { "keymapper","ENABLE_KEYMAPPER", "", false, "Keymapper support"}, - { "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there - // is just no current way of properly detecting this... + { "bink", "USE_BINK", "", true, "Bink video support" }, + { "scalers", "USE_SCALERS", "", true, "Scalers" }, + { "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" }, + { "16bit", "USE_RGB_COLOR", "", true, "16bit color support" }, + { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, + { "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling. + { "opengl", "USE_OPENGL", "opengl32", true, "OpenGL support" }, + { "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" }, + { "translation", "USE_TRANSLATION", "", true, "Translation support" }, + { "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"}, + { "keymapper", "ENABLE_KEYMAPPER", "", false, "Keymapper support"}, + { "eventrecorder", "ENABLE_EVENTRECORDER", "", false, "Event recorder support"}, + { "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there + // is just no current way of properly detecting this... }; const Tool s_tools[] = { @@ -829,7 +868,9 @@ const Tool s_tools[] = { { "create_hugo", true}, { "create_kyradat", true}, { "create_lure", true}, + { "create_neverhood", true}, { "create_teenagent", true}, + { "create_tony", true}, { "create_toon", true}, { "create_translations", true}, { "qtable", true} @@ -1114,69 +1155,66 @@ ProjectProvider::ProjectProvider(StringList &global_warnings, std::map<std::stri : _version(version), _globalWarnings(global_warnings), _projectWarnings(project_warnings) { } -void ProjectProvider::createProject(const BuildSetup &setup) { +void ProjectProvider::createProject(BuildSetup &setup) { + std::string targetFolder; + if (setup.devTools) { _uuidMap = createToolsUUIDMap(); + targetFolder = "/devtools/"; + } else if (!setup.tests) { + _uuidMap = createUUIDMap(setup); + targetFolder = "/engines/"; + } - // We also need to add the UUID of the main project file. - const std::string svmUUID = _uuidMap[setup.projectName] = createUUID(); - - createWorkspace(setup); - - StringList in, ex; - - // Create tools project files - for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { - if (i->first == setup.projectName) - continue; - - in.clear(); ex.clear(); - const std::string moduleDir = setup.srcDir + "/devtools/" + i->first; + // We also need to add the UUID of the main project file. + const std::string svmUUID = _uuidMap[setup.projectName] = createUUID(); - createModuleList(moduleDir, setup.defines, in, ex); - createProjectFile(i->first, i->second, setup, moduleDir, in, ex); - } + createWorkspace(setup); - // Create other misc. build files - createOtherBuildFiles(setup); + StringList in, ex; - } else { - _uuidMap = createUUIDMap(setup); - - // We also need to add the UUID of the main project file. - const std::string svmUUID = _uuidMap[setup.projectName] = createUUID(); - - // Create Solution/Workspace file - createWorkspace(setup); + // Create project files + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + if (i->first == setup.projectName) + continue; - StringList in, ex; + in.clear(); ex.clear(); + const std::string moduleDir = setup.srcDir + targetFolder + i->first; - // Create engine project files - for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { - if (i->first == setup.projectName) - continue; + createModuleList(moduleDir, setup.defines, setup.testDirs, in, ex); + createProjectFile(i->first, i->second, setup, moduleDir, in, ex); + } - in.clear(); ex.clear(); - const std::string moduleDir = setup.srcDir + "/engines/" + i->first; + if (setup.tests) { + // Create the main project file. + in.clear(); ex.clear(); - createModuleList(moduleDir, setup.defines, in, ex); - createProjectFile(i->first, i->second, setup, moduleDir, in, ex); - } + createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/base", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/common", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/engines", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/graphics", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/gui", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/audio", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/test", setup.defines, setup.testDirs, in, ex); + createProjectFile(setup.projectName, svmUUID, setup, setup.srcDir, in, ex); + } else if (!setup.devTools) { // Last but not least create the main project file. in.clear(); ex.clear(); // File list for the Project file - createModuleList(setup.srcDir + "/backends", setup.defines, in, ex); - createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, in, ex); - createModuleList(setup.srcDir + "/base", setup.defines, in, ex); - createModuleList(setup.srcDir + "/common", setup.defines, in, ex); - createModuleList(setup.srcDir + "/engines", setup.defines, in, ex); - createModuleList(setup.srcDir + "/graphics", setup.defines, in, ex); - createModuleList(setup.srcDir + "/gui", setup.defines, in, ex); - createModuleList(setup.srcDir + "/audio", setup.defines, in, ex); - createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, in, ex); - createModuleList(setup.srcDir + "/video", setup.defines, in, ex); + createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/base", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/common", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/engines", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/graphics", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/gui", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/audio", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/video", setup.defines, setup.testDirs, in, ex); // Resource files in.push_back(setup.srcDir + "/icons/" + setup.projectName + ".ico"); @@ -1195,10 +1233,10 @@ void ProjectProvider::createProject(const BuildSetup &setup) { // Create the main project file. createProjectFile(setup.projectName, svmUUID, setup, setup.srcDir, in, ex); - - // Create other misc. build files - createOtherBuildFiles(setup); } + + // Create other misc. build files + createOtherBuildFiles(setup); } ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const { @@ -1306,7 +1344,7 @@ void ProjectProvider::addFilesToProject(const std::string &dir, std::ofstream &p delete files; } -void ProjectProvider::createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const { +void ProjectProvider::createModuleList(const std::string &moduleDir, const StringList &defines, StringList &testDirs, StringList &includeList, StringList &excludeList) const { const std::string moduleMkFile = moduleDir + "/module.mk"; std::ifstream moduleMk(moduleMkFile.c_str()); if (!moduleMk) @@ -1437,6 +1475,59 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin ++i; } } + } else if (*i == "TESTS") { + if (tokens.size() < 3) + error("Malformed TESTS definition in " + moduleMkFile); + ++i; + + if (*i != ":=" && *i != "+=" && *i != "=") + error("Malformed TESTS definition in " + moduleMkFile); + ++i; + + while (i != tokens.end()) { + // Read input + std::string folder = unifyPath(*i); + + // Get include folder + const std::string source_dir = "$(srcdir)/"; + const std::string selector = getLastPathComponent(folder); + const std::string module = getLastPathComponent(moduleDir); + + folder.replace(folder.find(source_dir), source_dir.length(), ""); + folder.replace(folder.find(selector), selector.length(), ""); + folder.replace(folder.find(module), module.length(), moduleDir); + + // Scan all files in the include folder + FileList files = listDirectory(folder); + + if (files.empty()) + continue; + + // Add to list of test folders + testDirs.push_back(folder); + + for (FileList::const_iterator f = files.begin(); f != files.end(); ++f) { + if (f->isDirectory) + continue; + + std::string filename = folder + f->name; + + if (shouldInclude.top()) { + // In case we should include a file, we need to make + // sure it is not in the exclude list already. If it + // is we just drop it from the exclude list. + excludeList.remove(filename); + + includeList.push_back(filename); + } else if (std::find(includeList.begin(), includeList.end(), filename) == includeList.end()) { + // We only add the file to the exclude list in case it + // has not yet been added to the include list. + excludeList.push_back(filename); + } + } + + ++i; + } } else if (*i == "ifdef") { if (tokens.size() < 2) error("Malformed ifdef in " + moduleMkFile); diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h index de77793ee7..d0f2db364c 100644 --- a/devtools/create_project/create_project.h +++ b/devtools/create_project/create_project.h @@ -221,13 +221,16 @@ struct BuildSetup { StringList defines; ///< List of all defines for the build. StringList libraries; ///< List of all external libraries required for the build. + StringList testDirs; ///< List of all folders containing tests bool devTools; ///< Generate project files for the tools + bool tests; ///< Generate project files for the tests bool runBuildEvents; ///< Run build events as part of the build (generate revision number and copy engine/theme data & needed files to the build folder bool createInstaller; ///< Create NSIS installer after the build BuildSetup() { devTools = false; + tests = false; runBuildEvents = false; createInstaller = false; } @@ -339,7 +342,7 @@ public: * * @param setup Description of the desired build setup. */ - void createProject(const BuildSetup &setup); + void createProject(BuildSetup &setup); /** * Returns the last path component. @@ -430,10 +433,11 @@ protected: * * @param moduleDir Path to the module. * @param defines List of set defines. + * @param testDirs List of folders containing tests. * @param includeList Reference to a list, where included files should be added. * @param excludeList Reference to a list, where excluded files should be added. */ - void createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const; + void createModuleList(const std::string &moduleDir, const StringList &defines, StringList &testDirs, StringList &includeList, StringList &excludeList) const; /** * Creates an UUID for every enabled engine of the @@ -448,7 +452,7 @@ protected: * Creates an UUID for every enabled tool of the * passed build description. * - * @return A map, which includes UUIDs for all enabled engines. + * @return A map, which includes UUIDs for all enabled tools. */ UUIDMap createToolsUUIDMap() const; diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp index 0f77d91852..23bf1bc28a 100644 --- a/devtools/create_project/msbuild.cpp +++ b/devtools/create_project/msbuild.cpp @@ -52,6 +52,9 @@ int MSBuildProvider::getVisualStudioVersion() { if (_version == 11) return 2012; + if (_version == 12) + return 2013; + error("Unsupported version passed to getVisualStudioVersion"); } @@ -66,7 +69,7 @@ inline void outputConfiguration(std::ostream &project, const std::string &config inline void outputConfigurationType(const BuildSetup &setup, std::ostream &project, const std::string &name, const std::string &config, int version) { project << "\t<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='" << config << "'\" Label=\"Configuration\">\n" - "\t\t<ConfigurationType>" << ((name == setup.projectName || setup.devTools) ? "Application" : "StaticLibrary") << "</ConfigurationType>\n" + "\t\t<ConfigurationType>" << ((name == setup.projectName || setup.devTools || setup.tests) ? "Application" : "StaticLibrary") << "</ConfigurationType>\n" "\t\t<PlatformToolset>v" << version << "0</PlatformToolset>\n" "\t</PropertyGroup>\n"; } @@ -88,7 +91,7 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri error("Could not open \"" + projectFile + "\" for writing"); project << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" + "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" "\t<ItemGroup Label=\"ProjectConfigurations\">\n"; outputConfiguration(project, "Debug", "Win32"); @@ -105,7 +108,7 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri "\t\t<ProjectGuid>{" << uuid << "}</ProjectGuid>\n" "\t\t<RootNamespace>" << name << "</RootNamespace>\n" "\t\t<Keyword>Win32Proj</Keyword>\n" - "\t\t<VCTargetsPath Condition=\"'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''\">$(VCTargetsPath11)</VCTargetsPath>\n" + "\t\t<VCTargetsPath Condition=\"'$(VCTargetsPath" << _version << ")' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''\">$(VCTargetsPath" << _version << ")</VCTargetsPath>\n" "\t</PropertyGroup>\n"; // Shared configuration @@ -156,10 +159,26 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri if (name == setup.projectName) writeReferences(setup, project); + // Output auto-generated test runner + if (setup.tests) { + project << "\t<ItemGroup>\n"; + project << "\t\t<ClCompile Include=\"test_runner.cpp\" />\n"; + project << "\t</ItemGroup>\n"; + } + project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n" "\t<ImportGroup Label=\"ExtensionTargets\">\n" - "\t</ImportGroup>\n" - "</Project>\n"; + "\t</ImportGroup>\n"; + + if (setup.tests) { + // We override the normal target to ignore the exit code (this allows us to have a clean output and not message about the command exit code) + project << "\t\t<Target Name=\"PostBuildEvent\">\n" + << "\t\t\t<Message Text=\"Description: Run tests\" />\n" + << "\t\t\t<Exec Command=\"$(TargetPath)\" IgnoreExitCode=\"true\" />\n" + << "\t\t</Target>\n"; + } + + project << "</Project>\n"; // Output filter file if necessary createFiltersFile(setup, name); @@ -184,7 +203,7 @@ void MSBuildProvider::createFiltersFile(const BuildSetup &setup, const std::stri error("Could not open \"" + filtersFile + "\" for writing"); filters << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"; + "<Project ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"; // Output the list of filters filters << "\t<ItemGroup>\n"; @@ -245,7 +264,7 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s bool disableEditAndContinue = find(_disableEditAndContinue.begin(), _disableEditAndContinue.end(), name) != _disableEditAndContinue.end(); // Nothing to add here, move along! - if (!setup.devTools && name != setup.projectName && !enableLanguageExtensions && !disableEditAndContinue && warningsIterator == _projectWarnings.end()) + if ((!setup.devTools || !setup.tests) && name != setup.projectName && !enableLanguageExtensions && !disableEditAndContinue && warningsIterator == _projectWarnings.end()) return; std::string warnings = ""; @@ -257,7 +276,7 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s "\t\t<ClCompile>\n"; // Language Extensions - if (setup.devTools || name == setup.projectName || enableLanguageExtensions) + if (setup.devTools || setup.tests || name == setup.projectName || enableLanguageExtensions) project << "\t\t\t<DisableLanguageExtensions>false</DisableLanguageExtensions>\n"; // Edit and Continue @@ -271,18 +290,18 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s project << "\t\t</ClCompile>\n"; // Link configuration for main project - if (name == setup.projectName || setup.devTools) { + if (name == setup.projectName || setup.devTools || setup.tests) { std::string libraries; for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) libraries += *i + ".lib;"; project << "\t\t<Link>\n" - "\t\t\t<OutputFile>$(OutDir)" << (setup.devTools ? name : setup.projectName) << ".exe</OutputFile>\n" + "\t\t\t<OutputFile>$(OutDir)" << ((setup.devTools || setup.tests) ? name : setup.projectName) << ".exe</OutputFile>\n" "\t\t\t<AdditionalDependencies>" << libraries << "%(AdditionalDependencies)</AdditionalDependencies>\n" "\t\t</Link>\n"; - if (!setup.devTools && setup.runBuildEvents) { + if (!setup.devTools && !setup.tests && setup.runBuildEvents) { project << "\t\t<PreBuildEvent>\n" "\t\t\t<Message>Generate revision</Message>\n" "\t\t\t<Command>" << getPreBuildEvent() << "</Command>\n" @@ -293,6 +312,11 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s "\t\t\t<Message>Copy data files to the build folder</Message>\n" "\t\t\t<Command>" << getPostBuildEvent(isWin32, setup.createInstaller) << "</Command>\n" "\t\t</PostBuildEvent>\n"; + } else if (setup.tests) { + project << "\t\t<PreBuildEvent>\n" + "\t\t\t<Message>Generate runner.cpp</Message>\n" + "\t\t\t<Command>" << getTestPreBuildEvent(setup) << "</Command>\n" + "\t\t</PreBuildEvent>\n"; } } @@ -314,9 +338,8 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea definesList += REVISION_DEFINE ";"; properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" + "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" "\t<PropertyGroup>\n" - "\t\t<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n" "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_Global</_PropertySheetDisplayName>\n" "\t\t<ExecutablePath>$(" << LIBS_DEFINE << ")\\bin;$(ExecutablePath)</ExecutablePath>\n" "\t\t<LibraryPath>$(" << LIBS_DEFINE << ")\\lib\\" << (bits == 32 ? "x86" : "x64") << ";$(LibraryPath)</LibraryPath>\n" @@ -328,9 +351,9 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea "\t\t<ClCompile>\n" "\t\t\t<DisableLanguageExtensions>true</DisableLanguageExtensions>\n" "\t\t\t<DisableSpecificWarnings>" << warnings << ";%(DisableSpecificWarnings)</DisableSpecificWarnings>\n" - "\t\t\t<AdditionalIncludeDirectories>$(" << LIBS_DEFINE << ")\\include;" << prefix << ";" << prefix << "\\engines;$(TargetDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" + "\t\t\t<AdditionalIncludeDirectories>$(" << LIBS_DEFINE << ")\\include;" << prefix << ";" << prefix << "\\engines;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" "\t\t\t<PreprocessorDefinitions>" << definesList << "%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" - "\t\t\t<ExceptionHandling>" << (setup.devTools ? "Sync" : "") << "</ExceptionHandling>\n"; + "\t\t\t<ExceptionHandling>" << ((setup.devTools || setup.tests) ? "Sync" : "") << "</ExceptionHandling>\n"; #if NEEDS_RTTI properties << "\t\t\t<RuntimeTypeInfo>true</RuntimeTypeInfo>\n"; @@ -346,7 +369,7 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea "\t\t\t<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n" "\t\t\t<SubSystem>Console</SubSystem>\n"; - if (!setup.devTools) + if (!setup.devTools && !setup.tests) properties << "\t\t\t<EntryPointSymbol>WinMainCRTStartup</EntryPointSymbol>\n"; properties << "\t\t</Link>\n" @@ -368,12 +391,11 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" + "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" "\t<ImportGroup Label=\"PropertySheets\">\n" "\t\t<Import Project=\"" << setup.projectDescription << "_Global" << (isWin32 ? "" : "64") << ".props\" />\n" "\t</ImportGroup>\n" "\t<PropertyGroup>\n" - "\t\t<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n" "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << outputType << outputBitness << "</_PropertySheetDisplayName>\n" "\t\t<LinkIncremental>" << (isRelease ? "false" : "true") << "</LinkIncremental>\n" "\t</PropertyGroup>\n" @@ -383,7 +405,7 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b if (isRelease) { properties << "\t\t\t<IntrinsicFunctions>true</IntrinsicFunctions>\n" "\t\t\t<WholeProgramOptimization>true</WholeProgramOptimization>\n" - "\t\t\t<PreprocessorDefinitions>WIN32;RELEASE_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" + "\t\t\t<PreprocessorDefinitions>WIN32;DISABLE_GUI_BUILTIN_THEME;RELEASE_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" "\t\t\t<StringPooling>true</StringPooling>\n" "\t\t\t<BufferSecurityCheck>false</BufferSecurityCheck>\n" "\t\t\t<DebugInformationFormat></DebugInformationFormat>\n" @@ -395,7 +417,7 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b "\t\t\t<SetChecksum>true</SetChecksum>\n"; } else { properties << "\t\t\t<Optimization>Disabled</Optimization>\n" - "\t\t\t<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" + "\t\t\t<PreprocessorDefinitions>WIN32;DISABLE_GUI_BUILTIN_THEME;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" "\t\t\t<MinimalRebuild>true</MinimalRebuild>\n" "\t\t\t<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n" "\t\t\t<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n" diff --git a/devtools/create_project/msvc.cpp b/devtools/create_project/msvc.cpp index b8d2401af9..2fedadcba5 100644 --- a/devtools/create_project/msvc.cpp +++ b/devtools/create_project/msvc.cpp @@ -161,6 +161,16 @@ std::string MSVCProvider::getPreBuildEvent() const { return cmdLine; } +std::string MSVCProvider::getTestPreBuildEvent(const BuildSetup &setup) const { + // Build list of folders containing tests + std::string target = ""; + + for (StringList::const_iterator it = setup.testDirs.begin(); it != setup.testDirs.end(); ++it) + target += " $(SolutionDir)" + *it + "*.h"; + + return ""$(SolutionDir)../../test/cxxtest/cxxtestgen.py" --runner=ParenPrinter --no-std --no-eh -o $(SolutionDir)test_runner.cpp" + target; +} + std::string MSVCProvider::getPostBuildEvent(bool isWin32, bool createInstaller) const { std::string cmdLine = ""; diff --git a/devtools/create_project/msvc.h b/devtools/create_project/msvc.h index 5a854b596a..b9b93fe109 100644 --- a/devtools/create_project/msvc.h +++ b/devtools/create_project/msvc.h @@ -88,6 +88,13 @@ protected: std::string getPreBuildEvent() const; /** + * Get the command line for the test generator + * + * @param setup Description of the desired build setup. + */ + std::string getTestPreBuildEvent(const BuildSetup &setup) const; + + /** * Get the command line for copying data files to the build directory. * * @param isWin32 Bitness of property file. diff --git a/devtools/create_project/msvc12/create_project.sln b/devtools/create_project/msvc12/create_project.sln new file mode 100644 index 0000000000..759d5430f5 --- /dev/null +++ b/devtools/create_project/msvc12/create_project.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcxproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/devtools/create_project/msvc12/create_project.vcxproj b/devtools/create_project/msvc12/create_project.vcxproj new file mode 100644 index 0000000000..c26b1e5f45 --- /dev/null +++ b/devtools/create_project/msvc12/create_project.vcxproj @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CF177559-077D-4A08-AABE-BE0FD35F6C63}</ProjectGuid> + <RootNamespace>create_project</RootNamespace> + <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''">$(VCTargetsPath11)</VCTargetsPath> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level4</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <DisableLanguageExtensions>false</DisableLanguageExtensions> + <DisableSpecificWarnings>4003;4512;4127</DisableSpecificWarnings> + </ClCompile> + <Link> + <AdditionalDependencies>Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + </Link> + <PostBuildEvent> + <Command>@echo off +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc12\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc11\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc10\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc9\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc8\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\codeblocks\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4003;4512;4127</DisableSpecificWarnings> + </ClCompile> + <Link> + <AdditionalDependencies>Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <TargetMachine>MachineX86</TargetMachine> + </Link> + <PostBuildEvent> + <Command>@echo off +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc12\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc11\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc10\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc9\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc8\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\codeblocks\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> + </PostBuildEvent> + <PreBuildEvent> + <Command> + </Command> + </PreBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\codeblocks.cpp" /> + <ClCompile Include="..\create_project.cpp" /> + <ClCompile Include="..\msbuild.cpp" /> + <ClCompile Include="..\msvc.cpp" /> + <ClCompile Include="..\visualstudio.cpp" /> + <ClCompile Include="..\xcode.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\codeblocks.h" /> + <ClInclude Include="..\config.h" /> + <ClInclude Include="..\create_project.h" /> + <ClInclude Include="..\msbuild.h" /> + <ClInclude Include="..\msvc.h" /> + <ClInclude Include="..\visualstudio.h" /> + <ClInclude Include="..\xcode.h" /> + </ItemGroup> + <ItemGroup> + <None Include="..\scripts\installer.vbs" /> + <None Include="..\scripts\postbuild.cmd" /> + <None Include="..\scripts\prebuild.cmd" /> + <None Include="..\scripts\revision.vbs" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/devtools/create_project/msvc12/create_project.vcxproj.filters b/devtools/create_project/msvc12/create_project.vcxproj.filters new file mode 100644 index 0000000000..436d1d3436 --- /dev/null +++ b/devtools/create_project/msvc12/create_project.vcxproj.filters @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{2e3580c8-ec3a-4c81-8351-b668c668db2a}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{31aaf58c-d3cb-4ed6-8eca-163b4a9b31a6}</UniqueIdentifier> + </Filter> + <Filter Include="scripts"> + <UniqueIdentifier>{f980f6fb-41b6-4161-b035-58b200c85cad}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\codeblocks.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\create_project.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\msvc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\msbuild.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\visualstudio.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\xcode.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\codeblocks.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\create_project.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\msvc.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\msbuild.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\visualstudio.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\xcode.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\scripts\prebuild.cmd"> + <Filter>scripts</Filter> + </None> + <None Include="..\scripts\revision.vbs"> + <Filter>scripts</Filter> + </None> + <None Include="..\scripts\postbuild.cmd"> + <Filter>scripts</Filter> + </None> + <None Include="..\scripts\installer.vbs"> + <Filter>scripts</Filter> + </None> + </ItemGroup> +</Project> diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp index de2df96d78..23225d3435 100644 --- a/devtools/create_project/visualstudio.cpp +++ b/devtools/create_project/visualstudio.cpp @@ -83,7 +83,7 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: // Check for project-specific warnings: std::map< std::string, std::list<std::string> >::iterator warningsIterator = _projectWarnings.find(name); - if (setup.devTools || name == setup.projectName) { + if (setup.devTools || setup.tests || name == setup.projectName) { std::string libraries; for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) @@ -140,6 +140,11 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: else addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix); + // Output auto-generated test runner + if (setup.tests) { + project << "\t\t<File RelativePath=\"test_runner.cpp\" />\n"; + } + project << "\t</Files>\n" "</VisualStudioProject>\n"; } @@ -161,7 +166,7 @@ void VisualStudioProvider::outputConfiguration(const BuildSetup &setup, std::ost } void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildSetup &setup, const bool isWin32) { - if (!setup.devTools && setup.runBuildEvents) { + if (!setup.devTools && !setup.tests && setup.runBuildEvents) { project << "\t\t\t<Tool\tName=\"VCPreBuildEventTool\"\n" "\t\t\t\tCommandLine=\"" << getPreBuildEvent() << "\"\n" "\t\t\t/>\n" @@ -169,6 +174,17 @@ void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildS "\t\t\t\tCommandLine=\"" << getPostBuildEvent(isWin32, setup.createInstaller) << "\"\n" "\t\t\t/>\n"; } + + // Generate runner file before build for tests + if (setup.tests) { + project << "\t\t\t<Tool\tName=\"VCPreBuildEventTool\"\n" + "\t\t\t\tCommandLine=\"" << getTestPreBuildEvent(setup) << "\"\n" + "\t\t\t/>\n"; + + project << "\t\t\t<Tool\tName=\"VCPostBuildEventTool\"\n" + "\t\t\t\tCommandLine=\"$(TargetPath)\" IgnoreExitCode=\"true\"\n" + "\t\t\t/>\n"; + } } void VisualStudioProvider::writeReferences(const BuildSetup &setup, std::ofstream &output) { @@ -212,9 +228,9 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of "\t\tName=\"VCCLCompilerTool\"\n" "\t\tDisableLanguageExtensions=\"" << (setup.devTools ? "false" : "true") << "\"\n" "\t\tDisableSpecificWarnings=\"" << warnings << "\"\n" - "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;$(TargetDir)\"\n" + "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir)\"\n" "\t\tPreprocessorDefinitions=\"" << definesList << "\"\n" - "\t\tExceptionHandling=\"" << (setup.devTools ? "1" : "0") << "\"\n"; + "\t\tExceptionHandling=\"" << ((setup.devTools || setup.tests) ? "1" : "0") << "\"\n"; #if NEEDS_RTTI properties << "\t\tRuntimeTypeInfo=\"true\"\n"; @@ -235,7 +251,7 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of "\t\tIgnoreDefaultLibraryNames=\"\"\n" "\t\tSubSystem=\"1\"\n"; - if (!setup.devTools) + if (!setup.devTools && !setup.tests) properties << "\t\tEntryPointSymbol=\"WinMainCRTStartup\"\n"; properties << "\t\tAdditionalLibraryDirectories=\"$(" << LIBS_DEFINE << ")\\lib\\" << ((bits == 32) ? "x86" : "x64") << "\"\n" diff --git a/devtools/create_teenagent/static_tables.h b/devtools/create_teenagent/static_tables.h index 6e7fdfe91c..5c9b5b3d21 100644 --- a/devtools/create_teenagent/static_tables.h +++ b/devtools/create_teenagent/static_tables.h @@ -15148,7 +15148,7 @@ const static char* dialog_162[] = { }; // Note: -// The usage of this in the engine overlaps the previous dialog i.e. the +// The usage of this in the engine overlaps the previous dialog i.e. the // starting offset used is two bytes early, thus implicitly changing the // first command of this dialog from NEW_LINE to CHANGE_CHARACTER. const static char* dialog_163[] = { diff --git a/devtools/credits.pl b/devtools/credits.pl index 06df7fa50e..7d39730c63 100755 --- a/devtools/credits.pl +++ b/devtools/credits.pl @@ -754,10 +754,6 @@ begin_credits("Credits"); add_person("Angus Lees", "Gus", ""); end_section(); - begin_section("BADA"); - add_person("Chris Warren-Smith", "", ""); - end_section(); - begin_section("Dreamcast"); add_person("Marcus Comstedt", "", ""); end_section(); @@ -818,6 +814,10 @@ begin_credits("Credits"); add_person("Lars Persson", "AnotherGuest", ""); end_section(); + begin_section("Tizen / BADA"); + add_person("Chris Warren-Smith", "", ""); + end_section(); + begin_section("WebOS"); add_person("Klaus Reimer", "kayahr", ""); end_section(); diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt index 6e3bae1d7e..450860b587 100644 --- a/devtools/scumm-md5.txt +++ b/devtools/scumm-md5.txt @@ -654,6 +654,7 @@ pajama2 Pajama Sam 2: Thunder and Lightning Aren't so Frightening e5563c8358443c4352fcddf7402a5e0a -1 fr Windows HE 98.5 - - gist974 c6907d44f1166941d982864cd42cdc89 -1 de All HE 99 - - nachbarnebenan f8be685007a8b425ba2a455da732f59f -1 fr Mac HE 99 - - alamaz + 7477bc23d0383516c5e310cd8771dcc9 -1 fr Windows HE 99 - - Strangerke 32709cbeeb3044b34129950860a83f14 -1 ru Windows HE 99 - - sev 1af4eb581a33d808707d66d50e084dca -1 he Windows HE 99 - - Matan Bareket diff --git a/devtools/skycpt/cptcompiler.cpp b/devtools/skycpt/cptcompiler.cpp index 2c7d33c73b..657f51b8a0 100644 --- a/devtools/skycpt/cptcompiler.cpp +++ b/devtools/skycpt/cptcompiler.cpp @@ -376,6 +376,7 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE * uint32 asciiSize = (uint32)(asciiPos - asciiBuf); fwrite(&asciiSize, 1, 4, debOutf); fwrite(asciiBuf, 1, asciiSize, debOutf); + free(asciiBuf); // the direct links... fwrite(&dlinkCount, 2, 1, debOutf); @@ -438,6 +439,8 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE * diffNo++; } } + fclose(dif); + free(resCpts); assert(diffDest <= 8192); fwrite(&diffNo, 1, 2, debOutf); fwrite(&diffDest, 1, 2, debOutf); diff --git a/dists/msvc10/create_msvc10.bat b/dists/msvc10/create_msvc10.bat index 5616c2cc8b..be0434fc50 100644 --- a/dists/msvc10/create_msvc10.bat +++ b/dists/msvc10/create_msvc10.bat @@ -10,6 +10,8 @@ if "%~1"=="/all" goto all if "%~1"=="/ALL" goto all if "%~1"=="/tools" goto tools if "%~1"=="/TOOLS" goto tools +if "%~1"=="/tests" goto tests +if "%~1"=="/TESTS" goto tests if "%~1"=="/clean" goto clean_check if "%~1"=="/CLEAN" goto clean_check if "%~1"=="/help" goto command_help @@ -70,6 +72,13 @@ echo. create_project ..\.. --tools --msvc --msvc-version 10 goto done +:tests +echo. +echo Creating tests project files +echo. +create_project ..\.. --tests --msvc --msvc-version 10 +goto done + :clean_check echo. set cleananswer=N @@ -88,6 +97,7 @@ del /Q *.props > NUL 2>&1 del /Q *.sln* > NUL 2>&1 del /Q scummvm* > NUL 2>&1 del /Q devtools* > NUL 2>&1 +del /Q test_runner.cpp > NUL 2>&1 goto done :done diff --git a/dists/msvc11/create_msvc11.bat b/dists/msvc11/create_msvc11.bat index b6a5413e3b..fc5471f46f 100644 --- a/dists/msvc11/create_msvc11.bat +++ b/dists/msvc11/create_msvc11.bat @@ -10,6 +10,8 @@ if "%~1"=="/all" goto all if "%~1"=="/ALL" goto all if "%~1"=="/tools" goto tools if "%~1"=="/TOOLS" goto tools +if "%~1"=="/tests" goto tests +if "%~1"=="/TESTS" goto tests if "%~1"=="/clean" goto clean_check if "%~1"=="/CLEAN" goto clean_check if "%~1"=="/help" goto command_help @@ -70,6 +72,13 @@ echo. create_project ..\.. --tools --msvc --msvc-version 11 goto done +:tests +echo. +echo Creating tests project files +echo. +create_project ..\.. --tests --msvc --msvc-version 11 +goto done + :clean_check echo. set cleananswer=N @@ -88,6 +97,7 @@ del /Q *.props > NUL 2>&1 del /Q *.sln* > NUL 2>&1 del /Q scummvm* > NUL 2>&1 del /Q devtools* > NUL 2>&1 +del /Q test_runner.cpp > NUL 2>&1 goto done :done diff --git a/dists/msvc12/create_msvc12.bat b/dists/msvc12/create_msvc12.bat new file mode 100644 index 0000000000..d99001edb1 --- /dev/null +++ b/dists/msvc12/create_msvc12.bat @@ -0,0 +1,105 @@ +@echo off + +echo. +echo Automatic creation of the MSVC12 project files +echo. + +if "%~1"=="/stable" goto stable +if "%~1"=="/STABLE" goto stable +if "%~1"=="/all" goto all +if "%~1"=="/ALL" goto all +if "%~1"=="/tools" goto tools +if "%~1"=="/TOOLS" goto tools +if "%~1"=="/tests" goto tests +if "%~1"=="/TESTS" goto tests +if "%~1"=="/clean" goto clean_check +if "%~1"=="/CLEAN" goto clean_check +if "%~1"=="/help" goto command_help +if "%~1"=="/HELP" goto command_help +if "%~1"=="/?" goto command_help + +if "%~1"=="" goto check_tool + +echo Invalid command parameter: %~1 +echo. + +:command_help +echo Valid command parameters are: +echo stable Generated stable engines project files +echo all Generate all engines project files +echo tools Generate project files for the devtools +echo clean Clean generated project files +echo help Show help message +goto done + +:check_tool +if not exist create_project.exe goto no_tool + +:question +echo. +set batchanswer=S +set /p batchanswer="Enable stable engines only, or all engines? (S/a)" +if "%batchanswer%"=="s" goto stable +if "%batchanswer%"=="S" goto stable +if "%batchanswer%"=="a" goto all +if "%batchanswer%"=="A" goto all +goto question + +:no_tool +echo create_project.exe not found in the current folder. +echo You need to build it first and copy it in this +echo folder +goto done + +:all +echo. +echo Creating project files with all engines enabled (stable and unstable) +echo. +create_project ..\.. --enable-all-engines --msvc --msvc-version 12 --build-events +goto done + +:stable +echo. +echo Creating normal project files, with only the stable engines enabled +echo. +create_project ..\.. --msvc --msvc-version 12 +goto done + +:tools +echo. +echo Creating tools project files +echo. +create_project ..\.. --tools --msvc --msvc-version 12 +goto done + +:tests +echo. +echo Creating tests project files +echo. +create_project ..\.. --tests --msvc --msvc-version 12 +goto done + +:clean_check +echo. +set cleananswer=N +set /p cleananswer="This will remove all project files. Are you sure you want to continue? (N/y)" +if "%cleananswer%"=="n" goto done +if "%cleananswer%"=="N" goto done +if "%cleananswer%"=="y" goto clean +if "%cleananswer%"=="Y" goto clean +goto clean_check + +:clean +echo. +echo Removing all project files +del /Q *.vcxproj* > NUL 2>&1 +del /Q *.props > NUL 2>&1 +del /Q *.sln* > NUL 2>&1 +del /Q scummvm* > NUL 2>&1 +del /Q devtools* > NUL 2>&1 +del /Q test_runner.cpp > NUL 2>&1 +goto done + +:done +echo. +pause diff --git a/dists/msvc12/readme.txt b/dists/msvc12/readme.txt new file mode 100644 index 0000000000..760f9ff601 --- /dev/null +++ b/dists/msvc12/readme.txt @@ -0,0 +1,6 @@ +The Visual Studio project files can now be created automatically from the GCC +files using the create_project tool inside the /devtools/create_project folder. + +To create the default project files, build create_project.exe, copy it inside +this folder and run the create_msvc12.bat file for a default build. You can run +create_project.exe with no parameters to check the possible command-line options diff --git a/dists/msvc8/create_msvc8.bat b/dists/msvc8/create_msvc8.bat index 2261c9bcec..1e0d339001 100644 --- a/dists/msvc8/create_msvc8.bat +++ b/dists/msvc8/create_msvc8.bat @@ -10,6 +10,8 @@ if "%~1"=="/all" goto all if "%~1"=="/ALL" goto all if "%~1"=="/tools" goto tools if "%~1"=="/TOOLS" goto tools +if "%~1"=="/tests" goto tests +if "%~1"=="/TESTS" goto tests if "%~1"=="/clean" goto clean_check if "%~1"=="/CLEAN" goto clean_check if "%~1"=="/help" goto command_help @@ -70,6 +72,13 @@ echo. create_project ..\.. --tools --msvc --msvc-version 8 goto done +:tests +echo. +echo Creating tests project files +echo. +create_project ..\.. --tests --msvc --msvc-version 8 +goto done + :clean_check echo. set cleananswer=N @@ -88,6 +97,7 @@ del /Q *.vsprops > NUL 2>&1 del /Q *.sln* > NUL 2>&1 del /Q scummvm* > NUL 2>&1 del /Q devtools* > NUL 2>&1 +del /Q test_runner.cpp goto done :done diff --git a/dists/msvc9/create_msvc9.bat b/dists/msvc9/create_msvc9.bat index 1622cd9037..34bcccdd7b 100644 --- a/dists/msvc9/create_msvc9.bat +++ b/dists/msvc9/create_msvc9.bat @@ -10,6 +10,8 @@ if "%~1"=="/all" goto all if "%~1"=="/ALL" goto all if "%~1"=="/tools" goto tools if "%~1"=="/TOOLS" goto tools +if "%~1"=="/tests" goto tests +if "%~1"=="/TESTS" goto tests if "%~1"=="/clean" goto clean_check if "%~1"=="/CLEAN" goto clean_check if "%~1"=="/help" goto command_help @@ -70,6 +72,13 @@ echo. create_project ..\.. --tools --msvc --msvc-version 9 goto done +:tests +echo. +echo Creating tests project files +echo. +create_project ..\.. --tests --msvc --msvc-version 9 +goto done + :clean_check echo. set cleananswer=N @@ -88,6 +97,7 @@ del /Q *.vsprops > NUL 2>&1 del /Q *.sln* > NUL 2>&1 del /Q scummvm* > NUL 2>&1 del /Q devtools* > NUL 2>&1 +del /Q test_runner.cpp goto done :done diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index b1d1008b60..fd0c8dc2da 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -29,7 +29,7 @@ #include "common/system.h" #include "common/textconsole.h" #include "common/translation.h" - +#include "gui/EventRecorder.h" #include "engines/advancedDetector.h" #include "engines/obsolete.h" @@ -301,6 +301,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) return Common::kUserCanceled; debug(2, "Running %s", gameDescriptor.description().c_str()); + initSubSystems(agdDesc); if (!createInstance(syst, engine, agdDesc)) return Common::kNoGameDataFoundError; else @@ -606,3 +607,11 @@ AdvancedMetaEngine::AdvancedMetaEngine(const void *descs, uint descItemSize, con _maxScanDepth = 1; _directoryGlobs = NULL; } + +void AdvancedMetaEngine::initSubSystems(const ADGameDescription *gameDesc) const { +#ifdef ENABLE_EVENTRECORDER + if (gameDesc) { + g_eventRec.processGameDescription(gameDesc); + } +#endif +} diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h index 3eec33abe5..71d2c4a446 100644 --- a/engines/advancedDetector.h +++ b/engines/advancedDetector.h @@ -280,6 +280,9 @@ protected: return 0; } +private: + void initSubSystems(const ADGameDescription *gameDesc) const; + protected: /** * Detect games in specified directory. diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index 1c342183cd..57561c00ee 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -598,8 +598,8 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas _console = NULL; _egoHoldKey = false; - - + + } void AgiEngine::initialize() { diff --git a/engines/agi/preagi_troll.cpp b/engines/agi/preagi_troll.cpp index b7d2801076..17d980dfd8 100644 --- a/engines/agi/preagi_troll.cpp +++ b/engines/agi/preagi_troll.cpp @@ -190,6 +190,7 @@ void TrollEngine::inventory() { break; case IDI_TRO_MAX_TREASURE: drawStr(3, 17, kColorDefault, IDS_TRO_TREASURE_2); + break; default: sprintf(tmp, IDS_TRO_TREASURE_4, _treasuresLeft); drawStr(20, 10, kColorDefault, tmp); @@ -219,6 +220,7 @@ void TrollEngine::waitAnyKeyIntro() { switch (iMsg) { case 200: iMsg = 0; + // fall through case 0: drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_2); _gfx->doUpdate(); diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp index bbe9ddd0c6..1be385be37 100644 --- a/engines/agi/preagi_winnie.cpp +++ b/engines/agi/preagi_winnie.cpp @@ -985,6 +985,7 @@ void WinnieEngine::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) { } break; } + break; default: if (!event.kbd.flags) { // if the control/alt/shift keys are not pressed keyHelp(); diff --git a/engines/cge/cge.cpp b/engines/cge/cge.cpp index 6cc0c45963..af7e91f7eb 100644 --- a/engines/cge/cge.cpp +++ b/engines/cge/cge.cpp @@ -25,7 +25,6 @@ #include "common/debug.h" #include "common/debug-channels.h" #include "common/error.h" -#include "common/EventRecorder.h" #include "common/file.h" #include "common/fs.h" #include "engines/advancedDetector.h" diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp index d29c1224fd..3b01421903 100644 --- a/engines/cge/detection.cpp +++ b/engines/cge/detection.cpp @@ -121,7 +121,7 @@ static const CgeGameDescription gameDescriptions[] = { "sfinx", "Sfinx Freeware", { {"vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024}, - {"vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844}, + {"vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844}, AD_LISTEND }, Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0() diff --git a/engines/cge/snail.cpp b/engines/cge/snail.cpp index edb8972040..b9030efb4d 100644 --- a/engines/cge/snail.cpp +++ b/engines/cge/snail.cpp @@ -494,7 +494,7 @@ void CGEEngine::snGame(Sprite *spr, int num) { _sprK3->step(newRandom(6)); // check the ALT key as it's the solution of the puzzle - // the test has been restricted to some specific OSes + // the test has been restricted to some specific OSes // in order to avoid some obvious issues (like Android, iOS, NDS, N64...) // Not perfect, but at least better than nothing. #if defined(WIN32) || defined(UNIX) || defined(MACOSX) || defined(MOTOEZX) || defined(LINUPY) || defined(LINUXMOTO_SDL) diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h index e547503bee..c4d1c4c761 100644 --- a/engines/drascula/drascula.h +++ b/engines/drascula/drascula.h @@ -661,7 +661,7 @@ public: void animation_3_1(); // John talks with the bartender to book a room void animation_4_1(); // John talks with the pianist // - void animation_2_2(); // John enters the chapel via the window + void animation_2_2(); // John enters the chapel via the window void animation_4_2(); // John talks with the blind man (closeup) void animation_5_2(); // John breaks the chapel window with the pike void animation_6_2(); // The blind man (closeup) thanks John for giving him money and hands him the sickle diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp index c3ede46df2..08838a784a 100644 --- a/engines/dreamweb/dreamweb.cpp +++ b/engines/dreamweb/dreamweb.cpp @@ -23,7 +23,6 @@ #include "common/config-manager.h" #include "common/debug-channels.h" #include "common/events.h" -#include "common/EventRecorder.h" #include "common/file.h" #include "common/func.h" #include "common/system.h" diff --git a/engines/dreamweb/monitor.cpp b/engines/dreamweb/monitor.cpp index 1f9fa8d24f..108f9d2b60 100644 --- a/engines/dreamweb/monitor.cpp +++ b/engines/dreamweb/monitor.cpp @@ -104,7 +104,7 @@ void DreamWebEngine::useMon() { redrawMainScrn(); workToScreenM(); } - + int DreamWebEngine::findCommand(const char *const cmdList[]) { // Loop over all commands in the list and see if we get a match int cmd = 0; @@ -135,7 +135,7 @@ bool DreamWebEngine::execCommand() { "KEYS", NULL }; - + static const char *const comlistFR[] = { "SORTIR", "AIDE", @@ -145,7 +145,7 @@ bool DreamWebEngine::execCommand() { "TOUCHES", // should be CLES but it is translated as TOUCHES in the game... NULL }; - + static const char *const comlistDE[] = { "ENDE", "HILF", @@ -155,7 +155,7 @@ bool DreamWebEngine::execCommand() { "DATEN", NULL }; - + static const char *const comlistIT[] = { "ESCI", "AIUTO", @@ -165,7 +165,7 @@ bool DreamWebEngine::execCommand() { "CHIAVI", NULL }; - + static const char *const comlistES[] = { "SALIR", "AYUDA", diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp index bc75b97e71..bec58322d5 100644 --- a/engines/dreamweb/print.cpp +++ b/engines/dreamweb/print.cpp @@ -67,7 +67,7 @@ void DreamWebEngine::printChar(const GraphicsFile &charSet, uint16* x, uint16 y, // characters (0 - 31). if (c < 32 || c == 255) return; - + uint8 dummyWidth, dummyHeight; if (width == NULL) width = &dummyWidth; diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp index 6b65eb6ab9..839378a412 100644 --- a/engines/gob/surface.cpp +++ b/engines/gob/surface.cpp @@ -45,7 +45,7 @@ static void plotPixel(int x, int y, int color, void *data) { Pixel::Pixel(byte *vidMem, uint8 bpp, byte *min, byte *max) : _vidMem(vidMem), _bpp(bpp), _min(min), _max(max) { - assert((_bpp == 1) || (_bpp == 2)); + assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4)); assert(_vidMem >= _min); assert(_vidMem < _max); } @@ -91,6 +91,8 @@ uint32 Pixel::get() const { return *((byte *) _vidMem); if (_bpp == 2) return *((uint16 *) _vidMem); + if (_bpp == 4) + return *((uint32 *) _vidMem); return 0; } @@ -103,6 +105,8 @@ void Pixel::set(uint32 p) { *((byte *) _vidMem) = (byte) p; if (_bpp == 2) *((uint16 *) _vidMem) = (uint16) p; + if (_bpp == 4) + *((uint32 *) _vidMem) = (uint32) p; } bool Pixel::isValid() const { @@ -113,7 +117,7 @@ bool Pixel::isValid() const { ConstPixel::ConstPixel(const byte *vidMem, uint8 bpp, const byte *min, const byte *max) : _vidMem(vidMem), _bpp(bpp), _min(min), _max(max) { - assert((_bpp == 1) || (_bpp == 2)); + assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4)); assert(_vidMem >= _min); assert(_vidMem < _max); } @@ -159,6 +163,8 @@ uint32 ConstPixel::get() const { return *((const byte *) _vidMem); if (_bpp == 2) return *((const uint16 *) _vidMem); + if (_bpp == 4) + return *((const uint32 *) _vidMem); return 0; } @@ -172,7 +178,7 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem) : _width(width), _height(height), _bpp(bpp), _vidMem(vidMem) { assert((_width > 0) && (_height > 0)); - assert((_bpp == 1) || (_bpp == 2)); + assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4)); if (!_vidMem) { _vidMem = new byte[_bpp * _width * _height]; @@ -187,7 +193,7 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem) : _width(width), _height(height), _bpp(bpp), _vidMem(0) { assert((_width > 0) && (_height > 0)); - assert((_bpp == 1) || (_bpp == 2)); + assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4)); _vidMem = new byte[_bpp * _width * _height]; _ownVidMem = true; @@ -504,7 +510,7 @@ void Surface::fillRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uin return; } - assert(_bpp == 2); + assert((_bpp == 2) || (_bpp == 4)); // Otherwise, we have to fill by pixel diff --git a/engines/groovie/stuffit.cpp b/engines/groovie/stuffit.cpp index 37f12585e7..60a57a0129 100644 --- a/engines/groovie/stuffit.cpp +++ b/engines/groovie/stuffit.cpp @@ -249,7 +249,7 @@ void StuffItArchive::update14(uint16 first, uint16 last, byte *code, uint16 *fre do { while (++i < last && code[first] > code[i]) ; - + while (--j > first && code[first] < code[j]) ; diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp index 6cdfbf47d1..ab672d4c48 100644 --- a/engines/hopkins/dialogs.cpp +++ b/engines/hopkins/dialogs.cpp @@ -505,7 +505,7 @@ void DialogsManager::inventAnim() { return; if (_vm->_objectsMan->_eraseVisibleCounter && !_vm->_objectsMan->_visibleFl) { - _vm->_graphicsMan->copySurface(_vm->_graphicsMan->_backBuffer, _oldInventX, 27, 48, 38, + _vm->_graphicsMan->copySurface(_vm->_graphicsMan->_backBuffer, _oldInventX, 27, 48, 38, _vm->_graphicsMan->_frontBuffer, _oldInventX, 27); _vm->_graphicsMan->addDirtyRect(_oldInventX, 27, _oldInventX + 48, 65); --_vm->_objectsMan->_eraseVisibleCounter; diff --git a/engines/hopkins/globals.cpp b/engines/hopkins/globals.cpp index 28f22ed99e..a9a0a81f08 100644 --- a/engines/hopkins/globals.cpp +++ b/engines/hopkins/globals.cpp @@ -134,7 +134,7 @@ Globals::~Globals() { void Globals::setConfig() { // CHECKME: Should be in Globals() but it doesn't work // The Polish version is a translation of the English version. The filenames are the same. - // The Russian version looks like a translation of the English version, based on the filenames. + // The Russian version looks like a translation of the English version, based on the filenames. switch (_vm->getLanguage()) { case Common::EN_ANY: case Common::PL_POL: diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp index ebc5cfa8da..b83371d65f 100644 --- a/engines/hopkins/graphics.cpp +++ b/engines/hopkins/graphics.cpp @@ -1179,7 +1179,7 @@ void GraphicsManager::displayZones() { Common::Rect r(_vm->_objectsMan->_bob[bobId]._oldX, _vm->_objectsMan->_bob[bobId]._oldY, _vm->_objectsMan->_bob[bobId]._oldX + _vm->_objectsMan->_bob[bobId]._oldWidth, _vm->_objectsMan->_bob[bobId]._oldY + _vm->_objectsMan->_bob[bobId]._oldHeight); - + displayDebugRect(screenSurface, r, 0xff0000); } } @@ -1204,7 +1204,7 @@ void GraphicsManager::displayLines() { uint16* pixels = (uint16*)screenSurface->pixels; - for (int lineIndex = 0; lineIndex < _vm->_linesMan->_linesNumb; lineIndex++) { + for (int lineIndex = 0; lineIndex < _vm->_linesMan->_linesNumb; lineIndex++) { int i = 0; do { int x = _vm->_linesMan->_lineItem[lineIndex]._lineData[i] - _scrollPosX; @@ -1230,7 +1230,7 @@ void GraphicsManager::displayDebugRect(Graphics::Surface *surface, const Common: r.top = MAX(r.top, (int16)0); r.right = MIN(r.right, (int16)SCREEN_WIDTH); r.bottom = MIN(r.bottom, (int16)SCREEN_HEIGHT); - + // If there's an on-screen portion, display it if (r.isValidRect()) surface->frameRect(r, color); diff --git a/engines/hopkins/graphics.h b/engines/hopkins/graphics.h index 268db7fc2b..8767f5ec4d 100644 --- a/engines/hopkins/graphics.h +++ b/engines/hopkins/graphics.h @@ -125,7 +125,7 @@ public: public: GraphicsManager(HopkinsEngine *vm); ~GraphicsManager(); - + void clearPalette(); void clearScreen(); void clearVesaScreen(); diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp index 2aaf44c5d3..6d93019faa 100644 --- a/engines/hopkins/hopkins.cpp +++ b/engines/hopkins/hopkins.cpp @@ -35,12 +35,9 @@ namespace Hopkins { -HopkinsEngine *g_vm; - HopkinsEngine::HopkinsEngine(OSystem *syst, const HopkinsGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _randomSource("Hopkins") { DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); - g_vm = this; _animMan = new AnimationManager(this); _computer = new ComputerManager(this); _dialog = new DialogsManager(this); @@ -95,7 +92,7 @@ bool HopkinsEngine::canLoadGameStateCurrently() { * Returns true if it is currently okay to save the game */ bool HopkinsEngine::canSaveGameStateCurrently() { - return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl + return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl && _globals->_curRoomNum != 0 && !isUnderwaterSubScene(); } diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h index 777fd1c335..398e41a4d2 100644 --- a/engines/hopkins/hopkins.h +++ b/engines/hopkins/hopkins.h @@ -183,9 +183,6 @@ public: virtual void syncSoundSettings(); }; -// Global reference to the HopkinsEngine object -extern HopkinsEngine *g_vm; - } // End of namespace Hopkins #endif /* HOPKINS_HOPKINS_H */ diff --git a/engines/hopkins/saveload.cpp b/engines/hopkins/saveload.cpp index 45b4885c90..98fb15046e 100644 --- a/engines/hopkins/saveload.cpp +++ b/engines/hopkins/saveload.cpp @@ -43,12 +43,12 @@ SaveLoadManager::SaveLoadManager(HopkinsEngine *vm) { } bool SaveLoadManager::save(const Common::String &file, const void *buf, size_t n) { - Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(file); + Common::OutSaveFile *savefile = g_system->getSavefileManager()->openForSaving(file); - if (f) { - size_t bytesWritten = f->write(buf, n); - f->finalize(); - delete f; + if (savefile) { + size_t bytesWritten = savefile->write(buf, n); + savefile->finalize(); + delete savefile; return bytesWritten == n; } else @@ -69,13 +69,13 @@ void SaveLoadManager::initSaves() { } void SaveLoadManager::load(const Common::String &file, byte *buf) { - Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(file); - if (f == NULL) - error("Error openinig file - %s", file.c_str()); + Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(file); + if (savefile == NULL) + error("Error opening file - %s", file.c_str()); - int32 filesize = f->size(); - f->read(buf, filesize); - delete f; + int32 filesize = savefile->size(); + savefile->read(buf, filesize); + delete savefile; } bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header) { @@ -215,13 +215,13 @@ Common::Error SaveLoadManager::loadGame(int slot) { bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header) { // Try and open the save file for reading - Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( - g_vm->generateSaveName(slot)); - if (!saveFile) + Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading( + _vm->generateSaveName(slot)); + if (!savefile) return false; - bool result = readSavegameHeader(saveFile, header); - delete saveFile; + bool result = readSavegameHeader(savefile, header); + delete savefile; return result; } diff --git a/engines/hopkins/saveload.h b/engines/hopkins/saveload.h index 221a445fd2..6fee814180 100644 --- a/engines/hopkins/saveload.h +++ b/engines/hopkins/saveload.h @@ -63,7 +63,7 @@ public: static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header); void writeSavegameHeader(Common::OutSaveFile *out, hopkinsSavegameHeader &header); - static bool readSavegameHeader(int slot, hopkinsSavegameHeader &header); + bool readSavegameHeader(int slot, hopkinsSavegameHeader &header); Common::Error saveGame(int slot, const Common::String &saveName); Common::Error loadGame(int slot); diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp index bcf06055f8..b140cfdba2 100644 --- a/engines/hugo/hugo.cpp +++ b/engines/hugo/hugo.cpp @@ -66,7 +66,7 @@ HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(sy _console = new HugoConsole(this); _rnd = 0; - + _screen = NULL; _mouse = NULL; _inventory = NULL; diff --git a/engines/kyra/kyra_rpg.cpp b/engines/kyra/kyra_rpg.cpp index f8eb7d00cd..4f7adcc6e5 100644 --- a/engines/kyra/kyra_rpg.cpp +++ b/engines/kyra/kyra_rpg.cpp @@ -213,7 +213,7 @@ void KyraRpgEngine::drawDialogueButtons() { screen()->printText(_dialogueButtonString[i], (x + 37 - (screen()->getTextWidth(_dialogueButtonString[i])) / 2) & ~3, ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2) & ~7, _dialogueHighlightedButton == i ? 0xC1 : 0xE1, 0); } else { - int sjisYOffset = (_flags.lang == Common::JA_JPN && _dialogueButtonString[i][0] < 0) ? 2 : 0; + int sjisYOffset = (_flags.lang == Common::JA_JPN && (_dialogueButtonString[i][0] & 0x80)) ? 2 : 0; gui_drawBox(x, (_dialogueButtonYoffs + _dialogueButtonPosY[i]), _dialogueButtonWidth, guiSettings()->buttons.height, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill); screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonWidth >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2, (_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2 - sjisYOffset, _dialogueHighlightedButton == i ? _dialogueButtonLabelColor1 : _dialogueButtonLabelColor2, 0); diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 419b630714..054397a34a 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -1256,7 +1256,7 @@ int Screen::getTextWidth(const char *str) { while (1) { if (_sjisMixedFontMode) - setFont(*str < 0 ? FID_SJIS_FNT : curFont); + setFont((*str & 0x80) ? FID_SJIS_FNT : curFont); uint c = fetchChar(str); @@ -1296,7 +1296,7 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2 while (1) { if (_sjisMixedFontMode) - setFont(*str < 0 ? FID_SJIS_FNT : curFont); + setFont((*str & 0x80) ? FID_SJIS_FNT : curFont); uint8 charHeightFnt = getFontHeight(); diff --git a/engines/neverhood/background.cpp b/engines/neverhood/background.cpp index e9e5325e77..d6a9900d38 100644 --- a/engines/neverhood/background.cpp +++ b/engines/neverhood/background.cpp @@ -33,11 +33,11 @@ Background::Background(NeverhoodEngine *vm, int objectPriority) Background::Background(NeverhoodEngine *vm, uint32 fileHash, int objectPriority, int surfacePriority) : Entity(vm, objectPriority), _surface(NULL), _spriteResource(vm) { - + _spriteResource.load(fileHash); createSurface(surfacePriority, _spriteResource.getDimensions().width, _spriteResource.getDimensions().height); _surface->drawSpriteResource(_spriteResource); - + } Background::~Background() { diff --git a/engines/neverhood/blbarchive.cpp b/engines/neverhood/blbarchive.cpp index 9f5f46487c..d730d75718 100644 --- a/engines/neverhood/blbarchive.cpp +++ b/engines/neverhood/blbarchive.cpp @@ -58,8 +58,8 @@ BlbArchive::~BlbArchive() { void BlbArchive::open(const Common::String &filename) { BlbHeader header; uint16 *extDataOffsets; - - _entries.clear(); + + _entries.clear(); if (!_fd.open(filename)) error("BlbArchive::open() Could not open %s", filename.c_str()); @@ -83,16 +83,16 @@ void BlbArchive::open(const Common::String &filename) { entry.fileHash = _fd.readUint32LE(); _entries.push_back(entry); } - + extDataOffsets = new uint16[header.fileCount]; - + // Load file records for (uint i = 0; i < header.fileCount; i++) { BlbArchiveEntry &entry = _entries[i]; entry.type = _fd.readByte(); entry.comprType = _fd.readByte(); entry.extData = NULL; - extDataOffsets[i] = _fd.readUint16LE(); + extDataOffsets[i] = _fd.readUint16LE(); entry.timeStamp = _fd.readUint32LE(); entry.offset = _fd.readUint32LE(); entry.diskSize = _fd.readUint32LE(); @@ -101,7 +101,7 @@ void BlbArchive::open(const Common::String &filename) { entry.fileHash, entry.type, entry.comprType, extDataOffsets[i], entry.timeStamp, entry.offset, entry.diskSize, entry.size); } - + // Load ext data if (header.extDataSize > 0) { _extData = new byte[header.extDataSize]; @@ -120,9 +120,9 @@ void BlbArchive::load(uint index, byte *buffer, uint32 size) { void BlbArchive::load(BlbArchiveEntry *entry, byte *buffer, uint32 size) { Common::StackLock lock(_mutex); - + _fd.seek(entry->offset); - + switch (entry->comprType) { case 1: // Uncompressed if (size == 0) diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp index 7b5add65c7..733d7dd8a4 100644 --- a/engines/neverhood/console.cpp +++ b/engines/neverhood/console.cpp @@ -25,6 +25,7 @@ #include "neverhood/neverhood.h" #include "neverhood/gamemodule.h" #include "neverhood/scene.h" +#include "neverhood/sound.h" #include "neverhood/modules/module1600.h" namespace Neverhood { @@ -34,6 +35,7 @@ Console::Console(NeverhoodEngine *vm) : GUI::Debugger(), _vm(vm) { DCmd_Register("dumpvars", WRAP_METHOD(Console, Cmd_Dumpvars)); DCmd_Register("room", WRAP_METHOD(Console, Cmd_Room)); DCmd_Register("surfaces", WRAP_METHOD(Console, Cmd_Surfaces)); + DCmd_Register("playsound", WRAP_METHOD(Console, Cmd_PlaySound)); } Console::~Console() { @@ -79,7 +81,7 @@ bool Console::Cmd_Cheat(int argc, const char **argv) { DebugPrintf(" music - shows the correct index in the radio music puzzle, module 2800, scene 1\n"); DebugPrintf(" radio - enables the radio, module 3000, scene 9 - same as pulling the rightmost cord in the flytrap room\n"); DebugPrintf(" symbols - solves the symbols puzzle, module 1600, scene 8. Only available in that room\n"); - DebugPrintf(" tubes - shows the correct test tube combination in module 2800, scenes 7 and 10, can be used anywhere\n"); + DebugPrintf(" tubes - shows the correct test tube combination in module 2800, scenes 7 and 10\n"); return true; } @@ -169,4 +171,21 @@ bool Console::Cmd_Dumpvars(int argc, const char **argv) { return true; } +bool Console::Cmd_PlaySound(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Usage: %s <sound hash>\n", argv[0]); + } else { + uint32 soundHash = strtol(argv[1], NULL, 0); + AudioResourceManSoundItem *soundItem = new AudioResourceManSoundItem(_vm, soundHash); + soundItem->setVolume(100); + soundItem->playSound(false); + while (soundItem->isPlaying()) { + _vm->_system->delayMillis(10); + } + delete soundItem; + } + + return true; +} + } // End of namespace Neverhood diff --git a/engines/neverhood/console.h b/engines/neverhood/console.h index 40c11b50e3..62d65bd693 100644 --- a/engines/neverhood/console.h +++ b/engines/neverhood/console.h @@ -41,6 +41,7 @@ private: bool Cmd_Surfaces(int argc, const char **argv); bool Cmd_Cheat(int argc, const char **argv); bool Cmd_Dumpvars(int argc, const char **argv); + bool Cmd_PlaySound(int argc, const char **argv); }; } // End of namespace Neverhood diff --git a/engines/neverhood/detection.cpp b/engines/neverhood/detection.cpp index 5f860f8519..3de087051a 100644 --- a/engines/neverhood/detection.cpp +++ b/engines/neverhood/detection.cpp @@ -24,6 +24,7 @@ #include "engines/advancedDetector.h" #include "common/file.h" +#include "common/translation.h" #include "neverhood/neverhood.h" @@ -143,6 +144,13 @@ static const NeverhoodGameDescription gameDescriptions[] = { } // End of namespace Neverhood +static const ExtraGuiOption neverhoodExtraGuiOption = { + _s("Use original save/load screens"), + _s("Use the original save/load screens, instead of the ScummVM ones"), + "originalsaveload", + false +}; + class NeverhoodMetaEngine : public AdvancedMetaEngine { public: NeverhoodMetaEngine() : AdvancedMetaEngine(Neverhood::gameDescriptions, sizeof(Neverhood::NeverhoodGameDescription), neverhoodGames) { @@ -160,7 +168,7 @@ public: virtual bool hasFeature(MetaEngineFeature f) const; virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; - + virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const; SaveStateList listSaves(const char *target) const; virtual int getMaximumSaveSlot() const; void removeSaveState(const char *target, int slot) const; @@ -194,6 +202,12 @@ bool NeverhoodMetaEngine::createInstance(OSystem *syst, Engine **engine, const A return gd != 0; } +const ExtraGuiOptions NeverhoodMetaEngine::getExtraGuiOptions(const Common::String &target) const { + ExtraGuiOptions options; + options.push_back(neverhoodExtraGuiOption); + return options; +} + SaveStateList NeverhoodMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Neverhood::NeverhoodEngine::SaveHeader header; diff --git a/engines/neverhood/diskplayerscene.cpp b/engines/neverhood/diskplayerscene.cpp index 94a68a7526..ef2b856b2f 100644 --- a/engines/neverhood/diskplayerscene.cpp +++ b/engines/neverhood/diskplayerscene.cpp @@ -61,7 +61,7 @@ static const uint32 kDiskplayerSmackerFileHashes[] = { 0x04002810 }; -static const uint32 kDiskplayerSlotFileHashes1[] = { +static const uint32 kDiskplayerSlotFileHashes1[] = { 0x81312280, 0x01312281, 0x01312282, @@ -84,7 +84,7 @@ static const uint32 kDiskplayerSlotFileHashes1[] = { 0x04312281 }; -static const uint32 kDiskplayerSlotFileHashes2[] = { +static const uint32 kDiskplayerSlotFileHashes2[] = { 0x90443A00, 0x90443A18, 0x90443A28, @@ -107,8 +107,8 @@ static const uint32 kDiskplayerSlotFileHashes2[] = { 0xC0443A18 }; -static const uint32 kDiskplayerSlotFileHashes3[] = { - 0x10357320, +static const uint32 kDiskplayerSlotFileHashes3[] = { + 0x10357320, 0x10557320, 0x10957320, 0x11157320, @@ -130,7 +130,7 @@ static const uint32 kDiskplayerSlotFileHashes3[] = { 0x10543320 }; -static const uint32 kDiskplayerSlotFileHashes4[] = { +static const uint32 kDiskplayerSlotFileHashes4[] = { 0xDC8020E4, 0xDC802164, 0xDC802264, @@ -155,7 +155,7 @@ static const uint32 kDiskplayerSlotFileHashes4[] = { AsDiskplayerSceneKey::AsDiskplayerSceneKey(NeverhoodEngine *vm) : AnimatedSprite(vm, 1100) { - + createSurface1(0x100B90B4, 1200); _x = 211; _y = 195; @@ -193,7 +193,7 @@ void AsDiskplayerSceneKey::stDropKeyDone() { DiskplayerPlayButton::DiskplayerPlayButton(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene) : StaticSprite(vm, 1400), _diskplayerScene(diskplayerScene), _isPlaying(false) { - + loadSprite(0x24A4A664, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); setVisible(false); loadSound(0, 0x44043000); @@ -317,10 +317,10 @@ void DiskplayerSlot::stop() { DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int paletteIndex) : Scene(vm, parentModule), _diskIndex(0), _appearCountdown(0), _tuneInCountdown(0), - _hasAllDisks(false), _dropKey(false), _inputDisabled(true), _updateStatus(kUSStopped) { + _hasAllDisks(false), _dropKey(false), _inputDisabled(true), _updateStatus(kUSStopped) { int availableDisksCount = 0; - + setBackground(0x8A000044); setPalette(kDiskplayerPaletteFileHashes[paletteIndex]); @@ -344,7 +344,7 @@ DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int } _hasAllDisks = availableDisksCount == 20; - + if (_hasAllDisks && !getGlobalVar(V_HAS_FINAL_KEY)) _dropKey = true; @@ -360,8 +360,8 @@ DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int _palette->usePalette(); - SetMessageHandler(&DiskplayerScene::handleMessage); - SetUpdateHandler(&DiskplayerScene::update); + SetMessageHandler(&DiskplayerScene::handleMessage); + SetUpdateHandler(&DiskplayerScene::update); _appearCountdown = 6; } @@ -417,7 +417,7 @@ void DiskplayerScene::update() { } _diskIndex++; while (!_diskAvailable[_diskIndex] && _diskIndex < 19) - _diskIndex++; + _diskIndex++; if (_diskIndex < 20) { _appearCountdown = 1; } else { @@ -448,7 +448,7 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam ¶m, } else if (!_dropKey && param.asPoint().x > 38 && param.asPoint().x < 598 && param.asPoint().y > 400 && param.asPoint().y < 460) { - + _diskSlots[_diskIndex]->stop(); _diskIndex = (param.asPoint().x - 38) / 28; _diskSlots[_diskIndex]->activate(); @@ -462,10 +462,10 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam ¶m, break; case 0x2000: tuneIn(); - break; + break; case 0x2001: stop(); - break; + break; } } return 0; diff --git a/engines/neverhood/diskplayerscene.h b/engines/neverhood/diskplayerscene.h index 4afaf8af9f..150d5c58ed 100644 --- a/engines/neverhood/diskplayerscene.h +++ b/engines/neverhood/diskplayerscene.h @@ -36,7 +36,7 @@ class AsDiskplayerSceneKey : public AnimatedSprite { public: AsDiskplayerSceneKey(NeverhoodEngine *vm); void stDropKey(); -protected: +protected: uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); void stDropKeyDone(); }; @@ -47,7 +47,7 @@ public: void press(); void release(); protected: - DiskplayerScene *_diskplayerScene; + DiskplayerScene *_diskplayerScene; bool _isPlaying; uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); }; @@ -69,7 +69,7 @@ protected: int _blinkCountdown; bool _isLocked; bool _isBlinking; - void update(); + void update(); }; enum { diff --git a/engines/neverhood/entity.cpp b/engines/neverhood/entity.cpp index 8b1298916c..af65cfd025 100644 --- a/engines/neverhood/entity.cpp +++ b/engines/neverhood/entity.cpp @@ -25,25 +25,25 @@ namespace Neverhood { -uint32 MessageParam::asInteger() const { - assert(_type == mptInteger); - return _integer; +uint32 MessageParam::asInteger() const { + assert(_type == mptInteger); + return _integer; } -NPoint MessageParam::asPoint() const { +NPoint MessageParam::asPoint() const { assert(_type == mptInteger || _type == mptPoint); if (_type == mptInteger) { NPoint pt; pt.x = _integer & 0xFFFF; - pt.y = (_integer >> 16) & 0xFFFF; + pt.y = (_integer >> 16) & 0xFFFF; return pt; - } - return _point; + } + return _point; } Entity *MessageParam::asEntity() const { - assert(_type == mptEntity); - return _entity; + assert(_type == mptEntity); + return _entity; } Entity::Entity(NeverhoodEngine *vm, int priority) diff --git a/engines/neverhood/entity.h b/engines/neverhood/entity.h index cba1bb9a7f..0d5cf3fd50 100644 --- a/engines/neverhood/entity.h +++ b/engines/neverhood/entity.h @@ -98,7 +98,7 @@ public: void incGlobalVar(uint32 nameHash, int incrValue); void incSubVar(uint32 nameHash, uint32 subNameHash, int incrValue); int getPriority() const { return _priority; } - bool hasMessageHandler() const { return _messageHandlerCb != NULL; } + bool hasMessageHandler() const { return _messageHandlerCb != NULL; } protected: void (Entity::*_updateHandlerCb)(); uint32 (Entity::*_messageHandlerCb)(int messageNum, const MessageParam ¶m, Entity *sender); diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp index 96e8cc13a6..47cc818fea 100644 --- a/engines/neverhood/gamemodule.cpp +++ b/engines/neverhood/gamemodule.cpp @@ -77,7 +77,7 @@ GameModule::GameModule(NeverhoodEngine *vm) : Module(vm, NULL), _moduleNum(-1), _prevChildObject(NULL), _prevModuleNum(-1), _restoreGameRequested(false), _restartGameRequested(false), _canRequestMainMenu(true), _mainMenuRequested(false) { - + // Other initializations moved to actual engine class _vm->_soundMan->playSoundThree(0x002D0031, 0x8861079); SetMessageHandler(&GameModule::handleMessage); @@ -96,7 +96,7 @@ void GameModule::handleMouseMove(int16 x, int16 y) { mousePos.y = y; debug(2, "GameModule::handleMouseMove(%d, %d)", x, y); sendPointMessage(_childObject, 0, mousePos); - } + } } void GameModule::handleMouseDown(int16 x, int16 y) { @@ -106,7 +106,7 @@ void GameModule::handleMouseDown(int16 x, int16 y) { mousePos.y = y; debug(2, "GameModule::handleMouseDown(%d, %d)", x, y); sendPointMessage(_childObject, 0x0001, mousePos); - } + } } void GameModule::handleMouseUp(int16 x, int16 y) { @@ -116,21 +116,21 @@ void GameModule::handleMouseUp(int16 x, int16 y) { mousePos.y = y; debug(2, "GameModule::handleMouseUp(%d, %d)", x, y); sendPointMessage(_childObject, 0x0002, mousePos); - } + } } void GameModule::handleSpaceKey() { if (_childObject) { debug(2, "GameModule::handleSpaceKey()"); sendMessage(_childObject, 0x0009, 0); - } + } } void GameModule::handleAsciiKey(char key) { if (_childObject) { debug(2, "GameModule::handleAsciiKey()"); sendMessage(_childObject, 0x000A, (uint32)key); - } + } } void GameModule::handleKeyDown(Common::KeyCode keyCode) { @@ -141,7 +141,7 @@ void GameModule::handleKeyDown(Common::KeyCode keyCode) { handleSpaceKey(); debug(2, "GameModule::handleKeyDown()"); sendMessage(_childObject, 0x000B, keyCode); - } + } } void GameModule::handleEscapeKey() { @@ -166,7 +166,7 @@ void GameModule::initKeySlotsPuzzle() { void GameModule::initMemoryPuzzle() { if (!getSubVar(VA_IS_PUZZLE_INIT, 0xC8606803)) { - NonRepeatingRandomNumbers diceIndices(_vm->_rnd, 3); + NonRepeatingRandomNumbers diceIndices(_vm->_rnd, 3); NonRepeatingRandomNumbers availableTiles(_vm->_rnd, 48); NonRepeatingRandomNumbers tileSymbols(_vm->_rnd, 10); for (uint32 i = 0; i < 3; i++) @@ -320,11 +320,11 @@ uint32 GameModule::handleMessage(int messageNum, const MessageParam ¶m, Enti switch (messageNum) { case 0x0800: _canRequestMainMenu = true; - break; + break; case 0x1009: _moduleResult = param.asInteger(); _done = true; - break; + break; } return messageResult; } @@ -786,6 +786,7 @@ void GameModule::openMainMenu() { createModule(1000, 0); } _vm->_screen->saveParams(); + _vm->_screen->update(); _mainMenuRequested = false; createMenuModule(); } diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h index 1fb3557b81..2f2fecf463 100644 --- a/engines/neverhood/gamemodule.h +++ b/engines/neverhood/gamemodule.h @@ -49,7 +49,7 @@ public: void initWaterPipesPuzzle(); void initRadioPuzzle(); void initTestTubes1Puzzle(); - void initTestTubes2Puzzle(); + void initTestTubes2Puzzle(); void initCannonSymbolsPuzzle(); void initCodeSymbolsPuzzle(); void initCubeSymbolsPuzzle(); diff --git a/engines/neverhood/gamevars.cpp b/engines/neverhood/gamevars.cpp index dc25f74e56..9c080fea24 100644 --- a/engines/neverhood/gamevars.cpp +++ b/engines/neverhood/gamevars.cpp @@ -75,7 +75,7 @@ uint32 GameVars::getSubVar(uint32 nameHash, uint32 subNameHash) { int16 subVarIndex = findSubVarIndex(varIndex, subNameHash); if (subVarIndex != -1) value = _vars[subVarIndex].value; - } + } return value; } diff --git a/engines/neverhood/gamevars.h b/engines/neverhood/gamevars.h index de9ffb8ec5..3aec4d1da4 100644 --- a/engines/neverhood/gamevars.h +++ b/engines/neverhood/gamevars.h @@ -160,7 +160,7 @@ enum { VA_HAS_KEY = 0x0090EA95, VA_IS_KEY_INSERTED = 0x08D0AB11, VA_LOCKS_DISABLED = 0x14800353, - V_END_ + V_END_ }; struct GameVar { diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp index 66a7999e59..490959020f 100644 --- a/engines/neverhood/graphics.cpp +++ b/engines/neverhood/graphics.cpp @@ -29,7 +29,7 @@ namespace Neverhood { BaseSurface::BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, Common::String name) : _vm(vm), _priority(priority), _visible(true), _transparent(true), _clipRects(NULL), _clipRectsCount(0), _version(0), _name(name) { - + _drawRect.x = 0; _drawRect.y = 0; _drawRect.width = width; @@ -68,7 +68,7 @@ void BaseSurface::clear() { } void BaseSurface::drawSpriteResource(SpriteResource &spriteResource) { - if (spriteResource.getDimensions().width <= _drawRect.width && + if (spriteResource.getDimensions().width <= _drawRect.width && spriteResource.getDimensions().height <= _drawRect.height) { clear(); spriteResource.draw(_surface, false, false); @@ -77,7 +77,7 @@ void BaseSurface::drawSpriteResource(SpriteResource &spriteResource) { } void BaseSurface::drawSpriteResourceEx(SpriteResource &spriteResource, bool flipX, bool flipY, int16 width, int16 height) { - if (spriteResource.getDimensions().width <= _sysRect.width && + if (spriteResource.getDimensions().width <= _sysRect.width && spriteResource.getDimensions().height <= _sysRect.height) { if (width > 0 && width <= _sysRect.width) _drawRect.width = width; @@ -145,7 +145,7 @@ void ShadowSurface::draw() { FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight) : BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows, "font"), _charsPerRow(charsPerRow), _numRows(numRows), _firstChar(firstChar), _charWidth(charWidth), _charHeight(charHeight), _tracking(NULL) { - + _tracking = new NPointArray(); *_tracking = *tracking; @@ -154,7 +154,7 @@ FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsP FontSurface::FontSurface(NeverhoodEngine *vm, uint32 fileHash, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight) : BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows, "font"), _charsPerRow(charsPerRow), _numRows(numRows), _firstChar(firstChar), _charWidth(charWidth), _charHeight(charHeight), _tracking(NULL) { - + SpriteResource fontSpriteResource(_vm); fontSpriteResource.load(fileHash, true); drawSpriteResourceEx(fontSpriteResource, false, false, 0, 0); @@ -182,7 +182,7 @@ void FontSurface::drawString(BaseSurface *destSurface, int16 x, int16 y, const b for (; stringLen > 0; --stringLen, ++string) { drawChar(destSurface, x, y, *string); x += _tracking ? (*_tracking)[*string - _firstChar].x : _charWidth; - } + } } @@ -201,7 +201,7 @@ FontSurface *FontSurface::createFontSurface(NeverhoodEngine *vm, uint32 fileHash uint16 charHeight = fontData.getPoint(calcHash("meCharHeight")).x; NPointArray *tracking = fontData.getPointArray(calcHash("meTracking")); fontSprite.load(fileHash, true); - fontSurface = new FontSurface(vm, tracking, 16, numRows, firstChar, charWidth, charHeight); + fontSurface = new FontSurface(vm, tracking, 16, numRows, firstChar, charWidth, charHeight); fontSurface->drawSpriteResourceEx(fontSprite, false, false, 0, 0); return fontSurface; } @@ -219,7 +219,7 @@ enum BitmapFlags { void parseBitmapResource(const byte *sprite, bool *rle, NDimensions *dimensions, NPoint *position, const byte **palette, const byte **pixels) { uint16 flags; - + flags = READ_LE_UINT16(sprite); sprite += 2; @@ -278,7 +278,7 @@ void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int rows = READ_LE_UINT16(source); chunks = READ_LE_UINT16(source + 2); source += 4; - + do { if (chunks == 0) { dest += rows * destPitch; @@ -316,7 +316,7 @@ void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int void unpackSpriteNormal(const byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY) { const int sourcePitch = (width + 3) & 0xFFFC; - + if (flipY) { dest += destPitch * (height - 1); destPitch = -destPitch; diff --git a/engines/neverhood/graphics.h b/engines/neverhood/graphics.h index 9ab0d87ab9..703e274576 100644 --- a/engines/neverhood/graphics.h +++ b/engines/neverhood/graphics.h @@ -62,12 +62,12 @@ struct NRect { typedef Common::Array<NRect> NRectArray; -// TODO: Use Common::Rect +// TODO: Use Common::Rect struct NDrawRect { int16 x, y, width, height; NDrawRect() : x(0), y(0), width(0), height(0) {} NDrawRect(int16 x0, int16 y0, int16 width0, int16 height0) : x(x0), y(y0), width(width0), height(height0) {} - int16 x2() { return x + width; } + int16 x2() { return x + width; } int16 y2() { return y + height; } void set(int16 x0, int16 y0, int16 width0, int16 height0) { x = x0; diff --git a/engines/neverhood/klaymen.cpp b/engines/neverhood/klaymen.cpp index 70567806fa..8ed27c825a 100644 --- a/engines/neverhood/klaymen.cpp +++ b/engines/neverhood/klaymen.cpp @@ -33,19 +33,19 @@ static const KlaymenIdleTableItem klaymenIdleTable1[] = { {1, kIdleArms}, {1, kIdleChest}, {1, kIdleHeadOff} -}; +}; static const KlaymenIdleTableItem klaymenIdleTable2[] = { {1, kIdlePickEar}, {1, kIdleSpinHead}, {1, kIdleChest}, {1, kIdleHeadOff} -}; +}; static const KlaymenIdleTableItem klaymenIdleTable3[] = { {1, kIdleTeleporterHands}, {1, kIdleTeleporterHands2} -}; +}; static const KlaymenIdleTableItem klaymenIdleTable4[] = { {1, kIdleSpinHead}, @@ -56,7 +56,7 @@ static const KlaymenIdleTableItem klaymenIdleTable4[] = { static const KlaymenIdleTableItem klaymenIdleTable1002[] = { {1, kIdlePickEar}, {2, kIdleWonderAbout} -}; +}; // Klaymen @@ -66,7 +66,7 @@ Klaymen::Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRec _attachedSprite(NULL), _isWalking(false), _actionStatus(1), _parentScene(parentScene), _isSneaking(false), _isLargeStep(false), _doYHitIncr(false), _isLeverDown(false), _isSittingInTeleporter(false), _actionStatusChanged(false), _ladderStatus(0), _pathPoints(NULL), _soundFlag(false), _idleTableNum(0), _otherSprite(NULL), _moveObjectCountdown(0), _readyToSpit(false), _walkResumeFrameIncr(0) { - + createSurface(1000, 320, 200); _x = x; _y = y; @@ -447,7 +447,7 @@ void Klaymen::upIdleAnimation() { bool Klaymen::stStartActionFromIdle(AnimationCb callback) { if (_busyStatus == 2) { _busyStatus = 1; - _acceptInput = false; + _acceptInput = false; startAnimation(0x9A7020B8, 0, -1); SetUpdateHandler(&Klaymen::update); SetMessageHandler(&Klaymen::hmStartAction); @@ -684,35 +684,35 @@ void Klaymen::suAction() { _x += _deltaX; } _deltaX = 0; - + if (_doDeltaY) { _y -= _deltaY; } else { _y += _deltaY; } _deltaY = 0; - + if (_frameChanged) { if (xdiff > 6) _x += 6; else if (xdiff < -6) _x -= 6; else - _x = _destX; + _x = _destX; } - + updateBounds(); - + } void Klaymen::suSneaking() { - + int16 xdiff = _destX - _x; - + if (_currFrameIndex == 9) { if (xdiff > 26) _deltaX += xdiff - 26; - else if (xdiff < -26) + else if (xdiff < -26) _deltaX -= xdiff + 26; } @@ -720,7 +720,7 @@ void Klaymen::suSneaking() { xdiff = _deltaX; else if (xdiff < -_deltaX) xdiff = -_deltaX; - _deltaX = 0; + _deltaX = 0; if (_destX != _x) { HitRect *hitRectPrev = _parentScene->findHitRectAtPos(_x, _y); @@ -749,7 +749,7 @@ void Klaymen::suSneaking() { } updateBounds(); } - + } void Klaymen::stSneak() { @@ -761,7 +761,7 @@ void Klaymen::stSneak() { SetUpdateHandler(&Klaymen::update); SetMessageHandler(&Klaymen::hmSneaking); SetSpriteUpdate(&Klaymen::suSneaking); - FinalizeState(&Klaymen::evSneakingDone); + FinalizeState(&Klaymen::evSneakingDone); } void Klaymen::evSneakingDone() { @@ -801,7 +801,7 @@ void Klaymen::stStartWalking() { SetMessageHandler(&Klaymen::hmStartWalking); SetSpriteUpdate(&Klaymen::suWalkingTestExit); NextState(&Klaymen::stWalkingFirst); - FinalizeState(&Klaymen::evStartWalkingDone); + FinalizeState(&Klaymen::evStartWalkingDone); } } @@ -832,7 +832,7 @@ void Klaymen::stWalkingFirst() { SetMessageHandler(&Klaymen::hmWalking); SetSpriteUpdate(&Klaymen::suWalkingFirst); NextState(&Klaymen::stUpdateWalkingFirst); - FinalizeState(&Klaymen::evStartWalkingDone); + FinalizeState(&Klaymen::evStartWalkingDone); } void Klaymen::suWalkingFirst() { @@ -882,20 +882,20 @@ void Klaymen::stUpdateWalkingFirst() { SetUpdateHandler(&Klaymen::update); SetMessageHandler(&Klaymen::hmSneaking); SetSpriteUpdate(&Klaymen::suSneaking); - FinalizeState(&Klaymen::evSneakingDone); + FinalizeState(&Klaymen::evSneakingDone); } } void Klaymen::suWalkingTestExit() { int16 xdiff = ABS(_destX - _x); int16 xdelta = _destX - _x; - + if (xdelta > _deltaX) xdelta = _deltaX; else if (xdelta < -_deltaX) xdelta = -_deltaX; - - _deltaX = 0; + + _deltaX = 0; if (xdiff == 0 || (_actionStatus != 2 && _actionStatus != 3 && xdiff <= 42 && _currFrameIndex >= 5 && _currFrameIndex <= 11) || @@ -928,7 +928,7 @@ void Klaymen::suWalkingTestExit() { } updateBounds(); } - + } uint32 Klaymen::hmLever(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -1363,7 +1363,7 @@ void Klaymen::stLargeStep() { SetUpdateHandler(&Klaymen::update); SetMessageHandler(&Klaymen::hmLargeStep); SetSpriteUpdate(&Klaymen::suLargeStep); - FinalizeState(&Klaymen::evLargeStepDone); + FinalizeState(&Klaymen::evLargeStepDone); } void Klaymen::evLargeStepDone() { @@ -1372,11 +1372,11 @@ void Klaymen::evLargeStepDone() { void Klaymen::suLargeStep() { int16 xdiff = _destX - _x; - + if (_doDeltaX) { _deltaX = -_deltaX; } - + if (_currFrameIndex == 7) { _deltaX = xdiff; } @@ -1385,7 +1385,7 @@ void Klaymen::suLargeStep() { xdiff = _deltaX; _deltaX = 0; - + if (_x != _destX) { HitRect *hitRectPrev = _parentScene->findHitRectAtPos(_x, _y); _x += xdiff; @@ -1420,7 +1420,7 @@ uint32 Klaymen::hmLargeStep(int messageNum, const MessageParam ¶m, Entity *s case 0x3002: _x = _destX; gotoNextStateExt(); - break; + break; } return messageResult; } @@ -1681,7 +1681,7 @@ void Klaymen::stStartClimbLadderDown() { _ladderStatus = 2; _acceptInput = true; startAnimation(0x122D1505, 29 - _currFrameIndex, -1); - } + } } } @@ -1979,7 +1979,7 @@ uint32 Klaymen::hmMoveObjectTurn(int messageNum, const MessageParam ¶m, Enti break; case 0x480A: _isMoveObjectRequested = true; - return 0; + return 0; } return hmLowLevelAnimation(messageNum, param, sender); } @@ -2521,7 +2521,7 @@ void Klaymen::stInsertKey() { more = true; } while (more); _keysToInsert++; - } + } } if (_keysToInsert == 0) { GotoState(NULL); @@ -3049,7 +3049,7 @@ void Klaymen::stFallSkipJump() { void Klaymen::upMoveObject() { if (_x >= 380) gotoNextStateExt(); - Klaymen::update(); + Klaymen::update(); } uint32 Klaymen::hmMatch(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -3165,7 +3165,7 @@ void Klaymen::stTumbleHeadless() { void Klaymen::stCloseEyes() { if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stCloseEyes))) { _busyStatus = 1; - _acceptInput = false; + _acceptInput = false; startAnimation(0x5420E254, 0, -1); SetUpdateHandler(&Klaymen::update); SetMessageHandler(&Klaymen::hmLowLevel); @@ -3358,7 +3358,7 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4004: GotoState(&Klaymen::stTryStandIdle); - break; + break; case 0x4804: if (param.asInteger() == 2) GotoState(&Klaymen::stSleeping); @@ -3380,7 +3380,7 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); @@ -3408,10 +3408,10 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam ¶m) { sendMessage(_parentScene, 0x2002, 0); GotoState(&Klaymen::stWakeUp); } - break; + break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -3423,7 +3423,7 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - + setKlaymenIdleTable1(); } @@ -3438,7 +3438,7 @@ void KmScene1002::xUpdate() { _idleTableNum = 0; } } - + uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2001: @@ -3451,7 +3451,7 @@ uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4800: startWalkToX(param.asPoint().x, false); break; - case 0x4004: + case 0x4004: GotoState(&Klaymen::stTryStandIdle); break; case 0x4803: @@ -3479,42 +3479,42 @@ uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam ¶m) { break; } break; - case 0x480A: + case 0x480A: GotoState(&Klaymen::stMoveVenusFlyTrap); break; - case 0x480D: + case 0x480D: GotoState(&Klaymen::stJumpToRingVenusFlyTrap); break; - case 0x4816: + case 0x4816: if (param.asInteger() == 0) GotoState(&Klaymen::stPressDoorButton); break; - case 0x4817: + case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; - case 0x481B: + case 0x481B: startWalkToAttachedSpriteXDistance(param.asInteger()); break; - case 0x4820: + case 0x4820: sendMessage(_parentScene, 0x2005, 0); - GotoState(&Klaymen::stContinueClimbLadderUp); + GotoState(&Klaymen::stContinueClimbLadderUp); break; - case 0x4821: + case 0x4821: sendMessage(_parentScene, 0x2005, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderDown); + GotoState(&Klaymen::stStartClimbLadderDown); break; - case 0x4822: + case 0x4822: sendMessage(_parentScene, 0x2005, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderUp); + GotoState(&Klaymen::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2006, 0); - GotoState(&Klaymen::stClimbLadderHalf); + GotoState(&Klaymen::stClimbLadderHalf); break; - case 0x482E: + case 0x482E: if (param.asInteger() == 1) GotoState(&Klaymen::stWalkToFrontNoStep); else @@ -3529,7 +3529,7 @@ uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x483F: startSpecialWalkRight(param.asInteger()); break; - case 0x4840: + case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } @@ -3540,8 +3540,8 @@ uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - - _dataResource.load(0x01900A04); + + _dataResource.load(0x01900A04); } uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -3606,7 +3606,7 @@ uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - + // Empty } @@ -3615,7 +3615,7 @@ uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2000: _isSittingInTeleporter = param.asInteger() != 0; - messageResult = 1; + messageResult = 1; break; case 0x4001: case 0x4800: @@ -3653,7 +3653,7 @@ uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam ¶m) { sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klaymen::stSitInTeleporter); - break; + break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; @@ -3673,7 +3673,7 @@ uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - + setKlaymenIdleTable(klaymenIdleTable4, ARRAYSIZE(klaymenIdleTable4)); _doYHitIncr = true; } @@ -3741,7 +3741,7 @@ uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - + // Empty } @@ -3762,8 +3762,8 @@ uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - - // Empty + + // Empty } uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -3774,7 +3774,7 @@ uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4004: GotoState(&Klaymen::stTryStandIdle); - break; + break; case 0x4812: if (param.asInteger() == 2) GotoState(&Klaymen::stPickUpNeedle); @@ -3792,7 +3792,7 @@ uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam ¶m) { startWalkToXDistance(param.asPoint().y, param.asPoint().x); else startWalkToAttachedSpriteXDistance(param.asPoint().x); - break; + break; case 0x481F: if (param.asInteger() == 1) GotoState(&Klaymen::stTurnAwayFromUse); @@ -3803,7 +3803,7 @@ uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -3814,7 +3814,7 @@ uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - // Empty + // Empty } uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -3825,10 +3825,10 @@ uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4004: GotoState(&Klaymen::stTryStandIdle); - break; + break; case 0x4804: GotoState(&Klaymen::stCrashDown); - break; + break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); @@ -3839,7 +3839,7 @@ uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - + // Empty } @@ -3879,9 +3879,9 @@ uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481A: - GotoState(&Klaymen::stInsertDisk); + GotoState(&Klaymen::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) @@ -3936,7 +3936,7 @@ uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam ¶m) { sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klaymen::stSitInTeleporter); - break; + break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; @@ -3944,13 +3944,13 @@ uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483D: teleporterAppear(0xEE084A04); - break; + break; case 0x483E: teleporterDisappear(0xB86A4274); - break; + break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -3961,7 +3961,7 @@ uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - // Empty + // Empty } uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -3978,7 +3978,7 @@ uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam ¶m) { GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject); else GotoState(&Klaymen::stMoveObjectFaceObject); - break; + break; case 0x480D: GotoState(&Klaymen::stUseLever); break; @@ -3993,12 +3993,12 @@ uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481A: if (param.asInteger() == 1) - GotoState(&Klaymen::stInsertKey); + GotoState(&Klaymen::stInsertKey); else - GotoState(&Klaymen::stInsertDisk); + GotoState(&Klaymen::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) @@ -4020,7 +4020,7 @@ uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -4032,8 +4032,8 @@ uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1401::KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - - // Empty + + // Empty } uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -4044,13 +4044,13 @@ uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4004: GotoState(&Klaymen::stTryStandIdle); - break; + break; case 0x480A: if (param.asInteger() == 1) GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject); else GotoState(&Klaymen::stMoveObjectFaceObject); - break; + break; case 0x4816: if (param.asInteger() == 1) GotoState(&Klaymen::stPressButton); @@ -4068,7 +4068,7 @@ uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam ¶m) { startWalkToXDistance(param.asPoint().y, param.asPoint().x); else startWalkToAttachedSpriteXDistance(param.asPoint().x); - break; + break; case 0x481F: if (param.asInteger() == 1) GotoState(&Klaymen::stTurnAwayFromUse); @@ -4101,8 +4101,8 @@ uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1402::KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - - SetFilterY(&Sprite::defFilterY); + + SetFilterY(&Sprite::defFilterY); } uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -4113,13 +4113,13 @@ uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4004: GotoState(&Klaymen::stTryStandIdle); - break; + break; case 0x480A: if (param.asInteger() == 1) GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject); else GotoState(&Klaymen::stMoveObjectFaceObject); - break; + break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); @@ -4129,7 +4129,7 @@ uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam ¶m) { startWalkToXDistance(param.asPoint().y, param.asPoint().x); else startWalkToAttachedSpriteXDistance(param.asPoint().x); - break; + break; case 0x481D: GotoState(&Klaymen::stTurnToUse); break; @@ -4162,7 +4162,7 @@ uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam ¶m) { GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject); else GotoState(&Klaymen::stMoveObjectFaceObject); - break; + break; case 0x480D: GotoState(&Klaymen::stUseLever); break; @@ -4177,7 +4177,7 @@ uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); @@ -4189,7 +4189,7 @@ uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -4202,7 +4202,7 @@ uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1404::KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - // Empty + // Empty } uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -4219,7 +4219,7 @@ uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam ¶m) { GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject); else GotoState(&Klaymen::stMoveObjectFaceObject); - break; + break; case 0x4812: if (param.asInteger() == 2) GotoState(&Klaymen::stPickUpNeedle); @@ -4233,7 +4233,7 @@ uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam ¶m) { gotoNextStateExt(); break; case 0x481A: - GotoState(&Klaymen::stInsertDisk); + GotoState(&Klaymen::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) @@ -4307,7 +4307,7 @@ uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); @@ -4345,7 +4345,7 @@ uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam ¶m) { sendMessage(_parentScene, 0x2032, 1); _isSittingInTeleporter = true; GotoState(&Klaymen::stSitInTeleporter); - break; + break; case 0x4836: sendMessage(_parentScene, 0x2032, 0); _isSittingInTeleporter = false; @@ -4353,7 +4353,7 @@ uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -4366,7 +4366,7 @@ uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - // Empty + // Empty } uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -4388,7 +4388,7 @@ uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4803: GotoState(&Klaymen::stFallSkipJump); - break; + break; case 0x4812: if (param.asInteger() == 2) GotoState(&Klaymen::stPickUpNeedle); @@ -4435,7 +4435,7 @@ uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam ¶m) { sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klaymen::stSitInTeleporter); - break; + break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; @@ -4443,10 +4443,10 @@ uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483D: teleporterAppear(0x5E0A4905); - break; + break; case 0x483E: teleporterDisappear(0xD86E4477); - break; + break; } return messageResult; } @@ -4454,7 +4454,7 @@ uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - // Empty + // Empty } uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -4469,7 +4469,7 @@ uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481D: GotoState(&Klaymen::stTurnToUse); break; @@ -4482,7 +4482,7 @@ uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -4493,7 +4493,7 @@ uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - // Empty + // Empty } uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam ¶m) { @@ -4557,7 +4557,7 @@ uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - + // Empty } @@ -4600,7 +4600,7 @@ uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); @@ -4622,7 +4622,7 @@ uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam ¶m) { sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klaymen::stSitInTeleporter); - break; + break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; @@ -4635,7 +4635,7 @@ uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam ¶m) { teleporterDisappear(0x9A28CA1C); break; } - return messageResult; + return messageResult; } KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount) @@ -4684,7 +4684,7 @@ uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam ¶m) { setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; - case 0x482E: + case 0x482E: if (param.asInteger() == 1) GotoState(&Klaymen::stWalkToFrontNoStep); else @@ -4698,12 +4698,12 @@ uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } - return 0; + return 0; } KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) @@ -4711,7 +4711,7 @@ KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 // Empty } - + uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: @@ -4740,7 +4740,7 @@ uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; @@ -4748,7 +4748,7 @@ uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam ¶m) { GotoState(&Klaymen::stClayDoorOpen); break; case 0x481A: - GotoState(&Klaymen::stInsertDisk); + GotoState(&Klaymen::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) @@ -4768,7 +4768,7 @@ uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -4785,7 +4785,7 @@ KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 void KmScene2205::xUpdate() { setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex); } - + uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: @@ -4809,13 +4809,13 @@ uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -4837,7 +4837,7 @@ KmScene2206::~KmScene2206() { void KmScene2206::xUpdate() { setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex); } - + uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: @@ -4874,7 +4874,7 @@ uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); @@ -4897,7 +4897,7 @@ uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam ¶m) { setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; - case 0x482E: + case 0x482E: if (param.asInteger() == 1) GotoState(&Klaymen::stWalkToFrontNoStep); else @@ -4914,7 +4914,7 @@ uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -4927,7 +4927,7 @@ KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 // Empty } - + uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2001: @@ -4961,7 +4961,7 @@ uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); @@ -4977,7 +4977,7 @@ uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -5022,7 +5022,7 @@ uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); @@ -5080,7 +5080,7 @@ uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam ¶m case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481F: if (param.asInteger() == 0) GotoState(&Klaymen::stWonderAboutHalf); @@ -5133,7 +5133,7 @@ uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481F: if (param.asInteger() == 0) GotoState(&Klaymen::stWonderAboutHalf); @@ -5156,13 +5156,13 @@ uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam ¶m) { } return 0; } - + KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { // Empty } - + uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam ¶m) { uint32 messageResult = 0; switch (messageNum) { @@ -5184,7 +5184,7 @@ uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); @@ -5203,7 +5203,7 @@ uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam ¶m) { setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; - case 0x482E: + case 0x482E: if (param.asInteger() == 1) GotoState(&Klaymen::stWalkToFrontNoStep); else @@ -5228,7 +5228,7 @@ uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x483F: startSpecialWalkRight(param.asInteger()); - break; + break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; @@ -5357,23 +5357,23 @@ uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam ¶m) { else GotoState(&Klaymen::stWonderAbout); break; - case 0x4820: + case 0x4820: sendMessage(_parentScene, 0x2000, 0); - GotoState(&Klaymen::stContinueClimbLadderUp); + GotoState(&Klaymen::stContinueClimbLadderUp); break; - case 0x4821: + case 0x4821: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderDown); + GotoState(&Klaymen::stStartClimbLadderDown); break; - case 0x4822: + case 0x4822: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderUp); + GotoState(&Klaymen::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2001, 0); - GotoState(&Klaymen::stClimbLadderHalf); + GotoState(&Klaymen::stClimbLadderHalf); break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); @@ -5382,16 +5382,16 @@ uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x483F: startSpecialWalkRight(param.asInteger()); break; - case 0x4840: + case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return messageResult; } - + KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount) : Klaymen(vm, parentScene, x, y) { - + _surface->setClipRects(clipRects, clipRectsCount); } @@ -5425,7 +5425,7 @@ uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam ¶m) { gotoNextStateExt(); break; case 0x481A: - GotoState(&Klaymen::stInsertDisk); + GotoState(&Klaymen::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) @@ -5451,40 +5451,40 @@ uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam ¶m) { else GotoState(&Klaymen::stWonderAbout); break; - case 0x4820: + case 0x4820: sendMessage(_parentScene, 0x2000, 0); - GotoState(&Klaymen::stContinueClimbLadderUp); + GotoState(&Klaymen::stContinueClimbLadderUp); break; - case 0x4821: + case 0x4821: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderDown); + GotoState(&Klaymen::stStartClimbLadderDown); break; - case 0x4822: + case 0x4822: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderUp); + GotoState(&Klaymen::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2001, 0); - GotoState(&Klaymen::stClimbLadderHalf); + GotoState(&Klaymen::stClimbLadderHalf); break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; - case 0x4840: + case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return messageResult; } - + KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { // Empty } - + uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam ¶m) { uint32 messageResult = 0; switch (messageNum) { @@ -5505,7 +5505,7 @@ uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klaymen::stTurnToUseInTeleporter); @@ -5521,7 +5521,7 @@ uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam ¶m) { sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klaymen::stSitInTeleporter); - break; + break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; @@ -5536,7 +5536,7 @@ KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 // Empty } - + uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4804: @@ -5570,13 +5570,13 @@ uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481B: if (param.asPoint().y != 0) startWalkToXDistance(param.asPoint().y, param.asPoint().x); else startWalkToAttachedSpriteXDistance(param.asPoint().x); - break; + break; case 0x481D: GotoState(&Klaymen::stTurnToUse); break; @@ -5599,7 +5599,7 @@ uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam ¶m) { setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; - case 0x482E: + case 0x482E: if (param.asInteger() == 1) GotoState(&Klaymen::stWalkToFrontNoStep); else @@ -5620,7 +5620,7 @@ uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene2803::KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount) : Klaymen(vm, parentScene, x, y) { - + _surface->setClipRects(clipRects, clipRectsCount); _dataResource.load(0x00900849); } @@ -5648,7 +5648,7 @@ uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; @@ -5664,7 +5664,7 @@ uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam ¶m) { else GotoState(&Klaymen::stWonderAboutHalf); break; - case 0x482E: + case 0x482E: GotoState(&Klaymen::stWalkToFront); break; case 0x482F: @@ -5682,7 +5682,7 @@ uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam ¶m) { KmScene2803Small::KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { - + _dataResource.load(0x81120132); } @@ -5759,7 +5759,7 @@ uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klaymen::stTurnToUseInTeleporter); @@ -5775,7 +5775,7 @@ uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam ¶m) { sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klaymen::stSitInTeleporter); - break; + break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; @@ -5805,7 +5805,7 @@ KmScene2806::KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 loadSound(6, 0x166FC6E0); loadSound(7, 0x00018040); } - + _dataResource.load(0x98182003); _surface->setClipRects(clipRects, clipRectsCount); } @@ -5827,12 +5827,12 @@ uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4816: if (param.asInteger() == 0) - GotoState(&Klaymen::stPressButtonSide); + GotoState(&Klaymen::stPressButtonSide); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; @@ -5885,12 +5885,12 @@ uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4816: if (param.asInteger() == 0) - GotoState(&Klaymen::stPressButtonSide); + GotoState(&Klaymen::stPressButtonSide); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; @@ -5907,7 +5907,7 @@ uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam ¶m) { return 0; } -KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) +KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : Klaymen(vm, parentScene, x, y) { // Empty @@ -5925,7 +5925,7 @@ uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam ¶ case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x4818: startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x); break; @@ -5937,7 +5937,7 @@ uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam ¶ else GotoState(&Klaymen::stWonderAboutSmall); break; - case 0x482E: + case 0x482E: if (param.asInteger() == 1) GotoState(&Klaymen::stWalkToFrontNoStepSmall); else @@ -5961,7 +5961,7 @@ KmScene2810::KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 _surface->setClipRects(clipRects, clipRectsCount); } - + uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: @@ -5985,7 +5985,7 @@ uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); - break; + break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; @@ -6009,23 +6009,23 @@ uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam ¶m) { else GotoState(&Klaymen::stWonderAbout); break; - case 0x4820: + case 0x4820: sendMessage(_parentScene, 0x2000, 0); - GotoState(&Klaymen::stContinueClimbLadderUp); + GotoState(&Klaymen::stContinueClimbLadderUp); break; - case 0x4821: + case 0x4821: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderDown); + GotoState(&Klaymen::stStartClimbLadderDown); break; - case 0x4822: + case 0x4822: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderUp); + GotoState(&Klaymen::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2001, 0); - GotoState(&Klaymen::stClimbLadderHalf); + GotoState(&Klaymen::stClimbLadderHalf); break; case 0x4824: sendMessage(_parentScene, 0x2000, 0); @@ -6080,7 +6080,7 @@ uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam ¶m) { gotoNextStateExt(); break; case 0x481A: - GotoState(&Klaymen::stInsertDisk); + GotoState(&Klaymen::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) @@ -6094,29 +6094,29 @@ uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x481E: GotoState(&Klaymen::stReturnFromUse); break; - case 0x4820: + case 0x4820: sendMessage(_parentScene, 0x2001, 0); - GotoState(&Klaymen::stContinueClimbLadderUp); + GotoState(&Klaymen::stContinueClimbLadderUp); break; - case 0x4821: + case 0x4821: sendMessage(_parentScene, 0x2001, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderDown); + GotoState(&Klaymen::stStartClimbLadderDown); break; - case 0x4822: + case 0x4822: sendMessage(_parentScene, 0x2001, 0); _destY = param.asInteger(); - GotoState(&Klaymen::stStartClimbLadderUp); + GotoState(&Klaymen::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2002, 0); - GotoState(&Klaymen::stClimbLadderHalf); + GotoState(&Klaymen::stClimbLadderHalf); break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; - case 0x482E: + case 0x482E: if (param.asInteger() == 1) GotoState(&Klaymen::stWalkToFrontNoStep); else @@ -6131,7 +6131,7 @@ uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x483F: startSpecialWalkRight(param.asInteger()); break; - case 0x4840: + case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } diff --git a/engines/neverhood/klaymen.h b/engines/neverhood/klaymen.h index 25443b5a35..9e461a9c9c 100644 --- a/engines/neverhood/klaymen.h +++ b/engines/neverhood/klaymen.h @@ -77,24 +77,24 @@ public: void stIdleArms(); void evIdleArmsDone(); uint32 hmIdleArms(int messageNum, const MessageParam ¶m, Entity *sender); - + void stIdleChest(); uint32 hmIdleChest(int messageNum, const MessageParam ¶m, Entity *sender); - + void stIdleHeadOff(); uint32 hmIdleHeadOff(int messageNum, const MessageParam ¶m, Entity *sender); void stIdleWonderAbout(); void stIdleTeleporterHands(); - + void stIdleTeleporterHands2(); void stTryStandIdle(); void stStandAround(); void upStandIdle(); void stIdleBlink(); - + bool stStartAction(AnimationCb callback3); bool stStartActionFromIdle(AnimationCb callback); uint32 hmStartAction(int messageNum, const MessageParam ¶m, Entity *sender); @@ -134,7 +134,7 @@ public: void stPickUpTube(); uint32 hmPickUpTube(int messageNum, const MessageParam ¶m, Entity *sender); - + void stTurnToUse(); void stTurnToUseHalf(); void stTurnAwayFromUse(); @@ -263,10 +263,10 @@ public: void stJumpToGrabFall(); uint32 hmJumpToGrab(int messageNum, const MessageParam ¶m, Entity *sender); void suJumpToGrab(); - + void stJumpToGrabRelease(); uint32 hmJumpToGrabRelease(int messageNum, const MessageParam ¶m, Entity *sender); - + void stSitInTeleporter(); uint32 hmSitInTeleporter(int messageNum, const MessageParam ¶m, Entity *sender); @@ -326,7 +326,7 @@ public: void stFinishGrow(); uint32 hmFinishGrow(int messageNum, const MessageParam ¶m, Entity *sender); - + void stJumpToRingVenusFlyTrap(); uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender); @@ -363,7 +363,7 @@ public: //////////////////////////////////////////////////////////////////////////// void stopWalking(); - + void suAction(); void suUpdateDestX(); void suWalkingTestExit(); @@ -375,7 +375,7 @@ public: void setKlaymenIdleTable1(); void setKlaymenIdleTable2(); void setKlaymenIdleTable3(); - + void setSoundFlag(bool value) { _soundFlag = value; } void spitIntoPipe(); @@ -416,7 +416,7 @@ protected: NPointArray *_pathPoints; bool _soundFlag; - + int16 _spitOutCountdown; bool _isSittingInTeleporter; @@ -456,16 +456,16 @@ protected: void stStartWalkingSmall(); uint32 hmWalkingSmall(int messageNum, const MessageParam ¶m, Entity *sender); - + void enterIdleAnimation(uint idleAnimation); void walkAlongPathPoints(); - + }; class KmScene1001 : public Klaymen { public: KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: +protected: uint32 xHandleMessage(int messageNum, const MessageParam ¶m); }; @@ -473,7 +473,7 @@ class KmScene1002 : public Klaymen { public: KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); protected: - void xUpdate(); + void xUpdate(); uint32 xHandleMessage(int messageNum, const MessageParam ¶m); }; diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp index accdaca63f..d59afa4ba5 100644 --- a/engines/neverhood/menumodule.cpp +++ b/engines/neverhood/menumodule.cpp @@ -20,6 +20,11 @@ * */ +#include "common/config-manager.h" +#include "common/translation.h" + +#include "gui/saveload.h" + #include "neverhood/menumodule.h" #include "neverhood/gamemodule.h" @@ -68,9 +73,9 @@ static const uint32 kMakingOfSmackerFileHashList[] = { MenuModule::MenuModule(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule), _savegameList(NULL) { - + SetMessageHandler(&MenuModule::handleMessage); - + _savedPaletteData = _vm->_screen->getPaletteData(); _vm->_mixer->pauseAll(true); _vm->toggleSoundUpdate(false); @@ -193,24 +198,26 @@ uint32 MenuModule::handleMessage(int messageNum, const MessageParam ¶m, Enti } void MenuModule::createLoadGameMenu() { - _savegameSlot = -1; - _savegameList = new SavegameList(); - loadSavegameList(); + refreshSaveGameList(); _childObject = new LoadGameMenu(_vm, this, _savegameList); } void MenuModule::createSaveGameMenu() { - _savegameSlot = -1; - _savegameList = new SavegameList(); - loadSavegameList(); + refreshSaveGameList(); _childObject = new SaveGameMenu(_vm, this, _savegameList); } void MenuModule::createDeleteGameMenu() { + refreshSaveGameList(); + _childObject = new DeleteGameMenu(_vm, this, _savegameList); +} + +void MenuModule::refreshSaveGameList() { _savegameSlot = -1; + delete _savegameList; + _savegameList = NULL; _savegameList = new SavegameList(); loadSavegameList(); - _childObject = new DeleteGameMenu(_vm, this, _savegameList); } void MenuModule::handleLoadGameMenuAction(bool doLoad) { @@ -259,7 +266,7 @@ void MenuModule::loadSavegameList() { Neverhood::NeverhoodEngine::SaveHeader header; Common::String pattern = _vm->getTargetName(); pattern += ".???"; - + Common::StringArray filenames; filenames = saveFileMan->listSavefiles(pattern.c_str()); Common::sort(filenames.begin(), filenames.end()); @@ -317,7 +324,7 @@ uint32 MenuButton::handleMessage(int messageNum, const MessageParam ¶m, Enti MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule) : Scene(vm, parentModule) { - + static const uint32 kMenuButtonFileHashes[] = { 0x36C62120, 0x56C62120, @@ -329,7 +336,7 @@ MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule) 0x16C62130, 0x16C62100 }; - + static const NRect kMenuButtonCollisionBounds[] = { NRect(52, 121, 110, 156), NRect(52, 192, 109, 222), @@ -341,14 +348,14 @@ MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule) NRect(527, 384, 580, 412), NRect(522, 255, 580, 289) }; - + setBackground(0x08C0020C); setPalette(0x08C0020C); insertScreenMouse(0x00208084); - + insertStaticSprite(0x41137051, 100); insertStaticSprite(0xC10B2015, 100); - + // TODO Only if music is enabled _musicOnButton = insertStaticSprite(0x0C24C0EE, 100); @@ -357,9 +364,9 @@ MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule) kMenuButtonFileHashes[buttonIndex], kMenuButtonCollisionBounds[buttonIndex]); addCollisionSprite(menuButton); } - - SetUpdateHandler(&Scene::update); - SetMessageHandler(&MainMenu::handleMessage); + + SetUpdateHandler(&Scene::update); + SetMessageHandler(&MainMenu::handleMessage); } @@ -389,18 +396,18 @@ CreditsScene::CreditsScene(NeverhoodEngine *vm, Module *parentModule, bool canAb : Scene(vm, parentModule), _canAbort(canAbort), _screenIndex(0), _ticksDuration(0), _countdown(216) { - SetUpdateHandler(&CreditsScene::update); + SetUpdateHandler(&CreditsScene::update); SetMessageHandler(&CreditsScene::handleMessage); - + setBackground(0x6081128C); setPalette(0x6081128C); _ticksTime = _vm->_system->getMillis() + 202100; - + _musicResource = new MusicResource(_vm); _musicResource->load(0x30812225); _musicResource->play(0); - + } CreditsScene::~CreditsScene() { @@ -462,7 +469,7 @@ Widget::Widget(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene SetUpdateHandler(&Widget::update); SetMessageHandler(&Widget::handleMessage); - + setPosition(x, y); } @@ -525,7 +532,7 @@ TextLabelWidget::TextLabelWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStat const byte *string, int stringLen, BaseSurface *drawSurface, int16 tx, int16 ty, FontSurface *fontSurface) : Widget(vm, x, y, parentScene, baseObjectPriority, baseSurfacePriority), _string(string), _stringLen(stringLen), _drawSurface(drawSurface), _tx(tx), _ty(ty), _fontSurface(fontSurface) { - + } void TextLabelWidget::initialize() { @@ -566,7 +573,7 @@ TextEditWidget::TextEditWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateM _maxVisibleChars = (_rect.x2 - _rect.x1) / _fontSurface->getCharWidth(); _cursorPos = 0; - + SetUpdateHandler(&TextEditWidget::update); SetMessageHandler(&TextEditWidget::handleMessage); } @@ -759,9 +766,7 @@ void SavegameListBox::onClick() { mousePos.y -= _y + _rect.y1; if (mousePos.x >= 0 && mousePos.x <= _rect.x2 - _rect.x1 && mousePos.y >= 0 && mousePos.y <= _rect.y2 - _rect.y1) { - // We add 1 to the char height to ensure that the correct entry is chosen if the - // user clicks at the bottom the text entry - int newIndex = _firstVisibleItem + mousePos.y / (_fontSurface->getCharHeight() + 1); + int newIndex = _firstVisibleItem + mousePos.y / _fontSurface->getCharHeight(); if (newIndex <= _lastVisibleItem) { _currIndex = newIndex; refresh(); @@ -799,7 +804,7 @@ void SavegameListBox::buildItems() { void SavegameListBox::drawItems() { for (int i = 0; i < (int)_textLabelItems.size(); ++i) { - TextLabelWidget *label = _textLabelItems[i]; + TextLabelWidget *label = _textLabelItems[i]; if (i >= _firstVisibleItem && i <= _lastVisibleItem) { label->setY(_rect.y1 + (i - _firstVisibleItem) * _fontSurface->getCharHeight()); label->updateBounds(); @@ -848,17 +853,68 @@ void SavegameListBox::pageDown() { } } +int GameStateMenu::scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc) { + const EnginePlugin *plugin = NULL; + EngineMan.findGame(ConfMan.get("gameid"), &plugin); + GUI::SaveLoadChooser *dialog; + Common::String desc; + int slot; + + if (isSave) { + dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); + + slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + desc = dialog->getResultString(); + + if (desc.empty()) + desc = dialog->createDefaultSaveDescription(slot); + + if (desc.size() > 29) + desc = Common::String(desc.c_str(), 29); + + saveDesc = desc; + } else { + dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); + slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + } + + delete dialog; + + return slot; +} + GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList, const uint32 *buttonFileHashes, const NRect *buttonCollisionBounds, uint32 backgroundFileHash, uint32 fontFileHash, - uint32 mouseFileHash, const NRect *mouseRect, + uint32 mouseFileHash, const NRect *mouseRect, uint32 listBoxBackgroundFileHash, int16 listBoxX, int16 listBoxY, const NRect &listBoxRect, uint32 textEditBackgroundFileHash, uint32 textEditCursorFileHash, int16 textEditX, int16 textEditY, const NRect &textEditRect, - uint32 textFileHash1, uint32 textFileHash2) + uint32 textFileHash1, uint32 textFileHash2) : Scene(vm, parentModule), _currWidget(NULL), _savegameList(savegameList) { - + + bool isSave = (textEditCursorFileHash != 0); + _fontSurface = new FontSurface(_vm, fontFileHash, 32, 7, 32, 11, 17); - + + if (!ConfMan.getBool("originalsaveload")) { + Common::String saveDesc; + int saveCount = savegameList->size(); + int slot = scummVMSaveLoadDialog(isSave, saveDesc); + + if (slot >= 0) { + if (!isSave) { + ((MenuModule*)_parentModule)->setLoadgameInfo(slot); + } else { + ((MenuModule*)_parentModule)->setSavegameInfo(saveDesc, + slot, slot >= saveCount); + } + leaveScene(0); + } else { + leaveScene(1); + } + return; + } + setBackground(backgroundFileHash); setPalette(backgroundFileHash); insertScreenMouse(mouseFileHash, mouseRect); @@ -871,13 +927,13 @@ GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, Savegame _textEditWidget = new TextEditWidget(_vm, textEditX, textEditY, this, 29, _fontSurface, textEditBackgroundFileHash, textEditRect); - if (textEditCursorFileHash != 0) + if (isSave) _textEditWidget->setCursor(textEditCursorFileHash, 2, 13); else _textEditWidget->setReadOnly(true); _textEditWidget->initialize(); setCurrWidget(_textEditWidget); - + for (uint buttonIndex = 0; buttonIndex < 6; ++buttonIndex) { Sprite *menuButton = insertSprite<MenuButton>(this, buttonIndex, buttonFileHashes[buttonIndex], buttonCollisionBounds[buttonIndex]); @@ -886,7 +942,6 @@ GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, Savegame SetUpdateHandler(&Scene::update); SetMessageHandler(&GameStateMenu::handleMessage); - } GameStateMenu::~GameStateMenu() { @@ -1052,7 +1107,7 @@ static const NRect kDeleteGameMenuTextEditRect(0, 0, 320, 17); DeleteGameMenu::DeleteGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList) : GameStateMenu(vm, parentModule, savegameList, kDeleteGameMenuButtonFileHashes, kDeleteGameMenuButtonCollisionBounds, 0x4080E01C, 0x728523ED, - 0x0E018400, NULL, + 0x0E018400, NULL, 0xA5584211, 61, 64, kDeleteGameMenuListBoxRect, 0x250A3060, 0, 49, 414, kDeleteGameMenuTextEditRect, 0x80083C01, 0x84181E81) { @@ -1076,7 +1131,7 @@ QueryOverwriteMenu::QueryOverwriteMenu(NeverhoodEngine *vm, Module *parentModule NRect(145, 334, 260, 385), NRect(365, 340, 477, 388) }; - + setBackground(0x043692C4); setPalette(0x043692C4); insertScreenMouse(0x692C004B); @@ -1099,7 +1154,7 @@ QueryOverwriteMenu::QueryOverwriteMenu(NeverhoodEngine *vm, Module *parentModule fontSurface->drawString(_background->getSurface(), 106 + (423 - textLines[i].size() * 11) / 2, 127 + 31 + i * 17, (const byte*)textLines[i].c_str()); delete fontSurface; - + SetUpdateHandler(&Scene::update); SetMessageHandler(&QueryOverwriteMenu::handleMessage); } diff --git a/engines/neverhood/menumodule.h b/engines/neverhood/menumodule.h index 08858ad204..f201654ceb 100644 --- a/engines/neverhood/menumodule.h +++ b/engines/neverhood/menumodule.h @@ -45,6 +45,7 @@ public: void setLoadgameInfo(uint index); void setSavegameInfo(const Common::String &description, uint index, bool newSavegame); void setDeletegameInfo(uint index); + void refreshSaveGameList(); protected: int _sceneNum; byte *_savedPaletteData; @@ -123,8 +124,8 @@ protected: class TextLabelWidget : public Widget { public: TextLabelWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene, - int baseObjectPriority, int baseSurfacePriority, - const byte *string, int stringLen, BaseSurface *drawSurface, int16 tx, int16 ty, FontSurface *fontSurface); + int baseObjectPriority, int baseSurfacePriority, + const byte *string, int stringLen, BaseSurface *drawSurface, int16 tx, int16 ty, FontSurface *fontSurface); virtual void initialize(); virtual int16 getWidth(); virtual int16 getHeight(); @@ -205,13 +206,13 @@ protected: uint _currIndex; int _maxVisibleItemsCount; }; - + class GameStateMenu : public Scene { public: GameStateMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList, const uint32 *buttonFileHashes, const NRect *buttonCollisionBounds, uint32 backgroundFileHash, uint32 fontFileHash, - uint32 mouseFileHash, const NRect *mouseRect, + uint32 mouseFileHash, const NRect *mouseRect, uint32 listBoxBackgroundFileHash, int16 listBoxX, int16 listBoxY, const NRect &listBoxRect, uint32 textEditBackgroundFileHash, uint32 textEditCursorFileHash, int16 textEditX, int16 textEditY, const NRect &textEditRect, uint32 textFileHash1, uint32 textFileHash2); @@ -229,6 +230,7 @@ protected: Common::String _savegameDescription; uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); virtual void performAction(); + int scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc); }; class SaveGameMenu : public GameStateMenu { diff --git a/engines/neverhood/module.cpp b/engines/neverhood/module.cpp index e384b5a4d2..d1578e680c 100644 --- a/engines/neverhood/module.cpp +++ b/engines/neverhood/module.cpp @@ -31,9 +31,9 @@ namespace Neverhood { Module::Module(NeverhoodEngine *vm, Module *parentModule) : Entity(vm, 0), _parentModule(parentModule), _childObject(NULL), _done(false), _sceneType(kSceneTypeNormal) { - + SetMessageHandler(&Module::handleMessage); - + } Module::~Module() { diff --git a/engines/neverhood/modules/module1000.cpp b/engines/neverhood/modules/module1000.cpp index a28d934cf6..f65b89899d 100644 --- a/engines/neverhood/modules/module1000.cpp +++ b/engines/neverhood/modules/module1000.cpp @@ -26,8 +26,8 @@ namespace Neverhood { Module1000::Module1000(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - - _musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144; + + _musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144; _vm->_soundMan->addMusic(0x03294419, 0x061880C6); _vm->_soundMan->addMusic(0x03294419, _musicFileHash); @@ -118,11 +118,11 @@ void Module1000::updateScene() { } } -// Scene1001 +// Scene1001 AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm) : AnimatedSprite(vm, 1100) { - + createSurface(800, 137, 242); _x = 726; _y = 440; @@ -151,16 +151,16 @@ void AsScene1001Door::hammerHitsDoor() { case 1: playSound(0, 0x65482F03); startAnimation(0x624C0498, 1, 3); - NextState(&AsScene1001Door::stShowIdleDoor); + NextState(&AsScene1001Door::stShowIdleDoor); break; case 2: playSound(1); startAnimation(0x624C0498, 6, 6); - NextState(&AsScene1001Door::stBustedDoorMove); + NextState(&AsScene1001Door::stBustedDoorMove); break; default: // Nothing - break; + break; } incGlobalVar(V_DOOR_STATUS, 1); } @@ -196,9 +196,9 @@ void AsScene1001Door::stBustedDoorMove() { void AsScene1001Door::stBustedDoorGone() { playSound(0); stopAnimation(); - setVisible(false); + setVisible(false); } - + AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor) : AnimatedSprite(vm, 1100), _asDoor(asDoor) { @@ -262,7 +262,7 @@ uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam ¶ AsScene1001Lever::AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType) : AnimatedSprite(vm, 1100), _parentScene(parentScene) { - + createSurface(1010, 71, 73); setDoDeltaX(deltaXType); startAnimation(0x04A98C36, 0, -1); @@ -302,22 +302,22 @@ uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam ¶m } return messageResult; } - + SsCommonButtonSprite::SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash) : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene), _countdown(0) { _priority = 1100; - _soundFileHash = soundFileHash ? soundFileHash : 0x44141000; + _soundFileHash = soundFileHash ? soundFileHash : 0x44141000; setVisible(false); SetUpdateHandler(&SsCommonButtonSprite::update); SetMessageHandler(&SsCommonButtonSprite::handleMessage); } - + void SsCommonButtonSprite::update() { if (_countdown != 0 && (--_countdown) == 0) setVisible(false); } - + uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); switch (messageNum) { @@ -330,19 +330,19 @@ uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &p } return messageResult; } - + Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _asDoor(NULL), _asWindow(NULL) { Sprite *tempSprite; SetMessageHandler(&Scene1001::handleMessage); - + setHitRects(0x004B4860); setBackground(0x4086520E); setPalette(0x4086520E); insertScreenMouse(0x6520A400); - + if (which < 0) { // Restoring game setRectList(0x004B49F0); @@ -373,7 +373,7 @@ Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which) tempSprite = insertStaticSprite(0x2080A3A8, 1300); _klaymen->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480); - + if (!getGlobalVar(V_DOOR_BUSTED)) { _asDoor = insertSprite<AsScene1001Door>(); _asDoor->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480); @@ -445,7 +445,7 @@ AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool i : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) { SetUpdateHandler(&AsScene1002Ring::update); - + if (_isSpecial) { createSurface(990, 68, 314); if (isRingLow) { @@ -581,7 +581,7 @@ uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam ¶m AsScene1002Door::AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect) : StaticSprite(vm, 1200) { - + loadSprite(0x1052370F, kSLFDefDrawOffset | kSLFSetPosition, 800, 526, getGlobalVar(V_FLYTRAP_RING_DOOR) ? 49 : 239); setClipRect(clipRect); SetUpdateHandler(&AsScene1002Door::update); @@ -637,7 +637,7 @@ AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine createSurface(1025, 88, 165); setVisible(false); SetUpdateHandler(&AnimatedSprite::update); - SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage); + SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage); } uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -716,7 +716,7 @@ void AsScene1002DoorSpy::stDoorSpyBoxingGlove() { NextState(&AsScene1002DoorSpy::stDoorSpyIdle); } -SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash) +SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash) : StaticSprite(vm, 1100), _parentScene(parentScene), _status(0), _countdown(0) { _soundFileHash = soundFileHash != 0 ? soundFileHash : 0x44141000; @@ -788,7 +788,7 @@ AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *par stRingGrabbed(); } else { stIdle(); - } + } } _flags = 4; SetUpdateHandler(&AsScene1002VenusFlyTrap::update); @@ -850,12 +850,12 @@ uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam if (_isSecond) { if (_x >= 154 && _x <= 346) messageResult = 1; - else + else messageResult = 0; } else { if (_x >= 174 && _x <= 430) messageResult = 1; - else + else messageResult = 0; } break; @@ -1023,7 +1023,7 @@ AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngi } else setVisible(false); SetUpdateHandler(&AsScene1002OutsideDoorBackground::update); - SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage); + SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage); } void AsScene1002OutsideDoorBackground::update() { @@ -1083,7 +1083,7 @@ void AsScene1002OutsideDoorBackground::stDoorClosed() { AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen) : AnimatedSprite(vm, 1200), _klaymen(klaymen) { - + createSurface(1200, 40, 163); setVisible(false); SetUpdateHandler(&AsScene1002KlaymenLadderHands::update); @@ -1095,15 +1095,15 @@ void AsScene1002KlaymenLadderHands::update() { startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1); _newStickFrameIndex = _klaymen->getFrameIndex(); setVisible(true); - _x = _klaymen->getX(); - _y = _klaymen->getY(); + _x = _klaymen->getX(); + _y = _klaymen->getY(); setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0); } else if (_klaymen->getCurrAnimFileHash() == 0x122D1505) { startAnimation(0x1319150C, _klaymen->getFrameIndex(), -1); _newStickFrameIndex = _klaymen->getFrameIndex(); setVisible(true); - _x = _klaymen->getX(); - _y = _klaymen->getY(); + _x = _klaymen->getX(); + _y = _klaymen->getY(); setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0); } else setVisible(false); @@ -1113,7 +1113,7 @@ void AsScene1002KlaymenLadderHands::update() { AsScene1002KlaymenPeekHand::AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen) : AnimatedSprite(vm, 1200), _parentScene(parentScene), _klaymen(klaymen), _isClipRectSaved(false) { - + createSurface(1000, 33, 41); setVisible(false); SetUpdateHandler(&AsScene1002KlaymenPeekHand::update); @@ -1245,7 +1245,7 @@ Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which) sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap); _asOutsideDoorBackground = insertSprite<AsScene1002OutsideDoorBackground>(); - + setRectList(0x004B43A0); loadSound(1, 0x60755842); @@ -1322,11 +1322,11 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam ¶m, Entit break; case 0x2002: _messageList = NULL; - break; + break; case 0x2005: _isClimbingLadder = true; setRectList(0x004B4418); - break; + break; case 0x2006: _isClimbingLadder = false; setRectList(0x004B43A0); @@ -1360,11 +1360,11 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam ¶m, Entit if (getGlobalVar(V_FLYTRAP_RING_DOOR)) { sendMessage(_asRing3, 0x4807, 0); } - } + } break; case 0x480B: sendEntityMessage(_klaymen, 0x1014, _asDoorSpy); - break; + break; case 0x480F: setGlobalVar(V_RADIO_ENABLED, 0); playSound(1); @@ -1379,7 +1379,7 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam ¶m, Entit setSpriteSurfacePriority(_ssCeiling, 1015); setSpriteSurfacePriority(_ssLadderArch, 1015); break; - } + } return messageResult; } @@ -1389,7 +1389,7 @@ StaticScene::StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backg : Scene(vm, parentModule) { SetMessageHandler(&StaticScene::handleMessage); - + setBackground(backgroundFileHash); setPalette(backgroundFileHash); insertPuzzleMouse(cursorFileHash, 20, 620); @@ -1442,7 +1442,7 @@ Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _paletteAreaStatus(-1) { Sprite *tempSprite; - + SetUpdateHandler(&Scene1004::update); SetMessageHandler(&Scene1004::handleMessage); @@ -1475,16 +1475,16 @@ Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which) insertKlaymen<KmScene1004>(_dataResource.getPoint(0x80052A29).x, 27); setMessageList(0x004B7BF0); } - + updatePaletteArea(); - + _asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen); insertStaticSprite(0x800034A0, 1100); insertStaticSprite(0x64402020, 1100); insertStaticSprite(0x3060222E, 1300); tempSprite = insertStaticSprite(0x0E002004, 1300); - + _klaymen->setClipRect(0, tempSprite->getDrawRect().y, 640, 480); _asKlaymenLadderHands->setClipRect(_klaymen->getClipRect()); @@ -1518,7 +1518,7 @@ uint32 Scene1004::handleMessage(int messageNum, const MessageParam ¶m, Entit break; } return messageResult; -} +} void Scene1004::updatePaletteArea() { if (_klaymen->getY() < 150) { @@ -1557,7 +1557,7 @@ Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which) } drawTextToBackground(); - + } uint32 Scene1005::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -1565,7 +1565,7 @@ uint32 Scene1005::handleMessage(int messageNum, const MessageParam ¶m, Entit switch (messageNum) { case 0x0001: if (param.asPoint().x <= 20 || param.asPoint().x >= 620) - leaveScene(0); + leaveScene(0); break; } return 0; @@ -1614,19 +1614,19 @@ uint32 Scene1005::getTextIndex1() { textIndex = 23; else if (!getSubVar(VA_HAS_KEY, 0) && !getSubVar(VA_IS_KEY_INSERTED, 0)) textIndex = 24; - else if (!getGlobalVar(V_HAS_FINAL_KEY)) + else if (!getGlobalVar(V_HAS_FINAL_KEY)) textIndex = 26; else if (!getSubVar(VA_HAS_KEY, 1) && !getSubVar(VA_IS_KEY_INSERTED, 1)) textIndex = 27; - else if (!getGlobalVar(V_HAS_FINAL_KEY)) + else if (!getGlobalVar(V_HAS_FINAL_KEY)) textIndex = 28; - else + else textIndex = 29; } else if (!getGlobalVar(V_FELL_DOWN_HOLE)) textIndex = 20; else if (!getGlobalVar(V_SEEN_SYMBOLS_NO_LIGHT)) textIndex = 21; - else + else textIndex = 22; } else if (getGlobalVar(V_BOLT_DOOR_UNLOCKED)) { if (!getGlobalVar(V_WALL_BROKEN)) @@ -1641,7 +1641,7 @@ uint32 Scene1005::getTextIndex1() { textIndex = 15; else if (!getGlobalVar(V_BEEN_STATUE_ROOM)) textIndex = 16; - else + else textIndex = 17; } else if (!getGlobalVar(V_FLYTRAP_RING_EATEN)) { textIndex = 0; @@ -1660,7 +1660,7 @@ uint32 Scene1005::getTextIndex1() { textIndex = 9; else if (!getSubVar(VA_LOCKS_DISABLED, 0x01180951)) textIndex = 10; - else + else textIndex = 11; } else if (!getGlobalVar(V_CREATURE_ANGRY)) { textIndex = 1; diff --git a/engines/neverhood/modules/module1000.h b/engines/neverhood/modules/module1000.h index 9977590a6a..8461ecfc6f 100644 --- a/engines/neverhood/modules/module1000.h +++ b/engines/neverhood/modules/module1000.h @@ -85,7 +85,7 @@ protected: Scene *_parentScene; uint32 _soundFileHash; int16 _countdown; - void update(); + void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); }; diff --git a/engines/neverhood/modules/module1100.cpp b/engines/neverhood/modules/module1100.cpp index dbd8c60210..03810915dd 100644 --- a/engines/neverhood/modules/module1100.cpp +++ b/engines/neverhood/modules/module1100.cpp @@ -40,7 +40,7 @@ static const uint32 kModule1100SoundList[] = { Module1100::Module1100(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + if (which < 0) { createScene(_vm->gameState().sceneNum, -1); } else if (which == 1) { @@ -271,7 +271,7 @@ static const uint32 kSsScene1105SymbolDieFileHashes[] = { SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds) : StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) { - + _collisionBounds = collisionBounds; SetMessageHandler(&SsScene1105Button::handleMessage); SetUpdateHandler(&SsScene1105Button::update); @@ -347,7 +347,7 @@ void SsScene1105SymbolDie::hide() { AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 1100), _parentScene(parentScene) { - + createSurface(100, 556, 328); _x = 320; _y = 240; @@ -396,7 +396,7 @@ void AsScene1105TeddyBear::hide() { SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene) : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) { - + loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); setVisible(false); loadSound(0, 0x44045140); @@ -432,26 +432,26 @@ uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam & Scene1105::Scene1105(NeverhoodEngine *vm, Module *parentModule) : Scene(vm, parentModule), _countdown(0), _isPanelOpen(false), _isActionButtonClicked(false), _doMoveTeddy(false), _isClosePanelDone(false), _leaveResult(0), _backgroundIndex(0) { - + Sprite *ssOpenButton; - + _vm->gameModule()->initMemoryPuzzle(); - + SetUpdateHandler(&Scene1105::update); SetMessageHandler(&Scene1105::handleMessage); - + setBackground(0x20010002); setPalette(0x20010002); - + _asTeddyBear = insertSprite<AsScene1105TeddyBear>(this); ssOpenButton = insertSprite<SsScene1105OpenButton>(this); addCollisionSprite(ssOpenButton); insertPuzzleMouse(0x10006208, 20, 620); - + loadSound(0, 0x48442057); loadSound(1, 0xC025014F); loadSound(2, 0x68E25540); - + } uint32 Scene1105::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -569,13 +569,13 @@ void Scene1105::createObjects() { addCollisionSprite(_ssSymbol3DownButton); _ssActionButton = insertSprite<SsScene1105Button>(this, 0x8248AD35, NRect(280, 170, 354, 245)); addCollisionSprite(_ssActionButton); - + _isPanelOpen = true; - + _asTeddyBear->show(); insertPuzzleMouse(0x18666208, 20, 620); - + } void Scene1105::upOpenPanel() { @@ -639,13 +639,13 @@ void Scene1105::update() { Scene1109::Scene1109(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + SetMessageHandler(&Scene1109::handleMessage); - + setBackground(0x8449E02F); setPalette(0x8449E02F); insertScreenMouse(0x9E02B84C); - + _sprite1 = insertStaticSprite(0x600CEF01, 1100); if (which < 0) { diff --git a/engines/neverhood/modules/module1200.cpp b/engines/neverhood/modules/module1200.cpp index 3e67ddb35a..e7766419f9 100644 --- a/engines/neverhood/modules/module1200.cpp +++ b/engines/neverhood/modules/module1200.cpp @@ -26,7 +26,7 @@ namespace Neverhood { Module1200::Module1200(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + SetMessageHandler(&Module1200::handleMessage); if (which < 0) @@ -124,7 +124,7 @@ static const uint32 kScene1201TntFileHashList2[] = { 0xB140A1E6, 0x5088A068, 0x5088A068, 0x74C4C866, 0x3192C059, 0x3192C059 }; - + SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2) : StaticSprite(vm, 900) { @@ -133,13 +133,13 @@ SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 poi if (x < 300) loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50); else - loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y); + loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20); setClipRect(0, 0, 640, clipY2); } - + AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash) : AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) { - + if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) { SetMessageHandler(&AsScene1201Tape::handleMessage); } else { @@ -253,10 +253,10 @@ void AsScene1201RightDoor::stCloseDoorDone() { stopAnimation(); setVisible(false); } - + AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm) : AnimatedSprite(vm, 1200) { - + createSurface(1200, 69, 98); SetUpdateHandler(&AnimatedSprite::update); SetMessageHandler(&AsScene1201KlaymenHead::handleMessage); @@ -301,7 +301,7 @@ AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sp AsScene1201TntMan::~AsScene1201TntMan() { _vm->_soundMan->deleteSoundGroup(0x01D00560); -} +} uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); @@ -396,7 +396,7 @@ void AsScene1201TntManFlame::suUpdate() { AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) { - + createSurface(1100, 57, 60); SetUpdateHandler(&AsScene1201Match::update); SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove); @@ -518,7 +518,7 @@ AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene : AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) { // NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed - + createSurface(1100, 203, 199); SetUpdateHandler(&AsScene1201Creature::update); SetMessageHandler(&AsScene1201Creature::hmWaiting); @@ -664,7 +664,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which) SetMessageHandler(&Scene1201::handleMessage); setHitRects(0x004AEBD0); - + if (!getSubVar(VA_IS_PUZZLE_INIT, 0xE8058B52)) { setSubVar(VA_IS_PUZZLE_INIT, 0xE8058B52, 1); for (uint32 index = 0; index < 18; index++) @@ -672,25 +672,25 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which) } insertScreenMouse(0x9A2C0409); - + _asTape = insertSprite<AsScene1201Tape>(this, 3, 1100, 243, 340, 0x9148A011); addCollisionSprite(_asTape); - + tempSprite = insertStaticSprite(0x03C82530, 100); - topY1 = tempSprite->getY() + tempSprite->getDrawRect().height; + topY1 = tempSprite->getY() + tempSprite->getDrawRect().height; tempSprite = insertStaticSprite(0x88182069, 200); - topY2 = tempSprite->getY() + tempSprite->getDrawRect().height; + topY2 = tempSprite->getY() + tempSprite->getDrawRect().height; tempSprite = insertStaticSprite(0x476014E0, 300); - topY3 = tempSprite->getY() + tempSprite->getDrawRect().height; + topY3 = tempSprite->getY() + tempSprite->getDrawRect().height; tempSprite = insertStaticSprite(0x04063110, 500); - topY4 = tempSprite->getY() + 1; + topY4 = tempSprite->getY() + 1; _asTntManRope = insertSprite<AsScene1201TntManRope>(getGlobalVar(V_TNT_DUMMY_BUILT) && which != 1); _asTntManRope->setClipRect(0, topY4, 640, 480); - + insertStaticSprite(0x400B04B0, 1200); tempSprite = insertStaticSprite(0x40295462, 1200); @@ -735,7 +735,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which) _klaymen->setClipRect(x1, 0, x2, 480); _klaymen->setRepl(64, 0); - + if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED)) { setBackground(0x4019A2C4); setPalette(0x4019A2C4); @@ -756,8 +756,8 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which) tempSprite = insertSprite<AsScene1201TntManFlame>(_asTntMan); tempSprite->setClipRect(x1, 0, x2, 480); } - - uint32 tntIndex = 1; + + uint32 tntIndex = 1; while (tntIndex < 18) { uint32 elemIndex = getSubVar(VA_TNT_POSITIONS, tntIndex); int16 clipY2; @@ -783,10 +783,10 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which) setRectList(0x004AEE58); } else { setRectList(0x004AEDC8); - } - + } + } else { - + insertStaticSprite(0x8E8A1981, 900); uint32 tntIndex = 0; @@ -795,7 +795,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which) int16 clipY2; if (kScene1201PointArray[elemIndex].x < 300) { clipY2 = 480; - } else { + } else { if (kScene1201PointArray[elemIndex].y < 175) clipY2 = topY1; else if (kScene1201PointArray[elemIndex].y < 230) @@ -811,7 +811,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which) setRectList(0x004AEE18); else setRectList(0x004AED88); - + } tempSprite = insertStaticSprite(0x63D400BC, 900); @@ -875,7 +875,7 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam ¶m, Entit setMessageList2(0x004AECC0); } break; - case 0x2002: + case 0x2002: if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) { // Move the TNT dummy if the fuse is burning sendEntityMessage(_klaymen, 0x1014, _asTntMan); @@ -903,7 +903,7 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam ¶m, Entit break; case 0x8000: sendMessage(_asKlaymenHead, 0x2006, 0); - break; + break; } return messageResult; } @@ -956,7 +956,7 @@ uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam ¶m, case 0x2001: _newPosition = (int)param.asInteger(); stChangePositionFadeOut(); - break; + break; } return messageResult; } @@ -998,7 +998,7 @@ void AsScene1202TntItem::stChangePositionDone() { } Scene1202::Scene1202(NeverhoodEngine *vm, Module *parentModule) - : Scene(vm, parentModule), _paletteResource(vm), + : Scene(vm, parentModule), _paletteResource(vm), _soundToggle(true), _isPuzzleSolved(false), _counter(0), _clickedIndex(-1) { SetMessageHandler(&Scene1202::handleMessage); @@ -1093,8 +1093,8 @@ uint32 Scene1202::hmSolved(int messageNum, const MessageParam ¶m, Entity *se } bool Scene1202::isSolved() { - return - getSubVar(VA_TNT_POSITIONS, 0) == 0 && getSubVar(VA_TNT_POSITIONS, 3) == 3 && + return + getSubVar(VA_TNT_POSITIONS, 0) == 0 && getSubVar(VA_TNT_POSITIONS, 3) == 3 && getSubVar(VA_TNT_POSITIONS, 6) == 6 && getSubVar(VA_TNT_POSITIONS, 9) == 9 && getSubVar(VA_TNT_POSITIONS, 12) == 12 && getSubVar(VA_TNT_POSITIONS, 15) == 15; } diff --git a/engines/neverhood/modules/module1300.cpp b/engines/neverhood/modules/module1300.cpp index cc5c22085c..c8a561af76 100644 --- a/engines/neverhood/modules/module1300.cpp +++ b/engines/neverhood/modules/module1300.cpp @@ -45,7 +45,7 @@ static const uint32 kModule1300SoundList[] = { Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + _vm->_soundMan->addMusic(0x61C090, 0x00203197); _vm->_soundMan->addSoundList(0x61C090, kModule1300SoundList); _vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 50, 600, 20, 150); @@ -56,7 +56,7 @@ Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which) if (which < 0) { if (_vm->gameState().sceneNum >= 1 && _vm->gameState().sceneNum <= 17) createScene(_vm->gameState().sceneNum, -1); - else + else createScene(11, 0); } else { switch (which) { @@ -101,7 +101,7 @@ Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which) break; } } - + } Module1300::~Module1300() { @@ -218,7 +218,7 @@ void Module1300::createScene(int sceneNum, int which) { SetUpdateHandler(&Module1300::updateScene); _childObject->handleUpdate(); } - + void Module1300::updateScene() { if (!updateChild()) { switch (_sceneNum) { @@ -274,7 +274,7 @@ void Module1300::updateScene() { createScene(11, 1); break; case 12: - if (_moduleResult == 0) + if (_moduleResult == 0) createScene(14, 1); else if (_moduleResult == 1) createScene(15, 1); @@ -367,7 +367,7 @@ void AsScene1302Bridge::cbLowerBridgeEvent() { SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm) : StaticSprite(vm, 0x11122122, 200) { - + _firstY = _y; if (getGlobalVar(V_FLYTRAP_RING_FENCE)) _y += 152; @@ -459,7 +459,7 @@ Scene1302::Scene1302(NeverhoodEngine *vm, Module *parentModule, int which) addCollisionSprite(_asVenusFlyTrap); sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap); - + } uint32 Scene1302::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -513,7 +513,7 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam ¶m, Entit case 0x2000: if (_klaymen->getY() > 360) { sendEntityMessage(_klaymen, 0x1014, _asVenusFlyTrap); - setMessageList2(0x004B08F0); + setMessageList2(0x004B08F0); } else setMessageList2(0x004B0920); break; @@ -583,7 +583,7 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam ¶m, Entit AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 1100), _parentScene(parentScene) { - + createSurface(200, 128, 315); _x = 289; _y = 390; @@ -643,7 +643,7 @@ Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule) _asBalloon = insertSprite<AsScene1303Balloon>(this); addCollisionSprite(_asBalloon); } - + _sprite1 = insertStaticSprite(0xA014216B, 1100); insertKlaymen<KmScene1303>(207, 332); @@ -671,7 +671,7 @@ uint32 Scene1303::handleMessage(int messageNum, const MessageParam ¶m, Entit AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y) : AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) { - // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself + // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself SetMessageHandler(&AsScene1304Needle::handleMessage); } @@ -693,14 +693,14 @@ uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam ¶ Scene1304::Scene1304(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _asNeedle(NULL) { - + SetMessageHandler(&Scene1304::handleMessage); setRectList(0x004B91A8); setBackground(0x062C0214); setPalette(0x062C0214); insertScreenMouse(0xC021006A); - + if (getGlobalVar(V_BALLOON_POPPED)) { _asKey = insertSprite<AsCommonKey>(this, 0, 1100, 278, 347); addCollisionSprite(_asKey); @@ -774,7 +774,7 @@ Scene1305::Scene1305(NeverhoodEngine *vm, Module *parentModule, int which) insertKlaymen<KmScene1305>(212, 441); setMessageList(0x004B6E48); } - + } uint32 Scene1305::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -800,7 +800,7 @@ void AsScene1306Elevator::update() { if (_isUp && _countdown != 0 && (--_countdown == 0)) stGoingDown(); AnimatedSprite::update(); - if (_currFrameIndex == 7) { + if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) { playSound(1); _asElevatorDoor->setVisible(false); } @@ -868,10 +868,10 @@ void AsScene1306Elevator::cbGoingDownEvent() { Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0) setGlobalVar(V_KEY3_LOCATION, 4); - + SetMessageHandler(&Scene1306::handleMessage); setBackground(0x05303114); @@ -949,7 +949,7 @@ Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which) } } - + Scene1306::~Scene1306() { setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0); } @@ -1073,7 +1073,7 @@ static const NPoint kAsScene1307KeyPoints[] = { const uint kAsScene1307KeyFrameIndicesCount = 20; static const int16 kAsScene1307KeyFrameIndices[] = { - 1, 4, 8, 11, 15, 16, 17, 17, 17, 16, + 1, 4, 8, 11, 15, 16, 17, 17, 17, 16, 15, 14, 12, 10, 9, 7, 5, 3, 2, 1 }; @@ -1084,10 +1084,10 @@ const int16 kAsScene1307KeyYDelta = -12; AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects) : AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects), _isClickable(true) { - + NPoint pt; - const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; - + const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; + _dataResource.load(0x22102142); _pointList = _dataResource.getPointArray(0xAC849240); pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)]; @@ -1173,7 +1173,7 @@ void AsScene1307Key::suMoveKey() { } void AsScene1307Key::stRemoveKey() { - const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; + const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; _pointIndex = 0; startAnimation(fileHashes[0], 0, -1); playSound(1); @@ -1199,7 +1199,7 @@ void AsScene1307Key::stMoveKey() { if (newX == _x && newY == _y) { stInsertKey(); } else { - const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; + const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; _pointIndex = 0; _frameIndex = 0; _deltaX = newX - _x; @@ -1210,13 +1210,13 @@ void AsScene1307Key::stMoveKey() { } void AsScene1307Key::stUnlock() { - const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; + const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; startAnimation(fileHashes[1], 0, -1); _newStickFrameIndex = STICK_LAST_FRAME; } void AsScene1307Key::stInsert() { - const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; + const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex]; startAnimation(fileHashes[2], 0, -1); _newStickFrameIndex = STICK_LAST_FRAME; } @@ -1226,9 +1226,9 @@ Scene1307::Scene1307(NeverhoodEngine *vm, Module *parentModule) _isInsertingKey(false), _doLeaveScene(false), _isPuzzleSolved(false) { Sprite *tempSprite; - + _vm->gameModule()->initKeySlotsPuzzle(); - + _dataResource.load(0x22102142); _keyHolePoints = _dataResource.getPointArray(0xAC849240); @@ -1279,7 +1279,7 @@ void Scene1307::update() { if (_doLeaveScene && !isSoundPlaying(0)) { leaveScene(1); setGlobalVar(V_KEYDOOR_UNLOCKED, 1); - } + } } uint32 Scene1307::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -1294,7 +1294,7 @@ uint32 Scene1307::handleMessage(int messageNum, const MessageParam ¶m, Entit int16 mouseY = param.asPoint().y; uint clickedKeyHoleIndex; for (clickedKeyHoleIndex = 0; clickedKeyHoleIndex < 16; clickedKeyHoleIndex++) { - if (mouseX >= _keyHoleRects[clickedKeyHoleIndex].x1 && mouseX <= _keyHoleRects[clickedKeyHoleIndex].x2 && + if (mouseX >= _keyHoleRects[clickedKeyHoleIndex].x1 && mouseX <= _keyHoleRects[clickedKeyHoleIndex].x2 && mouseY >= _keyHoleRects[clickedKeyHoleIndex].y1 && mouseY <= _keyHoleRects[clickedKeyHoleIndex].y2) break; } @@ -1362,7 +1362,7 @@ static const uint32 kScene1308NumberFileHashes[] = { AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) { - + setVisible(false); stopAnimation(); SetMessageHandler(&AsScene1308JaggyDoor::handleMessage); @@ -1412,12 +1412,12 @@ void AsScene1308JaggyDoor::stCloseDoorDone() { AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) { - + playSound(0, 0x51456049); SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage); NextState(&AsScene1308KeyboardDoor::stFallingKeys); } - + uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); switch (messageNum) { @@ -1443,7 +1443,7 @@ void AsScene1308KeyboardDoor::stFallingKeysDone() { AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) { - + setVisible(false); stopAnimation(); Entity::_priority = 1200; @@ -1486,7 +1486,7 @@ void AsScene1308LightWallSymbols::stFadeOutDone() { SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index) : StaticSprite(vm, fileHash, 100) { - + setVisible(false); _x = _spriteResource.getPosition().x + index * 20; updatePosition(); @@ -1520,11 +1520,11 @@ uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam ¶m Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _isProjecting(false), _asProjector(NULL) { - + _vm->gameModule()->initKeySlotsPuzzle(); SetMessageHandler(&Scene1308::handleMessage); - + setBackground(0x41024202); setPalette(0x41024202); insertScreenMouse(0x24206418); @@ -1536,7 +1536,7 @@ Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which) insertSprite<AsScene1308Mouse>(); insertSprite<AnimatedSprite>(0x461A1490, 200, 235, 429); } - + _sprite1 = insertStaticSprite(0x0A042060, 1100); _asJaggyDoor = insertSprite<AsScene1308JaggyDoor>(this); _asLightWallSymbols = insertSprite<AsScene1308LightWallSymbols>(this); @@ -1546,7 +1546,7 @@ Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which) _sprite2 = insertStaticSprite(0x40043120, 995); _sprite3 = insertStaticSprite(0x43003100, 995); _sprite4 = NULL; - + if (which < 0) { // Restoring game insertKlaymen<KmScene1308>(380, 440); @@ -1698,7 +1698,7 @@ uint32 Scene1308::handleMessage(int messageNum, const MessageParam ¶m, Entit Scene1317::Scene1317(NeverhoodEngine *vm, Module *parentModule) : Scene(vm, parentModule) { - + SetMessageHandler(&Scene1317::handleMessage); _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, 0x08982841, true, false)); _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder()); @@ -1720,7 +1720,7 @@ void Scene1317::update() { void Scene1317::upChooseKing() { if (!_klaymenBlinks && _klaymenBlinkCountdown != 0 && (--_klaymenBlinkCountdown == 0)) _klaymenBlinks = true; - + if (!_klaymenBlinks && _smackerPlayer->getFrameNumber() + 1 >= 2) { _smackerPlayer->rewind(); } else if (_klaymenBlinks && _smackerPlayer->getFrameNumber() + 1 >= 6) { @@ -1731,7 +1731,7 @@ void Scene1317::upChooseKing() { if (!_klaymenBlinks && _decisionCountdown != 0 && (--_decisionCountdown == 0)) stNoDecisionYet(); - + if (_smackerFileHash) { _smackerPlayer->open(_smackerFileHash, _keepLastSmackerFrame); _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder()); @@ -1739,7 +1739,7 @@ void Scene1317::upChooseKing() { } Scene::update(); - + } uint32 Scene1317::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -1751,7 +1751,7 @@ uint32 Scene1317::handleMessage(int messageNum, const MessageParam ¶m, Entit } return messageResult; } - + uint32 Scene1317::hmChooseKing(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Scene::handleMessage(messageNum, param, sender); switch (messageNum) { diff --git a/engines/neverhood/modules/module1400.cpp b/engines/neverhood/modules/module1400.cpp index 56c6ca5f13..0a029632b6 100644 --- a/engines/neverhood/modules/module1400.cpp +++ b/engines/neverhood/modules/module1400.cpp @@ -31,7 +31,7 @@ namespace Neverhood { Module1400::Module1400(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + _vm->_soundMan->addMusic(0x00AD0012, 0x06333232); _vm->_soundMan->addMusic(0x00AD0012, 0x624A220E); @@ -139,7 +139,7 @@ void Module1400::updateScene() { AsScene1401Pipe::AsScene1401Pipe(NeverhoodEngine *vm) : AnimatedSprite(vm, 1100), _countdown1(0), _countdown2(0) { - + createSurface(900, 152, 147); _x = 454; _y = 217; @@ -179,10 +179,10 @@ uint32 AsScene1401Pipe::handleMessage(int messageNum, const MessageParam ¶m, _countdown1 = 70; _countdown2 = 8; stStartSucking(); - break; + break; case 0x483A: stSuckInProjector(); - break; + break; } return messageResult; } @@ -221,7 +221,7 @@ void AsScene1401Pipe::stSuckInProjector() { AsScene1401Mouse::AsScene1401Mouse(NeverhoodEngine *vm) : AnimatedSprite(vm, 1100) { - + createSurface(100, 71, 41); _x = 478; _y = 433; @@ -243,7 +243,7 @@ uint32 AsScene1401Mouse::handleMessage(int messageNum, const MessageParam ¶m break; case 0x4839: stSuckedIn(); - break; + break; } return messageResult; } @@ -280,7 +280,7 @@ uint32 AsScene1401Cheese::handleMessage(int messageNum, const MessageParam ¶ switch (messageNum) { case 0x4839: stSuckedIn(); - break; + break; } return messageResult; } @@ -332,7 +332,7 @@ uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &pa case 0x2001: if (_isOpen) _countdown = 168; - messageResult = _isOpen ? 1 : 0; + messageResult = _isOpen ? 1 : 0; break; case 0x3002: gotoNextState(); @@ -341,7 +341,7 @@ uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &pa _countdown = 168; if (!_isOpen) stOpenDoor(); - break; + break; } return messageResult; } @@ -540,7 +540,7 @@ void AsCommonProjector::moveProjector() { playSound(1, 0x5440E474); _lockedInSlot = true; } - + } void AsCommonProjector::stSuckedIn() { @@ -627,8 +627,8 @@ void AsCommonProjector::stStartSuckedIn() { } Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which) - : Scene(vm, parentModule), _projectorBorderFlag(false), _ssFloorButton(NULL), _asProjector(NULL), - _asPipe(NULL), _asMouse(NULL), _asCheese(NULL), _asBackDoor(NULL), + : Scene(vm, parentModule), _projectorBorderFlag(false), _ssFloorButton(NULL), _asProjector(NULL), + _asPipe(NULL), _asMouse(NULL), _asCheese(NULL), _asBackDoor(NULL), _sprite1(NULL), _sprite2(NULL), _sprite3(NULL), _ssButton(NULL) { SetMessageHandler(&Scene1401::handleMessage); @@ -638,7 +638,7 @@ Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which) setBackground(0x08221FA5); setPalette(0x08221FA5); insertScreenMouse(0x21FA108A); - + _ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x980F3124, 0x12192892, 100, 0); _asPipe = insertSprite<AsScene1401Pipe>(); @@ -692,7 +692,7 @@ Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which) } _asProjector->setClipRect(_sprite3->getDrawRect().x, _sprite2->getDrawRect().y, 640, 480); } - + _klaymen->setClipRect(_sprite3->getDrawRect().x, 0, 640, 480); if (which == 0 && _asProjector) @@ -752,7 +752,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam ¶m, Entit setMessageList2(0x004B6658); } else setMessageList2(0x004B65F0); - } + } break; case 0x482A: _sprite1->setVisible(true); @@ -772,7 +772,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam ¶m, Entit SsScene1402BridgePart::SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority) : StaticSprite(vm, fileHash, surfacePriority) { - + SetFilterY(&Sprite::defFilterY); SetUpdateHandler(&StaticSprite::updatePosition); } @@ -892,7 +892,7 @@ Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which) startShaking(); } } - + if (_asPuzzleBox) _asPuzzleBox->setClipRect(0, 0, 640, _ssBridgePart3->getDrawRect().y2()); @@ -914,7 +914,7 @@ Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which) } _klaymen->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x2(), _ssBridgePart3->getDrawRect().y2()); - + } void Scene1402::upShaking() { @@ -1082,7 +1082,7 @@ static const struct { AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) { - + createSurface(100, 117, 45); _x = 108; _y = 106; @@ -1096,7 +1096,7 @@ void AsScene1407Mouse::suWalkTo() { xdelta = _deltaX; else if (xdelta < -_deltaX) xdelta = -_deltaX; - _deltaX = 0; + _deltaX = 0; if (_walkDestX == _x) sendMessage(this, 0x1019, 0); else { @@ -1231,7 +1231,7 @@ Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule) _asMouse = insertSprite<AsScene1407Mouse>(this); _ssResetButton = insertStaticSprite(0x12006600, 100); - _ssResetButton->setVisible(false); + _ssResetButton->setVisible(false); } @@ -1279,9 +1279,9 @@ uint32 Scene1407::handleMessage(int messageNum, const MessageParam ¶m, Entit Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _asProjector(NULL), _isProjecting(false) { - + SetMessageHandler(&Scene1403::handleMessage); - + setRectList(0x004B1FF8); setBackground(0x2110A234); setPalette(0x2110A234); @@ -1383,10 +1383,10 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam ¶m, Entit Scene1404::Scene1404(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _asProjector(NULL), _asKey(NULL) { - + if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0) setGlobalVar(V_KEY3_LOCATION, 5); - + SetMessageHandler(&Scene1404::handleMessage); setRectList(0x004B8D80); @@ -1555,14 +1555,14 @@ Scene1405::Scene1405(NeverhoodEngine *vm, Module *parentModule) : Scene(vm, parentModule), _selectFirstTile(true), _tilesLeft(48), _countdown(0) { _vm->gameModule()->initMemoryPuzzle(); - + SetUpdateHandler(&Scene1405::update); SetMessageHandler(&Scene1405::handleMessage); setBackground(0x0C0C007D); setPalette(0x0C0C007D); insertPuzzleMouse(0xC00790C8, 20, 620); - + for (uint32 tileIndex = 0; tileIndex < 48; tileIndex++) { _tiles[tileIndex] = insertSprite<AsScene1405Tile>(this, tileIndex); addCollisionSprite(_tiles[tileIndex]); diff --git a/engines/neverhood/modules/module1500.cpp b/engines/neverhood/modules/module1500.cpp index 00d64a8c2d..3ce9783b69 100644 --- a/engines/neverhood/modules/module1500.cpp +++ b/engines/neverhood/modules/module1500.cpp @@ -26,7 +26,7 @@ namespace Neverhood { Module1500::Module1500(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + if (which < 0) createScene(_vm->gameState().sceneNum, -1); else @@ -86,7 +86,7 @@ Scene1501::Scene1501(NeverhoodEngine *vm, Module *parentModule, uint32 backgroun SetUpdateHandler(&Scene1501::update); SetMessageHandler(&Scene1501::handleMessage); - + setBackground(backgroundFileHash); setPalette(); addEntity(_palette); @@ -118,7 +118,7 @@ void Scene1501::update() { _countdown1 = 12; _palette->startFadeToBlack(11); } - + } uint32 Scene1501::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { diff --git a/engines/neverhood/modules/module1600.cpp b/engines/neverhood/modules/module1600.cpp index 40faa1e82d..a5a785e130 100644 --- a/engines/neverhood/modules/module1600.cpp +++ b/engines/neverhood/modules/module1600.cpp @@ -34,7 +34,7 @@ static const uint32 kModule1600SoundList[] = { Module1600::Module1600(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + if (which < 0) createScene(_vm->gameState().sceneNum, -1); else if (which == 1) @@ -109,7 +109,7 @@ void Module1600::createScene(int sceneNum, int which) { if (getGlobalVar(V_TALK_COUNTING_INDEX) >= 2) setGlobalVar(V_TALK_COUNTING_INDEX, 0); else - incGlobalVar(V_TALK_COUNTING_INDEX, +1); + incGlobalVar(V_TALK_COUNTING_INDEX, +1); break; } SetUpdateHandler(&Module1600::updateScene); @@ -185,11 +185,11 @@ void Module1600::updateScene() { AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) : AnimatedSprite(vm, 1000), _parentScene(parentScene) { - + createSurface(200, 556, 328); _x = x; _y = y; - + _inMainArea = false; _exitDirection = 0; _currPointIndex = 0; @@ -207,7 +207,7 @@ AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 _soundCounter = 0; _pathPoints = NULL; _currMoveDirection = 0; - + startAnimation(0xD4220027, 0, -1); setDoDeltaX(getGlobalVar(V_CAR_DELTA_X)); @@ -517,7 +517,7 @@ void AsCommonCar::moveToNextPoint() { if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) && ((_currMoveDirection == 2 && nextPt.x < currPt.x) || (_currMoveDirection == 4 && nextPt.x >= currPt.x))) { - if (_currMoveDirection == 2) + if (_currMoveDirection == 2) _currMoveDirection = 4; else if (_currMoveDirection == 4) _currMoveDirection = 2; @@ -605,7 +605,7 @@ void AsCommonCar::moveToPrevPoint() { if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) && ((_currMoveDirection == 2 && prevPt.x < currPt.x) || (_currMoveDirection == 4 && prevPt.x >= currPt.x))) { - if (_currMoveDirection == 2) + if (_currMoveDirection == 2) _currMoveDirection = 4; else if (_currMoveDirection == 4) _currMoveDirection = 2; @@ -668,7 +668,7 @@ void AsCommonCar::suMoveToNextPoint() { bool firstTime = true; _ySteps = _steps; int stepsCtr = _steps; - + while (stepsCtr > 0) { NPoint pt1; NPoint pt2 = pathPoint(_currPointIndex); @@ -739,7 +739,7 @@ void AsCommonCar::suMoveToNextPoint() { stepsCtr = 0; } } - firstTime = false; + firstTime = false; } if (_yMoveTotalSteps != 0) { @@ -811,7 +811,7 @@ void AsCommonCar::suMoveToPrevPoint() { bool firstTime = true; _ySteps = _steps; int stepsCtr = _steps; - + while (stepsCtr > 0) { if (_stepError == 0) _currPointIndex--; @@ -884,7 +884,7 @@ void AsCommonCar::suMoveToPrevPoint() { stepsCtr = 0; } } - firstTime = false; + firstTime = false; } if (_yMoveTotalSteps != 0) { @@ -971,7 +971,7 @@ AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y) AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar) : AnimatedSprite(vm, 1100), _asCar(asCar) { - + createSurface1(0x60281C10, 150); startAnimation(0x60281C10, -1, -1); _newStickFrameIndex = STICK_LAST_FRAME; @@ -1006,9 +1006,9 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _asCar(NULL), _countdown1(0) { setGlobalVar(V_CAR_DELTA_X, 1); - + SetMessageHandler(&Scene1608::hmLowerFloor); - + _asKey = insertSprite<AsCommonKey>(this, 1, 1100, 198, 220); addCollisionSprite(_asKey); @@ -1092,9 +1092,9 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which) _carClipFlag = false; _carStatus = 0; setRectList(0x004B4810); - } + } - // NOTE: Not in the else because 'which' is set to 1 in the true branch + // NOTE: Not in the else because 'which' is set to 1 in the true branch if (which == 1) { // Klaymen riding the car _vm->gameState().which = 1; @@ -1134,9 +1134,9 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which) _carClipFlag = true; _carStatus = 0; } - + _palette->addPalette("paKlayRed", 0, 64, 0); - + } Scene1608::~Scene1608() { @@ -1308,7 +1308,7 @@ uint32 Scene1608::hmCarAtHome(int messageNum, const MessageParam ¶m, Entity } return 0; } - + void Scene1608::updateKlaymenCliprect() { if (_kmScene1608->getX() <= 375) _kmScene1608->setClipRect(_clipRect1); @@ -1321,17 +1321,17 @@ Scene1609::Scene1609(NeverhoodEngine *vm, Module *parentModule) _vm->gameModule()->initCodeSymbolsPuzzle(); _noisySymbolIndex = getGlobalVar(V_NOISY_SYMBOL_INDEX); - + SetMessageHandler(&Scene1609::handleMessage); SetUpdateHandler(&Scene1609::update); - + setBackground(0x92124A14); setPalette(0x92124A14); insertPuzzleMouse(0x24A10929, 20, 620); - + for (int symbolPosition = 0; symbolPosition < 12; symbolPosition++) _asSymbols[symbolPosition] = insertSprite<AsScene3011Symbol>(symbolPosition, false); - + _ssButton = insertSprite<SsScene3011Button>(this, true); addCollisionSprite(_ssButton); loadSound(0, 0x68E25540); @@ -1408,5 +1408,5 @@ bool Scene1609::testVars() { return true; } - + } // End of namespace Neverhood diff --git a/engines/neverhood/modules/module1700.cpp b/engines/neverhood/modules/module1700.cpp index 38ed561d51..2aeae466ff 100644 --- a/engines/neverhood/modules/module1700.cpp +++ b/engines/neverhood/modules/module1700.cpp @@ -36,7 +36,7 @@ static const uint32 kModule1700SoundList[] = { Module1700::Module1700(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + _vm->_soundMan->addMusic(0x04212331, 0x31114225); _vm->_soundMan->addSoundList(0x04212331, kModule1700SoundList); _vm->_soundMan->setSoundListParams(kModule1700SoundList, true, 50, 600, 5, 150); @@ -125,7 +125,7 @@ void Module1700::updateScene() { } } } - + // Scene1705 static const uint32 kScene1705FileHashes[] = { @@ -137,7 +137,7 @@ static const uint32 kScene1705FileHashes[] = { SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex) : StaticSprite(vm, fileHash, 100) { - + _x = _spriteResource.getPosition().x + symbolIndex * 30; _y = _spriteResource.getPosition().y + 160; updatePosition(); @@ -171,7 +171,7 @@ uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam ¶m, setSubVar(VA_HAS_TAPE, _tapeIndex, 1); setVisible(false); SetMessageHandler(NULL); - break; + break; } return messageResult; } @@ -180,7 +180,7 @@ Scene1705::Scene1705(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _paletteArea(1) { Sprite *tempSprite; - + setGlobalVar(V_FELL_DOWN_HOLE, 1); _vm->gameModule()->initCannonSymbolsPuzzle(); @@ -271,7 +271,7 @@ uint32 Scene1705::handleMessage(int messageNum, const MessageParam ¶m, Entit sendEntityMessage(_klaymen, 0x1014, sender); setMessageList(0x004B6AC0); } - break; + break; } return 0; } diff --git a/engines/neverhood/modules/module1700.h b/engines/neverhood/modules/module1700.h index f57c411a18..deb5573f2b 100644 --- a/engines/neverhood/modules/module1700.h +++ b/engines/neverhood/modules/module1700.h @@ -50,7 +50,7 @@ public: class SsScene1705Tape : public StaticSprite { public: SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash); -protected: +protected: Scene *_parentScene; uint32 _tapeIndex; uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); diff --git a/engines/neverhood/modules/module1800.cpp b/engines/neverhood/modules/module1800.cpp index b7371c9a4a..b312678467 100644 --- a/engines/neverhood/modules/module1800.cpp +++ b/engines/neverhood/modules/module1800.cpp @@ -38,7 +38,7 @@ static const uint32 kModule1800SoundList[] = { Module1800::Module1800(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + _vm->_soundMan->addSoundList(0x04A14718, kModule1800SoundList); _vm->_soundMan->setSoundListParams(kModule1800SoundList, true, 50, 600, 10, 150); _vm->_soundMan->playTwoSounds(0x04A14718, 0x8A382B55, 0x0C242F1D, 0); @@ -177,5 +177,5 @@ void Module1800::updateScene() { } } } - + } // End of namespace Neverhood diff --git a/engines/neverhood/modules/module1900.cpp b/engines/neverhood/modules/module1900.cpp index 7f08b01d3f..29c20083f9 100644 --- a/engines/neverhood/modules/module1900.cpp +++ b/engines/neverhood/modules/module1900.cpp @@ -35,8 +35,8 @@ static const uint32 kModule1900SoundList[] = { Module1900::Module1900(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - // NOTE: The original has a Scene1908 here as well but it's not used here but in another module... - + // NOTE: The original has a Scene1908 here as well but it's not used here but in another module... + if (which < 0) createScene(_vm->gameState().sceneNum, -1); else @@ -88,7 +88,7 @@ void Module1900::updateScene() { Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + Sprite *tempSprite; setRectList(0x004B34C8); @@ -98,7 +98,7 @@ Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which) insertScreenMouse(0x0322301B); insertStaticSprite(0x42213133, 1100); - + if (!getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) insertStaticSprite(0x40A40168, 100); else if (getGlobalVar(V_STAIRS_DOWN)) { @@ -132,16 +132,16 @@ static const NPoint kAsScene1907SymbolGroundPositions[] = { {400, 375}, {370, 435}, {475, 415} }; -static const NPoint kAsScene1907SymbolPluggedInPositions[] = { +static const NPoint kAsScene1907SymbolPluggedInPositions[] = { {275, 125}, {244, 125}, {238, 131}, {221, 135}, {199, 136}, {168, 149}, {145, 152}, {123, 154}, {103, 157} }; static const NPoint kAsScene1907SymbolGroundHitPositions[] = { - {275, 299}, {244, 299}, {238, 305}, - {221, 309}, {199, 310}, {168, 323}, - {145, 326}, {123, 328}, {103, 331} + {275, 299}, {244, 299}, {238, 305}, + {221, 309}, {199, 310}, {168, 323}, + {145, 326}, {123, 328}, {103, 331} }; static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = { @@ -164,7 +164,7 @@ AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene _plugInFailed = false; _plugInTryCount = 0; - + if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) { _isPluggedIn = true; _currPositionIndex = elementIndex; @@ -289,7 +289,7 @@ void AsScene1907Symbol::suMoveDown() { _y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y; _isMoving = false; SetSpriteUpdate(NULL); - } + } } void AsScene1907Symbol::suMoveUp() { @@ -423,7 +423,7 @@ void AsScene1907Symbol::moveDown() { SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol) : StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol), _countdown1(0) { - + loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400); setVisible(false); loadSound(0, 0x44061000); @@ -474,7 +474,7 @@ void SsScene1907UpDownButton::setToDownPosition() { AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm) : AnimatedSprite(vm, 1400) { - + createSurface1(0x110A1061, 1500); _x = 320; _y = 240; @@ -515,10 +515,10 @@ void AsScene1907WaterHint::hide() { SetMessageHandler(&Sprite::handleMessage); } -Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule) - : Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0), +Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule) + : Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0), _moveDownCountdown(0), _moveUpCountdown(0), _countdown3(0), _hasPlugInFailed(false) { - + setBackground(0x20628E05); setPalette(0x20628E05); @@ -529,12 +529,12 @@ Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule) _asSymbols[i] = insertSprite<AsScene1907Symbol>(this, i, getRandomPositionIndex()); addCollisionSprite(_asSymbols[i]); } - + _ssUpDownButton = insertSprite<SsScene1907UpDownButton>(this, _asSymbols[8]); addCollisionSprite(_ssUpDownButton); _asWaterHint = insertSprite<AsScene1907WaterHint>(); - + insertPuzzleMouse(0x28E0120E, 20, 620); SetMessageHandler(&Scene1907::handleMessage); @@ -542,7 +542,7 @@ Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule) if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) _pluggedInCount = 9; - + loadSound(0, 0x72004A10); loadSound(1, 0x22082A12); loadSound(2, 0x21100A10); @@ -552,7 +552,7 @@ Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule) void Scene1907::update() { Scene::update(); - + if (_hasPlugInFailed) { int fallOffDelay = 0; _hasPlugInFailed = false; @@ -619,7 +619,7 @@ uint32 Scene1907::handleMessage(int messageNum, const MessageParam ¶m, Entit playSound(3); setGlobalVar(V_STAIRS_PUZZLE_SOLVED, 1); break; - } + } return 0; } diff --git a/engines/neverhood/modules/module2000.cpp b/engines/neverhood/modules/module2000.cpp index 644b7c479a..fcccdefbdd 100644 --- a/engines/neverhood/modules/module2000.cpp +++ b/engines/neverhood/modules/module2000.cpp @@ -28,7 +28,7 @@ namespace Neverhood { Module2000::Module2000(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + if (which < 0) createScene(_vm->gameState().sceneNum, -1); else if (which == 0) @@ -137,9 +137,9 @@ Scene2001::Scene2001(NeverhoodEngine *vm, Module *parentModule, int which) sendMessage(this, 0x2000, 0); _klaymen->setDoDeltaX(1); } - + _klaymen->setClipRect(tempSprite->getDrawRect().x, 0, 640, 480); - + } uint32 Scene2001::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -153,7 +153,7 @@ uint32 Scene2001::handleMessage(int messageNum, const MessageParam ¶m, Entit setRectList(0x004B3670); _klaymen->setKlaymenIdleTable1(); } - } + } return 0; } diff --git a/engines/neverhood/modules/module2100.cpp b/engines/neverhood/modules/module2100.cpp index b664e93dde..bcff9d9d1b 100644 --- a/engines/neverhood/modules/module2100.cpp +++ b/engines/neverhood/modules/module2100.cpp @@ -30,7 +30,7 @@ Module2100::Module2100(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { _vm->_soundMan->addMusic(0x10A10C14, 0x11482B95); - + if (which < 0) createScene(_vm->gameState().sceneNum, -1); else if (which == 1) @@ -129,7 +129,7 @@ void AsScene2101Door::stCloseDoorDone() { AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen) : AnimatedSprite(vm, 1400), _klaymen(klaymen) { - + SetUpdateHandler(&AnimatedSprite::update); SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage); createSurface(1200, 88, 165); @@ -176,8 +176,8 @@ void SsCommonFloorButton::update() { else setVisible(false); } -} - +} + uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); switch (messageNum) { @@ -195,12 +195,12 @@ uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &pa Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + Sprite *tempSprite; - + SetMessageHandler(&Scene2101::handleMessage); SetUpdateHandler(&Scene2101::update); - + setBackground(0x44242305); setPalette(0x44242305); insertScreenMouse(0x4230144A); @@ -210,9 +210,9 @@ Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which) _ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x72427010, 0x32423010, 200, 0); _asTape1 = insertSprite<AsScene1201Tape>(this, 18, 1100, 412, 443, 0x9148A011); addCollisionSprite(_asTape1); - _asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9148A011); + _asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9048A093); addCollisionSprite(_asTape2); - + if (which < 0) { insertKlaymen<KmScene2101>(380, 438); setMessageList(0x004B8E48); @@ -256,10 +256,10 @@ Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which) _doorStatus = 1; _countdown1 = 0; } - + _asHitByDoorEffect = insertSprite<AsScene2101HitByDoorEffect>(_klaymen); _klaymen->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480); - + } void Scene2101::update() { diff --git a/engines/neverhood/modules/module2100.h b/engines/neverhood/modules/module2100.h index 369f5ac0cc..d76bed0780 100644 --- a/engines/neverhood/modules/module2100.h +++ b/engines/neverhood/modules/module2100.h @@ -68,7 +68,7 @@ protected: uint32 _soundFileHash; uint32 _fileHash1, _fileHash2; int16 _countdown; - void update(); + void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); }; diff --git a/engines/neverhood/modules/module2200.cpp b/engines/neverhood/modules/module2200.cpp index 08ed274eb3..99f21cad74 100644 --- a/engines/neverhood/modules/module2200.cpp +++ b/engines/neverhood/modules/module2200.cpp @@ -30,8 +30,8 @@ namespace Neverhood { Module2200::Module2200(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - - _vm->_soundMan->addMusic(0x11391412, 0x601C908C); + + _vm->_soundMan->addMusic(0x11391412, 0x601C908C); if (which < 0) createScene(_vm->gameState().sceneNum, -1); @@ -50,6 +50,7 @@ void Module2200::createScene(int sceneNum, int which) { switch (_sceneNum) { case 0: _vm->gameState().sceneNum = 0; + _vm->_soundMan->startMusic(0x601C908C, 0, 2); _childObject = new Scene2201(_vm, this, which); break; case 1: @@ -439,7 +440,7 @@ void Module2200::updateScene() { } #undef HallOfRecordsSceneLink - + void Module2200::createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId) { _childObject = new HallOfRecordsScene(_vm, this, which, hallOfRecordsInfoId); } @@ -460,7 +461,7 @@ AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite * : AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) { _x = 408; - _y = 290; + _y = 290; createSurface(900, 63, 266); SetUpdateHandler(&AsScene2201Door::update); SetMessageHandler(&AsScene2201Door::handleMessage); @@ -527,7 +528,7 @@ void AsScene2201Door::stCloseDoor() { SsScene2201PuzzleCube::SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex) : StaticSprite(vm, 900) { - + createSurface(100, 16, 16); loadSprite(kSsScene2201PuzzleCubeFileHashes[cubeIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 0, kSsScene2201PuzzleCubePoints[positionIndex].x, kSsScene2201PuzzleCubePoints[positionIndex].y); @@ -542,7 +543,7 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which) SetMessageHandler(&Scene2201::handleMessage); SetUpdateHandler(&Scene2201::update); - + loadDataResource(0x04104242); loadHitRectList(); setBackground(0x40008208); @@ -550,9 +551,9 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which) insertScreenMouse(0x0820C408); _asTape = insertSprite<AsScene1201Tape>(this, 7, 1100, 459, 432, 0x9148A011); - addCollisionSprite(_asTape); + addCollisionSprite(_asTape); _ssDoorButton = insertSprite<SsCommonPressButton>(this, 0xE4A43E29, 0xE4A43E29, 100, 0); - + for (uint32 cubeIndex = 0; cubeIndex < 9; cubeIndex++) if ((int16)getSubVar(VA_CUBE_POSITIONS, cubeIndex) >= 0) insertSprite<SsScene2201PuzzleCube>(cubeIndex, (int16)getSubVar(VA_CUBE_POSITIONS, cubeIndex)); @@ -561,10 +562,10 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which) _clipRects[0].x2 = 640; _clipRects[1].x2 = 640; _clipRects[1].y2 = 480; - + if (!getGlobalVar(V_TILE_PUZZLE_SOLVED)) insertStaticSprite(0x00026027, 900); - + tempSprite = insertStaticSprite(0x030326A0, 1100); _clipRects[0].x1 = tempSprite->getDrawRect().x; insertStaticSprite(0x811DA061, 1100); @@ -601,7 +602,7 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which) setMessageList(0x004B8120); _asDoor = insertSprite<AsScene2201Door>(_klaymen, _ssDoorLight, true); } - + insertSprite<AsScene2201CeilingFan>(); _vm->_soundMan->addSound(0x04106220, 0x81212040); @@ -718,7 +719,7 @@ uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam & } return messageResult; } - + void SsScene2202PuzzleCube::suMoveCubeX() { bool done = false; @@ -745,9 +746,9 @@ void SsScene2202PuzzleCube::suMoveCubeX() { if (_x == _xFlagPos) _counterDirection = true; } - + if (done) - stopMoving(); + stopMoving(); updateBounds(); @@ -779,9 +780,9 @@ void SsScene2202PuzzleCube::suMoveCubeY() { if (_x == _xFlagPos) _counterDirection = true; } - + if (done) - stopMoving(); + stopMoving(); updateBounds(); @@ -793,7 +794,7 @@ void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) { setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1); setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol); - + _cubePosition = newCubePosition; _errValue = 0; _counterDirection = false; @@ -836,7 +837,7 @@ void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) { if (_newX - _x >= 180) _xFlagPos = _newX - 90; else - _xFlagPos = _x + _newX / 2; + _xFlagPos = _x + _newX / 2; } else { if (_x - _newX >= 180) _xFlagPos = _x + 90; @@ -850,7 +851,7 @@ void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) { if (_newY - _y >= 180) _xFlagPos = _newY - 90; else - _xFlagPos = _y + _newY / 2; + _xFlagPos = _y + _newY / 2; } else { if (_y - _newY >= 180) _xFlagPos = _y + 90; @@ -859,7 +860,7 @@ void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) { } playSound(1); } - + } void SsScene2202PuzzleCube::stopMoving() { @@ -938,7 +939,7 @@ void Scene2202::update() { _isSolved = true; } } - + } uint32 Scene2202::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -980,7 +981,7 @@ int16 Scene2202::getFreeCubePosition(int16 cubePosition) { } bool Scene2202::testIsSolved() { - return + return getSubVar(VA_CUBE_POSITIONS, 0) == 0 && getSubVar(VA_CUBE_POSITIONS, 2) == 2 && getSubVar(VA_CUBE_POSITIONS, 3) == 3 && @@ -1145,7 +1146,7 @@ Scene2203::Scene2203(NeverhoodEngine *vm, Module *parentModule, int which) _ssSmallRightDoor->setVisible(false); _klaymen->setClipRect(_leftDoorClipRect); } - + } Scene2203::~Scene2203() { @@ -1219,7 +1220,7 @@ Scene2205::Scene2205(NeverhoodEngine *vm, Module *parentModule, int which) SetMessageHandler(&Scene2205::handleMessage); SetUpdateHandler(&Scene2205::update); - + setHitRects(0x004B0620); if (getGlobalVar(V_LIGHTS_ON)) { _isLightOn = true; @@ -1262,11 +1263,11 @@ Scene2205::Scene2205(NeverhoodEngine *vm, Module *parentModule, int which) _klaymen->setClipRect(_ssDoorFrame->getDrawRect().x, 0, 640, 480); _klaymen->setSoundFlag(true); - + loadDataResource(0x00144822); - + } - + void Scene2205::update() { Scene::update(); if (!_isLightOn && getGlobalVar(V_LIGHTS_ON)) { @@ -1342,7 +1343,7 @@ static const int16 kAsScene2206DoorSpikesXDeltasClose[] = { AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash) : StaticSprite(vm, fileHash, 200) { - + if (getGlobalVar(V_SPIKES_RETRACTED)) _x -= 63; SetUpdateHandler(&AsScene2206DoorSpikes::update); @@ -1456,10 +1457,10 @@ Scene2206::Scene2206(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { uint32 fileHash; - + SetUpdateHandler(&Scene::update); SetMessageHandler(&Scene2206::handleMessage); - + if (getGlobalVar(V_LIGHTS_ON)) { fileHash = 0x41983216; _sprite1 = insertStaticSprite(0x2201266A, 100); @@ -1494,7 +1495,7 @@ Scene2206::Scene2206(NeverhoodEngine *vm, Module *parentModule, int which) if (!getGlobalVar(V_LIGHTS_ON)) _palette->addPalette(0x0263D144, 0, 65, 0); addCollisionSprite(_ssTestTube); - + if (which < 0) { // Restoring game insertKlaymen<KmScene2206>(200, 430); @@ -1643,7 +1644,7 @@ void AsScene2207Elevator::update() { if (_destPointIndex + _destPointIndexDelta > _pointIndex) { _pointIndex++; startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex); - _newStickFrameIndex = _pointIndex; + _newStickFrameIndex = _pointIndex; if (_destPointIndex + _destPointIndexDelta == _pointIndex) { if (_destPointIndexDelta != 0) _destPointIndexDelta = 0; @@ -1659,7 +1660,7 @@ void AsScene2207Elevator::update() { if (_pointIndex == 0) sendMessage(_parentScene, 0x2003, 0); startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex); - _newStickFrameIndex = _pointIndex; + _newStickFrameIndex = _pointIndex; if (_destPointIndex + _destPointIndexDelta == _pointIndex) { if (_destPointIndexDelta != 0) _destPointIndexDelta = 0; @@ -1674,14 +1675,14 @@ void AsScene2207Elevator::update() { sendMessage(_parentScene, 0x2002, 900); else if (_pointIndex < 20 && _surface->getPriority() != 1100) sendMessage(_parentScene, 0x2002, 1100); - + AnimatedSprite::update(); - + if (_destPointIndex + _destPointIndexDelta == _pointIndex && _isMoving) { sendMessage(_parentScene, 0x2004, 0); _isMoving = false; } - + } void AsScene2207Elevator::suSetPosition() { @@ -1705,14 +1706,14 @@ void AsScene2207Elevator::moveToY(int16 y) { if (!_pointArray || _pointArray->size() == 0) return; - + for (uint i = 0; i < _pointArray->size(); i++) { int16 distance = ABS(y - (*_pointArray)[i].y); if (distance < minDistance) { minDistance = distance; _destPointIndex = i; } - } + } if (_destPointIndex != _pointIndex) { if (_destPointIndex == 0 || _destPointIndex == (int)_pointArray->size() - 1) @@ -1731,7 +1732,7 @@ void AsScene2207Elevator::moveToY(int16 y) { AsScene2207Lever::AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX) : AnimatedSprite(vm, 1100), _parentScene(parentScene) { - + _x = x; _y = y; createSurface(1010, 71, 73); @@ -1792,7 +1793,7 @@ void AsScene2207Lever::stLeverUpEvent() { AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 1200), _idle(true) { - + _x = 309; _y = 320; createSurface1(0xCCFD6090, 100); @@ -1873,7 +1874,7 @@ void AsScene2207WallRobotAnimation::cbStopAnimation() { AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm) : AnimatedSprite(vm, 1200), _idle(true) { - + _x = 309; _y = 320; createSurface1(0x8CAA0099, 100); @@ -1924,7 +1925,7 @@ SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int i _x = 330; _y = 246 + index * 50; - updatePosition(); + updatePosition(); } Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule) @@ -1942,7 +1943,7 @@ Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule) _klaymen->setRepl(64, 0); setMessageList(0x004B38E8); _asElevator = insertSprite<AsScene2207Elevator>(this); - + if (getGlobalVar(V_LIGHTS_ON)) { setBackground(0x88C00241); setPalette(0x88C00241); @@ -1951,7 +1952,7 @@ Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule) _ssMaskPart2 = insertStaticSprite(0x688F62A5, 1100); _ssMaskPart3 = insertStaticSprite(0x0043B038, 1100); _asTape = insertSprite<AsScene1201Tape>(this, 4, 1100, 277, 428, 0x9148A011); - addCollisionSprite(_asTape); + addCollisionSprite(_asTape); _asLever = insertSprite<AsScene2207Lever>(this, 527, 333, 0); addCollisionSprite(_asLever); _asWallRobotAnimation = insertSprite<AsScene2207WallRobotAnimation>(this); @@ -2105,7 +2106,7 @@ static const uint32 kScene2208FileHashes1[] = { 0x041023CB, 0x041020CB, 0x041026CB, 0x04102ACB, 0x041032CB, 0x041002CB }; - + static const uint32 kScene2208FileHashes2[] = { 0x091206C9, 0x091406C9, 0x091806C9, 0x090006C9, 0x093006C9, 0x095006C9 @@ -2121,13 +2122,13 @@ Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which) setGlobalVar(V_COLUMN_TEXT_NAME, calcHash("stLineagex")); _textResource.load(getGlobalVar(V_COLUMN_TEXT_NAME)); - + textStart = _textResource.getString(getGlobalVar(V_CLICKED_COLUMN_INDEX), textEnd); while (textStart < textEnd) { _strings.push_back(textStart); textStart += strlen(textStart) + 1; } - + _maxRowIndex = 8 + 10 * (3 - (getGlobalVar(V_COLUMN_TEXT_NAME) == calcHash("stLineagex") ? 1 : 0)); _background = new Background(_vm, 0); @@ -2153,7 +2154,7 @@ Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which) _bottomBackgroundSurface = new BaseSurface(_vm, 0, 640, 192, "bottom background"); spriteResource.load(kScene2208FileHashes2[getGlobalVar(V_CLICKED_COLUMN_INDEX) % 6], true); _bottomBackgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0); - + SetUpdateHandler(&Scene2208::update); SetMessageHandler(&Scene2208::handleMessage); @@ -2164,7 +2165,7 @@ Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which) if (_newRowIndex < 6) _newRowIndex = 0; _rowScrollY = 0; - _backgroundScrollY = 48 * _newRowIndex; + _backgroundScrollY = 48 * _newRowIndex; _currRowIndex = _newRowIndex; for (int16 rowIndex = 0; rowIndex < _visibleRowsCount; rowIndex++) @@ -2184,7 +2185,7 @@ Scene2208::~Scene2208() { void Scene2208::update() { int16 mouseY = _vm->getMouseY(); - + if (mouseY < 48) { if (_currRowIndex > 0) _newRowIndex = _currRowIndex - 1; @@ -2234,7 +2235,7 @@ uint32 Scene2208::handleMessage(int messageNum, const MessageParam ¶m, Entit } void Scene2208::drawRow(int16 rowIndex) { - NDrawRect sourceRect; + NDrawRect sourceRect; int16 y = (rowIndex * 48) % 528; if (rowIndex < 4) { sourceRect.x = 0; @@ -2279,7 +2280,7 @@ Scene2242::Scene2242(NeverhoodEngine *vm, Module *parentModule, int which) SetMessageHandler(&Scene2242::handleMessage); SetUpdateHandler(&Scene2242::update); - + if (getGlobalVar(V_LIGHTS_ON)) { setBackground(0x11840E24); setPalette(0x11840E24); @@ -2296,7 +2297,7 @@ Scene2242::Scene2242(NeverhoodEngine *vm, Module *parentModule, int which) } _asTape = insertSprite<AsScene1201Tape>(this, 10, 1100, 464, 435, 0x9148A011); - addCollisionSprite(_asTape); + addCollisionSprite(_asTape); if (which < 0) { // Restoring game @@ -2379,7 +2380,7 @@ void Scene2242::readClickedColumn() { } static const int16 kHallOfRecordsKlaymenXPos[] = { - 68, 157, 246, 335, + 68, 157, 246, 335, 424, 513, 602 }; @@ -2395,7 +2396,7 @@ static const uint32 kHallOfRecordsSceneMessageListIds1[] = { HallOfRecordsScene::HallOfRecordsScene(NeverhoodEngine *vm, Module *parentModule, int which, uint32 hallOfRecordsInfoId) : Scene(vm, parentModule) { - + _hallOfRecordsInfo = _vm->_staticData->getHallOfRecordsInfoItem(hallOfRecordsInfoId); SetMessageHandler(&HallOfRecordsScene::handleMessage); @@ -2486,7 +2487,7 @@ static const uint32 kScene2247MessageListIds1[] = { Scene2247::Scene2247(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + SetMessageHandler(&Scene2247::handleMessage); SetUpdateHandler(&Scene::update); @@ -2523,7 +2524,7 @@ Scene2247::Scene2247(NeverhoodEngine *vm, Module *parentModule, int which) } _klaymen->setSoundFlag(true); - + } Scene2247::~Scene2247() { diff --git a/engines/neverhood/modules/module2200.h b/engines/neverhood/modules/module2200.h index af7171dd53..5c19f2a818 100644 --- a/engines/neverhood/modules/module2200.h +++ b/engines/neverhood/modules/module2200.h @@ -100,7 +100,7 @@ class SsScene2202PuzzleCube : public StaticSprite { public: SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol); protected: - Scene *_parentScene; + Scene *_parentScene; int16 _cubeSymbol; int16 _cubePosition; int16 _newX, _newY; @@ -135,7 +135,7 @@ protected: void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); int16 getFreeCubePosition(int16 index); - bool testIsSolved(); + bool testIsSolved(); }; class AsCommonKey : public AnimatedSprite { diff --git a/engines/neverhood/modules/module2300.cpp b/engines/neverhood/modules/module2300.cpp index b434fb98c0..2a46df1ee2 100644 --- a/engines/neverhood/modules/module2300.cpp +++ b/engines/neverhood/modules/module2300.cpp @@ -32,12 +32,12 @@ static const uint32 kModule2300SoundList[] = { Module2300::Module2300(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule), _soundVolume(0) { - + _vm->_soundMan->addSoundList(0x1A214010, kModule2300SoundList); _vm->_soundMan->setSoundListParams(kModule2300SoundList, true, 50, 600, 10, 150); _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0; - + if (_isWallBroken) { _vm->_soundMan->setSoundVolume(0x90F0D1C3, 0); _vm->_soundMan->playSoundLooping(0x90F0D1C3); @@ -161,12 +161,12 @@ void Module2300::updateScene() { } else { switch (_sceneNum) { case 1: - if (_isWallBroken && navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 4 && + if (_isWallBroken && navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 4 && navigationScene()->getFrameNumber() % 2) { _soundVolume++; _vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume); } - if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 0 && + if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 0 && navigationScene()->getFrameNumber() == 50) { _vm->_soundMan->playTwoSounds(0x1A214010, 0x48498E46, 0x50399F64, 0); _vm->_soundMan->setSoundVolume(0x48498E46, 70); @@ -182,5 +182,5 @@ void Module2300::updateScene() { } } } - + } // End of namespace Neverhood diff --git a/engines/neverhood/modules/module2400.cpp b/engines/neverhood/modules/module2400.cpp index 47f842b939..3a152543cf 100644 --- a/engines/neverhood/modules/module2400.cpp +++ b/engines/neverhood/modules/module2400.cpp @@ -26,11 +26,11 @@ namespace Neverhood { Module2400::Module2400(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + _vm->_soundMan->addMusic(0x202D1010, 0xB110382D); if (which < 0) - createScene(_vm->gameState().sceneNum, _vm->gameState().which); + createScene(_vm->gameState().sceneNum, -1); else createScene(0, 0); @@ -187,7 +187,7 @@ static const uint32 kAsScene2401WaterSpitFileHashes1[] = { AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm) : AnimatedSprite(vm, 1200) { - + _x = 240; _y = 447; createSurface(100, 146, 74); @@ -222,7 +222,7 @@ uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam &p AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm) : AnimatedSprite(vm, 1200), _isWaterFlowing(false) { - + _x = 88; _y = 421; createSurface1(0x10203116, 100); @@ -262,10 +262,10 @@ uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam } return messageResult; } - + AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y) : AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) { - + _x = x; _y = y; createSurface1(0xB8596884, 100); @@ -308,7 +308,7 @@ uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessagePara AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen) : AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) { - + _x = 320; _y = 240; createSurface1(0x44687810, 100); @@ -398,7 +398,7 @@ Scene2401::Scene2401(NeverhoodEngine *vm, Module *parentModule, int which) _ssWaterPipes[i] = insertStaticSprite(kScene2401FileHashes1[i], 300); _ssWaterPipes[i]->setVisible(false); } - + _asWaterSpit[0] = insertSprite<AsScene2401WaterSpit>(); _asWaterSpit[1] = insertSprite<AsScene2401WaterSpit>(); @@ -461,7 +461,7 @@ void Scene2401::update() { if (_countdown2 != 0 && (--_countdown2) == 0) sendMessage(_asFlowingWater, 0x2003, 0); - + Scene::update(); } @@ -559,7 +559,7 @@ AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool i } else { stopAnimation(); setVisible(false); - } + } SetUpdateHandler(&AsScene2402Door::update); SetMessageHandler(&AsScene2402Door::handleMessage); } @@ -654,7 +654,7 @@ void AsScene2402TV::upFocusKlaymen() { _newStickFrameIndex = _currFrameIndex; if (_countdown2 == 0) { _vm->_soundMan->addSound(0x01520123, 0xC42D4528); - _vm->_soundMan->playSoundLooping(0xC42D4528); + _vm->_soundMan->playSoundLooping(0xC42D4528); } _countdown2 = 5; } else if (_countdown2 != 0 && (--_countdown2 == 0)) @@ -698,7 +698,7 @@ Scene2402::Scene2402(NeverhoodEngine *vm, Module *parentModule, int which) _asTape = insertSprite<AsScene1201Tape>(this, 9, 1100, 286, 409, 0x9148A011); addCollisionSprite(_asTape); _ssButton = insertSprite<SsCommonButtonSprite>(this, 0x15288120, 100, 0); - + if (which < 0) { // Restoring game insertKlaymen<KmScene2402>(198, 404); @@ -779,7 +779,7 @@ uint32 Scene2402::handleMessage(int messageNum, const MessageParam ¶m, Entit } return messageResult; } - + void Scene2402::playPipeSound(uint32 fileHash) { playSound(_soundToggle ? 0 : 1, fileHash); _soundToggle = !_soundToggle; @@ -787,7 +787,7 @@ void Scene2402::playPipeSound(uint32 fileHash) { Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + Sprite *tempSprite1, *tempSprite2, *tempSprite3; SetMessageHandler(&Scene2403::handleMessage); @@ -799,7 +799,7 @@ Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which) addCollisionSprite(_asTape); _asLightCord = insertSprite<AsScene2803LightCord>(this, 0xA1095A10, 0x836D3813, 368, 200); _asLightCord->setClipRect(0, 25, 640, 480); - + if (which < 0) { // Restoring game _isClimbingLadder = false; @@ -828,11 +828,11 @@ Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which) } _ssButton = insertSprite<SsCommonButtonSprite>(this, 0x3130B0EB, 100, 0); - tempSprite1 = insertStaticSprite(0x20C24220, 1100); + tempSprite1 = insertStaticSprite(0x20C24220, 1100); tempSprite2 = insertStaticSprite(0x03080900, 1300); tempSprite3 = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen); tempSprite3->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2()); - _klaymen->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2()); + _klaymen->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2()); loadSound(1, calcHash("fxFogHornSoft")); } @@ -887,7 +887,7 @@ Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which) setGlobalVar(V_KEY3_LOCATION, 2); SetMessageHandler(&Scene2406::handleMessage); - + setRectList(0x004B78C8); insertScreenMouse(0xB03001A8); @@ -913,7 +913,7 @@ Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which) setPalette(0x0A038595); tempSprite1 = insertStaticSprite(0x1712112A, 1100); } - + tempSprite2 = insertStaticSprite(0x22300924, 1300); _clipRects[1].x1 = tempSprite1->getDrawRect().x; _clipRects[1].y1 = tempSprite2->getDrawRect().y; diff --git a/engines/neverhood/modules/module2500.cpp b/engines/neverhood/modules/module2500.cpp index e3a3b74280..1b525f12af 100644 --- a/engines/neverhood/modules/module2500.cpp +++ b/engines/neverhood/modules/module2500.cpp @@ -51,7 +51,7 @@ static const NRect kScene2508ClipRect2 = NRect(0, 0, 594, 448); Module2500::Module2500(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule), _soundIndex(0) { - + _vm->_soundMan->addMusic(0x29220120, 0x05343184); _vm->_soundMan->startMusic(0x05343184, 0, 0); SetMessageHandler(&Module2500::handleMessage); @@ -212,14 +212,14 @@ uint32 Module2500::handleMessage(int messageNum, const MessageParam ¶m, Enti } return messageResult; } - + void Module2500::createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites, const NRect *clipRect) { _childObject = new Scene2704(_vm, this, which, sceneInfoId, value, staticSprites, clipRect); } Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B2628)); _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B264C)); _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B2670)); @@ -282,7 +282,7 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which) _asCarTrackShadow = insertSprite<AsCommonCarTrackShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4); _asCarConnectorShadow = insertSprite<AsCommonCarConnectorShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4); insertSprite<AsCommonCarConnector>(_asCar); - + _newTrackIndex = -1; _dataResource.load(calcHash("Ashooded")); @@ -300,9 +300,9 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which) if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480) sendMessage(_asCar, 0x2008, 150); } - + _carStatus = 0; - + } Scene2501::~Scene2501() { @@ -391,7 +391,7 @@ uint32 Scene2501::handleMessage(int messageNum, const MessageParam ¶m, Entit } return messageResult; } - + uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Scene::handleMessage(messageNum, param, sender); switch (messageNum) { @@ -434,7 +434,7 @@ uint32 Scene2501::hmCarAtHome(int messageNum, const MessageParam ¶m, Entity } return messageResult; } - + void Scene2501::moveCarToPoint(NPoint &pt) { int minMatchTrackIndex, minMatchDistance; _tracks.findTrackPoint(pt, minMatchTrackIndex, minMatchDistance, _dataResource); @@ -472,7 +472,7 @@ void Scene2501::updateKlaymenClipRect() { SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm) : StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) { - + loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); setVisible(false); loadSound(0, 0x4600204C); @@ -520,9 +520,9 @@ uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam ¶ Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + Sprite *ssButton; - + setBackground(0x90791B80); setPalette(0x90791B80); ssButton = insertSprite<SsScene2504Button>(); diff --git a/engines/neverhood/modules/module2600.cpp b/engines/neverhood/modules/module2600.cpp index 56b4c65f8d..2fce82b777 100644 --- a/engines/neverhood/modules/module2600.cpp +++ b/engines/neverhood/modules/module2600.cpp @@ -35,7 +35,7 @@ static const uint32 kModule2600SoundList[] = { Module2600::Module2600(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { - + if (which < 0) createScene(_vm->gameState().sceneNum, -1); else if (which == 1) @@ -218,10 +218,10 @@ void Module2600::updateScene() { } } } - + SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene) : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) { - + SetUpdateHandler(&SsScene2609Button::update); SetMessageHandler(&SsScene2609Button::handleMessage); @@ -273,7 +273,7 @@ uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam ¶ AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm) : AnimatedSprite(vm, 1000) { - + _x = 240; _y = 420; setDoDeltaX(1); @@ -309,7 +309,7 @@ uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam ¶m Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _isBusy(false) { - + SetUpdateHandler(&Scene::update); SetMessageHandler(&Scene2609::handleMessage); diff --git a/engines/neverhood/modules/module2700.cpp b/engines/neverhood/modules/module2700.cpp index 19655d128b..f8f3c71042 100644 --- a/engines/neverhood/modules/module2700.cpp +++ b/engines/neverhood/modules/module2700.cpp @@ -83,8 +83,8 @@ static const uint32 kScene2725StaticSprites[] = { }; Module2700::Module2700(NeverhoodEngine *vm, Module *parentModule, int which) - : Module(vm, parentModule), _soundIndex(0), _raidoMusicInitialized(false) { - + : Module(vm, parentModule), _soundIndex(0), _radioMusicInitialized(false) { + _vm->_soundMan->addMusic(0x42212411, 0x04020210); _vm->_soundMan->startMusic(0x04020210, 24, 2); SetMessageHandler(&Module2700::handleMessage); @@ -500,7 +500,7 @@ void Module2700::updateScene() { } else { switch (_sceneNum) { case 21: - if (!_raidoMusicInitialized) { + if (!_radioMusicInitialized) { _vm->_soundMan->stopMusic(0x04020210, 0, 1); _vm->gameModule()->initRadioPuzzle(); _musicFileHash = getGlobalVar(V_GOOD_RADIO_MUSIC_NAME); @@ -508,7 +508,7 @@ void Module2700::updateScene() { _vm->_soundMan->startMusic(_musicFileHash, 0, 2); _vm->_soundMan->addSound(0x42212411, 0x44014282); _vm->_soundMan->setSoundParams(0x44014282, true, 120, 360, 72, 0); - _raidoMusicInitialized = true; + _radioMusicInitialized = true; } break; } @@ -527,7 +527,7 @@ uint32 Module2700::handleMessage(int messageNum, const MessageParam ¶m, Enti } return messageResult; } - + void Module2700::createScene2703(int which, uint32 trackInfoId) { _childObject = new Scene2703(_vm, this, which, trackInfoId); } @@ -545,7 +545,7 @@ static const NPoint kCarShadowOffsets[] = { SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash) : StaticSprite(vm, 0) { - + loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0); } @@ -555,7 +555,7 @@ AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, SetUpdateHandler(&AsCommonCarShadow::update); createShadowSurface(shadowSurface, 211, 147, 100); updateShadow(); -} +} void AsCommonCarShadow::update() { updateShadow(); @@ -589,8 +589,8 @@ AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Spri SetUpdateHandler(&AsCommonCarConnectorShadow::update); createShadowSurface1(shadowSurface, 0x60281C10, 150); startAnimation(0x60281C10, -1, -1); - _newStickFrameIndex = STICK_LAST_FRAME; -} + _newStickFrameIndex = STICK_LAST_FRAME; +} void AsCommonCarConnectorShadow::update() { _x = _asCar->getX() + kCarShadowOffsets[_index].x; @@ -605,7 +605,7 @@ AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCa createShadowSurface1(shadowSurface, 0x0759129C, 100); startAnimation(0x0759129C, frameIndex, -1); _newStickFrameIndex = frameIndex; -} +} void AsCommonCarTrackShadow::update() { _x = _asCar->getX(); @@ -615,19 +615,19 @@ void AsCommonCarTrackShadow::update() { Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + Sprite *tempSprite; - + NRect clipRect; TrackInfo *tracks = _vm->_staticData->getTrackInfo(0x004B2240); setGlobalVar(V_CAR_DELTA_X, 1); - + setBackground(tracks->bgFilename); setPalette(tracks->bgFilename); _palette->addPalette(calcHash("paPodFloor"), 65, 31, 65); _palette->addPalette(calcHash("paKlayFloor"), 0, 65, 0); insertScreenMouse(0x08B08180); - + tempSprite = insertStaticSprite(0x1E086325, 1200); clipRect.set(0, 0, 640, tempSprite->getDrawRect().y2()); @@ -661,7 +661,7 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which) if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480) sendMessage(_asCar, 0x2008, 150); } - + _asCar->setClipRect(clipRect); _asCarConnector->setClipRect(clipRect); @@ -715,10 +715,10 @@ uint32 Scene2701::hmCarAtHome(int messageNum, const MessageParam ¶m, Entity Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _isInLight(true), _newTrackIndex(-1) { - + SetMessageHandler(&Scene2702::handleMessage); SetUpdateHandler(&Scene2702::update); - + setBackground(0x18808B00); setPalette(0x18808B00); _palette->addPalette(calcHash("paPodFloor"), 65, 31, 65); @@ -734,7 +734,7 @@ Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which) _asCarTrackShadow = insertSprite<AsCommonCarTrackShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4); _asCarConnectorShadow = insertSprite<AsCommonCarConnectorShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4); _dataResource.load(0x04310014); - + if (which == 1) { _isUpperTrack = false; _currTrackIndex = 1; @@ -765,11 +765,11 @@ Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which) } if (_isUpperTrack) { - _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5F68)); + _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5F68)); _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5F8C)); _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5FB0)); } else { - _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5FD8)); + _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5FD8)); _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5FFC)); _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B6020)); } @@ -873,19 +873,19 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3 : Scene(vm, parentModule) { TrackInfo *tracks = _vm->_staticData->getTrackInfo(trackInfoId); - + SetMessageHandler(&Scene2703::handleMessage); SetUpdateHandler(&Scene2703::update); - + setBackground(tracks->bgFilename); setPalette(tracks->bgFilename); _palette->addPalette(calcHash("paPodShade"), 65, 31, 65); _palette->addPalette(calcHash("paKlayShade"), 0, 65, 0); addEntity(_palette); insertScreenMouse(tracks->mouseCursorFilename); - + _palStatus = 2; - + if (tracks->bgShadowFilename) { _ssTrackShadowBackground = createSprite<SsCommonTrackShadowBackground>(tracks->bgShadowFilename); addEntity(_ssTrackShadowBackground); @@ -905,7 +905,7 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3 _dataResource.load(tracks->dataResourceFilename); _trackPoints = _dataResource.getPointArray(tracks->trackPointsName); _asCar->setPathPoints(_trackPoints); - + if (which == _which2) { NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1]; sendMessage(_asCar, 0x2002, _trackPoints->size() - 1); @@ -921,7 +921,7 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3 else sendMessage(_asCar, 0x2008, 150); } - + if (which == 0) { _palette->addPalette(calcHash("paPodShade"), 65, 31, 65); _palette->addPalette(calcHash("paKlayShade"), 0, 65, 0); @@ -931,9 +931,9 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3 _palette->addPalette(calcHash("paKlayBlack"), 0, 65, 0); _palStatus = 0; } - + _palette->copyBasePalette(0, 256, 0); - + } void Scene2703::update() { @@ -981,16 +981,16 @@ uint32 Scene2703::handleMessage(int messageNum, const MessageParam ¶m, Entit } return 0; } - + Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint32 trackInfoId, int16 value, const uint32 *staticSprites, const NRect *clipRect) : Scene(vm, parentModule) { TrackInfo *tracks = _vm->_staticData->getTrackInfo(trackInfoId); - + SetMessageHandler(&Scene2704::handleMessage); SetUpdateHandler(&Scene2704::update); - + setBackground(tracks->bgFilename); setPalette(tracks->bgFilename); @@ -999,12 +999,12 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3 if (tracks->exPaletteFilename2) _palette->addPalette(tracks->exPaletteFilename2, 65, 31, 65); - + while (staticSprites && *staticSprites) insertStaticSprite(*staticSprites++, 1100); insertScreenMouse(tracks->mouseCursorFilename); - + if (tracks->bgShadowFilename) { _ssTrackShadowBackground = createSprite<SsCommonTrackShadowBackground>(tracks->bgShadowFilename); addEntity(_ssTrackShadowBackground); @@ -1024,7 +1024,7 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3 _dataResource.load(tracks->dataResourceFilename); _trackPoints = _dataResource.getPointArray(tracks->trackPointsName); _asCar->setPathPoints(_trackPoints); - + if (which == _which2) { NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1]; sendMessage(_asCar, 0x2002, _trackPoints->size() - 1); @@ -1040,21 +1040,21 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3 else sendMessage(_asCar, 0x2008, 0); } - + if (clipRect) { _asCar->getClipRect() = *clipRect; if (_asCarShadow) - _asCarShadow->getClipRect() = *clipRect; + _asCarShadow->getClipRect() = *clipRect; if (_asCarTrackShadow) - _asCarTrackShadow->getClipRect() = *clipRect; + _asCarTrackShadow->getClipRect() = *clipRect; if (_asCarConnectorShadow) - _asCarConnectorShadow->getClipRect() = *clipRect; + _asCarConnectorShadow->getClipRect() = *clipRect; if (_asCarConnector) _asCarConnector->getClipRect() = *clipRect; } } - + void Scene2704::update() { Scene::update(); if (_mouseClicked) { @@ -1083,24 +1083,24 @@ uint32 Scene2704::handleMessage(int messageNum, const MessageParam ¶m, Entit Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _newTrackIndex(-1) { - + SetMessageHandler(&Scene2706::handleMessage); - _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B22A0)); + _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B22A0)); _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B22C4)); _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B22E8)); - + setBackground(0x18808B88); setPalette(0x18808B88); - + _palette->addPalette(calcHash("paPodShade"), 65, 31, 65); _palette->addPalette(calcHash("paKlayShade"), 0, 65, 0); - + insertScreenMouse(0x08B8C180); _ssTrackShadowBackground = createSprite<SsCommonTrackShadowBackground>(0x18808B88); addEntity(_ssTrackShadowBackground); - + _asCar = insertSprite<AsCommonCar>(this, 320, 240); _asCarShadow = insertSprite<AsCommonCarShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4); _asCarConnector = insertSprite<AsCommonCarConnector>(_asCar); @@ -1108,10 +1108,10 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which) _asCarConnectorShadow = insertSprite<AsCommonCarConnectorShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4); _dataResource.load(0x06000162); - + if (which == 5) _currTrackIndex = 2; - else if (which == 6) + else if (which == 6) _currTrackIndex = 1; else _currTrackIndex = 0; @@ -1123,16 +1123,16 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which) sendMessage(_asCar, 0x2002, _trackPoints->size() - 1); if (which == 5) sendMessage(_asCar, 0x2007, 50); - else + else sendMessage(_asCar, 0x2007, 150); } else { sendMessage(_asCar, 0x2002, 0); if (which == 5) sendMessage(_asCar, 0x2008, 50); - else + else sendMessage(_asCar, 0x2008, 150); } - + } uint32 Scene2706::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -1192,7 +1192,7 @@ void Scene2706::changeTrack() { Scene2732::Scene2732(NeverhoodEngine *vm, Module *parentModule) : Scene(vm, parentModule) { - + Sprite *tempSprite; setBackground(0x0220C041); diff --git a/engines/neverhood/modules/module2700.h b/engines/neverhood/modules/module2700.h index 003666bb7f..158bb609e9 100644 --- a/engines/neverhood/modules/module2700.h +++ b/engines/neverhood/modules/module2700.h @@ -39,7 +39,7 @@ public: protected: int _sceneNum; int _soundIndex; - bool _raidoMusicInitialized; + bool _radioMusicInitialized; uint32 _scene2711StaticSprites[6]; uint32 _musicFileHash; void createScene(int sceneNum, int which); diff --git a/engines/neverhood/modules/module2800.cpp b/engines/neverhood/modules/module2800.cpp index 3d76d05762..1c0f9fc9fb 100644 --- a/engines/neverhood/modules/module2800.cpp +++ b/engines/neverhood/modules/module2800.cpp @@ -36,7 +36,7 @@ Module2800::Module2800(NeverhoodEngine *vm, Module *parentModule, int which) _currentMusicFileHash = 0; _vm->_soundMan->addMusic(0x64210814, 0xD2FA4D14); setGlobalVar(V_RADIO_MOVE_DISH_VIDEO, 1); - + if (which < 0) { createScene(_vm->gameState().sceneNum, which); } else if (which == 2) { @@ -224,7 +224,7 @@ void Module2800::updateScene() { _musicResource = NULL; } _currentMusicFileHash = 0; - } + } if (_moduleResult == 1) { createScene(2, 0); } else if (_moduleResult == 2) { @@ -251,7 +251,7 @@ void Module2800::updateScene() { createScene(9, 0); else if (_moduleResult == 5) createScene(25, 0); - else + else createScene(0, 1); break; case 3: @@ -318,7 +318,7 @@ void Module2800::updateScene() { createScene(22, 0); else if (_moduleResult == 22) createScene(23, 0); - else + else createScene(2, 4); break; case 10: @@ -331,7 +331,7 @@ void Module2800::updateScene() { createScene(26, 0); else if (_moduleResult == 3) createScene(9, 5); - else + else createScene(9, 1); break; case 12: @@ -401,7 +401,7 @@ void Module2800::updateMusic(bool halfVolume) { if (!_musicResource) _musicResource = new MusicResource(_vm); - + if (newMusicFileHash != _currentMusicFileHash) { _currentMusicFileHash = newMusicFileHash; if (_currentMusicFileHash != 0) { @@ -469,7 +469,7 @@ Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which) _klaymen->setClipRect(_sprite1->getDrawRect().x, 0, _sprite2->getDrawRect().x2(), 480); insertScreenMouse(0x0066201C); _asTape = insertSprite<AsScene1201Tape>(this, 8, 1100, 302, 437, 0x9148A011); - addCollisionSprite(_asTape); + addCollisionSprite(_asTape); } else if (getGlobalVar(V_RADIO_ROOM_RIGHT_DOOR)) { setRectList(0x004B6CD0); setBackground(0x11E00684); @@ -480,7 +480,7 @@ Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which) _klaymen->setClipRect(0, 0, _sprite2->getDrawRect().x2(), 480); insertScreenMouse(0x00680116); _asTape = insertSprite<SsScene1705Tape>(this, 8, 1100, 302, 437, 0x01142428); - addCollisionSprite(_asTape); + addCollisionSprite(_asTape); } else { setRectList(0x004B6CF0); setBackground(0x030006E6); @@ -491,9 +491,9 @@ Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which) _klaymen->setClipRect(0, 0, _sprite2->getDrawRect().x2(), 480); insertScreenMouse(0x006E2038); _asTape = insertSprite<AsScene1201Tape>(this, 8, 1100, 302, 437, 0x9148A011); - addCollisionSprite(_asTape); + addCollisionSprite(_asTape); } - + addEntity(_palette); if (which == 1) { @@ -503,7 +503,7 @@ Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which) _palette->addPalette(_paletteHash, 0, 65, 0); _palette->addBasePalette(_paletteHash, 0, 65, 0); } - + } Scene2801::~Scene2801() { @@ -565,7 +565,7 @@ Scene2802::~Scene2802() { } setGlobalVar(V_CURR_RADIO_MUSIC_INDEX, _currRadioMusicIndex); } - + void Scene2802::update() { int prevTuneStatus = _currTuneStatus; uint prevRadioMusicIndex = _currRadioMusicIndex; @@ -577,7 +577,7 @@ void Scene2802::update() { _currTuneStatus = 3; else if (_currTuneStatus == 4) _currTuneStatus = 6; - + switch (_currTuneStatus) { case 2: if (_currRadioMusicIndex < 90) @@ -607,20 +607,20 @@ void Scene2802::update() { } else _currTuneStatus = 0; break; - + } if (prevRadioMusicIndex != _currRadioMusicIndex) _smackerPlayer->gotoFrame(_currRadioMusicIndex); - + if (prevTuneStatus != _currTuneStatus) changeTuneStatus(prevTuneStatus, _currTuneStatus); - + if (getGlobalVar(V_RADIO_MOVE_DISH_VIDEO) && prevTuneStatus != _currTuneStatus && _currRadioMusicIndex != 0) { setGlobalVar(V_RADIO_MOVE_DISH_VIDEO, 0); leaveScene(1); } - + } uint32 Scene2802::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -758,7 +758,7 @@ void AsScene2803LightCord::setFileHashes(uint32 fileHash1, uint32 fileHash2) { AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2) : AnimatedSprite(vm, 1200), _fileHash1(fileHash1), _fileHash2(fileHash2) { - + createSurface1(fileHash1, 100); SetUpdateHandler(&AnimatedSprite::update); SetMessageHandler(&AsScene2803TestTubeOne::handleMessage); @@ -781,7 +781,7 @@ uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x) : AnimatedSprite(vm, 1100), _parentScene(parentScene) { - + createSurface(990, 68, 476); SetUpdateHandler(&AnimatedSprite::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); @@ -837,7 +837,7 @@ void AsScene2803Rope::stHide() { Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _paletteArea(0) { - + static const uint32 kScene2803FileHashes1[] = { 0, 0x081000F1, @@ -854,20 +854,20 @@ Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which) setGlobalVar(V_BEEN_SHRINKING_ROOM, 1); _vm->gameModule()->initTestTubes1Puzzle(); - + SetMessageHandler(&Scene2803::handleMessage); - + loadDataResource(0x00900849); - + _background = new Background(_vm, 0); _background->createSurface(0, 640, 480); addBackground(_background); - + setPalette(0x412A423E); addEntity(_palette); - + insertScreenMouse(0xA423A41A); - + if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0) == 0) { _asTestTubeOne = (StaticSprite*)insertStaticSprite(0x66121222, 100); } else { @@ -875,13 +875,13 @@ Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which) kScene2803FileHashes1[getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0)], kScene2803FileHashes2[getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0)]); } - + if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1) == 3) _asTestTubeTwo = (StaticSprite*)insertStaticSprite(0x64330236, 100); if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2) == 3) _asTestTubeThree = (StaticSprite*)insertStaticSprite(0x2E4A22A2, 100); - + _asLightCord = insertSprite<AsScene2803LightCord>(this, 0x8FAD5932, 0x276E1A3D, 578, 200); _sprite3 = (StaticSprite*)insertStaticSprite(0xA40EF2FB, 1100); _sprite4 = (StaticSprite*)insertStaticSprite(0x0C03AA23, 1100); @@ -896,7 +896,7 @@ Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which) _clipRectsFloor[0].y1 = 0; _clipRectsFloor[0].x2 = 640; _clipRectsFloor[0].y2 = _sprite8->getDrawRect().y2(); - + _clipRectsFloor[1].x1 = _sprite8->getDrawRect().x2(); _clipRectsFloor[1].y1 = _sprite8->getDrawRect().y2(); _clipRectsFloor[1].x2 = 640; @@ -906,12 +906,12 @@ Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which) _clipRectsStairs[0].y1 = 0; _clipRectsStairs[0].x2 = _sprite5->getDrawRect().x2(); _clipRectsStairs[0].y2 = _sprite5->getDrawRect().y2(); - + _clipRectsStairs[1].x1 = _sprite6->getDrawRect().x; _clipRectsStairs[1].y1 = 0; _clipRectsStairs[1].x2 = _sprite3->getDrawRect().x; _clipRectsStairs[1].y2 = _sprite6->getDrawRect().y2(); - + _clipRectsStairs[2].x1 = _sprite3->getDrawRect().x; _clipRectsStairs[2].y1 = 0; _clipRectsStairs[2].x2 = _sprite4->getDrawRect().x2(); @@ -1112,7 +1112,7 @@ Scene2803Small::Scene2803Small(NeverhoodEngine *vm, Module *parentModule, int wh static const uint32 kScene2803SmallFileHashes2[] = { 0, 0x286800D4, 0x286806D4, 0x28680AD4 }; - + SetMessageHandler(&Scene2803Small::handleMessage); loadDataResource(0x81120132); @@ -1160,7 +1160,7 @@ Scene2803Small::Scene2803Small(NeverhoodEngine *vm, Module *parentModule, int wh if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2) == 3) insertStaticSprite(0x30022689, 100); } - + _sprite6->setVisible(false); _sprite7->setVisible(false); @@ -1352,7 +1352,7 @@ void Scene2803Small::updatePaletteArea(bool instantly) { SsScene2804RedButton::SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene) : StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene) { - + loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? 0x51A10202 : 0x11814A21, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); setVisible(false); SetUpdateHandler(&SsScene2804RedButton::update); @@ -1385,7 +1385,7 @@ uint32 SsScene2804RedButton::handleMessage(int messageNum, const MessageParam &p SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm) : StaticSprite(vm, 900) { - + loadSprite(0x8889B008, kSLFDefDrawOffset | kSLFDefPosition, 400); setVisible(false); SetMessageHandler(&SsScene2804LightCoil::handleMessage); @@ -1410,7 +1410,7 @@ uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam &p SsScene2804LightTarget::SsScene2804LightTarget(NeverhoodEngine *vm) : StaticSprite(vm, 900) { - + loadSprite(0x06092132, kSLFDefDrawOffset | kSLFDefPosition, 400); setVisible(false); SetMessageHandler(&SsScene2804LightTarget::handleMessage); @@ -1435,7 +1435,7 @@ uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam SsScene2804Flash::SsScene2804Flash(NeverhoodEngine *vm) : StaticSprite(vm, 900) { - + loadSprite(0x211003A0, kSLFDefDrawOffset | kSLFDefPosition, 400); setVisible(false); loadSound(0, 0xCB36BA54); @@ -1449,7 +1449,7 @@ void SsScene2804Flash::show() { SsScene2804BeamCoilBody::SsScene2804BeamCoilBody(NeverhoodEngine *vm) : StaticSprite(vm, 900) { - + loadSprite(0x9A816000, kSLFDefDrawOffset | kSLFDefPosition, 400); setVisible(false); } @@ -1585,7 +1585,7 @@ SsScene2804CrystalButton::SsScene2804CrystalButton(NeverhoodEngine *vm, Scene280 0xA8042525, 0x5008292B }; - + loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? kSsScene2804CrystalButtonFileHashes1[crystalIndex] : kSsScene2804CrystalButtonFileHashes2[crystalIndex], kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); setVisible(false); @@ -1619,7 +1619,7 @@ uint32 SsScene2804CrystalButton::handleMessage(int messageNum, const MessagePara AsScene2804BeamCoil::AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody) : AnimatedSprite(vm, 1400), _parentScene(parentScene), _ssBeamCoilBody(ssBeamCoilBody), _countdown(0) { - + createSurface1(0x00494891, 1000); _x = 125; _y = 184; @@ -1659,7 +1659,7 @@ uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam &pa } return messageResult; } - + void AsScene2804BeamCoil::show() { _ssBeamCoilBody->setVisible(true); setVisible(true); @@ -1695,7 +1695,7 @@ uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam ¶m, AsScene2804BeamTarget::AsScene2804BeamTarget(NeverhoodEngine *vm) : AnimatedSprite(vm, 1400) { - + createSurface1(0x03842000, 1000); _x = 475; _y = 278; @@ -1750,7 +1750,7 @@ Scene2804::Scene2804(NeverhoodEngine *vm, Module *parentModule, int which) _asTarget = insertSprite<AsScene2804BeamTarget>(); _ssFlash = insertSprite<SsScene2804Flash>(); } - + _ssRedButton = insertSprite<SsScene2804RedButton>(this); addCollisionSprite(_ssRedButton); @@ -1797,7 +1797,7 @@ uint32 Scene2804::handleMessage(int messageNum, const MessageParam ¶m, Entit void Scene2804::update() { Scene::update(); - + if (_countdown1 != 0 && (--_countdown1) == 0) { leaveScene(0); } @@ -1836,7 +1836,7 @@ void Scene2804::update() { Scene2805::Scene2805(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + SetMessageHandler(&Scene2805::handleMessage); setBackground(0x08021E04); @@ -1894,7 +1894,7 @@ uint32 Scene2805::handleMessage(int messageNum, const MessageParam ¶m, Entit AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm) : AnimatedSprite(vm, 1200) { - + createSurface1(0x04211490, 1200); _x = 378; _y = 423; @@ -1919,7 +1919,7 @@ uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam ¶m, } return messageResult; } - + Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { @@ -1927,16 +1927,16 @@ Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which) SetMessageHandler(&Scene2806::handleMessage); SetUpdateHandler(&Scene2806::update); - + loadDataResource(0x98182003); loadHitRectList(); - + _pointList = _dataResource.getPointArray(0x3606A422); - insertScreenMouse(0x22114C13); + insertScreenMouse(0x22114C13); setBackground(0xC1B22110); setPalette(0xC1B22110); - + _sprite1 = insertStaticSprite(0xA21F82CB, 1100); _clipRects[0].x1 = _sprite1->getDrawRect().x; _clipRects[0].y1 = _sprite1->getDrawRect().y; @@ -1951,7 +1951,7 @@ Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which) _sprite4 = insertStaticSprite(0x72090342, 1100); _clipRects[1].x1 = _sprite4->getDrawRect().x; _clipRects[1].y1 = _sprite4->getDrawRect().y; - + tempSprite = insertStaticSprite(0xD2012C02, 1100); _clipRects[2].x1 = tempSprite->getDrawRect().x; _clipRects[2].y2 = tempSprite->getDrawRect().y2(); @@ -2027,7 +2027,7 @@ void Scene2806::findClosestPoint() { int16 x = MIN<int16>(_klaymen->getX(), 639); int index = 1; - + while (index < (int)_pointList->size() && (*_pointList)[index].x < x) ++index; --index; @@ -2036,12 +2036,12 @@ void Scene2806::findClosestPoint() { _pointIndex = index; _palette->addPalette(kScene2806PaletteFileHashes[index], 0, 64, 0); } - + } Scene2807::Scene2807(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { - + SetMessageHandler(&Scene2807::handleMessage); if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0) == 1) { @@ -2136,7 +2136,7 @@ static const int16 kClass490FrameIndices2[] = { SsScene2808Dispenser::SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex) : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _testTubeSetNum(testTubeSetNum), _testTubeIndex(testTubeIndex) { - + loadSprite(kClass428FileHashes[testTubeSetNum * 3 + testTubeIndex], kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1500); setVisible(false); SetUpdateHandler(&SsScene2808Dispenser::update); @@ -2149,7 +2149,7 @@ void SsScene2808Dispenser::update() { setVisible(false); } } - + uint32 SsScene2808Dispenser::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); switch (messageNum) { @@ -2197,16 +2197,16 @@ AsScene2808TestTube::AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum loadSound(7, 0x70A43D2D); loadSound(8, 0xF0601E2D); } - + startAnimation(kClass490FileHashes[testTubeIndex], 0, -1); _newStickFrameIndex = 0; - + SetUpdateHandler(&AnimatedSprite::update); SetMessageHandler(&AsScene2808TestTube::handleMessage); - + if (_fillLevel == 0) setVisible(false); - + } uint32 AsScene2808TestTube::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -2253,7 +2253,7 @@ void AsScene2808TestTube::flush() { AsScene2808Handle::AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum) : AnimatedSprite(vm, 1300), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum), _isActivated(false) { - + loadSound(0, 0xE18D1F30); _x = 320; _y = 240; @@ -2325,7 +2325,7 @@ AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int te SetUpdateHandler(&AnimatedSprite::update); AnimatedSprite::updatePosition(); } - + uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); switch (messageNum) { @@ -2351,7 +2351,7 @@ void AsScene2808Flow::stKeepFlowing() { AsScene2808LightEffect::AsScene2808LightEffect(NeverhoodEngine *vm, int testTubeSetNum) : AnimatedSprite(vm, 800), _countdown(1) { - + _x = 320; _y = 240; if (testTubeSetNum == 1) @@ -2381,7 +2381,7 @@ Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which) _vm->gameModule()->initTestTubes1Puzzle(); else _vm->gameModule()->initTestTubes2Puzzle(); - + SetMessageHandler(&Scene2808::handleMessage); SetUpdateHandler(&Scene2808::update); @@ -2400,7 +2400,7 @@ Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which) _asTestTubes[testTubeIndex] = insertSprite<AsScene2808TestTube>(which, testTubeIndex, ssDispenser); addCollisionSprite(_asTestTubes[testTubeIndex]); } - + insertScreenMouse(kScene2808FileHashes2[which]); } @@ -2498,13 +2498,13 @@ Scene2809::Scene2809(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { Sprite *tempSprite; - + SetMessageHandler(&Scene2809::handleMessage); SetUpdateHandler(&Scene2809::update); - + loadDataResource(0x1830009A); loadHitRectList(); - + _pointList = _dataResource.getPointArray(0x064A310E); setBackground(0xB22116C5); @@ -2535,7 +2535,7 @@ Scene2809::Scene2809(NeverhoodEngine *vm, Module *parentModule, int which) tempSprite = insertStaticSprite(0x877F6252, 1100); _clipRects[3].x2 = tempSprite->getDrawRect().x2(); - + insertStaticSprite(0x01612A22, 1100); insertStaticSprite(0x877F6252, 1100); @@ -2610,7 +2610,7 @@ void Scene2809::findClosestPoint() { _pointIndex = index; _palette->addPalette(kScene2809PaletteFileHashes[index], 0, 64, 0); } - + } AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x) @@ -2647,7 +2647,7 @@ Scene2810::Scene2810(NeverhoodEngine *vm, Module *parentModule, int which) Sprite *tempSprite; SetMessageHandler(&Scene2810::handleMessage); - + setBackground(0x26508804); setPalette(0x26508804); insertScreenMouse(0x0880026D); @@ -2683,7 +2683,7 @@ Scene2810::Scene2810(NeverhoodEngine *vm, Module *parentModule, int which) } _sprite4->setClipRect(0, _sprite1->getDrawRect().y, 640, 480); } - + if (which < 0) { if (getGlobalVar(V_KLAYMEN_SMALL)) { insertKlaymen<KmScene2810Small>(240, 448); @@ -2864,7 +2864,7 @@ uint32 Scene2810::handleMessage(int messageNum, const MessageParam ¶m, Entit AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm) : AnimatedSprite(vm, 1100) { - + createSurface1(0x20DA08A0, 1200); SetUpdateHandler(&AnimatedSprite::update); SetMessageHandler(&AsScene2812Winch::handleMessage); @@ -2895,7 +2895,7 @@ uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam ¶m AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene) : AnimatedSprite(vm, 1100), _parentScene(parentScene) { - + createSurface(990, 68, 476); SetUpdateHandler(&AnimatedSprite::update); SetMessageHandler(&AsScene2812Rope::handleMessage); @@ -2940,7 +2940,7 @@ void AsScene2812Rope::stRopingDown() { AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm) : AnimatedSprite(vm, 0x805D0029, 100, 320, 240) { - + SetMessageHandler(&AsScene2812TrapDoor::handleMessage); _newStickFrameIndex = 0; } @@ -2959,15 +2959,15 @@ uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &pa Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _paletteArea(0) { - + if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0) setGlobalVar(V_KEY3_LOCATION, 3); SetMessageHandler(&Scene2812::handleMessage); SetUpdateHandler(&Scene2812::update); - + setRectList(0x004AF700); - + setBackground(0x03600606); setPalette(0x03600606); addEntity(_palette); @@ -2983,7 +2983,7 @@ Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which) _ssTape = insertSprite<SsScene1705Tape>(this, 6, 1100, 513, 437, 0xA1361863); addCollisionSprite(_ssTape); - + _asWinch = insertSprite<AsScene2812Winch>(); _asTrapDoor = insertSprite<AsScene2812TrapDoor>(); _asRope = insertSprite<AsScene2812Rope>(this); @@ -3023,9 +3023,9 @@ Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which) _sprite1->setVisible(false); _klaymen->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2()); } - + _asRope->setClipRect(0, _sprite2->getDrawRect().y, 640, _sprite3->getDrawRect().y2()); - + } void Scene2812::update() { @@ -3120,7 +3120,7 @@ Scene2822::Scene2822(NeverhoodEngine *vm, Module *parentModule, int which) addBackground(_background); _background->getSurface()->getDrawRect().y = -10; setPalette(0xD542022E); - insertPuzzleMouse(0x0028D089, 20, 620); + insertPuzzleMouse(0x2022AD5C, 20, 620); _ssButton = insertStaticSprite(0x1A4D4120, 1100); _ssButton->setVisible(false); loadSound(2, 0x19044E72); @@ -3140,7 +3140,7 @@ void Scene2822::update() { _ssButton->setVisible(false); _countdownStatus = 1; _countdown = 48; - } else if (_countdownStatus == 1) { + } else if (_countdownStatus == 1 && getGlobalVar(V_LADDER_DOWN_ACTION)) { playSound(0, 0x1384CB60); _countdownStatus = 2; _countdown = 12; diff --git a/engines/neverhood/modules/module2800.h b/engines/neverhood/modules/module2800.h index fe62f11307..54a9daeb16 100644 --- a/engines/neverhood/modules/module2800.h +++ b/engines/neverhood/modules/module2800.h @@ -79,7 +79,7 @@ public: protected: Scene *_parentScene; uint32 _fileHash1, _fileHash2; - bool _isPulled, _isBusy; + bool _isPulled, _isBusy; uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); uint32 hmPulled(int messageNum, const MessageParam ¶m, Entity *sender); }; @@ -323,7 +323,7 @@ protected: Scene *_parentScene; int _countdown; int _testTubeSetNum, _testTubeIndex; - void update(); + void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); }; @@ -408,7 +408,7 @@ protected: Sprite *_sprite3; Sprite *_sprite4; Sprite *_asSpew; - void update(); + void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); void findClosestPoint(); }; diff --git a/engines/neverhood/modules/module2900.cpp b/engines/neverhood/modules/module2900.cpp index 248fb81bdc..9e51001a2e 100644 --- a/engines/neverhood/modules/module2900.cpp +++ b/engines/neverhood/modules/module2900.cpp @@ -36,7 +36,7 @@ Module2900::Module2900(NeverhoodEngine *vm, Module *parentModule, int which) if (which >= 0) setGlobalVar(V_TELEPORTER_WHICH, which); - + createScene(0, 0); } @@ -255,7 +255,7 @@ SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene : StaticSprite(vm, 900), _parentScene(parentScene), _index(index), _countdown1(0) { const NPoint &pt = kSsScene2901LocationButtonPoints[_index]; - + loadSprite(kSsScene2901LocationButtonFileHashes[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 800); _collisionBounds.set(pt.x - 25, pt.y - 25, pt.x + 25, pt.y + 25); setVisible(false); @@ -263,7 +263,7 @@ SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene SetUpdateHandler(&SsScene2901LocationButton::update); SetMessageHandler(&SsScene2901LocationButton::handleMessage); } - + void SsScene2901LocationButton::update() { updatePosition(); if (_countdown1 != 0 && (--_countdown1) == 0) { @@ -289,7 +289,7 @@ uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessagePar SsScene2901LocationButtonLight::SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index) : StaticSprite(vm, 900), _index(index) { - + loadSprite(kSsScene2901LocationButtonLightFileHashes1[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 900); setVisible(false); loadSound(0, kSsScene2901LocationButtonLightFileHashes2[_index]); @@ -315,7 +315,7 @@ SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which) SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which) : StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) { - loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400); + loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400); _collisionBounds.set(62, 94, 322, 350); setVisible(false); loadSound(0, 0xF3D420C8); @@ -330,7 +330,7 @@ void SsScene2901BigButton::update() { sendMessage(_parentScene, 0x2000, 0); } } - + uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); switch (messageNum) { @@ -361,7 +361,7 @@ Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which) setBackground(kScene2901FileHashes1[_currLocationButtonNum]); setPalette(kScene2901FileHashes1[_currLocationButtonNum]); - + for (uint i = 0; i < 6; ++i) { if (i != 2 || !_isButton2Broken) { _ssLocationButtons[i] = insertSprite<SsScene2901LocationButton>(this, _currLocationButtonNum, i); @@ -369,7 +369,7 @@ Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which) _ssLocationButtonLights[i] = insertSprite<SsScene2901LocationButtonLight>(_currLocationButtonNum, i); } } - + if (_isButton2Broken) insertSprite<SsScene2901BrokenButton>(_currLocationButtonNum); @@ -377,10 +377,10 @@ Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which) addCollisionSprite(_ssBigButton); insertPuzzleMouse(kScene2901FileHashes2[_currLocationButtonNum], 20, 620); - + SetUpdateHandler(&Scene2901::update); SetMessageHandler(&Scene2901::handleMessage); - + } void Scene2901::update() { diff --git a/engines/neverhood/modules/module2900.h b/engines/neverhood/modules/module2900.h index 75b29567f6..142f39a35c 100644 --- a/engines/neverhood/modules/module2900.h +++ b/engines/neverhood/modules/module2900.h @@ -49,7 +49,7 @@ protected: Scene *_parentScene; uint _index; int _countdown1; - void update(); + void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); }; @@ -74,7 +74,7 @@ protected: Scene *_parentScene; int _which; int _countdown1; - void update(); + void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); }; diff --git a/engines/neverhood/modules/module3000.cpp b/engines/neverhood/modules/module3000.cpp index 373bfb57f6..ab3c18d1f4 100644 --- a/engines/neverhood/modules/module3000.cpp +++ b/engines/neverhood/modules/module3000.cpp @@ -39,7 +39,7 @@ static const uint32 kModule3000SoundList[] = { Module3000::Module3000(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule), _soundVolume(0) { - + _vm->_soundMan->addSoundList(0x81293110, kModule3000SoundList); _vm->_soundMan->setSoundListParams(kModule3000SoundList, true, 50, 600, 5, 150); _vm->_soundMan->setSoundParams(0x90F0D1C3, false, 20000, 30000, 20000, 30000); @@ -49,7 +49,7 @@ Module3000::Module3000(NeverhoodEngine *vm, Module *parentModule, int which) _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0; - if (_isWallBroken) { + if (!_isWallBroken) { _vm->_soundMan->setSoundVolume(0x90F0D1C3, 0); _vm->_soundMan->playSoundLooping(0x90F0D1C3); } @@ -73,15 +73,16 @@ Module3000::~Module3000() { } void Module3000::createScene(int sceneNum, int which) { - static const byte kNavigationTypes05[] = {3, 0}; + static const byte kNavigationTypes05[] = {2, 0}; static const byte kNavigationTypes06[] = {5}; debug(1, "Module3000::createScene(%d, %d)", sceneNum, which); _vm->gameState().sceneNum = sceneNum; + _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0; switch (_vm->gameState().sceneNum) { case 1: if (!getGlobalVar(V_BOLT_DOOR_OPEN)) { createNavigationScene(0x004B7C80, which); - } else if (getGlobalVar(V_WALL_BROKEN)) { + } else if (_isWallBroken) { createNavigationScene(0x004B7CE0, which); } else { createNavigationScene(0x004B7CB0, which); @@ -89,11 +90,11 @@ void Module3000::createScene(int sceneNum, int which) { break; case 2: _vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0); - if (_isWallBroken) { + if (!_isWallBroken) { _soundVolume = 90; _vm->_soundMan->setSoundVolume(0x90F0D1C3, 90); } - if (getGlobalVar(V_WALL_BROKEN)) { + if (_isWallBroken) { createNavigationScene(0x004B7D58, which); } else { createNavigationScene(0x004B7D10, which); @@ -102,7 +103,7 @@ void Module3000::createScene(int sceneNum, int which) { case 3: if (getGlobalVar(V_STAIRS_DOWN)) createNavigationScene(0x004B7E60, which); - else if (getGlobalVar(V_WALL_BROKEN)) + else if (_isWallBroken) createNavigationScene(0x004B7DA0, which); else createNavigationScene(0x004B7E00, which); @@ -150,12 +151,12 @@ void Module3000::createScene(int sceneNum, int which) { // NOTE: Newly introduced sceneNums case 1001: if (!getGlobalVar(V_BOLT_DOOR_OPEN)) - if (getGlobalVar(V_WALL_BROKEN)) + if (_isWallBroken) createSmackerScene(0x00940021, true, true, false); else createSmackerScene(0x01140021, true, true, false); else - if (getGlobalVar(V_WALL_BROKEN)) + if (_isWallBroken) createSmackerScene(0x001011B1, true, true, false); else createSmackerScene(0x001021B1, true, true, false); @@ -299,7 +300,7 @@ void Module3000::updateScene() { } else if (frameNumber == 10) { _vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0); } - if (_isWallBroken && _soundVolume < 90 && frameNumber % 2) { + if (!_isWallBroken && _soundVolume < 90 && frameNumber % 2) { if (frameNumber == 0) _soundVolume = 40; else @@ -313,7 +314,7 @@ void Module3000::updateScene() { if (navigationScene()->isWalkingForward()) { uint32 frameNumber = navigationScene()->getFrameNumber(); int navigationIndex = navigationScene()->getNavigationIndex(); - if (_isWallBroken && _soundVolume > 1 && frameNumber % 2) { + if (!_isWallBroken && _soundVolume > 1 && frameNumber % 2) { _soundVolume--; _vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume); } @@ -338,7 +339,7 @@ void Module3000::updateScene() { if (frameNumber == 40) { _vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0); } - if (_isWallBroken && _soundVolume < 90 && frameNumber % 2) { + if (!_isWallBroken && _soundVolume < 90 && frameNumber % 2) { if (frameNumber == 0) _soundVolume = 40; else @@ -439,7 +440,7 @@ static const uint32 kAsScene3009SymbolFileHashes[] = { }; static const uint32 kSsScene3009SymbolArrowFileHashes1[] = { - 0x24016060, + 0x24016060, 0x21216221, 0x486160A0, 0x42216422, @@ -454,7 +455,7 @@ static const uint32 kSsScene3009SymbolArrowFileHashes1[] = { }; static const uint32 kSsScene3009SymbolArrowFileHashes2[] = { - 0x40092024, + 0x40092024, 0x01636002, 0x8071E028, 0x02A56064, @@ -470,7 +471,7 @@ static const uint32 kSsScene3009SymbolArrowFileHashes2[] = { SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene) : StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) { - + loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); setVisible(false); SetUpdateHandler(&SsScene3009FireCannonButton::update); @@ -636,7 +637,7 @@ uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const Message AsScene3009HorizontalIndicator::AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus) : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) { - + _x = getGlobalVar(V_CANNON_TURNED) ? 533 : 92; _y = 150; createSurface1(0xC0C12954, 1200); @@ -701,7 +702,7 @@ AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene : AnimatedSprite(vm, 1100), _parentScene(parentScene), _symbolPosition(symbolPosition) { _symbolIndex = getSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition); - + _x = kAsScene3009SymbolPoints[_symbolPosition].x; _y = kAsScene3009SymbolPoints[_symbolPosition].y; createSurface1(kAsScene3009SymbolFileHashes[_symbolPosition / 3], 1200); @@ -752,17 +753,17 @@ void AsScene3009Symbol::hide() { } Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which) - : Scene(vm, parentModule), _keepVideo(false), _moveCannonLeftFirst(false), + : Scene(vm, parentModule), _keepVideo(false), _moveCannonLeftFirst(false), _isTurning(false), _lockSymbolsPart1Countdown(1), _lockSymbolsPart2Countdown(1) { _cannonTargetStatus = getGlobalVar(V_CANNON_TARGET_STATUS); - + _vm->gameModule()->initCannonSymbolsPuzzle(); - + setGlobalVar(V_CANNON_SMACKER_NAME, 0); - + _vm->_screen->clear(); - + setBackground(0xD000420C); setPalette(0xD000420C); insertPuzzleMouse(0x04208D08, 20, 620); @@ -820,7 +821,7 @@ void Scene3009::openSmacker(uint32 fileHash, bool keepLastFrame) { void Scene3009::update() { Scene::update(); - + if (!_keepVideo && _cannonSmackerPlayer->isDone() && _cannonTargetStatus <= kCTSCount) { switch (_cannonTargetStatus) { case kCTSNull: @@ -849,9 +850,9 @@ void Scene3009::update() { if (_moveCannonLeftFirst) { if (_cannonTargetStatus == kCTSLeftRobotNoTarget) openSmacker(0x110A000F, false); - else if (_cannonTargetStatus == kCTSLeftRobotIsTarget) + else if (_cannonTargetStatus == kCTSLeftRobotIsTarget) openSmacker(0x500B004F, false); - else if (_cannonTargetStatus == kCTSLeftNoRobot) + else if (_cannonTargetStatus == kCTSLeftNoRobot) openSmacker(0x100B010E, false); _moveCannonLeftFirst = false; _asHorizontalIndicator->stMoveLeft(); @@ -1118,7 +1119,7 @@ AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene loadSound(0, 0x420073DC); loadSound(1, 0x420073DC); } - + setVisible(false); stIdle(); if (initUnlocked) @@ -1126,7 +1127,7 @@ AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene _needRefresh = true; AnimatedSprite::updatePosition(); - + } void AsScene3010DeadBolt::update() { @@ -1216,7 +1217,7 @@ void AsScene3010DeadBolt::stDisabledMessage() { Scene3010::Scene3010(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule), _countdown(0), _doorUnlocked(false), _checkUnlocked(false) { - + int initCountdown = 0; setBackground(0x80802626); @@ -1347,7 +1348,7 @@ static const uint32 kAsScene3011SymbolFileHashes[] = { SsScene3011Button::SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag) : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) { - + loadSprite(flag ? 0x11282020 : 0x994D0433, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); setVisible(false); loadSound(0, 0x44061000); @@ -1445,7 +1446,7 @@ Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which) SetMessageHandler(&Scene3011::handleMessage); SetUpdateHandler(&Scene3011::update); - + setBackground(0x92124A04); setPalette(0xA4070114); addEntity(_palette); @@ -1457,12 +1458,12 @@ Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which) _ssButton = insertSprite<SsScene3011Button>(this, true); addCollisionSprite(_ssButton); - + } void Scene3011::update() { Scene::update(); - + if (_countdown != 0 && (--_countdown == 0)) { switch (_updateStatus) { case 0: diff --git a/engines/neverhood/modules/module3000.h b/engines/neverhood/modules/module3000.h index 797be1885f..a6cecb227e 100644 --- a/engines/neverhood/modules/module3000.h +++ b/engines/neverhood/modules/module3000.h @@ -244,7 +244,7 @@ protected: bool _buttonClicked; int _countdown; int _noisySymbolIndex; - int _currentSymbolIndex; + int _currentSymbolIndex; int _noisyRandomSymbolIndex; void update(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); diff --git a/engines/neverhood/mouse.cpp b/engines/neverhood/mouse.cpp index 632f56fb74..13fba41e92 100644 --- a/engines/neverhood/mouse.cpp +++ b/engines/neverhood/mouse.cpp @@ -26,9 +26,9 @@ namespace Neverhood { Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, const NRect &mouseRect) - : StaticSprite(vm, 2000), _mouseType(kMouseType433), + : StaticSprite(vm, 2000), _mouseType(kMouseType433), _mouseCursorResource(vm), _frameNum(0) { - + _mouseRect = mouseRect; init(fileHash); if (_x >= _mouseRect.x1 && _x <= _mouseRect.x2 && @@ -43,7 +43,7 @@ Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, const NRect &mouseRect) Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, int16 x1, int16 x2) : StaticSprite(vm, 2000), _mouseType(kMouseType435), _mouseCursorResource(vm), _frameNum(0), _x1(x1), _x2(x2) { - + init(fileHash); if (_x <= _x1) { _mouseCursorResource.setCursorNum(6); @@ -69,8 +69,8 @@ Mouse::~Mouse() { void Mouse::init(uint32 fileHash) { _mouseCursorResource.load(fileHash); - _x = _vm->getMouseX(); - _y = _vm->getMouseY(); + _x = _vm->getMouseX(); + _y = _vm->getMouseY(); createSurface(2000, 32, 32); SetUpdateHandler(&Mouse::update); SetMessageHandler(&Mouse::handleMessage); @@ -99,7 +99,7 @@ void Mouse::update() { _frameNum++; if (_frameNum >= 6) _frameNum = 0; - _needRefresh = _frameNum % 2 == 0; + _needRefresh = _frameNum % 2 == 0; } uint32 Mouse::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -113,40 +113,40 @@ uint32 Mouse::handleMessage(int messageNum, const MessageParam ¶m, Entity *s case 1: if (_x >= 320) messageResult = 1; - else + else messageResult = 0; break; case 2: default: if (_x < 100) messageResult = 0; - else if (_x > 540) + else if (_x > 540) messageResult = 1; - else + else messageResult = 2; break; case 3: if (_x < 100) messageResult = 0; - else if (_x > 540) + else if (_x > 540) messageResult = 1; - else + else messageResult = 4; break; case 4: if (_x < 100) messageResult = 0; - else if (_x > 540) + else if (_x > 540) messageResult = 1; - else if (_y >= 150) + else if (_y >= 150) messageResult = 2; - else + else messageResult = 3; break; case 5: if (_y >= 240) messageResult = 4; - else + else messageResult = 3; break; } @@ -162,7 +162,7 @@ uint32 Mouse::handleMessage(int messageNum, const MessageParam ¶m, Entity *s } void Mouse::updateCursor() { - + if (!_surface) return; @@ -213,44 +213,44 @@ void Mouse::updateCursorNum() { case 1: if (_x >= 320) _mouseCursorResource.setCursorNum(5); - else + else _mouseCursorResource.setCursorNum(6); break; case 2: default: if (_x < 100) _mouseCursorResource.setCursorNum(6); - else if (_x > 540) + else if (_x > 540) _mouseCursorResource.setCursorNum(5); - else + else _mouseCursorResource.setCursorNum(0); break; case 3: if (_x < 100) _mouseCursorResource.setCursorNum(1); - else if (_x > 540) + else if (_x > 540) _mouseCursorResource.setCursorNum(1); break; case 4: if (_x < 100) _mouseCursorResource.setCursorNum(6); - else if (_x > 540) + else if (_x > 540) _mouseCursorResource.setCursorNum(5); - else if (_y >= 150) + else if (_y >= 150) _mouseCursorResource.setCursorNum(0); - else + else _mouseCursorResource.setCursorNum(3); break; case 5: if (_y >= 240) _mouseCursorResource.setCursorNum(2); - else + else _mouseCursorResource.setCursorNum(3); break; } break; } - + } } // End of namespace Neverhood diff --git a/engines/neverhood/mouse.h b/engines/neverhood/mouse.h index 0b927de4df..d6f42b4071 100644 --- a/engines/neverhood/mouse.h +++ b/engines/neverhood/mouse.h @@ -52,7 +52,7 @@ protected: int16 _x1; int16 _x2; int _type; - void init(uint32 fileHash); + void init(uint32 fileHash); void update(); void updateCursorNum(); uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); diff --git a/engines/neverhood/navigationscene.cpp b/engines/neverhood/navigationscene.cpp index 33e2a264a8..51ab96ef37 100644 --- a/engines/neverhood/navigationscene.cpp +++ b/engines/neverhood/navigationscene.cpp @@ -25,31 +25,35 @@ namespace Neverhood { +enum AreaType { + kAreaCanMoveForward = 0, + kAreaCannotMoveForward = 1 +}; + NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, const byte *itemsTypes) : Scene(vm, parentModule), _itemsTypes(itemsTypes), _navigationIndex(navigationIndex), _smackerDone(false), _isWalkingForward(false), _isTurning(false), _smackerFileHash(0), _interactive(true), _leaveSceneAfter(false) { _navigationList = _vm->_staticData->getNavigationList(navigationListId); - + if (_navigationIndex < 0) { _navigationIndex = (int)getGlobalVar(V_NAVIGATION_INDEX); if (_navigationIndex >= (int)_navigationList->size()) - _navigationIndex = 0; + _navigationIndex = 0; } setGlobalVar(V_NAVIGATION_INDEX, _navigationIndex); - + SetUpdateHandler(&NavigationScene::update); SetMessageHandler(&NavigationScene::handleMessage); - - _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true)); - + + _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true)); + createMouseCursor(); _vm->_screen->clear(); _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder()); sendMessage(_parentModule, 0x100A, _navigationIndex); - } NavigationScene::~NavigationScene() { @@ -95,7 +99,7 @@ void NavigationScene::update() { _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder()); sendMessage(_parentModule, 0x100A, _navigationIndex); } - } + } Scene::update(); } @@ -121,39 +125,34 @@ uint32 NavigationScene::handleMessage(int messageNum, const MessageParam ¶m, } void NavigationScene::createMouseCursor() { - const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex]; uint32 mouseCursorFileHash; int areaType; - if (_mouseCursor) { + if (_mouseCursor) deleteSprite((Sprite**)&_mouseCursor); - } mouseCursorFileHash = navigationItem.mouseCursorFileHash; if (mouseCursorFileHash == 0) mouseCursorFileHash = 0x63A40028; - - if (_itemsTypes) { + + if (_itemsTypes) areaType = _itemsTypes[_navigationIndex]; - } else if (navigationItem.middleSmackerFileHash != 0 || navigationItem.middleFlag) { - areaType = 0; - } else { - areaType = 1; - } + else if (navigationItem.middleSmackerFileHash != 0 || navigationItem.middleFlag) + areaType = kAreaCanMoveForward; + else + areaType = kAreaCannotMoveForward; insertNavigationMouse(mouseCursorFileHash, areaType); sendPointMessage(_mouseCursor, 0x4002, _vm->getMousePos()); - } void NavigationScene::handleNavigation(const NPoint &mousePos) { - const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex]; bool oldIsWalkingForward = _isWalkingForward; bool oldIsTurning = _isTurning; uint32 direction = sendPointMessage(_mouseCursor, 0x2064, mousePos); - + switch (direction) { case 0: if (navigationItem.leftSmackerFileHash != 0) { @@ -204,13 +203,12 @@ void NavigationScene::handleNavigation(const NPoint &mousePos) { } break; } - + if (oldIsTurning != _isTurning) _vm->_soundMan->setSoundThreePlayFlag(_isTurning); if (oldIsWalkingForward != _isWalkingForward) _vm->_soundMan->setTwoSoundsPlayFlag(_isWalkingForward); - } } // End of namespace Neverhood diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp index d60d8b760f..061e6d1279 100644 --- a/engines/neverhood/neverhood.cpp +++ b/engines/neverhood/neverhood.cpp @@ -77,6 +77,9 @@ Common::Error NeverhoodEngine::run() { _gameState.sceneNum = 0; _gameState.which = 0; + // Assign default values to the config manager, in case settings are missing + ConfMan.registerDefault("originalsaveload", "false"); + _staticData = new StaticData(); _staticData->load("neverhood.dat"); _gameVars = new GameVars(); @@ -101,9 +104,9 @@ Common::Error NeverhoodEngine::run() { _soundMan = new SoundMan(this); _audioResourceMan = new AudioResourceMan(this); - + _gameModule = new GameModule(this); - + _isSaveAllowed = true; _updateSound = true; @@ -119,14 +122,15 @@ Common::Error NeverhoodEngine::run() { (*navigationList)[5].middleSmackerFileHash = 0; (*navigationList)[5].middleFlag = 1; } - - if (ConfMan.hasKey("save_slot")) - loadGameState(ConfMan.getInt("save_slot")); - else + + if (ConfMan.hasKey("save_slot")) { + if (loadGameState(ConfMan.getInt("save_slot")).getCode() != Common::kNoError) + _gameModule->startup(); + } else _gameModule->startup(); - + mainLoop(); - + delete _gameModule; delete _soundMan; delete _audioResourceMan; @@ -137,7 +141,7 @@ Common::Error NeverhoodEngine::run() { delete _gameVars; delete _staticData; - + return Common::kNoError; } diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h index 39bc9cef2c..5643e345ad 100644 --- a/engines/neverhood/neverhood.h +++ b/engines/neverhood/neverhood.h @@ -93,7 +93,7 @@ public: AudioResourceMan *_audioResourceMan; public: - + /* Save/load */ enum kReadSaveHeaderError { @@ -118,12 +118,12 @@ public: bool canLoadGameStateCurrently() { return _isSaveAllowed; } bool canSaveGameStateCurrently() { return _isSaveAllowed; } - + Common::Error loadGameState(int slot); Common::Error saveGameState(int slot, const Common::String &description); Common::Error removeGameState(int slot); - void savegame(const char *filename, const char *description); - void loadgame(const char *filename); + bool savegame(const char *filename, const char *description); + bool loadgame(const char *filename); const char *getSavegameFilename(int num); static Common::String getSavegameFilename(const Common::String &target, int num); static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header); diff --git a/engines/neverhood/palette.cpp b/engines/neverhood/palette.cpp index d4b9b67f53..c381f46671 100644 --- a/engines/neverhood/palette.cpp +++ b/engines/neverhood/palette.cpp @@ -81,7 +81,7 @@ void Palette::addPalette(uint32 fileHash, int toIndex, int count, int fromIndex) if (toIndex + count > 256) count = 256 - toIndex; paletteResource.load(fileHash); - memcpy(_palette + toIndex * 4, paletteResource.palette() + fromIndex * 4, count * 4); + memcpy(_palette + toIndex * 4, paletteResource.palette() + fromIndex * 4, count * 4); _vm->_screen->testPalette(_palette); } @@ -90,20 +90,20 @@ void Palette::addBasePalette(uint32 fileHash, int toIndex, int count, int fromIn if (toIndex + count > 256) count = 256 - toIndex; paletteResource.load(fileHash); - memcpy(_basePalette + toIndex * 4, paletteResource.palette() + fromIndex * 4, count * 4); + memcpy(_basePalette + toIndex * 4, paletteResource.palette() + fromIndex * 4, count * 4); } void Palette::copyPalette(const byte *palette, int toIndex, int count, int fromIndex) { if (toIndex + count > 256) count = 256 - toIndex; - memcpy(_palette + toIndex * 4, palette + fromIndex * 4, count * 4); + memcpy(_palette + toIndex * 4, palette + fromIndex * 4, count * 4); _vm->_screen->testPalette(_palette); } void Palette::copyBasePalette(int toIndex, int count, int fromIndex) { if (toIndex + count > 256) count = 256 - toIndex; - memcpy(_basePalette + toIndex * 4, _palette + fromIndex * 4, count * 4); + memcpy(_basePalette + toIndex * 4, _palette + fromIndex * 4, count * 4); } void Palette::startFadeToBlack(int counter) { @@ -115,7 +115,7 @@ void Palette::startFadeToBlack(int counter) { _fadeToB = 0; _palCounter = counter; _fadeStep = 255 / counter; - _status = 1; + _status = 1; } void Palette::startFadeToWhite(int counter) { @@ -127,7 +127,7 @@ void Palette::startFadeToWhite(int counter) { _fadeToB = 255; _palCounter = counter; _fadeStep = 255 / counter; - _status = 1; + _status = 1; } void Palette::startFadeToPalette(int counter) { @@ -136,7 +136,7 @@ void Palette::startFadeToPalette(int counter) { counter = 1; _palCounter = counter; _fadeStep = 255 / counter; - _status = 2; + _status = 2; } void Palette::fillBaseWhite(int index, int count) { diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp index 442713196e..5f7aea86f4 100644 --- a/engines/neverhood/resource.cpp +++ b/engines/neverhood/resource.cpp @@ -57,7 +57,7 @@ bool SpriteResource::load(uint32 fileHash, bool doLoadPosition) { const byte *spriteData = _resourceHandle.data(); NPoint *position = doLoadPosition ? &_position : NULL; parseBitmapResource(spriteData, &_rle, &_dimensions, position, NULL, &_pixels); - } + } return _pixels != NULL; } @@ -134,11 +134,11 @@ bool AnimResource::load(uint32 fileHash) { return true; unload(); - + _vm->_res->queryResource(fileHash, _resourceHandle); if (!_resourceHandle.isValid() || _resourceHandle.type() != kResTypeAnimation) return false; - + const byte *resourceData, *animList, *frameList; uint16 animInfoStartOfs, animListIndex, animListCount; uint16 frameListStartOfs, frameCount; @@ -146,20 +146,20 @@ bool AnimResource::load(uint32 fileHash) { _vm->_res->loadResource(_resourceHandle); resourceData = _resourceHandle.data(); - + animListCount = READ_LE_UINT16(resourceData); animInfoStartOfs = READ_LE_UINT16(resourceData + 2); spriteDataOfs = READ_LE_UINT32(resourceData + 4); paletteDataOfs = READ_LE_UINT32(resourceData + 8); - + animList = resourceData + 12; for (animListIndex = 0; animListIndex < animListCount; animListIndex++) { debug(8, "hash: %08X", READ_LE_UINT32(animList)); if (READ_LE_UINT32(animList) == fileHash) break; - animList += 8; + animList += 8; } - + if (animListIndex >= animListCount) { _vm->_res->unloadResource(_resourceHandle); return false; @@ -168,12 +168,12 @@ bool AnimResource::load(uint32 fileHash) { _spriteData = resourceData + spriteDataOfs; if (paletteDataOfs > 0) _paletteData = resourceData + paletteDataOfs; - + frameCount = READ_LE_UINT16(animList + 4); frameListStartOfs = READ_LE_UINT16(animList + 6); - + debug(8, "frameCount = %d; frameListStartOfs = %04X; animInfoStartOfs = %04X", frameCount, frameListStartOfs, animInfoStartOfs); - + frameList = resourceData + animInfoStartOfs + frameListStartOfs; _frames.clear(); @@ -189,13 +189,13 @@ bool AnimResource::load(uint32 fileHash) { frameInfo.drawOffset.height = READ_LE_UINT16(frameList + 12); frameInfo.deltaX = READ_LE_UINT16(frameList + 14); frameInfo.deltaY = READ_LE_UINT16(frameList + 16); - frameInfo.collisionBoundsOffset.x = READ_LE_UINT16(frameList + 18); - frameInfo.collisionBoundsOffset.y = READ_LE_UINT16(frameList + 20); - frameInfo.collisionBoundsOffset.width = READ_LE_UINT16(frameList + 22); + frameInfo.collisionBoundsOffset.x = READ_LE_UINT16(frameList + 18); + frameInfo.collisionBoundsOffset.y = READ_LE_UINT16(frameList + 20); + frameInfo.collisionBoundsOffset.width = READ_LE_UINT16(frameList + 22); frameInfo.collisionBoundsOffset.height = READ_LE_UINT16(frameList + 24); frameInfo.spriteDataOffs = READ_LE_UINT32(frameList + 28); - debug(8, "frameHash = %08X; counter = %d; rect = (%d,%d,%d,%d); deltaX = %d; deltaY = %d; collisionBoundsOffset = (%d,%d,%d,%d); spriteDataOffs = %08X", - frameInfo.frameHash, frameInfo.counter, + debug(8, "frameHash = %08X; counter = %d; rect = (%d,%d,%d,%d); deltaX = %d; deltaY = %d; collisionBoundsOffset = (%d,%d,%d,%d); spriteDataOffs = %08X", + frameInfo.frameHash, frameInfo.counter, frameInfo.drawOffset.x, frameInfo.drawOffset.y, frameInfo.drawOffset.width, frameInfo.drawOffset.height, frameInfo.deltaX, frameInfo.deltaY, frameInfo.collisionBoundsOffset.x, frameInfo.collisionBoundsOffset.y, frameInfo.collisionBoundsOffset.width, frameInfo.collisionBoundsOffset.height, @@ -203,11 +203,11 @@ bool AnimResource::load(uint32 fileHash) { frameList += 32; _frames.push_back(frameInfo); } - + _fileHash = fileHash; return true; - + } void AnimResource::unload() { @@ -229,7 +229,7 @@ int16 AnimResource::getFrameIndex(uint32 frameHash) { break; } debug(2, "AnimResource::getFrameIndex(%08X) -> %d", frameHash, frameIndex); - return frameIndex; + return frameIndex; } void AnimResource::setRepl(byte oldColor, byte newColor) { @@ -254,7 +254,7 @@ NDimensions AnimResource::loadSpriteDimensions(uint32 fileHash) { // MouseCursorResource -MouseCursorResource::MouseCursorResource(NeverhoodEngine *vm) +MouseCursorResource::MouseCursorResource(NeverhoodEngine *vm) : _cursorSprite(vm), _cursorNum(4), _currFileHash(0) { _rect.width = 32; @@ -265,7 +265,7 @@ void MouseCursorResource::load(uint32 fileHash) { if (_currFileHash != fileHash) { if (_cursorSprite.load(fileHash) && !_cursorSprite.isRle() && _cursorSprite.getDimensions().width == 96 && _cursorSprite.getDimensions().height == 224) { - _currFileHash = fileHash; + _currFileHash = fileHash; } else { unload(); } @@ -296,14 +296,14 @@ NDrawRect& MouseCursorResource::getRect() { void MouseCursorResource::draw(int frameNum, Graphics::Surface *destSurface) { if (_cursorSprite.getPixels()) { const int sourcePitch = (_cursorSprite.getDimensions().width + 3) & 0xFFFC; // 4 byte alignment - const int destPitch = destSurface->pitch; + const int destPitch = destSurface->pitch; const byte *source = _cursorSprite.getPixels() + _cursorNum * (sourcePitch * 32) + frameNum * 32; byte *dest = (byte*)destSurface->pixels; for (int16 yc = 0; yc < 32; yc++) { memcpy(dest, source, 32); source += sourcePitch; dest += destPitch; - } + } } } @@ -311,7 +311,7 @@ void MouseCursorResource::draw(int frameNum, Graphics::Surface *destSurface) { TextResource::TextResource(NeverhoodEngine *vm) : _vm(vm), _textData(NULL), _count(0) { - + } TextResource::~TextResource() { @@ -372,7 +372,7 @@ void DataResource::load(uint32 fileHash) { dataS.seek(2 + i * 8); DRDirectoryItem drDirectoryItem; drDirectoryItem.nameHash = dataS.readUint32LE(); - drDirectoryItem.offset = dataS.readUint16LE(); + drDirectoryItem.offset = dataS.readUint16LE(); drDirectoryItem.type = dataS.readUint16LE(); debug(2, "%03d nameHash = %08X; offset = %04X; type = %d", i, drDirectoryItem.nameHash, drDirectoryItem.offset, drDirectoryItem.type); dataS.seek(itemStartOffs + drDirectoryItem.offset); @@ -415,7 +415,7 @@ void DataResource::load(uint32 fileHash) { hitRect.rect.y1 = dataS.readUint16LE(); hitRect.rect.x2 = dataS.readUint16LE(); hitRect.rect.y2 = dataS.readUint16LE(); - hitRect.type = dataS.readUint16LE() + 0x5001; + hitRect.type = dataS.readUint16LE() + 0x5001; debug(3, "(%d, %d, %d, %d) -> %04d", hitRect.rect.x1, hitRect.rect.y1, hitRect.rect.x2, hitRect.rect.y2, hitRect.type); hitRectList->push_back(hitRect); } @@ -491,7 +491,7 @@ void DataResource::load(uint32 fileHash) { break; } } - _directory.push_back(drDirectoryItem); + _directory.push_back(drDirectoryItem); } } } @@ -540,12 +540,12 @@ HitRectList *DataResource::getHitRectList() { MessageList *DataResource::getMessageListAtPos(int16 klaymenX, int16 klaymenY, int16 mouseX, int16 mouseY) { for (uint i = 0; i < _drRects.size(); i++) { - if (klaymenX >= _drRects[i].rect.x1 && klaymenX <= _drRects[i].rect.x2 && + if (klaymenX >= _drRects[i].rect.x1 && klaymenX <= _drRects[i].rect.x2 && klaymenY >= _drRects[i].rect.y1 && klaymenY <= _drRects[i].rect.y2) { - DRSubRectList *drSubRectList = _drSubRectLists[_drRects[i].subRectIndex]; + DRSubRectList *drSubRectList = _drSubRectLists[_drRects[i].subRectIndex]; for (uint j = 0; j < drSubRectList->size(); j++) { DRSubRect &subRect = (*drSubRectList)[j]; - if (mouseX >= subRect.rect.x1 && mouseX <= subRect.rect.x2 && + if (mouseX >= subRect.rect.x1 && mouseX <= subRect.rect.x2 && mouseY >= subRect.rect.y1 && mouseY <= subRect.rect.y2) { return _messageLists[subRect.messageListItemIndex]; } diff --git a/engines/neverhood/resource.h b/engines/neverhood/resource.h index 6a84a69ecd..40236d9d22 100644 --- a/engines/neverhood/resource.h +++ b/engines/neverhood/resource.h @@ -168,7 +168,7 @@ protected: struct DRDirectoryItem { uint32 nameHash; - uint16 offset; + uint16 offset; uint16 type; }; @@ -195,7 +195,7 @@ protected: Common::Array<MessageList*> _messageLists; Common::Array<DRRect> _drRects; Common::Array<DRSubRectList*> _drSubRectLists; - DataResource::DRDirectoryItem *findDRDirectoryItem(uint32 nameHash, uint16 type); + DataResource::DRDirectoryItem *findDRDirectoryItem(uint32 nameHash, uint16 type); }; uint32 calcHash(const char *value); diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp index d5e7786c17..37089a5bd6 100644 --- a/engines/neverhood/resourceman.cpp +++ b/engines/neverhood/resourceman.cpp @@ -49,7 +49,7 @@ void ResourceMan::addArchive(const Common::String &filename) { if (archiveEntry->timeStamp > entry->archiveEntry->timeStamp) { entry->archive = archive; entry->archiveEntry = archiveEntry; - } + } } else { ResourceFileEntry newEntry; newEntry.resourceHandle = -1; diff --git a/engines/neverhood/saveload.cpp b/engines/neverhood/saveload.cpp index 578d9858ff..01988769e6 100644 --- a/engines/neverhood/saveload.cpp +++ b/engines/neverhood/saveload.cpp @@ -61,12 +61,12 @@ NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::Se return ((in->eos() || in->err()) ? kRSHEIoError : kRSHENoError); } -void NeverhoodEngine::savegame(const char *filename, const char *description) { +bool NeverhoodEngine::savegame(const char *filename, const char *description) { Common::OutSaveFile *out; if (!(out = g_system->getSavefileManager()->openForSaving(filename))) { warning("Can't create file '%s', game not saved", filename); - return; + return false; } TimeDate curTime; @@ -78,7 +78,7 @@ void NeverhoodEngine::savegame(const char *filename, const char *description) { byte descriptionLen = strlen(description); out->writeByte(descriptionLen); out->write(description, descriptionLen); - + Graphics::saveThumbnail(*out); // Not used yet, reserved for future usage @@ -96,50 +96,53 @@ void NeverhoodEngine::savegame(const char *filename, const char *description) { _gameVars->setGlobalVar(V_CURRENT_SCENE_WHICH, _gameState.which); _gameVars->saveState(out); - + out->finalize(); delete out; + return true; } -void NeverhoodEngine::loadgame(const char *filename) { +bool NeverhoodEngine::loadgame(const char *filename) { Common::InSaveFile *in; if (!(in = g_system->getSavefileManager()->openForLoading(filename))) { warning("Can't open file '%s', game not loaded", filename); - return; + return false; } SaveHeader header; kReadSaveHeaderError errorCode = readSaveHeader(in, false, header); - + if (errorCode != kRSHENoError) { warning("Error loading savegame '%s'", filename); delete in; - return; + return false; } - + g_engine->setTotalPlayTime(header.playTime * 1000); _gameVars->loadState(in); - + _gameState.sceneNum = _gameVars->getGlobalVar(V_CURRENT_SCENE); _gameState.which = _gameVars->getGlobalVar(V_CURRENT_SCENE_WHICH); _gameModule->requestRestoreGame(); delete in; - + return true; } Common::Error NeverhoodEngine::loadGameState(int slot) { const char *fileName = getSavegameFilename(slot); - loadgame(fileName); + if (!loadgame(fileName)) + return Common::kReadingFailed; return Common::kNoError; } Common::Error NeverhoodEngine::saveGameState(int slot, const Common::String &description) { const char *fileName = getSavegameFilename(slot); - savegame(fileName, description.c_str()); + if (!savegame(fileName, description.c_str())) + return Common::kWritingFailed; return Common::kNoError; } diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp index 80a2b69169..e76a9ca521 100644 --- a/engines/neverhood/scene.cpp +++ b/engines/neverhood/scene.cpp @@ -28,7 +28,7 @@ namespace Neverhood { Scene::Scene(NeverhoodEngine *vm, Module *parentModule) : Entity(vm, 0), _parentModule(parentModule), _dataResource(vm), _hitRects(NULL), _mouseCursorWasVisible(true) { - + _isKlaymenBusy = false; _doConvertMessages = false; _messageList = NULL; @@ -50,10 +50,10 @@ Scene::Scene(NeverhoodEngine *vm, Module *parentModule) _smackerPlayer = NULL; _isMessageListBusy = false; _messageValue = -1; - + SetUpdateHandler(&Scene::update); SetMessageHandler(&Scene::handleMessage); - + _vm->_screen->clearRenderQueue(); } @@ -71,7 +71,7 @@ Scene::~Scene() { delete *iter; // Don't delete surfaces since they always belong to an entity - + // Purge the resources after each scene _vm->_res->purgeResources(); @@ -84,7 +84,7 @@ void Scene::draw() { } else { for (Common::Array<BaseSurface*>::iterator iter = _surfaces.begin(); iter != _surfaces.end(); iter++) (*iter)->draw(); - } + } } void Scene::addEntity(Entity *entity) { @@ -99,7 +99,7 @@ void Scene::addEntity(Entity *entity) { if (insertIndex >= 0) _entities.insert_at(insertIndex, entity); else - _entities.push_back(entity); + _entities.push_back(entity); } bool Scene::removeEntity(Entity *entity) { @@ -108,7 +108,7 @@ bool Scene::removeEntity(Entity *entity) { _entities.remove_at(index); return true; } - return false; + return false; } void Scene::addSurface(BaseSurface *surface) { @@ -124,7 +124,7 @@ void Scene::addSurface(BaseSurface *surface) { if (insertIndex >= 0) _surfaces.insert_at(insertIndex, surface); else - _surfaces.push_back(surface); + _surfaces.push_back(surface); } } @@ -135,7 +135,7 @@ bool Scene::removeSurface(BaseSurface *surface) { return true; } } - return false; + return false; } void Scene::printSurfaces(Console *con) { @@ -246,12 +246,12 @@ void Scene::update() { if (_mouseClicked) { if (_klaymen) { if (_canAcceptInput && - _klaymen->hasMessageHandler() && + _klaymen->hasMessageHandler() && sendMessage(_klaymen, 0x1008, 0) != 0 && queryPositionSprite(_mouseClickPos.x, _mouseClickPos.y)) { _mouseClicked = false; } else if (_canAcceptInput && - _klaymen->hasMessageHandler() && + _klaymen->hasMessageHandler() && sendMessage(_klaymen, 0x1008, 0) != 0) { _mouseClicked = !queryPositionRectList(_mouseClickPos.x, _mouseClickPos.y); } @@ -262,7 +262,7 @@ void Scene::update() { processMessageList(); - // Update all entities + // Update all entities for (Common::Array<Entity*>::iterator iter = _entities.begin(); iter != _entities.end(); iter++) (*iter)->handleUpdate(); @@ -283,7 +283,7 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam ¶m, Entity *s _mouseClickPos = param.asPoint(); break; case 0x0006: - sendMessage(_parentModule, 0x1009, param); + sendMessage(_parentModule, 0x1009, param); break; case 0x1006: // Sent by Klaymen when its animation sequence has finished @@ -332,7 +332,7 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam ¶m, Entity *s bool Scene::queryPositionSprite(int16 mouseX, int16 mouseY) { for (uint i = 0; i < _collisionSprites.size(); i++) { Sprite *sprite = _collisionSprites[i]; - if (sprite->hasMessageHandler() && sprite->isPointInside(mouseX, mouseY) && + if (sprite->hasMessageHandler() && sprite->isPointInside(mouseX, mouseY) && sendPointMessage(sprite, 0x1011, _mouseClickPos) != 0) { return true; } @@ -412,8 +412,8 @@ void Scene::processMessageList() { _messageList2 = NULL; _messageListStatus = 0; } - - if (_messageList && _klaymen) { + + if (_messageList && _klaymen) { #if 0 debug("MessageList: %p, %d", (void*)_messageList, _messageList->size()); @@ -423,11 +423,11 @@ void Scene::processMessageList() { } debug("--------------------------------"); #endif - + while (_messageList && _messageListIndex < _messageListCount && !_isKlaymenBusy) { uint32 messageNum = (*_messageList)[_messageListIndex].messageNum; uint32 messageParam = (*_messageList)[_messageListIndex].messageValue; - + ++_messageListIndex; if (_messageListIndex == _messageListCount) sendMessage(_klaymen, 0x1021, 0); @@ -460,7 +460,7 @@ void Scene::processMessageList() { if (_klaymen->hasMessageHandler() && sendMessage(_klaymen, messageNum, messageParam) != 0) { _isKlaymenBusy = false; } - } + } if (_messageListIndex == _messageListCount) { _canAcceptInput = true; _messageList = NULL; @@ -469,7 +469,7 @@ void Scene::processMessageList() { } _isMessageListBusy = false; - + } void Scene::cancelMessageList() { @@ -531,7 +531,7 @@ uint16 Scene::convertMessageNum(uint32 messageNum) { case 0x42002200: return 0x4004; case 0x428D4894: - return 0x101A; + return 0x101A; } return 0x1000; } @@ -546,7 +546,7 @@ HitRect *Scene::findHitRectAtPos(int16 x, int16 y) { for (HitRectList::iterator it = _hitRects->begin(); it != _hitRects->end(); it++) if ((*it).rect.contains(x, y)) return &(*it); - return &kDefaultHitRect; + return &kDefaultHitRect; } void Scene::addCollisionSprite(Sprite *sprite) { @@ -561,7 +561,7 @@ void Scene::addCollisionSprite(Sprite *sprite) { if (insertIndex >= 0) _collisionSprites.insert_at(insertIndex, sprite); else - _collisionSprites.push_back(sprite); + _collisionSprites.push_back(sprite); } void Scene::removeCollisionSprite(Sprite *sprite) { @@ -583,7 +583,7 @@ void Scene::checkCollision(Sprite *sprite, uint16 flags, int messageNum, uint32 if ((sprite->getFlags() & flags) && collSprite->checkCollision(sprite->getCollisionBounds())) { sprite->sendMessage(collSprite, messageNum, messageParam); } - } + } } void Scene::insertMouse(Mouse *mouseCursor) { diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h index 813ffba0bb..5e42e34418 100644 --- a/engines/neverhood/scene.h +++ b/engines/neverhood/scene.h @@ -76,89 +76,89 @@ public: void checkCollision(Sprite *sprite, uint16 flags, int messageNum, uint32 messageParam); // Some crazy templated functions to make the logic code smaller/simpler (imo!) // insertKlaymen - template<class T> + template<class T> void insertKlaymen() { _klaymen = (T*)addSprite(new T(_vm, this)); } - template<class T, class Arg1> + template<class T, class Arg1> void insertKlaymen(Arg1 arg1) { _klaymen = (T*)addSprite(new T(_vm, this, arg1)); } - template<class T, class Arg1, class Arg2> + template<class T, class Arg1, class Arg2> void insertKlaymen(Arg1 arg1, Arg2 arg2) { _klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2)); } - template<class T, class Arg1, class Arg2, class Arg3> + template<class T, class Arg1, class Arg2, class Arg3> void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3) { _klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3)); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4> void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { _klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4)); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { _klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4, arg5)); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { _klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4, arg5, arg6)); } // insertSprite - template<class T> + template<class T> T* insertSprite() { return (T*)addSprite(new T(_vm)); } - template<class T, class Arg1> + template<class T, class Arg1> T* insertSprite(Arg1 arg1) { return (T*)addSprite(new T(_vm, arg1)); } - template<class T, class Arg1, class Arg2> + template<class T, class Arg1, class Arg2> T* insertSprite(Arg1 arg1, Arg2 arg2) { return (T*)addSprite(new T(_vm, arg1, arg2)); } - template<class T, class Arg1, class Arg2, class Arg3> + template<class T, class Arg1, class Arg2, class Arg3> T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3) { return (T*)addSprite(new T(_vm, arg1, arg2, arg3)); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4> T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4)); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4, arg5)); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6)); } // createSprite - template<class T> + template<class T> T* createSprite() { return new T(_vm); } - template<class T, class Arg1> + template<class T, class Arg1> T* createSprite(Arg1 arg1) { return new T(_vm, arg1); } - template<class T, class Arg1, class Arg2> + template<class T, class Arg1, class Arg2> T* createSprite(Arg1 arg1, Arg2 arg2) { return new T(_vm, arg1, arg2); } - template<class T, class Arg1, class Arg2, class Arg3> + template<class T, class Arg1, class Arg2, class Arg3> T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3) { return new T(_vm, arg1, arg2, arg3); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4> T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { return new T(_vm, arg1, arg2, arg3, arg4); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { return new T(_vm, arg1, arg2, arg3, arg4, arg5); } - template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> + template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { return new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6); } diff --git a/engines/neverhood/screen.cpp b/engines/neverhood/screen.cpp index 5a748cfab4..4a5bfb92ce 100644 --- a/engines/neverhood/screen.cpp +++ b/engines/neverhood/screen.cpp @@ -28,16 +28,16 @@ namespace Neverhood { Screen::Screen(NeverhoodEngine *vm) : _vm(vm), _paletteData(NULL), _paletteChanged(false), _smackerDecoder(NULL), _yOffset(0), _fullRefresh(false) { - + _ticks = _vm->_system->getMillis(); - + _backScreen = new Graphics::Surface(); _backScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); - + _renderQueue = new RenderQueue(); _prevRenderQueue = new RenderQueue(); _microTiles = new MicroTileArray(640, 480); - + } Screen::~Screen() { @@ -72,13 +72,13 @@ void Screen::update() { } } } - + for (RenderQueue::iterator jt = _prevRenderQueue->begin(); jt != _prevRenderQueue->end(); ++jt) { RenderItem &prevRenderItem = (*jt); if (prevRenderItem._refresh) _microTiles->addRect(Common::Rect(prevRenderItem._destX, prevRenderItem._destY, prevRenderItem._destX + prevRenderItem._width, prevRenderItem._destY + prevRenderItem._height)); } - + for (RenderQueue::iterator it = _renderQueue->begin(); it != _renderQueue->end(); ++it) { RenderItem &renderItem = (*it); if (renderItem._refresh) @@ -93,7 +93,7 @@ void Screen::update() { for (RectangleList::iterator ri = updateRects->begin(); ri != updateRects->end(); ++ri) blitRenderItem(renderItem, *ri); } - + SWAP(_renderQueue, _prevRenderQueue); _renderQueue->clear(); @@ -202,12 +202,12 @@ void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, destX = drawRect.x; ddRect.x1 = 0; } - + if (drawRect.y + drawRect.height >= clipRect.y2) ddRect.y2 = clipRect.y2 - drawRect.y; else ddRect.y2 = drawRect.height; - + if (drawRect.y < clipRect.y1) { destY = clipRect.y1; ddRect.y1 = clipRect.y1 - drawRect.y; @@ -215,7 +215,7 @@ void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, destY = drawRect.y; ddRect.y1 = 0; } - + queueBlit(surface, destX, destY, ddRect, transparent, version, shadowSurface); } @@ -224,12 +224,12 @@ void Screen::drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, ND int16 destX, destY; NRect ddRect; - + if (x + drawRect.width >= clipRect.x2) ddRect.x2 = clipRect.x2 - drawRect.x - x; else ddRect.x2 = drawRect.x + drawRect.width; - + if (x < clipRect.x1) { destX = clipRect.x1; ddRect.x1 = clipRect.x1 + drawRect.x - x; @@ -242,7 +242,7 @@ void Screen::drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, ND ddRect.y2 = clipRect.y2 + drawRect.y - y; else ddRect.y2 = drawRect.y + drawRect.height; - + if (y < clipRect.y1) { destY = clipRect.y1; ddRect.y1 = clipRect.y1 + drawRect.y - y; @@ -250,7 +250,7 @@ void Screen::drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, ND destY = y; ddRect.y1 = drawRect.y; } - + queueBlit(surface, destX, destY, ddRect, transparent, version); } @@ -270,13 +270,13 @@ void Screen::drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &dra dest += _backScreen->pitch; dest += _backScreen->pitch; } - + _fullRefresh = true; // See Screen::update } void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDrawRect &sysRect, NRect &clipRect, bool transparent, byte version) { - + int16 x, y; bool xflag, yflag; NDrawRect newDrawRect; @@ -292,26 +292,26 @@ void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDra y = y % sysRect.height; if (y < 0) y += sysRect.height; - + xflag = x <= 0; yflag = y <= 0; - + newDrawRect.x = x; newDrawRect.width = sysRect.width - x; if (drawRect.width < newDrawRect.width) { xflag = true; newDrawRect.width = drawRect.width; } - + newDrawRect.y = y; newDrawRect.height = sysRect.height - y; if (drawRect.height < newDrawRect.height) { yflag = true; newDrawRect.height = drawRect.height; } - + drawSurface3(surface, drawRect.x, drawRect.y, newDrawRect, clipRect, transparent, version); - + if (!xflag) { newDrawRect.x = 0; newDrawRect.y = y; @@ -321,7 +321,7 @@ void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDra newDrawRect.height = drawRect.height; drawSurface3(surface, sysRect.width + drawRect.x - x, drawRect.y, newDrawRect, clipRect, transparent, version); } - + if (!yflag) { newDrawRect.x = x; newDrawRect.y = 0; @@ -331,7 +331,7 @@ void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDra newDrawRect.width = drawRect.width; drawSurface3(surface, drawRect.x, sysRect.height + drawRect.y - y, newDrawRect, clipRect, transparent, version); } - + if (!xflag && !yflag) { newDrawRect.x = 0; newDrawRect.y = 0; @@ -350,13 +350,13 @@ void Screen::drawSurfaceClipRects(const Graphics::Surface *surface, NDrawRect &d void Screen::queueBlit(const Graphics::Surface *surface, int16 destX, int16 destY, NRect &ddRect, bool transparent, byte version, const Graphics::Surface *shadowSurface) { - + const int width = ddRect.x2 - ddRect.x1; const int height = ddRect.y2 - ddRect.y1; if (width <= 0 || height <= 0) return; - + RenderItem renderItem; renderItem._surface = surface; renderItem._shadowSurface = shadowSurface; @@ -369,7 +369,7 @@ void Screen::queueBlit(const Graphics::Surface *surface, int16 destX, int16 dest renderItem._transparent = transparent; renderItem._version = version; _renderQueue->push_back(renderItem); - + } void Screen::blitRenderItem(const RenderItem &renderItem, const Common::Rect &clipRect) { diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp index 21d8851f48..187939faee 100644 --- a/engines/neverhood/smackerplayer.cpp +++ b/engines/neverhood/smackerplayer.cpp @@ -79,22 +79,22 @@ void SmackerDoubleSurface::draw() { void NeverhoodSmackerDecoder::forceSeekToFrame(uint frame) { if (!isVideoLoaded()) return; - + if (frame >= getFrameCount()) error("Can't force Smacker seek to invalid frame %d", frame); - + if (_header.audioInfo[0].hasAudio) error("Can't force Smacker frame seek with audio"); if (!rewind()) error("Failed to rewind"); - + SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0); uint32 offset = 0; for (uint32 i = 0; i < frame; i++) { videoTrack->increaseCurFrame(); offset += _frameSizes[i] & ~3; } - + _fileStream->seek(offset, SEEK_CUR); } @@ -124,7 +124,7 @@ SmackerPlayer::~SmackerPlayer() { void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) { debug(0, "SmackerPlayer::open(%08X)", fileHash); - + _fileHash = fileHash; _keepLastFrame = keepLastFrame; @@ -136,13 +136,13 @@ void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) { _smackerDecoder = new NeverhoodSmackerDecoder(); _smackerDecoder->loadStream(_stream); - + _palette = new Palette(_vm); _palette->usePalette(); if (!_paused) _smackerDecoder->start(); - + } void SmackerPlayer::close() { @@ -212,7 +212,7 @@ void SmackerPlayer::update() { _videoDone = false; } } - + } void SmackerPlayer::updateFrame() { @@ -240,7 +240,7 @@ void SmackerPlayer::updateFrame() { if (_smackerDecoder->hasDirtyPalette()) updatePalette(); - + } void SmackerPlayer::updatePalette() { diff --git a/engines/neverhood/smackerplayer.h b/engines/neverhood/smackerplayer.h index f13b653757..dd7199dd6d 100644 --- a/engines/neverhood/smackerplayer.h +++ b/engines/neverhood/smackerplayer.h @@ -62,7 +62,7 @@ public: void close(); void gotoFrame(int frameNumber); uint32 getFrameCount(); - uint32 getFrameNumber(); + uint32 getFrameNumber(); uint getStatus(); void setDrawPos(int16 x, int16 y); void rewind(); diff --git a/engines/neverhood/smackerscene.cpp b/engines/neverhood/smackerscene.cpp index 115aafe5be..d9d032a3b5 100644 --- a/engines/neverhood/smackerscene.cpp +++ b/engines/neverhood/smackerscene.cpp @@ -31,16 +31,16 @@ SmackerScene::SmackerScene(NeverhoodEngine *vm, Module *parentModule, bool doubl debug(0, "SmackerScene::SmackerScene(%d, %d, %d)", doubleSurface, canSkip, canAbort); // NOTE: Merged from SmackerScene::init, maybe split again if needed (incl. parameter flags) - + if (getGlobalVar(V_SMACKER_CAN_ABORT)) { _canSkip = true; _canAbort = true; } - + if (!_doubleSurface) _vm->_screen->clear(); - _fileHash[0] = 0; + _fileHash[0] = 0; _fileHash[1] = 0; SetUpdateHandler(&SmackerScene::update); @@ -67,7 +67,7 @@ void SmackerScene::nextVideo() { debug(0, "SmackerScene::nextVideo()"); _fileHashListIndex++; - + if (_fileHashList && _fileHashList[_fileHashListIndex] != 0) { uint32 smackerFileHash = _fileHashList[_fileHashListIndex]; ResourceHandle resourceHandle; diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp index 46ec8007b0..c3bc3501b5 100644 --- a/engines/neverhood/sound.cpp +++ b/engines/neverhood/sound.cpp @@ -35,7 +35,7 @@ SoundResource::~SoundResource() { unload(); } -bool SoundResource::isPlaying() { +bool SoundResource::isPlaying() { AudioResourceManSoundItem *soundItem = getSoundItem(); return soundItem ? soundItem->isPlaying() : false; } @@ -94,7 +94,7 @@ MusicResource::MusicResource(NeverhoodEngine *vm) bool MusicResource::isPlaying() { AudioResourceManMusicItem *musicItem = getMusicItem(); - return musicItem && musicItem->isPlaying(); + return musicItem && musicItem->isPlaying(); } void MusicResource::load(uint32 fileHash) { @@ -134,7 +134,7 @@ AudioResourceManMusicItem *MusicResource::getMusicItem() { MusicItem::MusicItem(NeverhoodEngine *vm, uint32 groupNameHash, uint32 musicFileHash) : _vm(vm), _musicResource(NULL) { - + _groupNameHash = groupNameHash; _fileHash = musicFileHash; _play = false; @@ -187,7 +187,7 @@ SoundItem::SoundItem(NeverhoodEngine *vm, uint32 groupNameHash, uint32 soundFile _playOnceAfterRandomCountdown(false), _minCountdown(0), _maxCountdown(0), _playOnceAfterCountdown(playOnceAfterCountdown), _initialCountdown(initialCountdown), _playLooping(false), _currCountdown(currCountdown) { - + _soundResource = new SoundResource(vm); _soundResource->load(soundFileHash); } @@ -200,7 +200,7 @@ SoundItem::~SoundItem() { void SoundItem::setSoundParams(bool playOnceAfterRandomCountdown, int16 minCountdown, int16 maxCountdown, int16 firstMinCountdown, int16 firstMaxCountdown) { - + _playOnceAfterCountdown = false; _playLooping = false; _playOnceAfterRandomCountdown = playOnceAfterRandomCountdown; @@ -361,7 +361,7 @@ void SoundMan::setSoundVolume(uint32 soundFileHash, int volume) { } void SoundMan::update() { - + for (uint i = 0; i < _soundItems.size(); ++i) { SoundItem *soundItem = _soundItems[i]; if (soundItem) @@ -456,7 +456,7 @@ void SoundMan::playSoundThree(uint32 groupNameHash, uint32 soundFileHash) { SoundItem *soundItem = new SoundItem(_vm, groupNameHash, soundFileHash, false, 0, 0, false, _initialCountdown3, false, 0); _soundIndex3 = addSoundItem(soundItem); } - + } void SoundMan::setTwoSoundsPlayFlag(bool playOnceAfterCountdown) { @@ -530,16 +530,16 @@ NeverhoodAudioStream::~NeverhoodAudioStream() { int NeverhoodAudioStream::readBuffer(int16 *buffer, const int numSamples) { int samplesLeft = numSamples; - + while (samplesLeft > 0 && !_endOfData) { const int maxSamples = MIN<int>(kSampleBufferLength, samplesLeft); const int bytesToRead = maxSamples * (_isCompressed ? 1 : 2); int bytesRead = _stream->read(_buffer, bytesToRead); int samplesRead = bytesRead / (_isCompressed ? 1 : 2); - + samplesLeft -= samplesRead; - + const byte *src = _buffer; if (_isCompressed) { while (samplesRead--) { @@ -694,7 +694,7 @@ void AudioResourceManMusicItem::update() { _start = false; _isPlaying = true; } - + if (_vm->_mixer->isSoundHandleActive(_soundHandle)) { if (_isFadingIn) { _fadeVolume += _fadeVolumeStep; @@ -787,11 +787,11 @@ int16 AudioResourceMan::loadMusic(uint32 fileHash) { return i; } } - + int16 musicIndex = _musicItems.size(); _musicItems.push_back(musicItem); return musicIndex; - + } void AudioResourceMan::updateMusic() { diff --git a/engines/neverhood/sound.h b/engines/neverhood/sound.h index aa5da284ea..0733346daa 100644 --- a/engines/neverhood/sound.h +++ b/engines/neverhood/sound.h @@ -70,7 +70,7 @@ public: void setVolume(int16 volume); protected: NeverhoodEngine *_vm; - int16 _musicIndex; + int16 _musicIndex; AudioResourceManMusicItem *getMusicItem(); }; @@ -83,7 +83,7 @@ public: void update(); uint32 getGroupNameHash() const { return _groupNameHash; } uint32 getFileHash() const { return _fileHash; } -protected: +protected: NeverhoodEngine *_vm; uint32 _groupNameHash; uint32 _fileHash; @@ -110,7 +110,7 @@ public: uint32 getGroupNameHash() const { return _groupNameHash; } uint32 getFileHash() const { return _fileHash; } int16 getCurrCountdown() const { return _currCountdown; } -protected: +protected: NeverhoodEngine *_vm; uint32 _groupNameHash; uint32 _fileHash; @@ -136,7 +136,7 @@ public: void deleteMusic(uint32 musicFileHash); void startMusic(uint32 musicFileHash, int16 countdown, int16 fadeVolumeStep); void stopMusic(uint32 musicFileHash, int16 countdown, int16 fadeVolumeStep); - + // Sound void addSound(uint32 groupNameHash, uint32 soundFileHash); void addSoundList(uint32 groupNameHash, const uint32 *soundFileHashList); @@ -148,7 +148,7 @@ public: void playSoundLooping(uint32 soundFileHash); void stopSound(uint32 soundFileHash); void setSoundVolume(uint32 soundFileHash, int volume); - + // Misc void update(); void deleteGroup(uint32 groupNameHash); @@ -161,25 +161,25 @@ public: protected: NeverhoodEngine *_vm; - + // TODO Find out what these special sounds are used for (door sounds?) int _soundIndex1, _soundIndex2; int16 _initialCountdown; bool _playOnceAfterCountdown; - + int _soundIndex3; int16 _initialCountdown3; bool _playOnceAfterCountdown3; Common::Array<MusicItem*> _musicItems; Common::Array<SoundItem*> _soundItems; - + MusicItem *getMusicItemByHash(uint32 musicFileHash); SoundItem *getSoundItemByHash(uint32 soundFileHash); int16 addMusicItem(MusicItem *musicItem); int16 addSoundItem(SoundItem *soundItem); void deleteSoundByIndex(int index); - + }; class NeverhoodAudioStream : public Audio::AudioStream { @@ -209,7 +209,7 @@ private: // TODO Rename these class AudioResourceManSoundItem { -public: +public: AudioResourceManSoundItem(NeverhoodEngine *vm, uint32 fileHash); void loadSound(); void unloadSound(); @@ -218,7 +218,7 @@ public: void playSound(bool looping); void stopSound(); bool isPlaying(); -protected: +protected: NeverhoodEngine *_vm; uint32 _fileHash; ResourceHandle _resourceHandle; @@ -243,7 +243,7 @@ public: bool canRestart() const { return _canRestart; } bool isTerminated() const { return _terminate; } uint32 getFileHash() const { return _fileHash; } -protected: +protected: NeverhoodEngine *_vm; uint32 _fileHash; bool _isPlaying; @@ -263,7 +263,7 @@ class AudioResourceMan { public: AudioResourceMan(NeverhoodEngine *vm); ~AudioResourceMan(); - + void stopAllSounds(); int16 addSound(uint32 fileHash); @@ -271,10 +271,10 @@ public: int16 loadMusic(uint32 fileHash); void updateMusic(); - + AudioResourceManSoundItem *getSoundItem(int16 index); AudioResourceManMusicItem *getMusicItem(int16 index); - + protected: NeverhoodEngine *_vm; diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp index 50880089f9..3c158ff7e3 100644 --- a/engines/neverhood/sprite.cpp +++ b/engines/neverhood/sprite.cpp @@ -28,11 +28,11 @@ namespace Neverhood { // Sprite Sprite::Sprite(NeverhoodEngine *vm, int objectPriority) - : Entity(vm, objectPriority), _x(0), _y(0), _spriteUpdateCb(NULL), _filterXCb(NULL), _filterYCb(NULL), + : Entity(vm, objectPriority), _x(0), _y(0), _spriteUpdateCb(NULL), _filterXCb(NULL), _filterYCb(NULL), _dataResource(vm), _doDeltaX(false), _doDeltaY(false), _needRefresh(false), _flags(0), _surface(NULL) { SetMessageHandler(&Sprite::handleMessage); - + } Sprite::~Sprite() { @@ -71,7 +71,7 @@ bool Sprite::isPointInside(int16 x, int16 y) { } bool Sprite::checkCollision(NRect &rect) { - return (_collisionBounds.x1 < rect.x2) && (rect.x1 < _collisionBounds.x2) && (_collisionBounds.y1 < rect.y2) && (rect.y1 < _collisionBounds.y2); + return (_collisionBounds.x1 < rect.x2) && (rect.x1 < _collisionBounds.x2) && (_collisionBounds.y1 < rect.y2) && (rect.y1 < _collisionBounds.y2); } uint32 Sprite::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -153,13 +153,13 @@ void StaticSprite::updatePosition() { if (!_surface) return; - + if (_doDeltaX) { _surface->getDrawRect().x = filterX(_x - _drawOffset.x - _drawOffset.width + 1); } else { _surface->getDrawRect().x = filterX(_x + _drawOffset.x); } - + if (_doDeltaY) { _surface->getDrawRect().y = filterY(_y - _drawOffset.y - _drawOffset.height + 1); } else { @@ -261,7 +261,7 @@ void AnimatedSprite::updateAnim() { } if (_newAnimFileHash == 0 && _currFrameIndex != _currStickFrameIndex) { if (_currFrameTicks != 0 && (--_currFrameTicks == 0) && _animResource.getFrameCount() != 0) { - + if (_nextAnimFileHash != 0) { if (_animResource.load(_nextAnimFileHash)) { _currAnimFileHash = _nextAnimFileHash; @@ -270,7 +270,7 @@ void AnimatedSprite::updateAnim() { _currAnimFileHash = 0; } if (_replOldColor != _replNewColor) { - _animResource.setRepl(_replOldColor, _replNewColor); + _animResource.setRepl(_replOldColor, _replNewColor); } _nextAnimFileHash = 0; if (_animStatus != 0) { @@ -278,17 +278,17 @@ void AnimatedSprite::updateAnim() { _lastFrameIndex = _plLastFrameHash != 0 ? MAX<int16>(0, _animResource.getFrameIndex(_plLastFrameHash)) : _animResource.getFrameCount() - 1; } else { _currFrameIndex = _plFirstFrameIndex != -1 ? _plFirstFrameIndex : _animResource.getFrameCount() - 1; - _lastFrameIndex = _plLastFrameIndex != -1 ? _plLastFrameIndex : _animResource.getFrameCount() - 1; + _lastFrameIndex = _plLastFrameIndex != -1 ? _plLastFrameIndex : _animResource.getFrameCount() - 1; } } else { updateFrameIndex(); } if (_newAnimFileHash == 0) updateFrameInfo(); - } + } } } - + if (_newAnimFileHash != 0) { if (_animStatus == 2) { _currStickFrameIndex = _currFrameIndex; @@ -301,7 +301,7 @@ void AnimatedSprite::updateAnim() { _currAnimFileHash = 0; } if (_replOldColor != _replNewColor) { - _animResource.setRepl(_replOldColor, _replNewColor); + _animResource.setRepl(_replOldColor, _replNewColor); } _newAnimFileHash = 0; _currFrameIndex = _plFirstFrameHash != 0 ? MAX<int16>(0, _animResource.getFrameIndex(_plFirstFrameHash)) : 0; @@ -314,7 +314,7 @@ void AnimatedSprite::updateAnim() { _currAnimFileHash = 0; } if (_replOldColor != _replNewColor) { - _animResource.setRepl(_replOldColor, _replNewColor); + _animResource.setRepl(_replOldColor, _replNewColor); } _newAnimFileHash = 0; _currFrameIndex = _plFirstFrameIndex != -1 ? _plFirstFrameIndex : _animResource.getFrameCount() - 1; diff --git a/engines/neverhood/staticdata.cpp b/engines/neverhood/staticdata.cpp index 3f89c2236f..006992641a 100644 --- a/engines/neverhood/staticdata.cpp +++ b/engines/neverhood/staticdata.cpp @@ -33,13 +33,13 @@ StaticData::~StaticData() { void StaticData::load(const char *filename) { Common::File fd; - + if (!fd.open(filename)) error("StaticData::load() Could not open %s", filename); - - fd.readUint32LE(); // magic + + fd.readUint32LE(); // magic fd.readUint32LE(); // version - + // Load message lists uint32 messageListsCount = fd.readUint32LE(); debug(3, "messageListsCount: %d", messageListsCount); @@ -84,7 +84,7 @@ void StaticData::load(const char *filename) { } _rectLists[id] = rectList; } - + // Load hit rects uint32 hitRectListsCount = fd.readUint32LE(); debug(3, "hitRectListsCount: %d", hitRectListsCount); diff --git a/engines/neverhood/todo.txt b/engines/neverhood/todo.txt deleted file mode 100644 index 9d781e06ec..0000000000 --- a/engines/neverhood/todo.txt +++ /dev/null @@ -1,45 +0,0 @@ -NOTE: -------- -Some of the TODOs should be done AFTER the whole game logic is implemented -else the game disasm and reimplemtation code become even more different -(unless I decide it's ok to do it :) - -TODOs which can be done any time: ------------------------------------ -- Cleanup -- Clean up staticdata structs to look more like the ones in create_neverhood - (e.g. by using template classes etc.) - - Or use a common base class and manage all stuff in one single table and cast stuff accordingly - -TODOs which should be done only after the game logic is finished: -------------------------------------------------------------------- -- Maybe rework organization of files (e.g. put ALL Sprites into one separate file, same with Modules and Scenes) - - This would solve the problem of how to organize stuff which is used several times, and less headers would have to be included - - The move special scenes (SmackerScene) into the scenes file - -DONE: -------- -- Implement game menus -- Rework sound system (I don't like that SoundResources need to be explicitly initialized in Scene constructors) - - Should be just a handle object which initializes itself - - Play routine should fill the handle so it can be stopped/queried later - - Basically like ScummVM own sound handles -- RE and implement yet unknown music/sound stuff -- Implement clever sprite redrawing code (dirty rectangles, microtiles etc.), only redraw what's neccessary -- Rework the resource system - - The current system can be simplified a lot - - Also resource purging needs to be implemented -- Maybe merge CollisionMan with Scene (since it's so far never used independently) -- Give placeholder stuff (e.g. sub?????, _flag??? etc.) better fitting names -- Use CursorMan for the mouse cursor (instead of using it like a normal sprite) - - This whould make it neccessary to call _system->updateScreen more often else - the mouse movement would be choppy - -TODOs which are experimental: -------------------------------- -NOTE: Since they affect the whole game, they really should be only implemented once the full game logic is implemented. -These are nothing more than wild ideas for now, any might never be implemented. -- Use states instead of separate callback methods -- Try to move more stuff to neverhood.dat -- Try to use more template functions instead of manually creating functions - (Can be coupled with the above to move parameters to the dat and only use IDs) diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp index fd602ff4fb..a99bd66e5e 100644 --- a/engines/saga/animation.cpp +++ b/engines/saga/animation.cpp @@ -185,7 +185,7 @@ int Anim::playCutaway(int cut, bool fade) { event.time = (40 / 3) * 1000 / _cutawayList[cut].frameRate; if (fade) - eventColumns = _vm->_events->chain(eventColumns, event); + _vm->_events->chain(eventColumns, event); else _vm->_events->queue(event); } diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index 812d967b9f..3ac89bc2c2 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -364,7 +364,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) { // Load MIDI/XMI resource data if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) { - // Load the external music file for Mac IHNM + // Load the external music file for Mac IHNM _player->playQuickTime(Common::String::format("Music/Music%02x", resourceId), flags & MUSIC_LOOP); } else { if (_currentMusicBuffer == &_musicBuffer[1]) { diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp index 49d24753a1..ca843af465 100644 --- a/engines/saga/sndres.cpp +++ b/engines/saga/sndres.cpp @@ -249,11 +249,11 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff if (!memcmp(header, "Creative", 8)) { resourceType = kSoundVOC; - } else if (!memcmp(header, "RIFF", 4) != 0) { + } else if (!memcmp(header, "RIFF", 4)) { resourceType = kSoundWAV; - } else if (!memcmp(header, "FORM", 4) != 0) { + } else if (!memcmp(header, "FORM", 4)) { resourceType = kSoundAIFF; - } else if (!memcmp(header, "ajkg", 4) != 0) { + } else if (!memcmp(header, "ajkg", 4)) { resourceType = kSoundShorten; } diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp index 64793efa6c..3c223bebbe 100644 --- a/engines/sci/engine/kpathing.cpp +++ b/engines/sci/engine/kpathing.cpp @@ -1966,7 +1966,7 @@ static bool isVertexCovered(const Patch &p, unsigned int wi) { // ---w1--1----p----w2--2---- // ^ \ (inside) if (wi > p.indexw1 && wi <= p.indexw2) - return true; + return true; // v / (outside) // ---w2--2----p----w1--1---- diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 15a9f54996..d72b1d1772 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -551,7 +551,7 @@ reg_t kMessage(EngineState *s, int argc, reg_t *argv) { // NOTE: To fix a corrupted jar object, type "send Glass_Jar message 52" // in the debugger. if (g_sci->getGameId() == GID_PEPPER && func == 0 && argc >= 6 && module == 894 && - tuple.noun == 26 && tuple.cond == 0 && tuple.seq == 1 && + tuple.noun == 26 && tuple.cond == 0 && tuple.seq == 1 && !s->_msgState->getMessage(module, tuple, NULL_REG)) tuple.verb = 0; diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index bf1ce6da64..bb960c8501 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -745,7 +745,7 @@ void GfxFrameout::kernelFrameout() { // Process global scaling, if needed. // TODO: Seems like SCI32 always processes global scaling for scaled objects // TODO: We can only process symmetrical scaling for now (i.e. same value for scaleX/scaleY) - if ((itemEntry->scaleSignal & kScaleSignalDoScaling32) && + if ((itemEntry->scaleSignal & kScaleSignalDoScaling32) && !(itemEntry->scaleSignal & kScaleSignalDisableGlobalScaling32) && (itemEntry->scaleX == itemEntry->scaleY) && itemEntry->scaleX != 128) diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp index 9546b1503f..6a78f494c7 100644 --- a/engines/sci/sound/midiparser_sci.cpp +++ b/engines/sci/sound/midiparser_sci.cpp @@ -57,6 +57,7 @@ MidiParser_SCI::MidiParser_SCI(SciVersion soundVersion, SciMusic *music) : _signalToSet = 0; _dataincAdd = false; _dataincToAdd = 0; + _jumpToHoldTick = false; _resetOnPause = false; _pSnd = 0; } @@ -452,6 +453,10 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { debugC(4, kDebugLevelSound, "signal %04x", _signalToSet); } + if (_jumpToHoldTick) { + _jumpToHoldTick = false; + jumpToTick(_loopTick, false, false); + } info.start = _position._playPos; info.delta = 0; @@ -531,10 +536,15 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { // Check if the hold ID marker is the same as the hold ID // marker set for that song by cmdSetSoundHold. // If it is, loop back, but don't stop notes when jumping. + // We need to wait for the delta of the current event before + // jumping, thus the jump will be performed on the next + // parseNextEvent() call, like with the signal set events. + // In LSL6, room 360, song 381, this ends up jumping forward + // one tick (the hold marker occurs at playtick 27, with + // _loopTick being 15 and the event itself having a delta of + // 13, total = 28) - bug #3614566. if (info.basic.param2 == _pSnd->hold) { - uint32 extraDelta = info.delta; - jumpToTick(_loopTick, false, false); - _nextEvent.delta += extraDelta; + _jumpToHoldTick = true; } break; case kUpdateCue: @@ -637,7 +647,14 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { // (e.g. song 110, during the intro). The original interpreter // treats this case as an infinite loop (bug #3311911). if (_pSnd->loop || _pSnd->hold > 0) { - // We need to play it again... + // TODO: this jump is also vulnerable to the same lockup as + // the MIDI hold one above. However, we can't perform the + // jump on the next tick like with the MIDI hold jump above, + // as there aren't any subsequent MIDI events after this one. + // This assert is here to detect cases where the song ends + // up jumping forward, like with bug #3614566 (see above). + assert(_loopTick + info.delta < _position._playTick); + uint32 extraDelta = info.delta; jumpToTick(_loopTick); _nextEvent.delta += extraDelta; diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h index d3fd337644..7bd68994c8 100644 --- a/engines/sci/sound/midiparser_sci.h +++ b/engines/sci/sound/midiparser_sci.h @@ -110,6 +110,7 @@ protected: int16 _signalToSet; bool _dataincAdd; int16 _dataincToAdd; + bool _jumpToHoldTick; bool _resetOnPause; bool _channelUsed[16]; diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index cb807997e9..395051d2a5 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -758,6 +758,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "pajama2", "PYJAMADB", kGenHEPC, Common::DE_DEU, UNK, 0 }, { "pajama2", "PyjamaDBMN", kGenHEPC, Common::DE_DEU, UNK, 0 }, { "pajama2", "PyjamaDBMN", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 }, + { "pajama2", "PyjamaHM", kGenHEPC, Common::FR_FRA, UNK, 0 }, { "pajama2", "PyjamaHM", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, { "pajama2", "PYJAMA2", kGenHEPC, Common::DE_DEU, UNK, 0 }, { "pajama2", "Pyjama Pit 2", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 }, diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp index 12ebfef9b7..0e96952a48 100644 --- a/engines/scumm/imuse/imuse.cpp +++ b/engines/scumm/imuse/imuse.cpp @@ -1483,7 +1483,7 @@ void IMuseInternal::initMT32(MidiDriver *midi) { } void IMuseInternal::initGM(MidiDriver *midi) { - byte buffer[11]; + byte buffer[12]; int i; // General MIDI System On message @@ -1509,7 +1509,7 @@ void IMuseInternal::initGM(MidiDriver *midi) { midi->sysEx(buffer, 9); debug(2, "GS SysEx: GS Reset"); _system->delayMillis(200); - + // Set global Master Tune to 442.0kHz, as on the MT-32 memcpy(&buffer[4], "\x40\x00\x00\x00\x04\x04\x0F\x29", 8); midi->sysEx(buffer, 12); @@ -1540,7 +1540,7 @@ void IMuseInternal::initGM(MidiDriver *midi) { // Set Channels 1-16 Reverb to 64, which is the // equivalent of MT-32 default Reverb Level 5 for (i = 0; i < 16; ++i) - midi->send((64 << 16) | (91 << 8) | (0xB0 | i)); + midi->send((64 << 16) | (91 << 8) | (0xB0 | i)); debug(2, "GM Controller 91 Change: Channels 1-16 Reverb Level is 64"); // Set Channels 1-16 Pitch Bend Sensitivity to diff --git a/engines/scumm/insane/insane_enemy.cpp b/engines/scumm/insane/insane_enemy.cpp index fa6d4264ec..3876966fd1 100644 --- a/engines/scumm/insane/insane_enemy.cpp +++ b/engines/scumm/insane/insane_enemy.cpp @@ -1519,8 +1519,6 @@ void Insane::chooseEnemyWeaponAnim(int32 buttons) { case INV_BOOT: case INV_HAND: case INV_DUST: - _actor[1].act[2].state = 0; - switchEnemyWeapon(); default: switchEnemyWeapon(); } @@ -2437,6 +2435,7 @@ void Insane::actor12Reaction(int32 buttons) { smlayer_setActorFacing(1, 2, 6, 180); smlayer_setActorLayer(1, 2, 25); _actor[1].act[2].state = 103; + break; case 103: _actor[1].kicking = false; diff --git a/engines/scumm/player_v3m.cpp b/engines/scumm/player_v3m.cpp index 0f222d84fe..bf65ec797f 100644 --- a/engines/scumm/player_v3m.cpp +++ b/engines/scumm/player_v3m.cpp @@ -124,7 +124,7 @@ bool Player_V3M::checkMusicAvailable() { return true; } } - + GUI::MessageDialog dialog(_( "Could not find the 'Loom' Macintosh executable to read the\n" "instruments from. Music will be disabled."), _("OK")); diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index db8da21bbc..7f0eb41a1e 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Sun Jun 23 22:18:47 2013 + This file was generated by the md5table tool on Tue Jul 09 01:43:38 2013 DO NOT EDIT MANUALLY! */ @@ -328,6 +328,7 @@ static const MD5Table md5table[] = { { "73e5ab7dbb9a8061cc6d25df02dbd1e7", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "7410a8ba9795020cd42f171c4320659e", "pajama3", "", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "746e88c172a5b7a1ae89ac0ee3ee681a", "freddi", "HE 90", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows }, + { "7477bc23d0383516c5e310cd8771dcc9", "pajama2", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "74da3494fbe1a7d20213b0afe0954755", "catalog", "HE CUP", "Preview", 10841544, Common::FR_FRA, Common::kPlatformUnknown }, { "754feb59d3bf86b8a00840df74fd7b26", "freddi3", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "75ba23fff4fd63fa446c02864f2a5a4b", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformDOS }, diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp index 206bd68b07..79ec060bc1 100644 --- a/engines/sword1/animation.cpp +++ b/engines/sword1/animation.cpp @@ -37,7 +37,14 @@ #include "gui/message.h" +#ifdef USE_MPEG2 +#include "video/avi_decoder.h" +#endif + +#ifdef USE_ZLIB #include "video/dxa_decoder.h" +#endif + #include "video/psx_decoder.h" #include "video/smk_decoder.h" @@ -176,27 +183,26 @@ bool MoviePlayer::load(uint32 id) { break; case kVideoDecoderPSX: filename = Common::String::format("%s.str", (_vm->_systemVars.isDemo) ? sequenceList[id] : sequenceListPSX[id]); + break; + case kVideoDecoderMP2: + filename = Common::String::format("%s.mp2", sequenceList[id]); + break; + } - // Need to switch to true color + // Need to switch to true color for PSX/MP2 videos + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) initGraphics(g_system->getWidth(), g_system->getHeight(), true, 0); - // Need to load here in case it fails in which case we'd need - // to go back to paletted mode - if (_decoder->loadFile(filename)) { - _decoder->start(); - return true; - } else { + if (!_decoder->loadFile(filename)) { + // Go back to 8bpp color + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) initGraphics(g_system->getWidth(), g_system->getHeight(), true); - return false; - } - break; - } - if (!_decoder->loadFile(filename)) return false; + } - // For DXA, also add the external sound file - if (_decoderType == kVideoDecoderDXA) + // For DXA/MP2, also add the external sound file + if (_decoderType == kVideoDecoderDXA || _decoderType == kVideoDecoderMP2) _decoder->addStreamFileTrack(sequenceList[id]); _decoder->start(); @@ -224,9 +230,9 @@ void MoviePlayer::play() { } void MoviePlayer::performPostProcessing(byte *screen) { - // TODO: We don't support the PSX stream videos yet + // TODO: We don't support displaying these in true color yet, // nor using the PSX fonts to display subtitles. - if (_vm->isPsx()) + if (_vm->isPsx() || _decoderType == kVideoDecoderMP2) return; if (!_movieTexts.empty()) { @@ -414,20 +420,19 @@ bool MoviePlayer::playVideo() { _vm->_system->delayMillis(10); } - if (_decoderType == kVideoDecoderPSX) { - // Need to jump back to paletted color + // Need to jump back to paletted color + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) initGraphics(g_system->getWidth(), g_system->getHeight(), true); - } return !_vm->shouldQuit() && !skipped; } uint32 MoviePlayer::getBlackColor() { - return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black; + return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black; } uint32 MoviePlayer::findTextColor() { - if (_decoderType == kVideoDecoderPSX) { + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) { // We're in true color mode, so return the actual colors switch (_textColor) { case 1: @@ -547,9 +552,16 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan * filename = Common::String::format("%s.mp2", sequenceList[id]); if (Common::File::exists(filename)) { - GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK")); +#ifdef USE_MPEG2 + // HACK: Old ScummVM builds ignored the AVI frame rate field and forced the video + // to be played back at 12fps. + Video::VideoDecoder *aviDecoder = new Video::AVIDecoder(12); + return new MoviePlayer(vm, textMan, resMan, system, aviDecoder, kVideoDecoderMP2); +#else + GUI::MessageDialog dialog(_("MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"), _("OK")); dialog.runModal(); return 0; +#endif } if (!vm->isPsx() || scumm_stricmp(sequenceList[id], "enddemo") != 0) { diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h index d0c61f5eb3..2c51a74f71 100644 --- a/engines/sword1/animation.h +++ b/engines/sword1/animation.h @@ -41,7 +41,8 @@ namespace Sword1 { enum DecoderType { kVideoDecoderDXA = 0, kVideoDecoderSMK = 1, - kVideoDecoderPSX = 2 + kVideoDecoderPSX = 2, + kVideoDecoderMP2 = 3 }; class MovieText { diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp index 00260f789a..713120ad43 100644 --- a/engines/sword2/animation.cpp +++ b/engines/sword2/animation.cpp @@ -42,7 +42,14 @@ #include "gui/message.h" +#ifdef USE_MPEG2 +#include "video/avi_decoder.h" +#endif + +#ifdef USE_ZLIB #include "video/dxa_decoder.h" +#endif + #include "video/smk_decoder.h" #include "video/psx_decoder.h" @@ -88,26 +95,26 @@ bool MoviePlayer::load(const char *name) { break; case kVideoDecoderPSX: filename = Common::String::format("%s.str", name); + break; + case kVideoDecoderMP2: + filename = Common::String::format("%s.mp2", name); + break; + } - // Need to switch to true color - initGraphics(640, 480, true, 0); + // Need to switch to true color for PSX/MP2 videos + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) + initGraphics(g_system->getWidth(), g_system->getHeight(), true, 0); - // Need to load here in case it fails in which case we'd need - // to go back to paletted mode - if (_decoder->loadFile(filename)) { - _decoder->start(); - return true; - } else { - initGraphics(640, 480, true); - return false; - } - } + if (!_decoder->loadFile(filename)) { + // Go back to 8bpp color + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) + initGraphics(g_system->getWidth(), g_system->getHeight(), true); - if (!_decoder->loadFile(filename)) return false; + } - // For DXA, also add the external sound file - if (_decoderType == kVideoDecoderDXA) + // For DXA/MP2, also add the external sound file + if (_decoderType == kVideoDecoderDXA || _decoderType == kVideoDecoderMP2) _decoder->addStreamFileTrack(name); _decoder->start(); @@ -136,10 +143,9 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI _vm->_sound->stopSpeech(); } - if (_decoderType == kVideoDecoderPSX) { - // Need to jump back to paletted color + // Need to jump back to paletted color + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) initGraphics(640, 480, true); - } } void MoviePlayer::openTextObject(uint32 index) { @@ -378,11 +384,11 @@ bool MoviePlayer::playVideo() { } uint32 MoviePlayer::getBlackColor() { - return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black; + return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black; } uint32 MoviePlayer::getWhiteColor() { - return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF) : _white; + return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF) : _white; } void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) { @@ -446,9 +452,16 @@ MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, OSystem *system filename = Common::String::format("%s.mp2", name); if (Common::File::exists(filename)) { - GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK")); +#ifdef USE_MPEG2 + // HACK: Old ScummVM builds ignored the AVI frame rate field and forced the video + // to be played back at 12fps. + Video::AVIDecoder *aviDecoder = new Video::AVIDecoder(12); + return new MoviePlayer(vm, system, aviDecoder, kVideoDecoderMP2); +#else + GUI::MessageDialog dialog(_("MPEG-2 cutscenes found but ScummVM has been built without MPEG-2 support"), _("OK")); dialog.runModal(); return NULL; +#endif } // The demo tries to play some cutscenes that aren't there, so make those warnings more discreet. diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h index b2a243b2ca..8669bdc8d8 100644 --- a/engines/sword2/animation.h +++ b/engines/sword2/animation.h @@ -40,7 +40,8 @@ namespace Sword2 { enum DecoderType { kVideoDecoderDXA = 0, kVideoDecoderSMK = 1, - kVideoDecoderPSX = 2 + kVideoDecoderPSX = 2, + kVideoDecoderMP2 = 3 }; struct MovieText { diff --git a/engines/sword25/gfx/dynamicbitmap.cpp b/engines/sword25/gfx/dynamicbitmap.cpp index 242508bf85..1f3d2d063d 100644 --- a/engines/sword25/gfx/dynamicbitmap.cpp +++ b/engines/sword25/gfx/dynamicbitmap.cpp @@ -53,7 +53,7 @@ DynamicBitmap::DynamicBitmap(InputPersistenceBlock &reader, RenderObjectPtr<Rend bool DynamicBitmap::createRenderedImage(uint width, uint height) { bool result = false; _image.reset(new RenderedImage(width, height, result)); - + _originalWidth = _width = width; _originalHeight = _height = height; @@ -77,7 +77,7 @@ bool DynamicBitmap::doRender(RectangleList *updateRects) { // Get the frame buffer object GraphicEngine *pGfx = Kernel::getInstance()->getGfx(); assert(pGfx); - + // Draw the bitmap bool result; if (_scaleFactorX == 1.0f && _scaleFactorY == 1.0f) { diff --git a/engines/sword25/gfx/image/image.h b/engines/sword25/gfx/image/image.h index 9d7fc43251..8db54e7c54 100644 --- a/engines/sword25/gfx/image/image.h +++ b/engines/sword25/gfx/image/image.h @@ -205,7 +205,7 @@ public: @brief Returns true, if the content of the BS_Image is allowed to be replaced by call of SetContent(). */ virtual bool isSetContentAllowed() const = 0; - + virtual bool isSolid() const { return false; } //@} diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp index c8a6666046..9b8cf2266d 100644 --- a/engines/sword25/gfx/image/renderedimage.cpp +++ b/engines/sword25/gfx/image/renderedimage.cpp @@ -41,6 +41,7 @@ #include "sword25/gfx/renderobjectmanager.h" #include "common/system.h" +#include "graphics/thumbnail.h" namespace Sword25 { @@ -293,7 +294,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe for (RectangleList::iterator it = updateRects->begin(); it != updateRects->end(); ++it) { const Common::Rect &clipRect = *it; - + int skipLeft = 0, skipTop = 0; int drawX = posX, drawY = posY; int drawWidth = img->w; @@ -305,7 +306,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe drawWidth -= skipLeft; drawX = clipRect.left; } - + if (drawY < clipRect.top) { skipTop = clipRect.top - drawY; drawHeight -= skipTop; @@ -314,13 +315,13 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe if (drawX + drawWidth >= clipRect.right) drawWidth = clipRect.right - drawX; - + if (drawY + drawHeight >= clipRect.bottom) drawHeight = clipRect.bottom - drawY; - + if ((drawWidth > 0) && (drawHeight > 0)) { int xp = 0, yp = 0; - + int inStep = 4; int inoStep = img->pitch; if (flipping & Image::FLIP_V) { @@ -329,14 +330,14 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe } else { xp = skipLeft; } - + if (flipping & Image::FLIP_H) { inoStep = -inoStep; yp = img->h - 1 - skipTop; } else { yp = skipTop; } - + byte *ino = (byte *)img->getBasePtr(xp, yp); byte *outo = (byte *)_backSurface->getBasePtr(drawX, drawY); @@ -350,7 +351,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe ino += inoStep; } } else -#endif +#endif { byte *in, *out; for (int i = 0; i < drawHeight; i++) { @@ -360,7 +361,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe uint32 pix = *(uint32 *)in; int a = (pix >> 24) & 0xff; in += inStep; - + if (ca != 255) { a = a * ca >> 8; } @@ -370,11 +371,11 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe out += 4; continue; } - + int b = (pix >> 0) & 0xff; int g = (pix >> 8) & 0xff; int r = (pix >> 16) & 0xff; - + if (a == 255) { #if defined(SCUMM_LITTLE_ENDIAN) if (cb != 255) @@ -459,7 +460,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe } } - + } if (imgScaled) { @@ -509,60 +510,4 @@ void RenderedImage::checkForTransparency() { } } -/** - * Scales a passed surface, creating a new surface with the result - * @param srcImage Source image to scale - * @param scaleFactor Scale amount. Must be between 0 and 1.0 (but not zero) - * @remarks Caller is responsible for freeing the returned surface - */ -Graphics::Surface *RenderedImage::scale(const Graphics::Surface &srcImage, int xSize, int ySize) { - Graphics::Surface *s = new Graphics::Surface(); - s->create(xSize, ySize, srcImage.format); - - int *horizUsage = scaleLine(xSize, srcImage.w); - int *vertUsage = scaleLine(ySize, srcImage.h); - - // Loop to create scaled version - for (int yp = 0; yp < ySize; ++yp) { - const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]); - byte *destP = (byte *)s->getBasePtr(0, yp); - - for (int xp = 0; xp < xSize; ++xp) { - const byte *tempSrcP = srcP + (horizUsage[xp] * srcImage.format.bytesPerPixel); - for (int byteCtr = 0; byteCtr < srcImage.format.bytesPerPixel; ++byteCtr) { - *destP++ = *tempSrcP++; - } - } - } - - // Delete arrays and return surface - delete[] horizUsage; - delete[] vertUsage; - return s; -} - -/** - * Returns an array indicating which pixels of a source image horizontally or vertically get - * included in a scaled image - */ -int *RenderedImage::scaleLine(int size, int srcSize) { - int scale = 100 * size / srcSize; - assert(scale > 0); - int *v = new int[size]; - Common::fill(v, &v[size], 0); - - int distCtr = 0; - int *destP = v; - for (int distIndex = 0; distIndex < srcSize; ++distIndex) { - distCtr += scale; - while (distCtr >= 100) { - assert(destP < &v[size]); - *destP++ = distIndex; - distCtr -= 100; - } - } - - return v; -} - } // End of namespace Sword25 diff --git a/engines/sword25/gfx/image/renderedimage.h b/engines/sword25/gfx/image/renderedimage.h index a25b258592..116f97de26 100644 --- a/engines/sword25/gfx/image/renderedimage.h +++ b/engines/sword25/gfx/image/renderedimage.h @@ -104,8 +104,6 @@ public: return true; } - static Graphics::Surface *scale(const Graphics::Surface &srcImage, int xSize, int ySize); - void setIsTransparent(bool isTransparent) { _isTransparent = isTransparent; } virtual bool isSolid() const { return !_isTransparent; } @@ -119,7 +117,6 @@ private: Graphics::Surface *_backSurface; void checkForTransparency(); - static int *scaleLine(int size, int srcSize); }; } // End of namespace Sword25 diff --git a/engines/sword25/gfx/panel.cpp b/engines/sword25/gfx/panel.cpp index 931b9cdbe7..b9bb8b087d 100644 --- a/engines/sword25/gfx/panel.cpp +++ b/engines/sword25/gfx/panel.cpp @@ -84,7 +84,7 @@ bool Panel::doRender(RectangleList *updateRects) { gfxPtr->fill(&intersectionRect, _color); } } - + return true; } diff --git a/engines/sword25/gfx/renderobject.cpp b/engines/sword25/gfx/renderobject.cpp index 807c1eb64b..1dd6f4590f 100644 --- a/engines/sword25/gfx/renderobject.cpp +++ b/engines/sword25/gfx/renderobject.cpp @@ -183,7 +183,7 @@ bool RenderObject::updateObjectState() { // Die Bounding-Box neu berechnen und Update-Regions registrieren. updateBoxes(); - + ++_version; // Änderungen Validieren diff --git a/engines/sword25/gfx/renderobject.h b/engines/sword25/gfx/renderobject.h index 7e0334ee88..1116c3284c 100644 --- a/engines/sword25/gfx/renderobject.h +++ b/engines/sword25/gfx/renderobject.h @@ -236,7 +236,7 @@ public: @brief Löscht alle Kinderobjekte. */ void deleteAllChildren(); - + // Accessor-Methoden // ----------------- /** @@ -305,11 +305,11 @@ public: int getZ() const { return _z; } - + int getAbsoluteZ() const { return _absoluteZ; } - + /** @brief Gibt die Breite des Objektes zurück. */ @@ -363,11 +363,11 @@ public: return _handle; } - // Get the RenderObjects current version + // Get the RenderObjects current version int getVersion() const { return _version; } - + bool isSolid() const { return _isSolid; } @@ -410,7 +410,7 @@ protected: bool _oldVisible; static int _nextGlobalVersion; - + int _version; // This should be set to true if the RenderObject is NOT alpha-blended to optimize drawing @@ -509,9 +509,9 @@ private: @brief Berechnet die absolute Position des Objektes. */ int calcAbsoluteY() const; - + int calcAbsoluteZ() const; - + /** @brief Sortiert alle Kinderobjekte nach ihrem Renderang. */ diff --git a/engines/sword25/gfx/renderobjectmanager.cpp b/engines/sword25/gfx/renderobjectmanager.cpp index 994d9367ab..77f944c9e0 100644 --- a/engines/sword25/gfx/renderobjectmanager.cpp +++ b/engines/sword25/gfx/renderobjectmanager.cpp @@ -113,7 +113,7 @@ bool RenderObjectManager::render() { RectangleList *updateRects = _uta->getRectangles(); Common::Array<int> updateRectsMinZ; - + updateRectsMinZ.reserve(updateRects->size()); // Calculate the minimum drawing Z value of each update rectangle @@ -144,9 +144,9 @@ bool RenderObjectManager::render() { } delete updateRects; - + SWAP(_currQueue, _prevQueue); - + return true; } diff --git a/engines/sword25/gfx/staticbitmap.cpp b/engines/sword25/gfx/staticbitmap.cpp index 91b93e8910..bb57fa3a03 100644 --- a/engines/sword25/gfx/staticbitmap.cpp +++ b/engines/sword25/gfx/staticbitmap.cpp @@ -71,7 +71,7 @@ bool StaticBitmap::initBitmapResource(const Common::String &filename) { // RenderObject Eigenschaften aktualisieren _originalWidth = _width = bitmapPtr->getWidth(); _originalHeight = _height = bitmapPtr->getHeight(); - + _isSolid = bitmapPtr->isSolid(); // Bild-Resource freigeben diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp index b7f5e30340..b7a8fd3c8b 100644 --- a/engines/sword25/util/pluto/pluto.cpp +++ b/engines/sword25/util/pluto/pluto.cpp @@ -1,6 +1,6 @@ /* $Id$ */ -/* Pluto - Heavy-duty persistence for Lua +/* Tamed Pluto - Heavy-duty persistence for Lua * Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public * domain. People making use of this software as part of an application * are politely requested to email the author at sneftel@gmail.com @@ -14,11 +14,17 @@ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Instrumented by Stefan Reich (info@luaos.net) + * for Mobile Lua (http://luaos.net/pages/mobile-lua.php) */ +#include "config.h" #include "sword25/util/lua/lua.h" #include "pluto.h" +#undef TOTEXT + #define USE_PDEP #ifdef USE_PDEP @@ -42,10 +48,20 @@ #include <string.h> +/* Define this if you want size_t values to be written in 64-bit + (even on 32-bit systems). Should eliminate at least one source of + 32/64 bit incompatibility. */ +#define SIZES64 + /* #define PLUTO_DEBUG */ +#ifdef SIZES64 +#define VERSION "Tamed Pluto 1.0 with SIZES64 flag" +#else +#define VERSION "Tamed Pluto 1.0" +#endif #ifdef PLUTO_DEBUG @@ -56,6 +72,23 @@ #define verify(x) { int v = (int)((x)); v=v; lua_assert(v); } +#define NUMTYPES 9 +static const char* typenames[] = { + "nil", + "boolean", + "lightuserdata", + "number", + "string", + "table", + "function", + "userdata", + "thread" +}; + +static int humanReadable = 0; +#define hrBufSize 200 +static char hrBuf[hrBufSize]; + typedef struct PersistInfo_t { lua_State *L; int counter; @@ -76,6 +109,77 @@ void printindent(int indent) } #endif +/* lua_Chunkwriter signature: (lua_State *L, const void *p, size_t sz, void *ud). + ud is a pointer to the WriterInfo struct (holds the buffer pointer) +*/ + +static void pi_write(PersistInfo *pi, const void *p, size_t size, void *ud) { + if (humanReadable) { + uint i; + snprintf(hrBuf, hrBufSize, " pi_write %d ", (int) size); + pi->writer(pi->L, hrBuf, strlen(hrBuf), ud); + for (i = 0; i < size; i++) { + char b = ((char *)p)[i]; + snprintf(hrBuf, hrBufSize, "%X%X", (b >> 4) & 0xF, b & 0xF); + pi->writer(pi->L, hrBuf, strlen(hrBuf), ud); + } + snprintf(hrBuf, hrBufSize, "\n"); + pi->writer(pi->L, hrBuf, strlen(hrBuf), ud); + } else { + pi->writer(pi->L, p, size, ud); + } +#ifdef TOTEXT + int i; + printf(" pi_write %d ", (int) size); + for (i = 0; i < size; i++) { + char b = ((char *)p)[i]; + printf("%X%X", (b >> 4) & 0xF, b & 0xF); + } + printf("\n"); +#endif +} + +static void hrOut(PersistInfo *pi) { + pi->writer(pi->L, hrBuf, strlen(hrBuf), pi->ud); +} + +static void write_size(PersistInfo *pi, size_t *val) +{ +#ifdef SIZES64 + int64 longval; /* yeah, you really need long long to get 8 bytes on win32... duh. */ + longval = *val; + pi_write(pi, &longval, 8, pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "write_size64 %ld\n", longval); + hrOut(pi); + } +#ifdef TOTEXT + printf("write_size64 %ld\n", longval); +#endif +#else + pi_write(pi, val, sizeof(size_t), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "write_size %ld\n", *((size_t *)val)); + hrOut(pi); + } +#ifdef TOTEXT + printf("write_size %ld\n", *val); +#endif +#endif +} + +static void read_size(ZIO *zio, size_t *val) +{ +#ifdef SIZES64 + int64 longval; + verify(LIF(Z,read)(zio, &longval, 8) == 0); + *val = longval; +#else + verify(LIF(Z,read)(zio, val, sizeof(size_t)) == 0); +#endif +} + + /* Mutual recursion requires prototype */ static void persist(PersistInfo *pi); @@ -107,7 +211,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction) if(defaction) { { int zero = 0; - pi->writer(pi->L, &zero, sizeof(int), pi->ud); + pi_write(pi, &zero, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistspecialobject_write_zero\n"); +#endif } return 0; } else { @@ -127,7 +238,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction) if(defaction) { { int zero = 0; - pi->writer(pi->L, &zero, sizeof(int), pi->ud); + pi_write(pi, &zero, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero2\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistspecialobject_write_zero2\n"); +#endif } return 0; } else { @@ -143,7 +261,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction) /* perms reftbl sptbl ... obj */ { int zero = 0; - pi->writer(pi->L, &zero, sizeof(int), pi->ud); + pi_write(pi, &zero, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero3\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistspecialobject_write_zero3\n"); +#endif } return 0; } else { @@ -176,7 +301,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction) /* perms reftbl ... obj mt func */ { int one = 1; - pi->writer(pi->L, &one, sizeof(int), pi->ud); + pi_write(pi, &one, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistspecialobject_write_one\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistspecialobject_write_one\n"); +#endif } persist(pi); /* perms reftbl ... obj mt func */ @@ -187,6 +319,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction) static void persisttable(PersistInfo *pi) { + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persisttable\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persisttable\n"); +#endif + /* perms reftbl ... tbl */ lua_checkstack(pi->L, 3); if(persistspecialobject(pi, 1)) { @@ -235,8 +375,15 @@ static void persistuserdata(PersistInfo *pi) { } else { /* Use literal persistence */ size_t length = uvalue(getobject(pi->L, -1))->len; - pi->writer(pi->L, &length, sizeof(size_t), pi->ud); - pi->writer(pi->L, lua_touserdata(pi->L, -1), length, pi->ud); + write_size(pi, &length); + pi_write(pi, lua_touserdata(pi->L, -1), length, pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistuserdata %ld\n", (long) length); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistuserdata %ld\n", (long) length); +#endif if(!lua_getmetatable(pi->L, -1)) { /* perms reftbl ... udata */ lua_pushnil(pi->L); @@ -269,8 +416,8 @@ static void pushproto(lua_State *L, Proto *proto) #define setuvvalue(L,obj,x) \ { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUPVAL; \ - checkliveness(G(L),i_o); } + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUPVAL; \ + checkliveness(G(L),i_o); } static void pushupval(lua_State *L, UpVal *upval) { @@ -309,7 +456,14 @@ static void persistfunction(PersistInfo *pi) { /* We don't really _NEED_ the number of upvals, * but it'll simplify things a bit */ - pi->writer(pi->L, &cl->l.p->nups, sizeof(lu_byte), pi->ud); + pi_write(pi, &cl->l.p->nups, sizeof(lu_byte), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistfunction_number_upvalues %d\n", (int) cl->l.p->nups); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistfunction_number_upvalues %d\n", (int) cl->l.p->nups); +#endif } /* Persist prototype */ { @@ -401,7 +555,14 @@ static void persistproto(PersistInfo *pi) /* Persist constant refs */ { int i; - pi->writer(pi->L, &p->sizek, sizeof(int), pi->ud); + pi_write(pi, &p->sizek, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_sizek %d\n", p->sizek); + hrOut(pi); + } + #ifdef TOTEXT + printf("persistproto_sizek %d\n", p->sizek); + #endif for(i=0; i<p->sizek; i++) { LIF(A,pushobject)(pi->L, &p->k[i]); /* perms reftbl ... proto const */ @@ -415,7 +576,14 @@ static void persistproto(PersistInfo *pi) /* serialize inner Proto refs */ { int i; - pi->writer(pi->L, &p->sizep, sizeof(int), pi->ud); + pi_write(pi, &p->sizep, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_sizep %d\n", p->sizep); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_sizep %d\n", p->sizep); +#endif for(i=0; i<p->sizep; i++) { pushproto(pi->L, p->p[i]); @@ -429,14 +597,37 @@ static void persistproto(PersistInfo *pi) /* Serialize code */ { - pi->writer(pi->L, &p->sizecode, sizeof(int), pi->ud); - pi->writer(pi->L, p->code, sizeof(Instruction) * p->sizecode, pi->ud); + int len; + pi_write(pi, &p->sizecode, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_sizecode %d\n", p->sizecode); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_sizecode %d\n", p->sizecode); +#endif + len = sizeof(Instruction) * p->sizecode; + pi_write(pi, p->code, len, pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_code %d\n", len); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_code %d\n", len); +#endif } /* Serialize upvalue names */ { int i; - pi->writer(pi->L, &p->sizeupvalues, sizeof(int), pi->ud); + pi_write(pi, &p->sizeupvalues, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_upvalues %d\n", p->sizeupvalues); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_upvalues %d\n", p->sizeupvalues); +#endif for(i=0; i<p->sizeupvalues; i++) { pushstring(pi->L, p->upvalues[i]); @@ -447,15 +638,36 @@ static void persistproto(PersistInfo *pi) /* Serialize local variable infos */ { int i; - pi->writer(pi->L, &p->sizelocvars, sizeof(int), pi->ud); + pi_write(pi, &p->sizelocvars, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_sizelocvars %d\n", p->sizelocvars); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_sizelocvars %d\n", p->sizelocvars); +#endif for(i=0; i<p->sizelocvars; i++) { pushstring(pi->L, p->locvars[i].varname); persist(pi); lua_pop(pi->L, 1); - pi->writer(pi->L, &p->locvars[i].startpc, sizeof(int), pi->ud); - pi->writer(pi->L, &p->locvars[i].endpc, sizeof(int), pi->ud); + pi_write(pi, &p->locvars[i].startpc, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_startpc %d\n", p->locvars[i].startpc); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_startpc %d\n", p->locvars[i].startpc); +#endif + pi_write(pi, &p->locvars[i].endpc, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_endpc %d\n", p->locvars[i].endpc); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_endpc %d\n", p->locvars[i].endpc); +#endif } } @@ -466,23 +678,81 @@ static void persistproto(PersistInfo *pi) /* Serialize line numbers */ { - pi->writer(pi->L, &p->sizelineinfo, sizeof(int), pi->ud); + pi_write(pi, &p->sizelineinfo, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_sizelineinfo %d\n", p->sizelineinfo); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_sizelineinfo %d\n", p->sizelineinfo); +#endif if (p->sizelineinfo) { - pi->writer(pi->L, p->lineinfo, sizeof(int) * p->sizelineinfo, pi->ud); + int len; + len = sizeof(int) * p->sizelineinfo; + pi_write(pi, p->lineinfo, len, pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_lineinfo %d\n", len); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_lineinfo %d\n", len); +#endif } } /* Serialize linedefined and lastlinedefined */ - pi->writer(pi->L, &p->linedefined, sizeof(int), pi->ud); - pi->writer(pi->L, &p->lastlinedefined, sizeof(int), pi->ud); + pi_write(pi, &p->linedefined, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_linedefined %d\n", p->linedefined); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_linedefined %d\n", p->linedefined); +#endif + pi_write(pi, &p->lastlinedefined, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_lastlinedefined %d\n", p->lastlinedefined); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_lastlinedefined %d\n", p->lastlinedefined); +#endif /* Serialize misc values */ { - pi->writer(pi->L, &p->nups, sizeof(lu_byte), pi->ud); - pi->writer(pi->L, &p->numparams, sizeof(lu_byte), pi->ud); - pi->writer(pi->L, &p->is_vararg, sizeof(lu_byte), pi->ud); - pi->writer(pi->L, &p->maxstacksize, sizeof(lu_byte), pi->ud); + pi_write(pi, &p->nups, sizeof(lu_byte), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_nups %d\n", (int) p->nups); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_nups %d\n", (int) p->nups); +#endif + pi_write(pi, &p->numparams, sizeof(lu_byte), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_numparams %d\n", (int) p->numparams); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_numparams %d\n", (int) p->numparams); +#endif + pi_write(pi, &p->is_vararg, sizeof(lu_byte), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_is_vararg %d\n", (int) p->is_vararg); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_is_vararg %d\n", (int) p->is_vararg); +#endif + pi_write(pi, &p->maxstacksize, sizeof(lu_byte), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistproto_maxstacksize %d\n", (int) p->maxstacksize); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistproto_maxstacksize %d\n", (int) p->maxstacksize); +#endif } /* We do not currently persist upvalue names, local variable names, * variable lifetimes, line info, or source code. */ @@ -518,7 +788,7 @@ static void persistthread(PersistInfo *pi) /* Persist the stack */ posremaining = revappendstack(L2, pi->L); /* perms reftbl ... thr (rev'ed contents of L2) */ - pi->writer(pi->L, &posremaining, sizeof(size_t), pi->ud); + write_size(pi, &posremaining); for(; posremaining > 0; posremaining--) { persist(pi); lua_pop(pi->L, 1); @@ -527,7 +797,7 @@ static void persistthread(PersistInfo *pi) /* Now, persist the CallInfo stack. */ { size_t i, numframes = (L2->ci - L2->base_ci) + 1; - pi->writer(pi->L, &numframes, sizeof(size_t), pi->ud); + write_size(pi, &numframes); for(i=0; i<numframes; i++) { CallInfo *ci = L2->base_ci + i; size_t stackbase = ci->base - L2->stack; @@ -536,11 +806,18 @@ static void persistthread(PersistInfo *pi) size_t savedpc = (ci != L2->base_ci) ? ci->savedpc - ci_func(ci)->l.p->code : 0; - pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud); - pi->writer(pi->L, &stackfunc, sizeof(size_t), pi->ud); - pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud); - pi->writer(pi->L, &ci->nresults, sizeof(int), pi->ud); - pi->writer(pi->L, &savedpc, sizeof(size_t), pi->ud); + write_size(pi, &stackbase); + write_size(pi, &stackfunc); + write_size(pi, &stacktop); + pi_write(pi, &ci->nresults, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistthread %d\n", ci->nresults); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistthread %d\n", ci->nresults); +#endif + write_size(pi, &savedpc); } } @@ -549,10 +826,18 @@ static void persistthread(PersistInfo *pi) size_t stackbase = L2->base - L2->stack; size_t stacktop = L2->top - L2->stack; lua_assert(L2->nCcalls <= 1); - pi->writer(pi->L, &L2->status, sizeof(lu_byte), pi->ud); - pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud); - pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud); - pi->writer(pi->L, &L2->errfunc, sizeof(ptrdiff_t), pi->ud); + pi_write(pi, &L2->status, sizeof(lu_byte), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistthread_status %d\n", (int) L2->status); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistthread_status %d\n", (int) L2->status); +#endif + write_size(pi, &stackbase); + write_size(pi, &stacktop); + pi_write(pi, &L2->errfunc, sizeof(ptrdiff_t), pi->ud); + //write_size(pi, (size_t *)&L2->errfunc); } /* Finally, record upvalues which need to be reopened */ @@ -573,7 +858,7 @@ static void persistthread(PersistInfo *pi) lua_pop(pi->L, 1); /* perms reftbl ... thr */ stackpos = uv->v - L2->stack; - pi->writer(pi->L, &stackpos, sizeof(size_t), pi->ud); + write_size(pi, &stackpos); } /* perms reftbl ... thr */ lua_pushnil(pi->L); @@ -588,26 +873,62 @@ static void persistthread(PersistInfo *pi) static void persistboolean(PersistInfo *pi) { int b = lua_toboolean(pi->L, -1); - pi->writer(pi->L, &b, sizeof(int), pi->ud); + pi_write(pi, &b, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistboolean %d\n", b); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistboolean %d\n", b); +#endif } static void persistlightuserdata(PersistInfo *pi) { void *p = lua_touserdata(pi->L, -1); - pi->writer(pi->L, &p, sizeof(void *), pi->ud); + pi_write(pi, &p, sizeof(void *), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistlightuserdata %p\n", p); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistlightuserdata %d\n", (int) p); +#endif } static void persistnumber(PersistInfo *pi) { lua_Number n = lua_tonumber(pi->L, -1); - pi->writer(pi->L, &n, sizeof(lua_Number), pi->ud); + pi_write(pi, &n, sizeof(lua_Number), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number)); + hrOut(pi); + } +#ifdef TOTEXT + printf("persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number)); +#endif } static void persiststring(PersistInfo *pi) { + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persiststring\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persiststring\n"); +#endif size_t length = lua_strlen(pi->L, -1); - pi->writer(pi->L, &length, sizeof(size_t), pi->ud); - pi->writer(pi->L, lua_tostring(pi->L, -1), length, pi->ud); + write_size(pi, &length); + const char* s = lua_tostring(pi->L, -1); + pi_write(pi, s, length, pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persiststring %d \"%s\"\n", (int)length, s); + hrOut(pi); + } +#ifdef TOTEXT + printf("persiststring %d \"%s\"\n", length, s); +#endif } /* Top-level delegating persist function @@ -630,8 +951,22 @@ static void persist(PersistInfo *pi) // since size_t is supposedly the same size as a pointer on most // (modern) architectures. int ref = (int)(size_t)lua_touserdata(pi->L, -1); - pi->writer(pi->L, &zero, sizeof(int), pi->ud); - pi->writer(pi->L, &ref, sizeof(int), pi->ud); + pi_write(pi, &zero, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persist_seenobject\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persist_seenobject\n"); +#endif + pi_write(pi, &ref, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persist_touserdata_ref %d\n", ref); + hrOut(pi); + } +#ifdef TOTEXT + printf("persist_touserdata_ref %d\n", ref); +#endif lua_pop(pi->L, 1); /* perms reftbl ... obj ref */ #ifdef PLUTO_DEBUG @@ -647,9 +982,16 @@ static void persist(PersistInfo *pi) if(lua_isnil(pi->L, -1)) { int zero = 0; /* firsttime */ - pi->writer(pi->L, &zero, sizeof(int), pi->ud); + pi_write(pi, &zero, sizeof(int), pi->ud); /* ref */ - pi->writer(pi->L, &zero, sizeof(int), pi->ud); + pi_write(pi, &zero, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persist_nil (last 2 lines)\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persist_nil (last 2 lines)\n"); +#endif #ifdef PLUTO_DEBUG printindent(pi->level); printf("0 0\n"); @@ -659,7 +1001,14 @@ static void persist(PersistInfo *pi) { /* indicate that it's the first time */ int one = 1; - pi->writer(pi->L, &one, sizeof(int), pi->ud); + pi_write(pi, &one, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persist_newobject\n"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persist_newobject\n"); +#endif } lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ @@ -668,7 +1017,14 @@ static void persist(PersistInfo *pi) lua_rawset(pi->L, 2); /* perms reftbl ... obj */ - pi->writer(pi->L, &pi->counter, sizeof(int), pi->ud); + pi_write(pi, &pi->counter, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persist_counter %d\n", pi->counter); + hrOut(pi); + } +#ifdef TOTEXT + printf("persist_counter %d\n", pi->counter); +#endif /* At this point, we'll give the permanents table a chance to play. */ @@ -685,7 +1041,14 @@ static void persist(PersistInfo *pi) printf("1 %d PERM\n", pi->counter); pi->level++; #endif - pi->writer(pi->L, &type, sizeof(int), pi->ud); + pi_write(pi, &type, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persist_permtype %d\n", type); + hrOut(pi); + } +#ifdef TOTEXT + printf("persist_permtype %d\n", type); +#endif persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... obj */ @@ -702,7 +1065,14 @@ static void persist(PersistInfo *pi) } { int type = lua_type(pi->L, -1); - pi->writer(pi->L, &type, sizeof(int), pi->ud); + pi_write(pi, &type, sizeof(int), pi->ud); + if (humanReadable) { + snprintf(hrBuf, hrBufSize, "persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?"); + hrOut(pi); + } +#ifdef TOTEXT + printf("persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?"); +#endif #ifdef PLUTO_DEBUG printindent(pi->level); @@ -798,8 +1168,8 @@ typedef struct WriterInfo_t { size_t buflen; } WriterInfo; -static int bufwriter (lua_State *L, const void* p, size_t sz, void* ud) { - const char* cp = (const char*)p; +static int bufwriter (lua_State *L, const void *p, size_t sz, void *ud) { + const char *cp = (const char *)p; WriterInfo *wi = (WriterInfo *)ud; LIF(M,reallocvector)(L, wi->buf, wi->buflen, wi->buflen+sz, char); @@ -819,7 +1189,7 @@ int persist_l(lua_State *L) wi.buf = NULL; wi.buflen = 0; - + lua_settop(L, 2); /* perms? rootobj? */ luaL_checktype(L, 1, LUA_TTABLE); @@ -895,10 +1265,13 @@ static void unpersistnumber(UnpersistInfo *upi) static void unpersiststring(UnpersistInfo *upi) { /* perms reftbl sptbl ref */ + /*int length;*/ size_t length; char* string; lua_checkstack(upi->L, 1); - verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0); + /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(int)) == 0);*/ + /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0);*/ + read_size(&upi->zio, &length); string = pdep_newvector(upi->L, length, char); verify(LIF(Z,read)(&upi->zio, string, length) == 0); lua_pushlstring(upi->L, string, length); @@ -1312,7 +1685,7 @@ static void unpersistthread(int ref, UnpersistInfo *upi) /* First, deserialize the object stack. */ { size_t i, stacksize; - verify(LIF(Z,read)(&upi->zio, &stacksize, sizeof(size_t)) == 0); + read_size(&upi->zio, &stacksize); LIF(D,growstack)(L2, (int)stacksize); /* Make sure that the first stack element (a nil, representing * the imaginary top-level C function) is written to the very, @@ -1331,16 +1704,16 @@ static void unpersistthread(int ref, UnpersistInfo *upi) /* Now, deserialize the CallInfo stack. */ { size_t i, numframes; - verify(LIF(Z,read)(&upi->zio, &numframes, sizeof(size_t)) == 0); + read_size(&upi->zio, &numframes); LIF(D,reallocCI)(L2,numframes*2); for(i=0; i<numframes; i++) { CallInfo *ci = L2->base_ci + i; size_t stackbase, stackfunc, stacktop, savedpc; - verify(LIF(Z,read)(&upi->zio, &stackbase, sizeof(size_t)) == 0); - verify(LIF(Z,read)(&upi->zio, &stackfunc, sizeof(size_t)) == 0); - verify(LIF(Z,read)(&upi->zio, &stacktop, sizeof(size_t)) == 0); + read_size(&upi->zio, &stackbase); + read_size(&upi->zio, &stackfunc); + read_size(&upi->zio, &stacktop); verify(LIF(Z,read)(&upi->zio, &ci->nresults, sizeof(int)) == 0); - verify(LIF(Z,read)(&upi->zio, &savedpc, sizeof(size_t)) == 0); + read_size(&upi->zio, &savedpc); if(stacklimit < stacktop) stacklimit = stacktop; @@ -1363,9 +1736,10 @@ static void unpersistthread(int ref, UnpersistInfo *upi) size_t stackbase, stacktop; L2->savedpc = L2->ci->savedpc; verify(LIF(Z,read)(&upi->zio, &L2->status, sizeof(lu_byte)) == 0); - verify(LIF(Z,read)(&upi->zio, &stackbase, sizeof(size_t)) == 0); - verify(LIF(Z,read)(&upi->zio, &stacktop, sizeof(size_t)) == 0); + read_size(&upi->zio, &stackbase); + read_size(&upi->zio, &stacktop); verify(LIF(Z,read)(&upi->zio, &L2->errfunc, sizeof(ptrdiff_t)) == 0); + //read_size(&upi->zio, (size_t *)&L2->errfunc); L2->base = L2->stack + stackbase; L2->top = L2->stack + stacktop; } @@ -1391,7 +1765,7 @@ static void unpersistthread(int ref, UnpersistInfo *upi) lua_pop(upi->L, 1); /* perms reftbl ... thr */ - verify(LIF(Z,read)(&upi->zio, &stackpos, sizeof(size_t)) == 0); + read_size(&upi->zio, &stackpos); uv->v = L2->stack + stackpos; gcunlink(upi->L, (GCObject *)uv); uv->marked = luaC_white(g); @@ -1443,7 +1817,7 @@ static void unpersistuserdata(int ref, UnpersistInfo *upi) /* perms reftbl ... udata */ } else { size_t length; - verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0); + read_size(&upi->zio, &length); lua_newuserdata(upi->L, length); /* perms reftbl ... udata */ @@ -1611,8 +1985,8 @@ void pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud) } typedef struct LoadInfo_t { - char *buf; - size_t size; + char *buf; + size_t size; } LoadInfo; @@ -1653,9 +2027,41 @@ int unpersist_l(lua_State *L) return 1; } +/* Stefan's first C function for Lua! :) + Returns a string describing the Pluto version you're using. */ + +int version_l(lua_State *L) +{ + const char *version = VERSION; + + lua_settop(L, 0); + /* (empty) */ + lua_pushlstring(L, version, strlen(version)); + /* str */ + return 1; +} + +/* Set human-readable output on or off. */ +int human_l(lua_State *L) +{ + /* flag? ...? */ + lua_settop(L, 1); + /* flag? */ + /*luaL_checktype(L, 1, LUA_TBOOLEAN);*/ + /* flag */ + + humanReadable = lua_toboolean(L, 1); + + lua_settop(L, 0); + /* (empty) */ + return 0; +} + static luaL_reg pluto_reg[] = { { "persist", persist_l }, { "unpersist", unpersist_l }, + { "version", version_l }, + { "human", human_l }, { NULL, NULL } }; diff --git a/engines/teenagent/callbacks.cpp b/engines/teenagent/callbacks.cpp index 2de81abb37..3e6e40a8fa 100644 --- a/engines/teenagent/callbacks.cpp +++ b/engines/teenagent/callbacks.cpp @@ -294,7 +294,7 @@ bool TeenAgentEngine::fnRobotSafeAlreadyUnlockedCheck() { } void TeenAgentEngine::fnRobotSafeUnlockCheck() { - if (CHECK_FLAG(dsAddr_MansionRobotSafeVoiceTestPassedFlag, 1) && + if (CHECK_FLAG(dsAddr_MansionRobotSafeVoiceTestPassedFlag, 1) && CHECK_FLAG(dsAddr_MansionRobotSafeScentTestPassedFlag, 1) && CHECK_FLAG(dsAddr_MansionRobotSafeViewTestPassedFlag, 1)) { waitLanAnimationFrame(1, 1); @@ -546,7 +546,7 @@ bool TeenAgentEngine::processCallback(uint16 addr) { break; case 0x4056: - // FIXME - This is the bird use callback in the first act at + // FIXME - This is the bird use callback in the first act at // the mudpool. Current Code based on behaviour. Need to analyse cseg data. dialog->popMark(scene, dsAddr_dialogStackMudpoolBird); break; @@ -1603,7 +1603,7 @@ bool TeenAgentEngine::processCallback(uint16 addr) { break; case 0x5b44: - // FIXME - This is the doorbell use callback on House #2 + // FIXME - This is the doorbell use callback on House #2 // i.e. Granny and Anne's House. Need to analyse cseg data properly. // Current code inferred from behaviour. // FIXME - Add animation call for Ego pushing doorbell. diff --git a/engines/teenagent/dialog.cpp b/engines/teenagent/dialog.cpp index 870aca6400..312757a462 100644 --- a/engines/teenagent/dialog.cpp +++ b/engines/teenagent/dialog.cpp @@ -28,7 +28,7 @@ namespace TeenAgent { void Dialog::show(uint16 dialogNum, Scene *scene, uint16 animation1, uint16 animation2, byte color1, byte color2, byte slot1, byte slot2) { uint16 addr = _vm->res->getDialogAddr(dialogNum); - // WORKAROUND: For Dialog 163, The usage of this in the engine overlaps the previous dialog i.e. the + // WORKAROUND: For Dialog 163, The usage of this in the engine overlaps the previous dialog i.e. the // starting offset used is two bytes early, thus implicitly changing the first command of this dialog // from NEW_LINE to CHANGE_CHARACTER. // FIXME: Unsure if this is correct behaviour or if this is a regression from the original. Check this. diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp index 3921414b01..104adf72a2 100644 --- a/engines/tinsel/handle.cpp +++ b/engines/tinsel/handle.cpp @@ -300,7 +300,7 @@ void LoadFile(MEMHANDLE *pH) { // discardable - unlock the memory MemoryUnlock(pH->_node); - + // set the loaded flag pH->filesize |= fLoaded; diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp index 17cb23b98f..43654fc3af 100644 --- a/engines/tinsel/scene.cpp +++ b/engines/tinsel/scene.cpp @@ -138,7 +138,7 @@ const SCENE_STRUC *GetSceneStruc(const byte *pStruc) { g_tempStruc.hEntrance = READ_32(p); p += sizeof(uint32); g_tempStruc.hPoly = READ_32(p); p += sizeof(uint32); g_tempStruc.hTaggedActor = READ_32(p); p += sizeof(uint32); - + return &g_tempStruc; } diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp index 479f4965f3..83c9e3ec70 100644 --- a/engines/toon/character.cpp +++ b/engines/toon/character.cpp @@ -58,6 +58,7 @@ Character::Character(ToonEngine *vm) : _vm(vm) { _animSpecialDefaultId = 0; _currentPathNode = 0; _currentWalkStamp = 0; + _currentFacingStamp = 0; _visible = true; _speed = 150; // 150 = nominal drew speed _lastWalkTime = 0; @@ -99,6 +100,9 @@ void Character::setFacing(int32 facing) { if (_blockingWalk) { _flags |= 2; + _currentFacingStamp++; + int32 localFacingStamp = _currentFacingStamp; + int32 dir = 0; _lastWalkTime = _vm->_system->getMillis(); @@ -127,6 +131,11 @@ void Character::setFacing(int32 facing) { else playWalkAnim(0, 0); _vm->doFrame(); + + if (_currentFacingStamp != localFacingStamp) { + // another setFacing was started in doFrame, we need to cancel this one. + return; + } }; _flags &= ~2; diff --git a/engines/toon/character.h b/engines/toon/character.h index d33c314bf7..b248e7ccf2 100644 --- a/engines/toon/character.h +++ b/engines/toon/character.h @@ -143,6 +143,7 @@ protected: Common::Array<Common::Point> _currentPath; uint32 _currentPathNode; int32 _currentWalkStamp; + int32 _currentFacingStamp; }; } // End of namespace Toon diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp index de5ac62425..bae0249eaa 100644 --- a/engines/tsage/converse.cpp +++ b/engines/tsage/converse.cpp @@ -543,7 +543,7 @@ void Obj44::load(const byte *dataP) { _lookupValue = s.readSint16LE(); _lookupIndex = s.readSint16LE(); _field6 = s.readSint16LE(); - _field8 = s.readSint16LE(); + _speakerMode = s.readSint16LE(); } _id = s.readSint16LE(); @@ -579,7 +579,7 @@ void Obj44::synchronize(Serializer &s) { s.syncAsSint16LE(_lookupValue); s.syncAsSint16LE(_lookupIndex); s.syncAsSint16LE(_field6); - s.syncAsSint16LE(_field8); + s.syncAsSint16LE(_speakerMode); s.syncAsSint16LE(_field16); } } @@ -843,8 +843,12 @@ void StripManager::signal() { } } - if ((g_vm->getGameID() == GType_Ringworld2) && (_obj44List.size() > 0)) - static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker)->proc15(); + if (g_vm->getGameID() == GType_Ringworld2) { + Ringworld2::VisualSpeaker *speaker = static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker); + speaker->_speakerMode = obj44._speakerMode; + if (_obj44List.size() > 0) + speaker->proc15(); + } _textShown = true; _activeSpeaker->setText(choiceList[strIndex]); diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h index 0c4eb9539d..accd2d49cd 100644 --- a/engines/tsage/converse.h +++ b/engines/tsage/converse.h @@ -190,7 +190,7 @@ public: // Return to Ringworld specific field int _mode; int _lookupValue, _lookupIndex, _field6; - int _field8, _field16; + int _speakerMode, _field16; public: void load(const byte *dataP); virtual void synchronize(Serializer &s); diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index 4a90e23a33..b6ed17aacb 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -2468,10 +2468,10 @@ void SceneObject::postInit(SceneObjectList *OwnerList) { if (!OwnerList) OwnerList = g_globals->_sceneObjects; - if (!OwnerList->contains(this)) { + if (!OwnerList->contains(this) || ((_flags & OBJFLAG_REMOVE) != 0)) { _percent = 100; _priority = 255; - _flags = 4; + _flags = OBJFLAG_ZOOMED; _visage = 0; _strip = 1; _frame = 1; @@ -2724,7 +2724,9 @@ void SceneObject::setup(int visage, int stripFrameNum, int frameNum, int posX, i } void SceneObject::setup(int visage, int stripFrameNum, int frameNum) { - postInit(); + if (g_vm->getGameID() != GType_Ringworld2) + postInit(); + setVisage(visage); setStrip(stripFrameNum); setFrame(frameNum); @@ -3103,6 +3105,7 @@ Visage::Visage() { _rlbNum = -1; _data = NULL; _flipHoriz = false; + _flipVert = false; } Visage::Visage(const Visage &v) { @@ -3112,6 +3115,7 @@ Visage::Visage(const Visage &v) { if (_data) g_vm->_memoryManager.incLocks(_data); _flipHoriz = false; + _flipVert = false; } Visage &Visage::operator=(const Visage &s) { @@ -3155,8 +3159,11 @@ void Visage::setVisage(int resNum, int rlbNum) { rlbNum = (int)(v & 0xff); } _flipHoriz = flags & 1; + _flipVert = flags & 2; _data = g_resourceManager->getResource(RES_VISAGE, resNum, rlbNum); + + DEALLOCATE(indexData); } } @@ -3179,7 +3186,9 @@ GfxSurface Visage::getFrame(int frameNum) { byte *frameData = _data + offset; GfxSurface result = surfaceFromRes(frameData); - if (_flipHoriz) flip(result); + if (_flipHoriz) flipHorizontal(result); + if (_flipVert) flipVertical(result); + return result; } @@ -3187,7 +3196,7 @@ int Visage::getFrameCount() const { return READ_LE_UINT16(_data); } -void Visage::flip(GfxSurface &gfxSurface) { +void Visage::flipHorizontal(GfxSurface &gfxSurface) { Graphics::Surface s = gfxSurface.lockSurface(); for (int y = 0; y < s.h; ++y) { @@ -3200,6 +3209,21 @@ void Visage::flip(GfxSurface &gfxSurface) { gfxSurface.unlockSurface(); } +void Visage::flipVertical(GfxSurface &gfxSurface) { + Graphics::Surface s = gfxSurface.lockSurface(); + + for (int y = 0; y < s.h / 2; ++y) { + // Flip the lines1 + byte *line1P = (byte *)s.getBasePtr(0, y); + byte *line2P = (byte *)s.getBasePtr(0, s.h - y - 1); + + for (int x = 0; x < s.w; ++x) + SWAP(line1P[x], line2P[x]); + } + + gfxSurface.unlockSurface(); +} + /*--------------------------------------------------------------------------*/ Player::Player(): SceneObject() { diff --git a/engines/tsage/core.h b/engines/tsage/core.h index 296754011e..655bd234e6 100644 --- a/engines/tsage/core.h +++ b/engines/tsage/core.h @@ -472,11 +472,13 @@ class Visage { private: byte *_data; - void flip(GfxSurface &s); + void flipHorizontal(GfxSurface &s); + void flipVertical(GfxSurface &s); public: int _resNum; int _rlbNum; bool _flipHoriz; + bool _flipVert; public: Visage(); Visage(const Visage &v); diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp index 4589a926c9..27cda63aaa 100644 --- a/engines/tsage/globals.cpp +++ b/engines/tsage/globals.cpp @@ -366,14 +366,28 @@ bool BlueForceGlobals::removeFlag(int flagNum) { namespace Ringworld2 { +Ringworld2Globals::Ringworld2Globals() { + _scannerDialog = new ScannerDialog(); +} + +Ringworld2Globals::~Ringworld2Globals() { + delete _scannerDialog; +} + void Ringworld2Globals::reset() { Globals::reset(); + if (!_scannerDialog) + _scannerDialog = new ScannerDialog(); + // Reset the inventory R2_INVENTORY.reset(); T2_GLOBALS._uiElements.updateInventory(); T2_GLOBALS._uiElements._active = false; + // Set the screen to track the player + _scrollFollower = &_player; + // Reset fields Common::fill(&_v1000[0], &_v1000[0x1000], 0); _v1000Flag = false; @@ -382,14 +396,15 @@ void Ringworld2Globals::reset() { _v558C2 = 0; _animationCtr = 0; _v5657C = 0; - _v565E1 = 0; - _v565E3 = 0; + _electromagnetChangeAmount = 0; + _electromagnetZoom = 0; _v565E5 = 0; _v565E7 = 0; _v565E9 = -5; _v565EB = 26; _v565F5 = 0; _v565F6 = 0; + _v565F8 = 0; _v565FA = 0; _v565AE = 0; _v56605[0] = 0; @@ -463,7 +478,7 @@ void Ringworld2Globals::reset() { _v565EC[2] = 27; _v565EC[3] = 4; _v565EC[4] = 4; - Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 1); + Common::fill(&_scannerFrequencies[0], &_scannerFrequencies[MAX_CHARACTERS], 1); _speechSubtitles = SPEECH_VOICE | SPEECH_TEXT; _insetUp = 0; _frameEdgeColour = 2; @@ -496,14 +511,15 @@ void Ringworld2Globals::synchronize(Serializer &s) { s.syncAsSint16LE(_v558C2); s.syncAsSint16LE(_animationCtr); s.syncAsSint16LE(_v5657C); - s.syncAsSint16LE(_v565E1); - s.syncAsSint16LE(_v565E3); + s.syncAsSint16LE(_electromagnetChangeAmount); + s.syncAsSint16LE(_electromagnetZoom); s.syncAsSint16LE(_v565E5); s.syncAsSint16LE(_v565E7); s.syncAsSint16LE(_v565E9); s.syncAsSint16LE(_v565EB); s.syncAsSint16LE(_v565F5); s.syncAsSint16LE(_v565F6); + s.syncAsSint16LE(_v565F8); s.syncAsSint16LE(_v565FA); s.syncAsSint16LE(_v566A3); s.syncAsSint16LE(_v566A6); @@ -525,7 +541,7 @@ void Ringworld2Globals::synchronize(Serializer &s) { s.syncAsByte(_v565EC[i]); for (i = 0; i < MAX_CHARACTERS; ++i) - s.syncAsByte(_v565F1[i]); + s.syncAsByte(_scannerFrequencies[i]); s.syncAsByte(_v565AE); s.syncAsByte(_v566A4); diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h index d190b6a2a4..40254bd11e 100644 --- a/engines/tsage/globals.h +++ b/engines/tsage/globals.h @@ -247,6 +247,8 @@ namespace Ringworld2 { #define k5A790 18 #define k5A791 17 +class ScannerDialog; + class Ringworld2Globals: public TsAGE2Globals { public: ASoundExt _sound1, _sound2, _sound3, _sound4; @@ -261,14 +263,15 @@ public: Rect _v558B6; int _v558C2; int _animationCtr; - int _v565E1; - int _v565E3; + int _electromagnetChangeAmount; + int _electromagnetZoom; int _v565E5; int _v565E7; int _v565E9; int _v565EB; int _v565F5; int _v565F6; + int _v565F8; int _v565FA; int _v5657C; byte _v565AE; @@ -302,9 +305,12 @@ public: int _v57C2C; int _speechSubtitles; byte _v565EC[5]; - byte _v565F1[4]; + byte _scannerFrequencies[4]; byte _stripManager_lookupList[12]; + ScannerDialog *_scannerDialog; + Ringworld2Globals(); + virtual ~Ringworld2Globals(); virtual void reset(); virtual void synchronize(Serializer &s); }; diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp index fb0b0b0cbb..a010b46ea5 100644 --- a/engines/tsage/graphics.cpp +++ b/engines/tsage/graphics.cpp @@ -234,9 +234,14 @@ GfxSurface::GfxSurface(const GfxSurface &s) { } GfxSurface::~GfxSurface() { + clear(); +} + +void GfxSurface::clear() { if (_customSurface) { _customSurface->free(); delete _customSurface; + _customSurface = NULL; } } @@ -289,8 +294,11 @@ void GfxSurface::addDirtyRect(const Rect &r) { r2.translate(_bounds.left, _bounds.top); // Add to the dirty rect list - _dirtyRects.push_back(Rect(r2.left, r2.top, - MIN(r2.right + 1, SCREEN_WIDTH), MIN(r2.bottom + 1, SCREEN_HEIGHT))); + r2.right = MIN(r2.right + 1, SCREEN_WIDTH); + r2.bottom = MIN(r2.bottom + 1, SCREEN_HEIGHT); + + if (r2.isValidRect()) + _dirtyRects.push_back(r2); } } @@ -1322,6 +1330,12 @@ void GfxManager::copyFrom(GfxSurface &src, int destX, int destY) { _surface.copyFrom(src, destX, destY); } +void GfxManager::copyFrom(GfxSurface &src, const Rect &srcBounds, const Rect &destBounds) { + _surface.setBounds(_bounds); + + _surface.copyFrom(src, srcBounds, destBounds); +} + /*--------------------------------------------------------------------------*/ diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h index 826f2fef6f..7239a99a68 100644 --- a/engines/tsage/graphics.h +++ b/engines/tsage/graphics.h @@ -100,6 +100,7 @@ public: void unlockSurface(); void synchronize(Serializer &s); void create(int width, int height); + void clear(); void setBounds(const Rect &bounds) { _bounds = bounds; } const Rect &getBounds() const { return _bounds; } @@ -302,6 +303,7 @@ public: } void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL); void copyFrom(GfxSurface &src, int destX, int destY); + void copyFrom(GfxSurface &src, const Rect &srcBounds, const Rect &destBounds); GfxSurface &getSurface() { _surface.setBounds(_bounds); diff --git a/engines/tsage/ringworld/ringworld_scenes1.cpp b/engines/tsage/ringworld/ringworld_scenes1.cpp index 4d9d565705..89c07273fc 100644 --- a/engines/tsage/ringworld/ringworld_scenes1.cpp +++ b/engines/tsage/ringworld/ringworld_scenes1.cpp @@ -2273,6 +2273,7 @@ void Scene60::Item1::doAction(int action) { } else { scene->setAction(&scene->_action2); } + break; default: SceneHotspot::doAction(action); break; diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp index 478fdcf5a5..57fdef6405 100644 --- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp +++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp @@ -236,7 +236,7 @@ void CharacterDialog::show() { // Play a transition sound as the character is changed if (R2_GLOBALS._player._characterScene[0] != 300) { - switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) { + switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex]) { case 0: R2_GLOBALS._sound4.stop(); break; @@ -255,8 +255,8 @@ void CharacterDialog::show() { default: break; } - } else if (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex] > 1) { - switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) { + } else if (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] > 1) { + switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex]) { case 2: R2_GLOBALS._sound4.play(45); break; @@ -272,8 +272,8 @@ void CharacterDialog::show() { default: break; } - } else if ((R2_GLOBALS._player._characterScene[1] == 300) && (R2_GLOBALS._v565F1[1] != 1)) { - switch (R2_GLOBALS._v565F1[1]) { + } else if ((R2_GLOBALS._player._characterScene[1] == 300) && (R2_GLOBALS._scannerFrequencies[1] != 1)) { + switch (R2_GLOBALS._scannerFrequencies[1]) { case 2: R2_GLOBALS._sound4.play(45); break; @@ -291,10 +291,10 @@ void CharacterDialog::show() { } } else if (R2_GLOBALS._player._characterScene[2] != 300) { R2_GLOBALS._sound4.stop(); - } else if (R2_GLOBALS._v565F1[2] == 1) { + } else if (R2_GLOBALS._scannerFrequencies[2] == 1) { R2_GLOBALS._sound4.stop(); } else { - switch (R2_GLOBALS._v565F1[1]) { + switch (R2_GLOBALS._scannerFrequencies[1]) { case 2: R2_GLOBALS._sound4.play(45); break; diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp index 97042cb621..6dabbbc368 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.cpp +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -21,6 +21,8 @@ */ #include "common/config-manager.h" +#include "common/rect.h" +#include "tsage/graphics.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" @@ -86,8 +88,10 @@ Scene *Ringworld2Game::createScene(int sceneNumber) { // Cutscene - Walking in hall return new Scene525(); case 600: + // Drive Room return new Scene600(); case 700: + // Lander Bay 2 return new Scene700(); case 800: // Sick bay @@ -99,6 +103,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) { // Deck #5 - By Lift return new Scene850(); case 900: + // Lander Bay 2 - Crane Controls return new Scene900(); /* Scene group #1 */ // @@ -166,7 +171,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) { // Ice Maze: Large empty room return new Scene2400(); case 2425: - // Ice Maze: + // Ice Maze: The Hall of Records return new Scene2425(); case 2430: // Ice Maze: Bedroom @@ -213,7 +218,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) { case 2900: error("Missing scene %d from group 2", sceneNumber); /* Scene group #3 */ - // + // ARM Base Hanager case 3100: return new Scene3100(); case 3125: @@ -258,16 +263,22 @@ Scene *Ringworld2Game::createScene(int sceneNumber) { // Cutscene - Ship landing return new Scene3350(); case 3375: + // Outer walkway return new Scene3375(); case 3385: + // Corridor return new Scene3385(); case 3395: + // Walkway return new Scene3395(); case 3400: + // Confrontation return new Scene3400(); case 3500: + // Maze action sequencec return new Scene3500(); case 3600: + // Cutscene - walking at gunpoint return new Scene3600(); case 3700: // Cutscene - Teleport outside @@ -407,14 +418,16 @@ bool SceneExt::display(CursorType action, Event &event) { SceneItem::display2(5, 0); break; case R2_SONIC_STUNNER: - if ((R2_GLOBALS._v565F1[1] == 2) || ((R2_GLOBALS._v565F1[1] == 1) && - (R2_GLOBALS._v565F1[2] == 2) && (R2_GLOBALS._sceneManager._previousScene == 300))) { + if ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 2) + || ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 1) && + (R2_GLOBALS._scannerFrequencies[R2_SEEKER] == 2) && + (R2_GLOBALS._sceneManager._previousScene == 300))) { R2_GLOBALS._sound4.stop(); R2_GLOBALS._sound3.play(46); SceneItem::display2(5, 15); } else { R2_GLOBALS._sound3.play(43, 0); - SceneItem::display2(2, 0); + SceneItem::display2(2, R2_SONIC_STUNNER); } R2_GLOBALS._sound4.play(45); @@ -573,7 +586,7 @@ void SceneHandlerExt::process(Event &event) { SceneExt *scene = static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene); if (scene && R2_GLOBALS._player._uiEnabled) { // Handle any scene areas that have been registered - SynchronizedList<SceneArea *>::iterator saIter; + SynchronizedList<EventHandler *>::iterator saIter; for (saIter = scene->_sceneAreas.begin(); saIter != scene->_sceneAreas.end() && !event.handled; ++saIter) { (*saIter)->process(event); } @@ -842,6 +855,7 @@ Ringworld2InvObjectList::Ringworld2InvObjectList(): _itemList.push_back(&_inv52); _selectedItem = NULL; + } void Ringworld2InvObjectList::reset() { @@ -904,6 +918,9 @@ void Ringworld2InvObjectList::reset() { setObjectScene(R2_ALCOHOL_LAMP_3, 2435); setObjectScene(R2_BROKEN_DISPLAY, 1580); setObjectScene(R2_TOOLBOX, 3260); + + // Set up the select item handler method + T2_GLOBALS._onSelectItem = SelectItem; } void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) { @@ -921,6 +938,125 @@ void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) { T2_GLOBALS._uiElements.updateInventory(); } +/** + * When an inventory item is selected, in Return to Ringworld two objects can be combined + */ +bool Ringworld2InvObjectList::SelectItem(int objectNumber) { + // If no existing item selected, don't go any further + int currentItem = R2_GLOBALS._events.getCursor(); + if (currentItem >= 256) + return false; + + switch (objectNumber) { + case R2_NEGATOR_GUN: + switch (currentItem) { + case R2_SENSOR_PROBE: + if (R2_GLOBALS.getFlag(1)) + SceneItem::display2(5, 1); + else if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) == 100) + SceneItem::display(5, 3); + else { + R2_GLOBALS._sound3.play(48); + SceneItem::display2(5, 2); + R2_INVENTORY.setObjectScene(R2_SPENT_POWER_CAPSULE, 1); + } + break; + case R2_COM_SCANNER: + R2_GLOBALS._sound3.play(44); + if (R2_GLOBALS.getFlag(1)) + SceneItem::display2(5, 9); + else if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) == 100) + SceneItem::display2(5, 8); + else + SceneItem::display2(5, 10); + break; + case R2_CHARGED_POWER_CAPSULE: + if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) == 1) { + R2_GLOBALS._sound3.play(49); + R2_INVENTORY.setObjectScene(R2_CHARGED_POWER_CAPSULE, 100); + R2_GLOBALS.setFlag(1); + SceneItem::display2(5, 4); + } else { + SceneItem::display2(5, 5); + } + break; + default: + selectDefault(objectNumber); + break; + } + break; + case R2_STEPPING_DISKS: + switch (currentItem) { + case R2_SENSOR_PROBE: + if (R2_INVENTORY.getObjectScene(R2_CHARGED_POWER_CAPSULE) == 400) { + R2_GLOBALS._sound3.play(48); + SceneItem::display2(5, 6); + R2_INVENTORY.setObjectScene(R2_CHARGED_POWER_CAPSULE, 1); + } else { + SceneItem::display2(5, 7); + } + break; + case R2_COM_SCANNER: + R2_GLOBALS._sound3.play(44); + if (R2_INVENTORY.getObjectScene(R2_CHARGED_POWER_CAPSULE) == 400) + SceneItem::display2(5, 16); + else + SceneItem::display2(5, 17); + R2_GLOBALS._sound3.stop(); + break; + default: + selectDefault(objectNumber); + break; + } + break; + case R2_ATTRACTOR_UNIT: + case R2_CABLE_HARNESS: + if (currentItem == R2_CABLE_HARNESS || + currentItem == R2_ATTRACTOR_UNIT) { + R2_INVENTORY.setObjectScene(R2_CABLE_HARNESS, 0); + R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0); + R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 1); + } else { + selectDefault(objectNumber); + } + break; + case R2_TANNER_MASK: + case R2_PURE_GRAIN_ALCOHOL: + if (currentItem == R2_TANNER_MASK || + currentItem == R2_PURE_GRAIN_ALCOHOL) { + R2_INVENTORY.setObjectScene(R2_TANNER_MASK, 0); + R2_INVENTORY.setObjectScene(R2_PURE_GRAIN_ALCOHOL, 0); + R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 1); + } else { + selectDefault(objectNumber); + } + break; + default: + // Standard item selection + return false; + } + + return true; +} + +void Ringworld2InvObjectList::selectDefault(int objectNumber) { + Common::String msg1 = g_resourceManager->getMessage(4, 53); + Common::String msg2 = g_resourceManager->getMessage(4, R2_GLOBALS._events.getCursor()); + Common::String msg3 = g_resourceManager->getMessage(4, 54); + Common::String msg4 = g_resourceManager->getMessage(4, objectNumber); + Common::String line = Common::String::format("%.5s%.5s%.5s%.5s%s %s %s %s.", + msg1.c_str(), msg2.c_str(), msg3.c_str(), msg4.c_str(), + msg1.c_str() + 5, msg2.c_str() + 5, msg3.c_str() + 5, msg4.c_str() + 5); + + SceneItem::display(-1, -1, line.c_str(), + SET_WIDTH, 280, + SET_X, 160, + SET_Y, 20, + SET_POS_MODE, 1, + SET_EXT_BGCOLOR, 7, + LIST_END); +} + /*--------------------------------------------------------------------------*/ void Ringworld2Game::start() { @@ -1083,6 +1219,14 @@ void SceneActor::postInit(SceneObjectList *OwnerList) { SceneObject::postInit(); } +void SceneActor::remove() { + R2_GLOBALS._sceneItems.remove(this); + _field9C = NULL; + _linkedActor = NULL; + + SceneObject::remove(); +} + bool SceneActor::startAction(CursorType action, Event &event) { bool handled = true; @@ -1268,287 +1412,206 @@ void SceneAreaObject::setDetails(int resNum, int lookLineNum, int talkLineNum, i /*****************************************************************************/ -UnkObject1200::UnkObject1200() { - _field16 = _field3A = NULL; - _field12 = _field14 = 0; - _field26 = _field28 = _field2A = _field2C = _field2E = _field30 = 0; - _field32 = _field34 = _field36 = _field38 = _field3E = _field40 = 0; +MazeUI::MazeUI() { + _mapData = NULL; + _cellsVisible.x = _cellsVisible.y = 0; + _mapCells.x = _mapCells.y = 0; + _cellSize.x = _cellSize.y = 0; + _mapOffset.x = _mapOffset.y = 0; + _resNum = _cellsResNum = 0; + _frameCount = _resCount = _mapImagePitch = _unused = 0; } -void UnkObject1200::synchronize(Serializer &s) { - SavedObject::synchronize(s); +MazeUI::~MazeUI() { + DEALLOCATE(_mapData); +} - _rect1.synchronize(s); - _rect2.synchronize(s); +void MazeUI::synchronize(Serializer &s) { + SavedObject::synchronize(s); - // FIXME: syncrhonize _field16 and _field3A + s.syncAsSint16LE(_resNum); + if (s.isLoading()) + load(_resNum); - s.syncAsSint16LE(_field12); - s.syncAsSint16LE(_field14); - s.syncAsSint16LE(_field26); - s.syncAsSint16LE(_field28); - s.syncAsSint16LE(_field2A); - s.syncAsSint16LE(_field2C); - s.syncAsSint16LE(_field2E); - s.syncAsSint16LE(_field30); - s.syncAsSint16LE(_field32); - s.syncAsSint16LE(_field34); - s.syncAsSint16LE(_field36); - s.syncAsSint16LE(_field38); - s.syncAsSint16LE(_field3E); - s.syncAsSint16LE(_field40); + s.syncAsSint16LE(_mapOffset.x); + s.syncAsSint16LE(_mapOffset.y); + s.syncAsSint16LE(_unused); } -void UnkObject1200::sub51AE9(int arg1) { - warning("STUB: UnkObject1200::sub51AE9()"); -} +void MazeUI::load(int resNum) { + postInit(); + clear(); + _resNum = resNum; -int UnkObject1200::sub51AF8(Common::Point pt) { - if (!_rect1.contains(pt)) - return -1; + const byte *header = g_resourceManager->getResource(RT17, resNum, 0); - int tmp1 = (pt.x - _rect1.left + _field2E) / _field2A; - int tmp2 = (pt.y - _rect1.top + _field30) / _field2C; + _cellsResNum = resNum + 1000; + _mapCells.x = READ_LE_UINT16(header + 2); + _mapCells.y = READ_LE_UINT16(header + 4); + _frameCount = 10; + _resCount = _frameCount << 3; - if ((tmp1 >= 0) && (tmp2 >= 0) && (_field26 > tmp1) && (_field28 > tmp2)) - return _field16[(((_field26 * tmp2) + tmp1)* 2)]; + Visage visage; + visage.setVisage(_cellsResNum, 1); - return -1; + GfxSurface frame = visage.getFrame(2); + _cellSize.x = frame.getBounds().width(); + _cellSize.y = frame.getBounds().height(); + + _mapData = g_resourceManager->getResource(RT17, resNum, 1); + + _mapOffset.y = _mapOffset.x = 0; + _cellsVisible.x = (_bounds.width() + _cellSize.x - 1) / _cellSize.x; + _cellsVisible.y = (_bounds.height() + _cellSize.y - 1) / _cellSize.y; + + _mapImagePitch = (_cellsVisible.x + 1) * _cellSize.x; + _mapImage.create(_mapImagePitch, _cellSize.y); + + _mapBounds = Rect(0, 0, _cellSize.x * _mapCells.x, _cellSize.y * _mapCells.y); } -bool UnkObject1200::sub51AFD(Common::Point pt) { - int retval = false; +void MazeUI::clear() { + if (!_resNum) + _resNum = 1; - _field2E = pt.x; - _field30 = pt.y; + if (_mapData) + DEALLOCATE(_mapData); + _mapData = NULL; - if (_field2E < _rect2.top) { - _field2E = _rect2.top; + _mapImage.clear(); +} + +bool MazeUI::setMazePosition(const Common::Point &pt) { + bool retval = false; + + _mapOffset = pt; + + if (_mapOffset.x < _mapBounds.top) { + _mapOffset.x = _mapBounds.top; retval = true; } - if (_field30 < _rect2.left) { - _field30 = _rect2.left; + if (_mapOffset.y < _mapBounds.left) { + _mapOffset.y = _mapBounds.left; retval = true; } - if (_field2E + _rect1.width() > _rect2.right) { - _field2E = _rect2.right - _rect1.width(); + if (_mapOffset.x + _bounds.width() > _mapBounds.right) { + _mapOffset.x = _mapBounds.right - _bounds.width(); retval = true; } - if (_field30 + _rect1.height() > _rect2.bottom) { - _field30 = _rect2.bottom - _rect1.height(); + if (_mapOffset.y + _bounds.height() > _mapBounds.bottom) { + _mapOffset.y = _mapBounds.bottom - _bounds.height(); retval = true; } return retval; } -void UnkObject1200::sub51B02() { - warning("STUB: UnkObject1200::sub51B02()"); +void MazeUI::reposition() { } -void UnkObject1200::sub9EDE8(Rect rect) { - _rect1 = rect; - warning("FIXME: UnkObject1200::sub9EDE8()"); -// _rect1.clip(g_globals->gfxManager()._bounds); -} +void MazeUI::draw() { + int yPos = 0; + int ySize; + Visage visage; -int UnkObject1200::sub9EE22(int &arg1, int &arg2) { - arg1 /= _field2A; - arg2 /= _field2C; + _cellsVisible.y = ((_mapOffset.y % _cellSize.y) + _bounds.height() + + (_cellSize.y - 1)) / _cellSize.y; - if ((arg1 >= 0) && (arg2 >= 0) && (_field26 > arg1) && (_field28 > arg2)) { - return _field16[(((_field26 * arg2) + arg1) * 2)]; - } + // Loop to handle the cell rows of the visible display area one at a time + for (int yCtr = 0; yCtr < _cellsVisible.y; ++yCtr, yPos += ySize) { + int cellY = _mapOffset.y / _cellSize.y + yCtr; - return -1; -} + // Loop to iterate through the horizontal visible cells to build up + // an entire cell high horizontal slice of the map + for (int xCtr = 0; xCtr < _cellsVisible.x; ++xCtr) { + int cellX = _mapOffset.x / _cellSize.x + xCtr; -void Scene1200::sub9DAD6(int indx) { - _object1.sub9EE22(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4); + // Get the type of content to display in the cell + int cell = getCellFromCellXY(Common::Point(cellX, cellY)) - 1; + if (cell >= 0) { + int frameNum = (cell % _frameCount) + 1; + int rlbNum = (cell % _resCount) / _frameCount + 1; + int resNum = _cellsResNum + (cell / _resCount); - switch (indx) { - case 0: - if ( ((_object1.sub51AF8(Common::Point(200, 50)) > 36) || (_object1.sub51AF8(Common::Point(200, 88)) > 36)) - && ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 33) && (_field418 != 4)) - || ((R2_GLOBALS._v56AA2 == 13) && (R2_GLOBALS._v56AA4 == 21) && (_field418 != 2)) - || ((R2_GLOBALS._v56AA2 == 29) && (R2_GLOBALS._v56AA4 == 17) && (_field418 != 1)) - || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 41)) ) - ) { - R2_GLOBALS._player.disableControl(); - _sceneMode = 1200; - setAction(&_sequenceManager, this, 1200, &_actor1, NULL); - } else if (_object1.sub51AF8(Common::Point(200, 69)) == 36) { - switch (_field412 - 1) { - case 0: - if (R2_GLOBALS._player._visage == 3155) - _sceneMode = 15; - else - _sceneMode = 10; - break; - case 1: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 76; - else - _sceneMode = 75; - break; - case 2: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 101; - else - _sceneMode = 100; - break; - case 3: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 111; - else - _sceneMode = 110; - break; - default: - break; - } - R2_GLOBALS._player.disableControl(); - _field412 = 1; - signal(); - } - break; - case 1: - if ( ((_object1.sub51AF8(Common::Point(120, 50)) > 36) || (_object1.sub51AF8(Common::Point(120, 88)) > 36)) - && ( ((R2_GLOBALS._v56AA2 == 7) && (R2_GLOBALS._v56AA4 == 33) && (_field418 != 4)) - || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 21) && (_field418 != 2)) - || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 17) && (_field418 != 1)) - || ((R2_GLOBALS._v56AA2 == 5) && (R2_GLOBALS._v56AA4 == 5)) ) - ) { - R2_GLOBALS._player.disableControl(); - _sceneMode = 1201; - setAction(&_sequenceManager, this, 1201, &_actor1, NULL); - } else if (_object1.sub51AF8(Common::Point(120, 69)) == 36) { - switch (_field412 - 1) { - case 0: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 56; - else - _sceneMode = 55; - break; - case 1: - if (R2_GLOBALS._player._visage == 3155) - _sceneMode = 25; - else - _sceneMode = 20; - break; - case 2: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 91; - else - _sceneMode = 90; - break; - case 3: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 121; - else - _sceneMode = 120; - break; - default: - break; - } - R2_GLOBALS._player.disableControl(); - _field412 = 2; - signal(); - } - break; - case 2: - if ( ((_object1.sub51AF8(Common::Point(140, 110)) > 36) || (_object1.sub51AF8(Common::Point(178, 110)) > 36)) - && ( ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 5) && (_field418 != 3)) - || ((R2_GLOBALS._v56AA2 == 41) && (R2_GLOBALS._v56AA4 == 21)) ) - ) { - R2_GLOBALS._player.disableControl(); - _sceneMode = 1203; - setAction(&_sequenceManager, this, 1203, &_actor1, NULL); - } else if (_object1.sub51AF8(Common::Point(160, 110)) == 36) { - switch (_field412 - 1) { - case 0: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 51; - else - _sceneMode = 50; - break; - case 1: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 81; - else - _sceneMode = 80; - break; - case 2: - if (R2_GLOBALS._player._visage == 3155) - _sceneMode = 35; - else - _sceneMode = 30; - break; - case 3: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 116; - else - _sceneMode = 115; - break; - default: - break; + visage.setVisage(resNum, rlbNum); + GfxSurface frame = visage.getFrame(frameNum); + + _mapImage.copyFrom(frame, xCtr * _cellSize.x, 0); + } else { + GfxSurface emptyRect; + emptyRect.create(_cellSize.x, _cellSize.y); + + _mapImage.copyFrom(emptyRect, xCtr * _cellSize.x, 0); } - R2_GLOBALS._player.disableControl(); - _field412 = 3; - signal(); } - break; - case 3: - if ( ((_object1.sub51AF8(Common::Point(140, 30)) > 36) || (_object1.sub51AF8(Common::Point(178, 30)) > 36)) - && ( ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 9) && (_field418 != 3)) - || ((R2_GLOBALS._v56AA2 == 35) && (R2_GLOBALS._v56AA4 == 17)) ) - ) { - R2_GLOBALS._player.disableControl(); - _sceneMode = 1202; - setAction(&_sequenceManager, this, 1202, &_actor1, NULL); - } else if (_object1.sub51AF8(Common::Point(160, 30)) == 36) { - switch (_field412 - 1) { - case 0: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 61; - else - _sceneMode = 60; - break; - case 1: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 71; - else - _sceneMode = 70; - break; - case 2: - if (R2_GLOBALS._player._visage == 3156) - _sceneMode = 96; - else - _sceneMode = 95; - break; - case 3: - if (R2_GLOBALS._player._visage == 3155) - _sceneMode = 45; - else - _sceneMode = 40; - break; - default: - _sceneMode = 1; - R2_GLOBALS._player.setup(3156, 4, 6); - break; + + if (yPos == 0) { + // First line of the map to be displayed - only the bottom portion of that + // first cell row may be visible + yPos = _bounds.top; + ySize = _cellSize.y - (_mapOffset.y % _cellSize.y); + + Rect srcBounds(_mapOffset.x % _cellSize.x, _mapOffset.y % _cellSize.y, + (_mapOffset.x % _cellSize.x) + _bounds.width(), _cellSize.y); + Rect destBounds(_bounds.left, yPos, _bounds.right, yPos + ySize); + + R2_GLOBALS.gfxManager().copyFrom(_mapImage, srcBounds, destBounds); + } else { + if ((yPos + _cellSize.y) < _bounds.bottom) { + ySize = _cellSize.y; + } else { + ySize = _bounds.bottom - yPos; } - R2_GLOBALS._player.disableControl(); - _field412 = 4; - signal(); + + Rect srcBounds(_mapOffset.x % _cellSize.x, 0, + (_mapOffset.x % _cellSize.x) + _bounds.width(), ySize); + Rect destBounds(_bounds.left, yPos, _bounds.right, yPos + ySize); + + R2_GLOBALS.gfxManager().copyFrom(_mapImage, srcBounds, destBounds); } - break; - default: - break; } } +int MazeUI::getCellFromPixelXY(const Common::Point &pt) { + if (!_bounds.contains(pt)) + return -1; + + int cellX = (pt.x - _bounds.left + _mapOffset.x) / _cellSize.x; + int cellY = (pt.y - _bounds.top + _mapOffset.y) / _cellSize.y; + + if ((cellX >= 0) && (cellY >= 0) && (cellX < _mapCells.x) && (cellY < _mapCells.y)) + return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * cellY + cellX) * 2); + + return -1; +} + +int MazeUI::getCellFromCellXY(const Common::Point &p) { + if (p.x < 0 || p.y < 0 || p.x >= _mapCells.x || p.y >= _mapCells.y) { + return -1; + } else { + return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * p.y + p.x) * 2); + } +} + +int MazeUI::pixelToCellXY(Common::Point &pt) { + pt.x /= _cellSize.x; + pt.y /= _cellSize.y; + + if ((pt.x >= 0) && (pt.y >= 0) && (pt.x < _mapCells.x) && (pt.y < _mapCells.y)) { + return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * pt.y + pt.x) * 2); + } + + return -1; +} + +void MazeUI::setDisplayBounds(const Rect &r) { + _bounds = r; + _bounds.clip(g_globals->gfxManager()._bounds); +} + /*--------------------------------------------------------------------------*/ void AnimationSlice::load(Common::File &f) { @@ -2001,6 +2064,347 @@ void AnimationPlayerExt::synchronize(Serializer &s) { s.syncAsSint16LE(_v); } +/*--------------------------------------------------------------------------*/ + +ModalDialog::ModalDialog() { + _field20 = 0; +} + +void ModalDialog::remove() { + R2_GLOBALS._sceneItems.remove(&_object1); + _object1.remove(); + + SceneArea::remove(); + + --R2_GLOBALS._insetUp; +} + +void ModalDialog::synchronize(Serializer &s) { + SceneArea::synchronize(s); + + s.syncAsByte(_field20); +} + +void ModalDialog::process(Event &event) { + if (_field20 != R2_GLOBALS._insetUp) + return; + + CursorType cursor = R2_GLOBALS._events.getCursor(); + + if (_object1._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) { + if (cursor == _cursorNum) { + R2_GLOBALS._events.setCursor(_savedCursorNum); + } + } else if (event.mousePos.y < 168) { + if (cursor != _cursorNum) { + _savedCursorNum = cursor; + R2_GLOBALS._events.setCursor(CURSOR_INVALID); + } + if (event.eventType == EVENT_BUTTON_DOWN) { + event.handled = true; + R2_GLOBALS._events.setCursor(_savedCursorNum); + remove(); + } + } +} + +void ModalDialog::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) { + Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene; + + _object1.postInit(); + _object1.setup(visage, stripFrameNum, frameNum); + _object1.setPosition(Common::Point(posX, posY)); + _object1.fixPriority(250); + _cursorNum = CURSOR_INVALID; + scene->_sceneAreas.push_front(this); + ++R2_GLOBALS._insetUp; + _field20 = R2_GLOBALS._insetUp; +} + +void ModalDialog::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) { + _object1.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL); +} + +/*--------------------------------------------------------------------------*/ + +ScannerDialog::Button::Button() { + _buttonId = 0; + _buttonDown = false; +} + +void ScannerDialog::Button::setup(int buttonId) { + _buttonId = buttonId; + _buttonDown = false; + SceneActor::postInit(); + + SceneObject::setup(4, 2, 2); + fixPriority(255); + + if (_buttonId == 1) + setPosition(Common::Point(141, 99)); + else if (_buttonId == 2) + setPosition(Common::Point(141, 108)); + + static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.push_front(this); +} + +void ScannerDialog::Button::synchronize(Serializer &s) { + SceneActor::synchronize(s); + s.syncAsSint16LE(_buttonId); +} + +void ScannerDialog::Button::process(Event &event) { + if (event.eventType == EVENT_BUTTON_DOWN && R2_GLOBALS._events.getCursor() == CURSOR_USE + && _bounds.contains(event.mousePos) && !_buttonDown) { + setFrame(3); + _buttonDown = true; + event.handled = true; + } + + if (event.eventType == EVENT_BUTTON_UP && _buttonDown) { + setFrame(2); + _buttonDown = false; + event.handled = true; + + reset(); + } +} + +bool ScannerDialog::Button::startAction(CursorType action, Event &event) { + if (action == CURSOR_USE) + return false; + + return startAction(action, event); +} + +void ScannerDialog::Button::reset() { + Scene *scene = R2_GLOBALS._sceneManager._scene; + ScannerDialog &scanner = *R2_GLOBALS._scannerDialog; + + switch (_buttonId) { + case 1: + // Talk button + switch (R2_GLOBALS._sceneManager._sceneNumber) { + case 1550: + scene->_sceneMode = 80; + scene->signal(); + break; + case 1700: + scene->_sceneMode = 30; + scene->signal(); + remove(); + break; + default: + break; + } + break; + case 2: + // Scan button + switch (R2_GLOBALS._sceneManager._sceneNumber) { + case 1550: + scanner._obj4.setup(4, 3, 1); + + scanner._obj5.postInit(); + scanner._obj5.setup(4, 4, 1); + scanner._obj5.setPosition(Common::Point(R2_GLOBALS._v565EC[1] + 145, + R2_GLOBALS._v565EC[3] + 59)); + scanner._obj5.fixPriority(257); + + scanner._obj6.postInit(); + scanner._obj6.setup(4, 4, 2); + scanner._obj6.setPosition(Common::Point(R2_GLOBALS._v565EC[2] + 145, + R2_GLOBALS._v565EC[4] + 59)); + scanner._obj6.fixPriority(257); + break; + case 1700: + case 1800: + if (R2_GLOBALS._v565F8 < 0 || (R2_GLOBALS._v565F8 == 0 && R2_GLOBALS._v565F6 < 1201)) + scanner._obj4.setup(4, 3, 3); + else if (R2_GLOBALS._v565F8 > 0 || (R2_GLOBALS._v565F8 == 0 && R2_GLOBALS._v565F6 < 1201)) + scanner._obj4.setup(4, 3, 4); + else + scanner._obj4.setup(4, 3, 5); + break; + case 3800: + case 3900: + if ((R2_GLOBALS._v56A93 + 1) == 0 && R2_GLOBALS._v566A9 == 0) { + do { + R2_GLOBALS._v566A9 = R2_GLOBALS._randomSource.getRandomNumber(3); + } while (R2_GLOBALS._v566A9 == R2_GLOBALS._v566AA); + } + + scanner._obj4.setup(4, 7, R2_GLOBALS._v566A9); + if (!R2_GLOBALS.getFlag(46)) + R2_GLOBALS.setFlag(46); + break; + default: + scanner._obj4.setup(4, 3, 2); + break; + } + break; + default: + break; + } +} + +/*--------------------------------------------------------------------------*/ + +ScannerDialog::Slider::Slider() { + _initial = _xStart = _yp = 0; + _width = _xInc = 0; + _sliderDown = false; +} + +void ScannerDialog::Slider::synchronize(Serializer &s) { + SceneActor::synchronize(s); + + s.syncAsSint16LE(_initial); + s.syncAsSint16LE(_xStart); + s.syncAsSint16LE(_yp); + s.syncAsSint16LE(_width); + s.syncAsSint16LE(_xInc); +} + +void ScannerDialog::Slider::remove() { + static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.remove(this); + SceneActor::remove(); +} + +void ScannerDialog::Slider::process(Event &event) { + if (event.eventType == EVENT_BUTTON_DOWN && R2_GLOBALS._events.getCursor() == CURSOR_USE + && _bounds.contains(event.mousePos)) { + _sliderDown = true; + } + + if (event.eventType == EVENT_BUTTON_UP && _sliderDown) { + _sliderDown = false; + event.handled = true; + update(); + } + + if (_sliderDown) { + event.handled = true; + if (event.mousePos.x < _xStart) { + setPosition(Common::Point(_xStart, _yp)); + } else if (event.mousePos.x >= (_xStart + _width)) { + setPosition(Common::Point(_xStart + _width, _yp)); + } else { + setPosition(Common::Point(event.mousePos.x, _yp)); + } + } +} + +bool ScannerDialog::Slider::startAction(CursorType action, Event &event) { + if (action == CURSOR_USE) + return false; + + return startAction(action, event); +} + +void ScannerDialog::Slider::update() { + int incHalf = (_width / (_xInc - 1)) / 2; + int newFrequency = ((_position.x - _xStart + incHalf) * _xInc) / (_width + incHalf * 2); + setPosition(Common::Point(_xStart + ((_width * newFrequency) / (_xInc - 1)), _yp)); + + R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] = newFrequency + 1; + + switch (newFrequency) { + case 0: + R2_GLOBALS._sound4.stop(); + break; + case 1: + R2_GLOBALS._sound4.play(45); + break; + case 2: + R2_GLOBALS._sound4.play(4); + break; + case 3: + R2_GLOBALS._sound4.play(5); + break; + case 4: + R2_GLOBALS._sound4.play(6); + break; + default: + break; + } +} + +void ScannerDialog::Slider::setup(int initial, int xStart, int yp, int width, int xInc) { + _initial = initial; + _xStart = xStart; + _yp = yp; + _width = width; + _xInc = xInc; + _sliderDown = false; + SceneActor::postInit(); + SceneObject::setup(4, 2, 1); + fixPriority(255); + setPosition(Common::Point(_width * (_initial - 1) / (_xInc - 1) + _xStart, yp)); + + static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.push_front(this); +} + +/*--------------------------------------------------------------------------*/ + +ScannerDialog::ScannerDialog() { +} + +void ScannerDialog::remove() { + switch (R2_GLOBALS._sceneManager._sceneNumber) { + case 1550: + case 1700: + R2_GLOBALS._events.setCursor(R2_GLOBALS._player._canWalk ? CURSOR_ARROW : CURSOR_USE); + break; + case 3800: + case 3900: { + Scene *scene = R2_GLOBALS._sceneManager._scene; + scene->_sceneMode = 3806; + scene->signal(); + break; + } + default: + break; + } + + SceneExt *scene = static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene); + scene->_sceneAreas.remove(&_talkButton); + scene->_sceneAreas.remove(&_scanButton); + _talkButton.remove(); + _scanButton.remove(); + _slider.remove(); + _obj4.remove(); + _obj5.remove(); + _obj6.remove(); + _obj7.remove(); + + ModalDialog::remove(); +} + +void ScannerDialog::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) { + // Stop player moving if currently doing so + if (R2_GLOBALS._player._mover) + R2_GLOBALS._player.addMover(NULL); + + R2_GLOBALS._events.setCursor(CURSOR_USE); + ModalDialog::proc12(visage, stripFrameNum, frameNum, posX, posY); + + proc13(100, -1, -1, -1); + _talkButton.setup(1); + _scanButton.setup(2); + _slider.setup(R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex], 142, 124, 35, 5); + + _obj4.postInit(); + _obj4.setup(4, 3, 2); + _obj4.setPosition(Common::Point(160, 83)); + _obj4.fixPriority(256); + + if (R2_GLOBALS._sceneManager._sceneNumber == 3800 || R2_GLOBALS._sceneManager._sceneNumber == 3900) { + Scene *scene = R2_GLOBALS._sceneManager._scene; + scene->_sceneMode = 3805; + scene->signal(); + } +} + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h index 0b573bf7f0..2e7dd64fa2 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.h +++ b/engines/tsage/ringworld2/ringworld2_logic.h @@ -88,7 +88,7 @@ public: SceneObject *_focusObject; Visage _cursorVisage; - SynchronizedList<SceneArea *> _sceneAreas; + SynchronizedList<EventHandler *> _sceneAreas; Rect _v51C34; public: @@ -159,6 +159,9 @@ public: /*--------------------------------------------------------------------------*/ class Ringworld2InvObjectList : public InvObjectList { +private: + static bool SelectItem(int objectNumber); + static void selectDefault(int obectNumber); public: InvObject _none; InvObject _inv1; @@ -260,6 +263,7 @@ class SceneActor: public SceneObject { public: virtual Common::String getClassName() { return "SceneActor"; } virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); virtual bool startAction(CursorType action, Event &event); }; @@ -276,6 +280,49 @@ public: } }; +enum MazeDirection { MAZEDIR_NONE = 0, MAZEDIR_NORTH = 1, MAZEDIR_NORTHEAST = 2, MAZEDIR_EAST = 3, + MAZEDIR_SOUTHEAST = 4, MAZEDIR_SOUTH = 5, MAZEDIR_SOUTHWEST = 6, MAZEDIR_WEST = 7, + MAZEDIR_NORTHWEST = 8 }; + +class MazeUI: public SceneObject { +private: + void clear(); +public: + // The dimensions (in cells) of the entire maze map + Rect _mapBounds; + + // Encoded cell map specifying the features of the maze + byte *_mapData; + // Image surface used to store a line of the map for rendering + GfxSurface _mapImage; + + Common::Point _cellsVisible; + Common::Point _mapCells; + Common::Point _cellSize; + Common::Point _mapOffset; + int _resNum; + int _cellsResNum; + int _frameCount; + int _resCount; + int _mapImagePitch; + int _unused; +public: + MazeUI(); + virtual ~MazeUI(); + + void setDisplayBounds(const Rect &r); + bool setMazePosition(const Common::Point &pt); + void load(int resNum); + int getCellFromPixelXY(const Common::Point &pt); + int getCellFromCellXY(const Common::Point &p); + int pixelToCellXY(Common::Point &pt); + + virtual Common::String getClassName() { return "MazeUI"; } + void synchronize(Serializer &s); + virtual void reposition(); + virtual void draw(); +}; + class SceneAreaObject: public SceneArea { class Object1: public SceneActor { public: @@ -290,41 +337,6 @@ public: void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum); }; -class UnkObject1200 : public SavedObject { -public: - Rect _rect1; - Rect _rect2; - - int *_field16; - int *_field3A; - - int _field12; - int _field14; - int _field26; - int _field28; - int _field2A; - int _field2C; - int _field2E; - int _field30; - int _field32; - int _field34; - int _field36; - int _field38; - int _field3E; - int _field40; - - UnkObject1200(); - void synchronize(Serializer &s); - - void sub51AE9(int arg1); - int sub51AF8(Common::Point pt); - bool sub51AFD(Common::Point pt); - void sub51B02(); - void sub9EDE8(Rect rect); - int sub9EE22(int &arg1, int &arg2); - virtual Common::String getClassName() { return "UnkObject1200"; } -}; - /*--------------------------------------------------------------------------*/ class AnimationSlice { @@ -432,6 +444,74 @@ public: virtual void synchronize(Serializer &s); }; +class ModalDialog: public SceneArea { +public: + SceneActor _object1; + byte _field20; +public: + ModalDialog(); + + virtual void remove(); + virtual void synchronize(Serializer &s); + virtual Common::String getClassName() { return "ModalDialog"; } + virtual void process(Event &event); + virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY); + virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum); +}; + +class ScannerDialog: public ModalDialog { + + class Button: public SceneActor { + private: + void reset(); + public: + int _buttonId; + bool _buttonDown; + public: + Button(); + void setup(int buttonId); + + virtual void synchronize(Serializer &s); + virtual Common::String getClassName() { return "ScannerButton"; } + virtual void process(Event &event); + virtual bool startAction(CursorType action, Event &event); + }; + class Slider: public SceneActor { + private: + void update(); + public: + int _initial; + int _xStart; + int _yp; + int _width; + int _xInc; + bool _sliderDown; + public: + Slider(); + void setup(int initial, int xStart, int yp, int width, int xInc); + + virtual void synchronize(Serializer &s); + virtual Common::String getClassName() { return "ScannerSlider"; } + virtual void remove(); + virtual void process(Event &event); + virtual bool startAction(CursorType action, Event &event); + }; +public: + Button _talkButton; + Button _scanButton; + Slider _slider; + SceneActor _obj4; + SceneActor _obj5; + SceneActor _obj6; + SceneActor _obj7; +public: + ScannerDialog(); + + virtual Common::String getClassName() { return "ScannerDialog"; } + virtual void remove(); + void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY); +}; + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp index 3b7d283e44..634ecf3ddb 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp @@ -2042,8 +2042,8 @@ void Scene200::WestExit::changeScene() { /*--------------------------------------------------------------------------*/ void Scene200::postInit(SceneObjectList *OwnerList) { - SceneExt::postInit(); loadScene(200); + SceneExt::postInit(); _westExit.setDetails(Rect(94, 0, 123, 58), EXITCURSOR_W, 175); _westExit.setDest(Common::Point(125, 52)); @@ -2708,6 +2708,8 @@ void Scene250::signal() { case 7: _field418 = 1; if ((_field414 + 12) == _field412) + _sceneMode = 9; + else _sceneMode = 8; signal(); break; @@ -2741,7 +2743,7 @@ void Scene250::signal() { R2_GLOBALS._sceneManager.changeScene(300); break; case 139: - R2_GLOBALS._sceneManager.changeScene(139); + R2_GLOBALS._sceneManager.changeScene(700); break; case 91: R2_GLOBALS._sceneManager.changeScene(850); @@ -3181,8 +3183,9 @@ void Scene300::synchronize(Serializer &s) { } void Scene300::postInit(SceneObjectList *OwnerList) { - SceneExt::postInit(); loadScene(300); + SceneExt::postInit(); + _sound1.play(23); setZoomPercents(75, 93, 120, 100); @@ -3233,7 +3236,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) { _protocolDisplay.postInit(); _protocolDisplay.setup(300, 6, 1); _protocolDisplay.setPosition(Common::Point(287, 71)); - _protocolDisplay.animate(ANIM_MODE_7, NULL); + _protocolDisplay.animate(ANIM_MODE_7, 0, NULL); _protocolDisplay._numFrames = 5; _object6.postInit(); @@ -4908,7 +4911,7 @@ bool Scene500::Doorway::startAction(CursorType action, Event &event) { scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL); } else { scene->_sceneMode = 500; - scene->setAction(&scene->_sequenceManager1, scene, 500, &R2_GLOBALS._player, NULL); + scene->setAction(&scene->_sequenceManager1, scene, 500, &R2_GLOBALS._player, this, NULL); } return true; @@ -4986,7 +4989,7 @@ bool Scene500::SonicStunner::startAction(CursorType action, Event &event) { if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) { R2_GLOBALS._player.disableControl(); scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 520 : 502; - scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL); + scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, this, NULL); return true; } else { return SceneActor::startAction(action, event); @@ -5075,7 +5078,7 @@ void Scene500::postInit(SceneObjectList *OwnerList) { } } - if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) != 500) && R2_GLOBALS.getFlag(27)) { + if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 500) && R2_GLOBALS.getFlag(27)) { _tanks1.postInit(); _tanks1.setup(502, 7, 1); _tanks1.setPosition(Common::Point(281, 120)); @@ -5230,7 +5233,7 @@ void Scene500::signal() { R2_GLOBALS._sceneManager.changeScene(700); break; case 501: - if (R2_GLOBALS._player._characterScene[R2_QUINN] == 500) { + if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500) { _stripNumber = 1100; _sceneMode = 523; setAction(&_sequenceManager1, this, 523, &R2_GLOBALS._player, NULL); @@ -5338,9 +5341,10 @@ void Scene525::signal() { } /*-------------------------------------------------------------------------- - * Scene 600 - + * Scene 600 - Drive Room * *--------------------------------------------------------------------------*/ + Scene600::Scene600() { _field412 = 0; for (int i = 0; i < 256; i++) @@ -5355,11 +5359,12 @@ void Scene600::synchronize(Serializer &s) { s.syncAsByte(_fieldAD2[i]); } -bool Scene600::Item1::startAction(CursorType action, Event &event) { +bool Scene600::CompartmentHotspot::startAction(CursorType action, Event &event) { if ((action != R2_NEGATOR_GUN) || (!R2_GLOBALS.getFlag(5)) || (R2_GLOBALS.getFlag(8))) return SceneHotspot::startAction(action, event); - SceneItem::display(600, 32, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + SceneItem::display(600, 32, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER, + SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END); return true; } @@ -5368,12 +5373,14 @@ bool Scene600::Item4::startAction(CursorType action, Event &event) { return SceneHotspot::startAction(action, event); if ((R2_GLOBALS.getFlag(5)) && (!R2_GLOBALS.getFlag(8))) { - SceneItem::display(600, 32, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + SceneItem::display(600, 32, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER, + SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END); return true; } if (R2_GLOBALS.getFlag(5)) { - SceneItem::display(600, 30, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + SceneItem::display(600, 30, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER, + SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END); return true; } @@ -5394,13 +5401,14 @@ bool Scene600::Item4::startAction(CursorType action, Event &event) { } void Scene600::Actor4::signal() { - Common::Point pt(36, 177 + R2_GLOBALS._randomSource.getRandomNumber(5)); + Common::Point pt(177 + R2_GLOBALS._randomSource.getRandomNumber(5), + 108 + R2_GLOBALS._randomSource.getRandomNumber(3)); NpcMover *mover = new NpcMover(); addMover(mover, &pt, this); } bool Scene600::Actor4::startAction(CursorType action, Event &event) { - if ((action >= CURSOR_WALK) && (action < R2CURSORS_START)) + if (action >= CURSOR_WALK) // Only action cursors return SceneActor::startAction(action, event); @@ -5412,7 +5420,7 @@ void Scene600::Actor4::draw() { SceneActor::draw(); } -bool Scene600::Actor5::startAction(CursorType action, Event &event) { +bool Scene600::Doorway::startAction(CursorType action, Event &event) { if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) return false; @@ -5423,10 +5431,10 @@ bool Scene600::Actor5::startAction(CursorType action, Event &event) { if ((R2_INVENTORY.getObjectScene(R2_CLAMP) == 600) && (!R2_GLOBALS.getFlag(6))) { R2_GLOBALS._player.disableControl(); - scene->_actor6.setDetails(600, 11, -1, -1, 3, (SceneItem *) NULL); + scene->_laser.setDetails(600, 11, -1, -1, 3, (SceneItem *) NULL); R2_GLOBALS.setFlag(6); scene->_sceneMode = 609; - scene->setAction(&scene->_sequenceManager1, scene, 609, &R2_GLOBALS._player, &scene->_actor5, &scene->_actor6, &scene->_actor1, NULL); + scene->setAction(&scene->_sequenceManager1, scene, 609, &R2_GLOBALS._player, &scene->_doorway, &scene->_laser, &scene->_actor1, NULL); return true; } @@ -5436,7 +5444,7 @@ bool Scene600::Actor5::startAction(CursorType action, Event &event) { if (!R2_GLOBALS.getFlag(6)) { R2_GLOBALS._player.disableControl(); scene->_sceneMode = 616; - scene->setAction(&scene->_sequenceManager1, scene, 616, &R2_GLOBALS._player, &scene->_actor5, &scene->_actor6, NULL); + scene->setAction(&scene->_sequenceManager1, scene, 616, &R2_GLOBALS._player, &scene->_doorway, &scene->_laser, NULL); return true; } @@ -5445,15 +5453,15 @@ bool Scene600::Actor5::startAction(CursorType action, Event &event) { else { R2_GLOBALS._player.disableControl(); scene->_sceneMode = 601; - scene->setAction(&scene->_sequenceManager1, scene, 601, &R2_GLOBALS._player, &scene->_actor5, NULL); + scene->setAction(&scene->_sequenceManager1, scene, 601, &R2_GLOBALS._player, &scene->_doorway, NULL); } return true; } -bool Scene600::Actor6::startAction(CursorType action, Event &event) { +bool Scene600::Laser::startAction(CursorType action, Event &event) { Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene; - if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) { + if (action < CURSOR_WALK) { switch (action) { case R2_COM_SCANNER: if (R2_GLOBALS.getFlag(6)) { @@ -5463,7 +5471,7 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) { } else { R2_GLOBALS._player.disableControl(); scene->_actor8.postInit(); - scene->_actor8.setDetails(600, 20, -1, -1, 4, &scene->_actor6); + scene->_actor8.setDetails(600, 20, -1, -1, 4, &scene->_laser); scene->_sceneMode = 607; scene->setAction(&scene->_sequenceManager1, scene, 607, &R2_GLOBALS._player, &scene->_actor8, NULL); return true; @@ -5478,8 +5486,8 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) { return true; } else { R2_GLOBALS._player.disableControl(); - scene->_actor7.postInit(); - scene->_actor7.setDetails(600, 27, -1, -1, 5, &scene->_actor6); + scene->_aerosol.postInit(); + scene->_aerosol.setDetails(600, 27, -1, -1, 5, &scene->_laser); scene->_actor4.postInit(); scene->_actor4.setup(601, 3, 1); @@ -5487,11 +5495,11 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) { scene->_actor4._moveDiff = Common::Point(1, 1); scene->_actor4._moveRate = 2; scene->_actor4._numFrames = 3; - scene->_actor4.setDetails(600, 24, 25, 26, 5, &scene->_actor7); + scene->_actor4.setDetails(600, 24, 25, 26, 5, &scene->_aerosol); scene->_sceneMode = 605; - scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_actor7, &scene->_actor4, &scene->_actor5, NULL); + scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_aerosol, &scene->_actor4, &scene->_doorway, NULL); return true; } break; @@ -5499,7 +5507,7 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) { if (R2_GLOBALS.getFlag(5)) { R2_GLOBALS._player.disableControl(); scene->_sceneMode = 606; - scene->setAction(&scene->_sequenceManager1, scene, 606, &R2_GLOBALS._player, &scene->_actor6, NULL); + scene->setAction(&scene->_sequenceManager1, scene, 606, &R2_GLOBALS._player, &scene->_laser, NULL); return true; } else { return SceneActor::startAction(action, event); @@ -5509,7 +5517,7 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) { return false; break; } - } else if (action != CURSOR_USE) { + } else if (action == CURSOR_USE) { if (R2_GLOBALS.getFlag(5)) { return SceneActor::startAction(action, event); } else { @@ -5522,7 +5530,7 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) { return SceneActor::startAction(action, event); } -bool Scene600::Actor7::startAction(CursorType action, Event &event) { +bool Scene600::Aerosol::startAction(CursorType action, Event &event) { Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene; if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) { @@ -5530,7 +5538,7 @@ bool Scene600::Actor7::startAction(CursorType action, Event &event) { } else if (action == CURSOR_USE) { R2_GLOBALS._player.disableControl(); scene->_sceneMode = 614; - scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_actor7, NULL); + scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_aerosol, NULL); return true; } else { return SceneActor::startAction(action, event); @@ -5544,7 +5552,7 @@ bool Scene600::Actor8::startAction(CursorType action, Event &event) { R2_GLOBALS._player.disableControl(); scene->_sceneMode = 615; scene->setAction(&scene->_sequenceManager1, scene, 615, &R2_GLOBALS._player, &scene->_actor8, NULL); - } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(9) == 600) && (R2_GLOBALS._v565F1[1] == 2) && (!R2_GLOBALS.getFlag(8))){ + } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(9) == 600) && (R2_GLOBALS._scannerFrequencies[1] == 2) && (!R2_GLOBALS.getFlag(8))){ R2_GLOBALS._player.disableControl(); scene->_sceneMode = 608; scene->setAction(&scene->_sequenceManager1, scene, 608, &R2_GLOBALS._player, &scene->_actor4, NULL); @@ -5564,21 +5572,21 @@ void Scene600::postInit(SceneObjectList *OwnerList) { warning("FIXME: loop to initialize _fieldAD2[]"); - _actor5.postInit(); - _actor5.setVisage(600); - _actor5.setPosition(Common::Point(29, 147)); - _actor5.fixPriority(10); - _actor5.setDetails(300, 3, -1, -1, 1, (SceneItem *) NULL); + _doorway.postInit(); + _doorway.setVisage(600); + _doorway.setPosition(Common::Point(29, 147)); + _doorway.fixPriority(10); + _doorway.setDetails(300, 3, -1, -1, 1, (SceneItem *) NULL); - _actor6.postInit(); - _actor6.setPosition(Common::Point(246, 41)); + _laser.postInit(); + _laser.setPosition(Common::Point(246, 41)); if (R2_INVENTORY.getObjectScene(9) == 600) { _actor8.postInit(); _actor8.setup(602, 5, 1); _actor8.setPosition(Common::Point(246, 41)); _actor8.setDetails(600, 20, -1, -1, 1, (SceneItem *) NULL); - switch (R2_GLOBALS._v565F1[1] - 2) { + switch (R2_GLOBALS._scannerFrequencies[1] - 2) { case 0: R2_GLOBALS._sound4.play(45); break; @@ -5597,11 +5605,11 @@ void Scene600::postInit(SceneObjectList *OwnerList) { } if (R2_GLOBALS.getFlag(6)) { - _actor6.setup(602, 7, 1); - _actor6.setDetails(600, 11, -1, -1, 1, (SceneItem *) NULL); + _laser.setup(602, 7, 1); + _laser.setDetails(600, 11, -1, -1, 1, (SceneItem *) NULL); } else { - _actor6.setup(600, 2, 1); - _actor6.setDetails(600, 10, -1, -1, 1, (SceneItem *) NULL); + _laser.setup(600, 2, 1); + _laser.setDetails(600, 10, -1, -1, 1, (SceneItem *) NULL); _actor1.postInit(); _actor1.setup(600, 3, 5); @@ -5614,10 +5622,10 @@ void Scene600::postInit(SceneObjectList *OwnerList) { if (R2_GLOBALS.getFlag(5)) { if (R2_INVENTORY.getObjectScene(12) == 600) { - _actor7.postInit(); - _actor7.setup(602, 2, 2); - _actor7.setPosition(Common::Point(189, 95)); - _actor7.setDetails(600, 27, -1, -1, 1, (SceneItem *) NULL); + _aerosol.postInit(); + _aerosol.setup(602, 2, 2); + _aerosol.setPosition(Common::Point(189, 95)); + _aerosol.setDetails(600, 27, -1, -1, 1, (SceneItem *) NULL); } if (R2_GLOBALS.getFlag(8)) { @@ -5651,30 +5659,30 @@ void Scene600::postInit(SceneObjectList *OwnerList) { _item3.setDetails(11, 600, 14, -1, -1); if (R2_GLOBALS.getFlag(9)) { - _item1.setDetails(Rect(159, 3, 315, 95), 600, 7, -1, -1, 1, NULL); + _background.setDetails(Rect(159, 3, 315, 95), 600, 7, -1, -1, 1, NULL); } else { _item4.setDetails(Rect(173, 15, 315, 45), 600, 21, -1, 23, 1, NULL); - _item1.setDetails(Rect(159, 3, 315, 95), 600, 6, -1, -1, 1, NULL); + _background.setDetails(Rect(159, 3, 315, 95), 600, 6, -1, -1, 1, NULL); } _item5.setDetails(Rect(0, 0, 320, 200), 600, 0, -1, -1, 1, NULL); _sceneMode = 600; if (R2_GLOBALS._sceneManager._previousScene == 700) { if (R2_GLOBALS.getFlag(6)) { - setAction(&_sequenceManager1, this, 600, &R2_GLOBALS._player, &_actor5, NULL); + setAction(&_sequenceManager1, this, 600, &R2_GLOBALS._player, &_doorway, NULL); } else if (R2_GLOBALS.getFlag(5)) { - setAction(&_sequenceManager1, this, 603, &R2_GLOBALS._player, &_actor5, &_actor6, &_actor1, NULL); + setAction(&_sequenceManager1, this, 603, &R2_GLOBALS._player, &_doorway, &_laser, &_actor1, NULL); } else { - setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_actor5, &_actor6, &_actor1, NULL); + setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_doorway, &_laser, &_actor1, NULL); } } else if (R2_GLOBALS.getFlag(5)) { R2_GLOBALS._player.setPosition(Common::Point(50, 140)); R2_GLOBALS._player.setStrip(3); - _actor6.setFrame(_actor6.getFrameCount()); + _laser.setFrame(_laser.getFrameCount()); signal(); } else { - _actor5.setFrame(7); - _actor6.setFrame(7); + _doorway.setFrame(7); + _laser.setFrame(7); R2_GLOBALS._player.setPosition(Common::Point(28, 140)); R2_GLOBALS._player.setStrip(5); signal(); @@ -5703,7 +5711,7 @@ void Scene600::signal() { R2_GLOBALS._walkRegions.enableRegion(9); R2_GLOBALS._walkRegions.enableRegion(10); - R2_INVENTORY.setObjectScene(12, 600); + R2_INVENTORY.setObjectScene(R2_AEROSOL, 600); R2_GLOBALS.setFlag(5); _actor4._effect = 3; @@ -5730,12 +5738,12 @@ void Scene600::signal() { _actor3.remove(); R2_GLOBALS._sceneItems.remove(&_item4); _actor2.setDetails(600, 21, -1, 23, 4, &_item4); - _item1.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL); + _background.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL); R2_GLOBALS._player.enableControl(CURSOR_USE); break; case 614: R2_GLOBALS._player.enableControl(); - _actor7.remove(); + _aerosol.remove(); R2_INVENTORY.setObjectScene(12, 1); R2_GLOBALS._walkRegions.disableRegion(7); break; @@ -5753,8 +5761,9 @@ void Scene600::signal() { } void Scene600::process(Event &event) { - if ((!R2_GLOBALS._player._canWalk) && (!R2_GLOBALS.getFlag(6)) && (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) { - if (!_actor5.contains(event.mousePos) || (_actor5._frame <= 1)) { + if (R2_GLOBALS._player._canWalk && (!R2_GLOBALS.getFlag(6)) && (event.eventType == EVENT_BUTTON_DOWN) + && (R2_GLOBALS._events.getCursor() == CURSOR_WALK)) { + if (!_doorway.contains(event.mousePos) || (_doorway._frame <= 1)) { if (R2_GLOBALS.getFlag(5)) { _field412 += 10; } else { @@ -5766,7 +5775,7 @@ void Scene600::process(Event &event) { } else { R2_GLOBALS._player.disableControl(); _sceneMode = 613; - setAction(&_sequenceManager1, this, 613, &R2_GLOBALS._player, &_actor6, NULL); + setAction(&_sequenceManager1, this, 613, &R2_GLOBALS._player, &_laser, NULL); event.handled = true; } } else if ((!R2_GLOBALS.getFlag(6)) && (R2_GLOBALS._player._mover) && (_field412 < 10)){ @@ -5778,9 +5787,9 @@ void Scene600::process(Event &event) { void Scene600::dispatch() { if ((_field412 != 0) && (_sceneMode != 600) && (_sceneMode != 603) && (_sceneMode != 602)) { - if ( ((_actor6._strip == 4) && (_actor6._frame > 1)) + if ( ((_laser._strip == 4) && (_laser._frame > 1)) || (_sceneMode == 601) - || ((_sceneMode == 616) && (_actor5._frame > 1)) ) + || ((_sceneMode == 616) && (_doorway._frame > 1)) ) _field412 = 0; else { _field412--; @@ -5803,7 +5812,7 @@ void Scene600::dispatch() { } /*-------------------------------------------------------------------------- - * Scene 700 - + * Scene 700 - Lander Bay 2 * *--------------------------------------------------------------------------*/ Scene700::Scene700() { @@ -5849,7 +5858,7 @@ bool Scene700::Item12::startAction(CursorType action, Event &event) { break; } - scene->setAction(&scene->_sequenceManager, this, 707, &R2_GLOBALS._player, &scene->_actor5, NULL); + scene->setAction(&scene->_sequenceManager, scene, 707, &R2_GLOBALS._player, &scene->_actor5, NULL); return true; } @@ -5910,7 +5919,7 @@ bool Scene700::Actor5::startAction(CursorType action, Event &event) { case 0: if ((_strip == 2) && (_frame == 1)) { R2_GLOBALS._player.disableControl(); - if (R2_GLOBALS._player._position.x <= 100) { + if (R2_GLOBALS._player._position.y <= 100) { scene->_sceneMode = 710; scene->setAction(&scene->_sequenceManager, scene, 710, &R2_GLOBALS._player, this, NULL); } else { @@ -5969,10 +5978,10 @@ bool Scene700::Actor6::startAction(CursorType action, Event &event) { } void Scene700::postInit(SceneObjectList *OwnerList) { + loadScene(700); if (R2_GLOBALS._sceneManager._previousScene == 900) - g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0)); + _sceneBounds = Rect(160, 0, 480, 200); - loadScene(700); R2_GLOBALS._v558B6.set(60, 0, 260, 200); SceneExt::postInit(); @@ -5994,7 +6003,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) { _actor1.postInit(); _actor1.setup(700, 4, 1); - _actor1.setPosition(Common::Point(355 - ((R2_GLOBALS._v565E3 * 8) / 5), ((R2_GLOBALS._v565E1 + 20 ) / 5) - 12)); + _actor1.setPosition(Common::Point(355 - ((R2_GLOBALS._electromagnetZoom * 8) / 5), ((R2_GLOBALS._electromagnetChangeAmount + 20 ) / 5) - 12)); _actor1.fixPriority(10); _actor1.setDetails(700, 12, -1, 14, 1, (SceneItem *) NULL); @@ -6041,7 +6050,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) { case 700: switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) { case 0: - if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) + if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) _actor5.setup(701, 2, 1); else _actor5.setup(701, 2, 8); @@ -6158,9 +6167,7 @@ void Scene700::signal() { } break; case 3: - R2_INVENTORY.setObjectScene(5, 600); - R2_INVENTORY.setObjectScene(16, 700); - R2_GLOBALS._player.enableControl(); + R2_GLOBALS._sceneManager.changeScene(600); break; case 4: _sceneMode = 5; @@ -6206,7 +6213,7 @@ void Scene700::signal() { _sceneMode = 17; _actor5.setup(701, 1, 8); _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL); - if ((R2_GLOBALS._v565E5 != 0) && (_actor5._position.x == _actor1._position.x + 1) && (_actor5._position.x == 148 - (((R2_GLOBALS._v565E1 + 10) / 5) * 4))) { + if ((R2_GLOBALS._v565E5 != 0) && (_actor5._position.x == _actor1._position.x + 1) && (_actor5._position.x == 148 - (((R2_GLOBALS._electromagnetChangeAmount + 10) / 5) * 4))) { _actor5.animate(ANIM_MODE_6, NULL); Common::Point pt(_actor5._position.x, _actor1._position.y + 120); NpcMover *mover = new NpcMover(); @@ -6231,7 +6238,7 @@ void Scene700::signal() { break; case 21: _actor5.fixPriority(77); - if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) + if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) _actor5.animate(ANIM_MODE_6, NULL); R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700); @@ -6249,7 +6256,7 @@ void Scene700::signal() { case 706: _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL); _actor5.fixPriority(77); - if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) + if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) _actor5.animate(ANIM_MODE_6, NULL); R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0); R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700); @@ -6416,8 +6423,8 @@ bool Scene800::Cabinet::startAction(CursorType action, Event &event) { /*--------------------------------------------------------------------------*/ void Scene800::postInit(SceneObjectList *OwnerList) { - SceneExt::postInit(); loadScene(800); + SceneExt::postInit(); _door.postInit(); _door.setVisage(800); @@ -7006,8 +7013,8 @@ bool Scene850::Panel::startAction(CursorType action, Event &event) { /*--------------------------------------------------------------------------*/ void Scene850::postInit(SceneObjectList *OwnerList) { - SceneExt::postInit(); loadScene(850); + SceneExt::postInit(); _liftDoor.postInit(); _liftDoor.setup(850, 2, 1); @@ -7103,44 +7110,47 @@ void Scene850::signal() { } /*-------------------------------------------------------------------------- - * Scene 900 - + * Scene 900 - Lander Bay 2 - Crane Controls * *--------------------------------------------------------------------------*/ -Scene900::Actor4::Actor4() { - _fieldA4 = 0; + +Scene900::Button::Button() { + _buttonId = 0; } -void Scene900::Actor4::synchronize(Serializer &s) { +void Scene900::Button::synchronize(Serializer &s) { SceneActor::synchronize(s); - s.syncAsSint16LE(_fieldA4); + s.syncAsSint16LE(_buttonId); } -void Scene900::Actor4::sub96135(int arg1) { - _fieldA4 = arg1; + +void Scene900::Button::initButton(int buttonId) { + _buttonId = buttonId; + postInit(); setDetails(900, -1, -1, -1, 2, (SceneItem *) NULL); } Scene900::Scene900() { _field412 = 0; - _field414 = 0; - _field416 = 0; + _magnetChangeAmount.x = 0; + _magnetChangeAmount.y = 0; } void Scene900::synchronize(Serializer &s) { SceneExt::synchronize(s); s.syncAsSint16LE(_field412); - s.syncAsSint16LE(_field414); - s.syncAsSint16LE(_field416); + s.syncAsSint16LE(_magnetChangeAmount.x); + s.syncAsSint16LE(_magnetChangeAmount.y); } -bool Scene900::Actor4::startAction(CursorType action, Event &event) { +bool Scene900::Button::startAction(CursorType action, Event &event) { Scene900 *scene = (Scene900 *)R2_GLOBALS._sceneManager._scene; if (action == CURSOR_USE) { R2_GLOBALS._sound2.play(14); - switch (_fieldA4) { + switch (_buttonId) { case 2: if (scene->_field412 == 1) { scene->_sceneMode = 2; @@ -7150,15 +7160,15 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) { scene->_aSound1.play(30); setup(900, 3, 11); R2_GLOBALS._v565E5 = 1; - if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS == 700)) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70) && (scene->_actor2._animateMode != ANIM_MODE_6)) { + if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS == 700)) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70) && (scene->_actor2._animateMode != ANIM_MODE_6)) { scene->_actor2.animate(ANIM_MODE_6, NULL); } else { - if (((scene->_actor3._percent * 49) / 100) + scene->_actor3._position.x == scene->_actor2._position.x) { - if (scene->_actor2._position.x == 166 - (R2_GLOBALS._v565E3 / 15)) { + if (((scene->_electromagnet._percent * 49) / 100) + scene->_electromagnet._position.x == scene->_actor2._position.x) { + if (scene->_actor2._position.x == 166 - (R2_GLOBALS._electromagnetZoom / 15)) { R2_GLOBALS._player.disableControl(); scene->_sceneMode = 4; - scene->_actor2._moveDiff.y = (scene->_actor2._position.y - (scene->_actor3._position.y + ((scene->_actor3._percent * 3) / 10) - 2)) / 9; - Common::Point pt(scene->_actor3._position.x + ((scene->_actor3._percent * 49) / 100), scene->_actor3._position.y + ((scene->_actor3._percent * 3) / 10) - 2); + scene->_actor2._moveDiff.y = (scene->_actor2._position.y - (scene->_electromagnet._position.y + ((scene->_electromagnet._percent * 3) / 10) - 2)) / 9; + Common::Point pt(scene->_electromagnet._position.x + ((scene->_electromagnet._percent * 49) / 100), scene->_electromagnet._position.y + ((scene->_electromagnet._percent * 3) / 10) - 2); NpcMover *mover = new NpcMover(); scene->_actor2.addMover(mover, &pt, this); scene->_actor2.animate(ANIM_MODE_6, NULL); @@ -7179,7 +7189,7 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) { scene->_sceneMode = 5; scene->_actor2.animate(ANIM_MODE_5, NULL); scene->_actor2._moveDiff.y = (166 - scene->_actor2._position.y) / 9; - Common::Point pt(scene->_actor2._position.x, 166 - (R2_GLOBALS._v565E3 / 15)); + Common::Point pt(scene->_actor2._position.x, 166 - (R2_GLOBALS._electromagnetZoom / 15)); NpcMover *mover = new NpcMover(); scene->_actor2.addMover(mover, &pt, this); } @@ -7196,30 +7206,30 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) { return true; break; case 4: - if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E3 != 0)) { + if ((scene->_magnetChangeAmount.y == 0) && (scene->_magnetChangeAmount.x == 0) && (R2_GLOBALS._electromagnetZoom != 0)) { scene->_aSound1.play(38); - scene->_field416 = -5; + scene->_magnetChangeAmount.y = -5; } return true; break; case 5: - if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E3 < 135)) { + if ((scene->_magnetChangeAmount.y == 0) && (scene->_magnetChangeAmount.x == 0) && (R2_GLOBALS._electromagnetZoom < 135)) { scene->_aSound1.play(38); - scene->_field416 = 5; + scene->_magnetChangeAmount.y = 5; } return true; break; case 6: - if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E1 > -10)) { + if ((scene->_magnetChangeAmount.y == 0) && (scene->_magnetChangeAmount.x == 0) && (R2_GLOBALS._electromagnetChangeAmount > -10)) { scene->_aSound1.play(38); - scene->_field414 = -5; + scene->_magnetChangeAmount.x = -5; } return true; break; case 7: - if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E1 < 20)) { + if ((scene->_magnetChangeAmount.y == 0) && (scene->_magnetChangeAmount.x == 0) && (R2_GLOBALS._electromagnetChangeAmount < 20)) { scene->_aSound1.play(38); - scene->_field414 = 5; + scene->_magnetChangeAmount.x = 5; } return true; break; @@ -7234,12 +7244,12 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) { default: if (scene->_field412 == 1) { R2_GLOBALS._player.disableControl(); - scene->_actor5.remove(); - scene->_actor6.remove(); - scene->_actor7.remove(); - scene->_actor8.remove(); - scene->_actor9.remove(); - scene->_actor10.remove(); + scene->_button2.remove(); + scene->_button3.remove(); + scene->_button4.remove(); + scene->_button5.remove(); + scene->_button6.remove(); + scene->_button7.remove(); R2_GLOBALS._sound2.play(37); scene->_sceneMode = 901; scene->setAction(&scene->_sequenceManager1, scene, 901, &scene->_actor1, this ,NULL); @@ -7252,10 +7262,8 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) { break; } } else if (action == CURSOR_LOOK) { - if ((_fieldA4 == 2) && (scene->_field412 == 2)) - SceneItem::display(900, 21, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); - else - SceneItem::display(900, _fieldA4, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); + SceneItem::display(900, ((_buttonId == 2) && (scene->_field412 == 2)) ? 21 : _buttonId + 11, + SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, 1, SET_Y, 20, SET_EXT_BGCOLOR, 7, -999); return true; } else { return SceneActor::startAction(action, event); @@ -7275,16 +7283,15 @@ void Scene900::postInit(SceneObjectList *OwnerList) { _actor1.postInit(); _actor1.setDetails(900, 3, -1, -1, 1, (SceneItem *) NULL); - _field414 = 0; - _field416 = 0; + _magnetChangeAmount.x = 0; + _magnetChangeAmount.y = 0; - _actor3.postInit(); - _actor3.fixPriority(1); - // useless, the original use it for debugging purposes: strcpy(_actor3._actorName, "Crane"); - _actor3.setup(900, 1, 2); - _actor3.setPosition(Common::Point(89, 0)); - _actor3._effect = 1; - _actor3.setDetails(900, 6, -1, 8, 1, (SceneItem *) NULL); + _electromagnet.postInit(); + _electromagnet.fixPriority(1); + _electromagnet.setup(900, 1, 2); + _electromagnet.setPosition(Common::Point(89, 0)); + _electromagnet._effect = 1; + _electromagnet.setDetails(900, 6, -1, 8, 1, (SceneItem *) NULL); if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) { _actor2.postInit(); @@ -7294,7 +7301,7 @@ void Scene900::postInit(SceneObjectList *OwnerList) { if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) { if (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 700) { _actor2.setup(901, 3, 2); - } else if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) { + } else if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) { _actor2.setup(901, 2, 1); } else { _actor2.setup(901, 2, 8); @@ -7306,7 +7313,7 @@ void Scene900::postInit(SceneObjectList *OwnerList) { if (R2_GLOBALS._v565E7 == 0) { _actor2.setup(901, 1, 8); // Original set two times the same values: skipped - _actor2.setPosition(Common::Point((((100 - ((R2_GLOBALS._v565EB * 350) / 100)) * 49) / 100) + ((R2_GLOBALS._v565E9 * _actor3._percent * 6) / 100) + 89, 166 - (R2_GLOBALS._v565EB / 3))); + _actor2.setPosition(Common::Point((((100 - ((R2_GLOBALS._v565EB * 350) / 100)) * 49) / 100) + ((R2_GLOBALS._v565E9 * _electromagnet._percent * 6) / 100) + 89, 166 - (R2_GLOBALS._v565EB / 3))); _actor2.changeZoom(((100 - ((R2_GLOBALS._v565EB * 350) / 100) + 52) / 10) * 10); } } @@ -7329,68 +7336,68 @@ void Scene900::signal() { _field412 = 1; R2_GLOBALS._sound2.play(37); - _actor5.remove(); - _actor6.remove(); - _actor7.remove(); - _actor8.remove(); - _actor9.remove(); - _actor10.remove(); + _button2.remove(); + _button3.remove(); + _button4.remove(); + _button5.remove(); + _button6.remove(); + _button7.remove(); - _actor5.sub96135(2); - _actor5.setup(900, 2, 1); - _actor5.setPosition(Common::Point(36, 166)); + _button2.initButton(2); + _button2.setup(900, 2, 1); + _button2.setPosition(Common::Point(36, 166)); - _actor6.sub96135(3); - _actor6.setup(900, 2, 5); - _actor6.setPosition(Common::Point(117, 166)); + _button3.initButton(3); + _button3.setup(900, 2, 5); + _button3.setPosition(Common::Point(117, 166)); break; case 2: _field412 = 2; - _actor5.remove(); - _actor6.remove(); + _button2.remove(); + _button3.remove(); - _actor5.sub96135(2); + _button2.initButton(2); if (R2_GLOBALS._v565E5 == 0) - _actor5.setup(900, 3, 9); + _button2.setup(900, 3, 9); else - _actor5.setup(900, 3, 11); - _actor5.setPosition(Common::Point(36, 166)); + _button2.setup(900, 3, 11); + _button2.setPosition(Common::Point(36, 166)); - _actor7.sub96135(5); - _actor7.setup(900, 3, 3); - _actor7.setPosition(Common::Point(76, 134)); + _button4.initButton(5); + _button4.setup(900, 3, 3); + _button4.setPosition(Common::Point(76, 134)); - _actor8.sub96135(4); - _actor8.setup(900, 3, 7); - _actor8.setPosition(Common::Point(76, 156)); + _button5.initButton(4); + _button5.setup(900, 3, 7); + _button5.setPosition(Common::Point(76, 156)); - _actor9.sub96135(6); - _actor9.setup(900, 3, 1); - _actor9.setPosition(Common::Point(55, 144)); + _button6.initButton(6); + _button6.setup(900, 3, 1); + _button6.setPosition(Common::Point(55, 144)); - _actor10.sub96135(7); - _actor10.setup(900, 3, 5); - _actor10.setPosition(Common::Point(99, 144)); + _button7.initButton(7); + _button7.setup(900, 3, 5); + _button7.setPosition(Common::Point(99, 144)); break; case 3: _field412 = 3; - _actor5.remove(); - _actor6.remove(); - _actor7.remove(); - _actor8.remove(); - _actor9.remove(); - _actor10.remove(); + _button2.remove(); + _button3.remove(); + _button4.remove(); + _button5.remove(); + _button6.remove(); + _button7.remove(); - _actor5.sub96135(8); - _actor5.setup(900, 4, 1); - _actor5.setPosition(Common::Point(36, 166)); + _button2.initButton(8); + _button2.setup(900, 4, 1); + _button2.setPosition(Common::Point(36, 166)); - _actor6.sub96135(9); - _actor6.setup(900, 4, 5); - _actor6.setPosition(Common::Point(117, 166)); + _button3.initButton(9); + _button3.setup(900, 4, 5); + _button3.setPosition(Common::Point(117, 166)); break; case 4: _sceneMode = 0; @@ -7404,9 +7411,9 @@ void Scene900::signal() { _actor1.setup(900, 1, 1); - _actor4.sub96135(1); - _actor4.setup(900, 1, 3); - _actor4.setPosition(Common::Point(77, 168)); + _button1.initButton(1); + _button1.setup(900, 1, 3); + _button1.setPosition(Common::Point(77, 168)); _sceneMode = 1; signal(); @@ -7425,26 +7432,28 @@ void Scene900::signal() { } void Scene900::dispatch() { - if (_field416 != 0) { - if (_field416 < 0) { - R2_GLOBALS._v565E3--; - ++_field416; + if (_magnetChangeAmount.y != 0) { + if (_magnetChangeAmount.y < 0) { + R2_GLOBALS._electromagnetZoom--; + ++_magnetChangeAmount.y; } else { - ++R2_GLOBALS._v565E3; - _field416--; + ++R2_GLOBALS._electromagnetZoom; + _magnetChangeAmount.y--; } } - if (_field414 != 0) { - R2_GLOBALS._v565E1--; - ++_field414; - } else { - ++R2_GLOBALS._v565E1; - _field414++; + if (_magnetChangeAmount.x != 0) { + if (_magnetChangeAmount.x < 0) { + R2_GLOBALS._electromagnetChangeAmount--; + ++_magnetChangeAmount.x; + } else { + ++R2_GLOBALS._electromagnetChangeAmount; + _magnetChangeAmount.x--; + } } if (R2_GLOBALS._sceneObjects->contains(&_actor2)) { - if ((R2_GLOBALS._v565E5 != 0) && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) { + if ((R2_GLOBALS._v565E5 != 0) && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) { if ((_actor2._frame > 1) && (_actor2._animateMode != ANIM_MODE_6)) _actor2.animate(ANIM_MODE_6, NULL); } else { @@ -7453,17 +7462,17 @@ void Scene900::dispatch() { } } - _actor3.changeZoom(100 - ((R2_GLOBALS._v565E3 * 70) / 100)); - _actor3.setPosition(Common::Point(((_actor3._percent * R2_GLOBALS._v565E1 * 6) / 100) + 89, R2_GLOBALS._v565E3)); + _electromagnet.changeZoom(100 - ((R2_GLOBALS._electromagnetZoom * 70) / 100)); + _electromagnet.setPosition(Common::Point(((_electromagnet._percent * R2_GLOBALS._electromagnetChangeAmount * 6) / 100) + 89, R2_GLOBALS._electromagnetZoom)); if ((R2_GLOBALS._sceneObjects->contains(&_actor2)) && (R2_GLOBALS._v565E7 != 0) && (!_actor2._mover) && (_actor2._animateMode == ANIM_MODE_NONE)) { - _actor2.setPosition(Common::Point(_actor3._position.x + ((_actor3._percent * 49) / 100), _actor3._position.y + ((_actor3._percent * 3) / 10))); - if (R2_GLOBALS._v565E3 >= 75) { + _actor2.setPosition(Common::Point(_electromagnet._position.x + ((_electromagnet._percent * 49) / 100), _electromagnet._position.y + ((_electromagnet._percent * 3) / 10))); + if (R2_GLOBALS._electromagnetZoom >= 75) { _actor2.setup(901, 1, 1); - _actor2.changeZoom(((_actor3._percent + 52) / 10) * 10); + _actor2.changeZoom(((_electromagnet._percent + 52) / 10) * 10); } else { _actor2.setup(901, 5, 1); - _actor2.changeZoom(((_actor3._percent / 10) * 10) + 30); + _actor2.changeZoom(((_electromagnet._percent / 10) * 10) + 30); } } Scene::dispatch(); diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h index 2f52f9578f..58dad85a4c 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.h +++ b/engines/tsage/ringworld2/ringworld2_scenes0.h @@ -615,7 +615,7 @@ public: }; class Scene600 : public SceneExt { - class Item1 : public NamedHotspot { + class CompartmentHotspot : public NamedHotspot { public: virtual bool startAction(CursorType action, Event &event); }; @@ -630,15 +630,15 @@ class Scene600 : public SceneExt { virtual bool startAction(CursorType action, Event &event); virtual void draw(); }; - class Actor5 : public SceneActor { + class Doorway : public SceneActor { public: virtual bool startAction(CursorType action, Event &event); }; - class Actor6 : public SceneActor { + class Laser : public SceneActor { public: virtual bool startAction(CursorType action, Event &event); }; - class Actor7 : public SceneActor { + class Aerosol : public SceneActor { public: virtual bool startAction(CursorType action, Event &event); }; @@ -648,19 +648,19 @@ class Scene600 : public SceneExt { }; public: int _field412; - Item1 _item1; - Item1 _item2; - Item1 _item3; + CompartmentHotspot _background; + CompartmentHotspot _item2; + CompartmentHotspot _item3; Item4 _item4; - Item1 _item5; + CompartmentHotspot _item5; BackgroundSceneObject _object1; SceneActor _actor1; SceneActor _actor2; SceneActor _actor3; Actor4 _actor4; - Actor5 _actor5; - Actor6 _actor6; - Actor7 _actor7; + Doorway _doorway; + Laser _laser; + Aerosol _aerosol; Actor8 _actor8; ASoundExt _aSound1; SequenceManager _sequenceManager1; @@ -865,30 +865,29 @@ public: }; class Scene900 : public SceneExt { - class Actor4 : public SceneActor { + class Button : public SceneActor { public: - int _fieldA4; + int _buttonId; - Actor4(); - void sub96135(int arg1); + Button(); + void initButton(int buttonId); virtual void synchronize(Serializer &s); virtual bool startAction(CursorType action, Event &event); }; public: int _field412; - int _field414; - int _field416; + Common::Point _magnetChangeAmount; NamedHotspot _item1; SceneActor _actor1; SceneActor _actor2; - SceneActor _actor3; - Actor4 _actor4; - Actor4 _actor5; - Actor4 _actor6; - Actor4 _actor7; - Actor4 _actor8; - Actor4 _actor9; - Actor4 _actor10; + SceneActor _electromagnet; + Button _button1; + Button _button2; + Button _button3; + Button _button4; + Button _button5; + Button _button6; + Button _button7; ASoundExt _aSound1; SequenceManager _sequenceManager1; diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp index af62ab6916..00605b3ef6 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp @@ -858,16 +858,17 @@ void Scene1100::saveCharacter(int characterIndex) { } /*-------------------------------------------------------------------------- - * Scene 1200 - + * Scene 1200 - Air Ducts Maze * *--------------------------------------------------------------------------*/ + Scene1200::Scene1200() { _field412 = 0; _field414 = 0; _field416 = 0; _field418 = 0; _field41A = 0; - _field41C = 1; //CHECKME: Only if fixup_flag == 6?? + _fixupMaze = false; } void Scene1200::synchronize(Serializer &s) { @@ -878,20 +879,13 @@ void Scene1200::synchronize(Serializer &s) { s.syncAsSint16LE(_field416); s.syncAsSint16LE(_field418); s.syncAsSint16LE(_field41A); - s.syncAsSint16LE(_field41C); -} - -Scene1200::Area1::Area1() { - _field20 = 0; + s.syncAsSint16LE(_fixupMaze); } -void Scene1200::Area1::synchronize(Serializer &s) { - SceneArea::synchronize(s); - - s.syncAsByte(_field20); +Scene1200::LaserPanel::LaserPanel() { } -void Scene1200::Area1::Actor3::init(int state) { +void Scene1200::LaserPanel::Jumper::init(int state) { _state = state; SceneActor::postInit(); @@ -912,6 +906,7 @@ void Scene1200::Area1::Actor3::init(int state) { default: break; } + break; case 2: switch (R2_GLOBALS._v56AA7) { case 1: @@ -929,6 +924,7 @@ void Scene1200::Area1::Actor3::init(int state) { default: break; } + break; case 3: switch (R2_GLOBALS._v56AA8) { case 1: @@ -942,6 +938,7 @@ void Scene1200::Area1::Actor3::init(int state) { default: break; } + break; default: break; } @@ -949,7 +946,7 @@ void Scene1200::Area1::Actor3::init(int state) { setDetails(1200, 12, -1, -1, 2, (SceneItem *) NULL); } -bool Scene1200::Area1::Actor3::startAction(CursorType action, Event &event) { +bool Scene1200::LaserPanel::Jumper::startAction(CursorType action, Event &event) { if (action != CURSOR_USE) return SceneActor::startAction(action, event); @@ -1018,7 +1015,7 @@ bool Scene1200::Area1::Actor3::startAction(CursorType action, Event &event) { return true; } -void Scene1200::Area1::postInit(SceneObjectList *OwnerList) { +void Scene1200::LaserPanel::postInit(SceneObjectList *OwnerList) { Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene; scene->_field41A = 1; @@ -1026,81 +1023,35 @@ void Scene1200::Area1::postInit(SceneObjectList *OwnerList) { proc12(1003, 1, 1, 100, 40); proc13(1200, 11, -1, -1); R2_GLOBALS._sound2.play(259); - _actor3.init(1); - _actor4.init(2); - _actor5.init(3); + _jumper1.init(1); + _jumper2.init(2); + _jumper3.init(3); R2_GLOBALS._player._canWalk = false; } -void Scene1200::Area1::remove() { +void Scene1200::LaserPanel::remove() { Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene; scene->_field41A = 0; warning("Unexpected _sceneAreas.remove() call"); -// scene->_sceneAreas.remove(&_actor3); -// scene->_sceneAreas.remove(&_actor4); -// scene->_sceneAreas.remove(&_actor5); - _actor3.remove(); - _actor4.remove(); - _actor5.remove(); +// scene->_sceneAreas.remove(&_jumper1); +// scene->_sceneAreas.remove(&_jumper2); +// scene->_sceneAreas.remove(&_jumper3); + _jumper1.remove(); + _jumper2.remove(); + _jumper3.remove(); // sub201EA R2_GLOBALS._sceneItems.remove((SceneItem *)this); - _actor2.remove(); + _object1.remove(); SceneArea::remove(); R2_GLOBALS._insetUp--; - // R2_GLOBALS._player._canWalk = true; } -void Scene1200::Area1::process(Event &event) { - if (_field20 != R2_GLOBALS._insetUp) - return; - - CursorType cursor = R2_GLOBALS._events.getCursor(); - - if (_actor2._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) { - if (cursor == _cursorNum) { - warning("TODO: _cursorState = ???"); - R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState); - } - } else if (event.mousePos.y < 168) { - if (cursor != _cursorNum) { - _savedCursorNum = cursor; - warning("TODO: _cursorState = ???"); - R2_GLOBALS._events.setCursor(CURSOR_INVALID); - } - if (event.eventType == EVENT_BUTTON_DOWN) { - event.handled = true; - warning("TODO: _cursorState = ???"); - R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState); - remove(); - } - } -} - -void Scene1200::Area1::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) { - Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene; - - _actor2.postInit(); - _actor2.setup(visage, stripFrameNum, frameNum); - _actor2.setPosition(Common::Point(posX, posY)); - _actor2.fixPriority(250); - _cursorNum = CURSOR_INVALID; - scene->_sceneAreas.push_front(this); - ++R2_GLOBALS._insetUp; - _field20 = R2_GLOBALS._insetUp; -} - -void Scene1200::Area1::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) { - _actor2.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL); -} - void Scene1200::postInit(SceneObjectList *OwnerList) { - Rect tmpRect; - loadScene(1200); SceneExt::postInit(); @@ -1112,7 +1063,6 @@ void Scene1200::postInit(SceneObjectList *OwnerList) { _field416 = 0; _field418 = 0; _field41A = 0; - _field41C = 0; if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1)) _field418 = 1; @@ -1133,14 +1083,10 @@ void Scene1200::postInit(SceneObjectList *OwnerList) { _actor1.postInit(); _actor1.hide(); - tmpRect.set(110, 20, 210, 120); - _object1.sub9EDE8(tmpRect); + _mazeUI.setDisplayBounds(Rect(110, 20, 210, 120)); - _object1.sub51AE9(1); - _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4)); - warning("int unk = set_pane_p(_paneNumber);"); - _object1.sub51B02(); - warning("set_pane_p(unk);"); + _mazeUI.load(1); + _mazeUI.setMazePosition(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4)); R2_GLOBALS._player.enableControl(); _item1.setDetails(Rect(0, 0, 320, 200), 1200, 0, 1, 2, 1, NULL); @@ -1337,7 +1283,7 @@ void Scene1200::signal() { case 111: // No break on purpose case 116: - R2_GLOBALS._player.setup(3157, 3, 1); + R2_GLOBALS._player.setup(3157, 4, 1); R2_GLOBALS._player.animate(ANIM_MODE_5, this); break; case 78: @@ -1396,50 +1342,52 @@ void Scene1200::process(Event &event) { return; if (event.eventType == EVENT_BUTTON_DOWN) { - _object1.sub9EE22(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4); - int unk = _object1.sub51AF8(event.mousePos); + Common::Point cellPos(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4); + _mazeUI.pixelToCellXY(cellPos); + + int cellId = _mazeUI.getCellFromPixelXY(event.mousePos); switch (R2_GLOBALS._events.getCursor()) { - case CURSOR_ARROW: + case CURSOR_WALK: event.handled = true; if ((event.mousePos.x > 179) && (event.mousePos.x < 210) && (event.mousePos.y > 50) && (event.mousePos.y < 89)) - sub9DAD6(1); + startCrawling(CRAWL_EAST); if ((event.mousePos.x > 109) && (event.mousePos.x < 140) && (event.mousePos.y > 50) && (event.mousePos.y < 89)) - sub9DAD6(2); + startCrawling(CRAWL_WEST); if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 89) && (event.mousePos.y < 120)) - sub9DAD6(3); + startCrawling(CRAWL_SOUTH); if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 19) && (event.mousePos.y < 50)) - sub9DAD6(4); + startCrawling(CRAWL_NORTH); break; case CURSOR_USE: - if (unk > 36) { - if ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 33)) - || ((R2_GLOBALS._v56AA2 == 7) && (R2_GLOBALS._v56AA4 == 33)) - || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 41)) - || ((R2_GLOBALS._v56AA2 == 5) && (R2_GLOBALS._v56AA4 == 5)) - || ((R2_GLOBALS._v56AA2 == 13) && (R2_GLOBALS._v56AA4 == 21)) - || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 21)) - || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 5)) - || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 9)) - || ((R2_GLOBALS._v56AA2 == 29) && (R2_GLOBALS._v56AA4 == 17)) - || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 17)) - || ((R2_GLOBALS._v56AA2 == 35) && (R2_GLOBALS._v56AA4 == 17)) - || ((R2_GLOBALS._v56AA2 == 41) && (R2_GLOBALS._v56AA4 == 21)) ) { - _area1.postInit(); + if (cellId > 36) { + if ( ((cellPos.x == 3) && (cellPos.y == 33)) + || ((cellPos.x == 7) && (cellPos.y == 33)) + || ((cellPos.x == 33) && (cellPos.y == 41)) + || ((cellPos.x == 5) && (cellPos.y == 5)) + || ((cellPos.x == 13) && (cellPos.y == 21)) + || ((cellPos.x == 17) && (cellPos.y == 21)) + || ((cellPos.x == 17) && (cellPos.y == 5)) + || ((cellPos.x == 17) && (cellPos.y == 9)) + || ((cellPos.x == 29) && (cellPos.y == 17)) + || ((cellPos.x == 33) && (cellPos.y == 17)) + || ((cellPos.x == 35) && (cellPos.y == 17)) + || ((cellPos.x == 41) && (cellPos.y == 21)) ) { + _laserPanel.postInit(); event.handled = true; } } - if ((unk == 1) || (unk == 4) || (unk == 11) || (unk == 14)) { - if ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 9)) - || ((R2_GLOBALS._v56AA2 == 11) && (R2_GLOBALS._v56AA4 == 27)) - || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 7)) - || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 27)) - || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 33)) - || (R2_GLOBALS._v56AA2 == 33) ) { - switch (R2_GLOBALS._v56AA2) { + if ((cellId == 1) || (cellId == 4) || (cellId == 11) || (cellId == 14)) { + if ( ((cellPos.x == 3) && (cellPos.y == 9)) + || ((cellPos.x == 11) && (cellPos.y == 27)) + || ((cellPos.x == 17) && (cellPos.y == 7)) + || ((cellPos.x == 17) && (cellPos.y == 27)) + || ((cellPos.x == 17) && (cellPos.y == 33)) + || (cellPos.x == 33) ) { + switch (cellPos.x) { case 3: R2_GLOBALS._sceneManager.changeScene(3150); break; @@ -1458,23 +1406,25 @@ void Scene1200::process(Event &event) { } break; case CURSOR_LOOK: - if ((unk == 1) || (unk == 4) || (unk == 11) || (unk == 14)) { + if ((cellId == 1) || (cellId == 4) || (cellId == 11) || (cellId == 14)) { event.handled = true; - switch (R2_GLOBALS._v56AA2) { + switch (cellPos.x) { case 3: + // It was your cell. SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); break; case 9: R2_GLOBALS._sceneManager.changeScene(3240); break; case 11: - if (R2_GLOBALS._v56AA4 == 27) + if (cellPos.y == 27) R2_GLOBALS._sceneManager.changeScene(3210); else + // A vent grill SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); break; case 17: - switch (R2_GLOBALS._v56AA4) { + switch (cellPos.y) { case 5: R2_GLOBALS._sceneManager.changeScene(3230); break; @@ -1485,6 +1435,7 @@ void Scene1200::process(Event &event) { R2_GLOBALS._sceneManager.changeScene(3200); break; default: + // A vent grill SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); break; } @@ -1496,7 +1447,8 @@ void Scene1200::process(Event &event) { break; } } - if (unk > 36) { + if (cellId > 36) { + // "An anti-pest laser" event.handled = true; SceneItem::display(1200, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999); } @@ -1516,19 +1468,19 @@ void Scene1200::process(Event &event) { switch (event.kbd.keycode) { case Common::KEYCODE_1: warning("FIXME: keycode = 0x4800"); - sub9DAD6(4); + startCrawling(CRAWL_NORTH); break; case Common::KEYCODE_2: warning("FIXME: keycode = 0x4B00"); - sub9DAD6(2); + startCrawling(CRAWL_WEST); break; case Common::KEYCODE_3: warning("FIXME: keycode = 0x4D00"); - sub9DAD6(1); + startCrawling(CRAWL_EAST); break; case Common::KEYCODE_4: warning("FIXME: keycode = 0x5000"); - sub9DAD6(3); + startCrawling(CRAWL_SOUTH); break; default: event.handled = false; @@ -1543,13 +1495,13 @@ void Scene1200::process(Event &event) { void Scene1200::dispatch() { Rect tmpRect; Scene::dispatch(); - if (_field41C != 0) { - _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4)); - warning("int unk = set_pane_p(_paneNumber);"); - _object1.sub51B02(); + + if (_fixupMaze) { + _mazeUI.setMazePosition(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4)); + warning("_gfxManager.sub294AC(unk);"); warning("tmpRect.sub14DF3();"); - _field41C = 0; + _fixupMaze = false; } if (_field414 != 0) { @@ -1571,11 +1523,10 @@ void Scene1200::dispatch() { default: break; } - _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4)); - warning("int unk = set_pane_p(_paneNumber);"); - _object1.sub51B02(); - warning("_gfxManager.sub294AC(unk);"); - warning("tmpRect.sub14DF3();"); + _mazeUI.setMazePosition(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4)); + + debug("_gfxManager.sub294AC(unk);"); + debug("tmpRect.sub14DF3();"); if (_field416 != 0) { switch(_field412 - 1) { @@ -1608,6 +1559,190 @@ void Scene1200::saveCharacter(int characterIndex) { SceneExt::saveCharacter(characterIndex); } +void Scene1200::startCrawling(CrawlDirection dir) { + Common::Point cellPos = Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4); + _mazeUI.pixelToCellXY(cellPos); + + switch (dir) { + case CRAWL_EAST: + if ( ((_mazeUI.getCellFromPixelXY(Common::Point(200, 50)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(200, 88)) > 36)) + && ( ((cellPos.x == 3) && (cellPos.y == 33) && (_field418 != 4)) + || ((cellPos.x == 13) && (cellPos.y == 21) && (_field418 != 2)) + || ((cellPos.x == 29) && (cellPos.y == 17) && (_field418 != 1)) + || ((cellPos.x == 33) && (cellPos.y == 41)) ) + ) { + R2_GLOBALS._player.disableControl(); + _sceneMode = 1200; + setAction(&_sequenceManager, this, 1200, &_actor1, NULL); + } else if (_mazeUI.getCellFromPixelXY(Common::Point(200, 69)) == 36) { + switch (_field412 - 1) { + case 0: + if (R2_GLOBALS._player._visage == 3155) + _sceneMode = 15; + else + _sceneMode = 10; + break; + case 1: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 76; + else + _sceneMode = 75; + break; + case 2: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 101; + else + _sceneMode = 100; + break; + case 3: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 111; + else + _sceneMode = 110; + break; + default: + break; + } + R2_GLOBALS._player.disableControl(); + _field412 = 1; + signal(); + } + break; + case CRAWL_WEST: + if ( ((_mazeUI.getCellFromPixelXY(Common::Point(120, 50)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(120, 88)) > 36)) + && ( ((cellPos.x == 7) && (cellPos.y == 33) && (_field418 != 4)) + || ((cellPos.x == 17) && (cellPos.y == 21) && (_field418 != 2)) + || ((cellPos.x == 33) && (cellPos.y == 17) && (_field418 != 1)) + || ((cellPos.x == 5) && (cellPos.y == 5)) ) + ) { + R2_GLOBALS._player.disableControl(); + _sceneMode = 1201; + setAction(&_sequenceManager, this, 1201, &_actor1, NULL); + } else if (_mazeUI.getCellFromPixelXY(Common::Point(120, 69)) == 36) { + switch (_field412 - 1) { + case 0: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 56; + else + _sceneMode = 55; + break; + case 1: + if (R2_GLOBALS._player._visage == 3155) + _sceneMode = 25; + else + _sceneMode = 20; + break; + case 2: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 91; + else + _sceneMode = 90; + break; + case 3: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 121; + else + _sceneMode = 120; + break; + default: + break; + } + R2_GLOBALS._player.disableControl(); + _field412 = 2; + signal(); + } + break; + case CRAWL_SOUTH: + if ( ((_mazeUI.getCellFromPixelXY(Common::Point(140, 110)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(178, 110)) > 36)) + && ( ((cellPos.x == 17) && (cellPos.y == 5) && (_field418 != 3)) + || ((cellPos.x == 41) && (cellPos.y == 21)) ) + ) { + R2_GLOBALS._player.disableControl(); + _sceneMode = 1203; + setAction(&_sequenceManager, this, 1203, &_actor1, NULL); + } else if (_mazeUI.getCellFromPixelXY(Common::Point(160, 110)) == 36) { + switch (_field412 - 1) { + case 0: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 51; + else + _sceneMode = 50; + break; + case 1: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 81; + else + _sceneMode = 80; + break; + case 2: + if (R2_GLOBALS._player._visage == 3155) + _sceneMode = 35; + else + _sceneMode = 30; + break; + case 3: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 116; + else + _sceneMode = 115; + break; + default: + break; + } + R2_GLOBALS._player.disableControl(); + _field412 = 3; + signal(); + } + break; + case CRAWL_NORTH: + if ( ((_mazeUI.getCellFromPixelXY(Common::Point(140, 30)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(178, 30)) > 36)) + && ( ((cellPos.x == 17) && (cellPos.y == 9) && (_field418 != 3)) + || ((cellPos.x == 35) && (cellPos.y == 17)) ) + ) { + R2_GLOBALS._player.disableControl(); + _sceneMode = 1202; + setAction(&_sequenceManager, this, 1202, &_actor1, NULL); + } else if (_mazeUI.getCellFromPixelXY(Common::Point(160, 30)) == 36) { + switch (_field412 - 1) { + case 0: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 61; + else + _sceneMode = 60; + break; + case 1: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 71; + else + _sceneMode = 70; + break; + case 2: + if (R2_GLOBALS._player._visage == 3156) + _sceneMode = 96; + else + _sceneMode = 95; + break; + case 3: + if (R2_GLOBALS._player._visage == 3155) + _sceneMode = 45; + else + _sceneMode = 40; + break; + default: + _sceneMode = 1; + R2_GLOBALS._player.setup(3156, 4, 6); + break; + } + R2_GLOBALS._player.disableControl(); + _field412 = 4; + signal(); + } + break; + default: + break; + } +} + /*-------------------------------------------------------------------------- * Scene 1337 - Card game * @@ -6924,7 +7059,7 @@ void Scene1550::UnkArea1550::remove() { } void Scene1550::UnkArea1550::process(Event &event) { -// This is a copy of Scene1200::Area1::process +// This is a copy of Scene1200::LaserPanel::process if (_field20 != R2_GLOBALS._insetUp) return; @@ -6988,7 +7123,7 @@ void Scene1550::UnkArea1550::proc12(int visage, int stripFrameNum, int frameNum, } void Scene1550::UnkArea1550::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) { - // Copy of Scene1200::Area1::proc13 + // Copy of Scene1200::LaserPanel::proc13 _areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL); } @@ -12947,7 +13082,7 @@ void Scene1950::Area1::remove() { } void Scene1950::Area1::process(Event &event) { -// This is a copy of Scene1200::Area1::process +// This is a copy of Scene1200::LaserPanel::process if (_field20 != R2_GLOBALS._insetUp) return; @@ -13000,7 +13135,7 @@ void Scene1950::Area1::proc12(int visage, int stripFrameNum, int frameNum, int p } void Scene1950::Area1::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) { - // Copy of Scene1200::Area1::proc13() + // Copy of Scene1200::LaserPanel::proc13() _areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL); } diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h index f65a89972d..a2865a4b94 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes1.h +++ b/engines/tsage/ringworld2/ringworld2_scenes1.h @@ -118,36 +118,31 @@ public: }; class Scene1200 : public SceneExt { - class Area1: public SceneArea { + enum CrawlDirection { CRAWL_EAST = 1, CRAWL_WEST = 2, CRAWL_SOUTH = 3, CRAWL_NORTH = 4 }; + + class LaserPanel: public ModalDialog { public: - class Actor3 : public SceneActorExt { + class Jumper : public SceneActorExt { public: void init(int state); virtual bool startAction(CursorType action, Event &event); }; - SceneActor _actor2; - Actor3 _actor3; - Actor3 _actor4; - Actor3 _actor5; - - byte _field20; + Jumper _jumper1; + Jumper _jumper2; + Jumper _jumper3; - Area1(); - void synchronize(Serializer &s); + LaserPanel(); virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void remove(); - virtual void process(Event &event); - virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY); - virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum); }; public: NamedHotspot _item1; SceneActor _actor1; - Area1 _area1; - UnkObject1200 _object1; + LaserPanel _laserPanel; + MazeUI _mazeUI; SequenceManager _sequenceManager; int _field412; @@ -155,12 +150,12 @@ public: int _field416; int _field418; int _field41A; - int _field41C; + bool _fixupMaze; Scene1200(); void synchronize(Serializer &s); - void sub9DAD6(int indx); + void startCrawling(CrawlDirection dir); virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void signal(); diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp index 6a030e5b44..9246c4b6a4 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp @@ -630,6 +630,7 @@ void Scene2000::Exit3::changeScene() { break; } } + void Scene2000::Exit4::changeScene() { Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene; @@ -756,19 +757,21 @@ void Scene2000::Exit5::changeScene() { } } -void Scene2000::postInit(SceneObjectList *OwnerList) { - SceneExt::postInit(); - loadScene(2000); - +Scene2000::Scene2000(): SceneExt() { if (R2_GLOBALS._sceneManager._previousScene != -1) { R2_GLOBALS._v56605[1] = 21; R2_GLOBALS._v56605[2] = 21; } - if ((R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex] != R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) && (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 2350)) { + if ((R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex] + != R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) + && (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 2350)) { R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 0; } + _exitingFlag = false; +} +void Scene2000::postInit(SceneObjectList *OwnerList) { _exit1.setDetails(Rect(0, 100, 14, 140), EXITCURSOR_W, 2000); _exit1.setDest(Common::Point(14, 129)); _exit2.setDetails(Rect(305, 100, 320, 140), EXITCURSOR_E, 2000); @@ -917,6 +920,8 @@ void Scene2000::postInit(SceneObjectList *OwnerList) { initPlayer(); _item1.setDetails(Rect(0, 0, 320, 200), 2000, 0, -1, 23, 1, NULL); + + SceneExt::postInit(); } void Scene2000::remove() { @@ -998,6 +1003,8 @@ void Scene2000::signal() { g_globals->_sceneManager.changeScene(2350); break; default: + R2_GLOBALS._v56AAB = 0; + R2_GLOBALS._player.enableControl(); break; } } diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.h b/engines/tsage/ringworld2/ringworld2_scenes2.h index 281d1da366..feceaa1537 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes2.h +++ b/engines/tsage/ringworld2/ringworld2_scenes2.h @@ -80,6 +80,7 @@ public: Action1 _action1, _action2, _action3, _action4, _action5; SequenceManager _sequenceManager; + Scene2000(); virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void remove(); virtual void signal(); diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp index 61711d0a4f..6af2a0cad4 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes3.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp @@ -2885,9 +2885,10 @@ void Scene3400::signal() { } /*-------------------------------------------------------------------------- - * Scene 3500 - + * Scene 3500 - Cavern Maze * *--------------------------------------------------------------------------*/ + Scene3500::Action1::Action1() { _field1E = 0; _field20 = 0; @@ -2919,9 +2920,10 @@ void Scene3500::Action1::sub108670(int arg1) { else scene->_actor5.show(); - if (scene->_actor1._frame % 2 == 0) - scene->_actor1._frameChange = _field1E; - scene->_actor1.setFrame(scene->_actor1.changeFrame()); + if (scene->_actor1._frame % 2 == 0) { + scene->_actor1._frameChange = _field1E; + scene->_actor1.setFrame(scene->_actor1.changeFrame()); + } setActionIndex(0); } @@ -2977,219 +2979,6 @@ void Scene3500::Action1::sub108732(int arg1) { } } -Scene3500::Action2::Action2() { - _field1E = 0; -} - -void Scene3500::Action2::synchronize(Serializer &s) { - Action::synchronize(s); - - s.syncAsSint16LE(_field1E); -} - -Scene3500::Item4::Item4() { - _field34 = 0; -} - -void Scene3500::Item4::synchronize(Serializer &s) { - NamedHotspot::synchronize(s); - - s.syncAsSint16LE(_field34); -} - -Scene3500::Actor7::Actor7() { - _fieldA4 = 0; - _fieldA6 = 0; - _fieldA8 = 0; - _fieldAA = 0; - _fieldAC = 0; - _fieldAE = 0; -} - -void Scene3500::Actor7::synchronize(Serializer &s) { - SceneActor::synchronize(s); - - s.syncAsSint16LE(_fieldA4); - s.syncAsSint16LE(_fieldA6); - s.syncAsSint16LE(_fieldA8); - s.syncAsSint16LE(_fieldAA); - s.syncAsSint16LE(_fieldAC); - s.syncAsSint16LE(_fieldAE); -} - -void Scene3500::Actor7::sub109466(int arg1, int arg2, int arg3, int arg4, int arg5) { - _fieldAE = 0; - _fieldA4 = arg1; - _fieldA6 = arg2; - _fieldA8 = arg3; - _fieldAA = arg4; - _fieldAC = _fieldAA / _fieldA8; - - postInit(); - setup(10501, 3, 1); - fixPriority(255); - sub109663(arg5); -} - -void Scene3500::Actor7::sub1094ED() { - Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene; - - scene->_field1270 = _position.x - _fieldA4; -} - -void Scene3500::Actor7::sub109663(int arg1){ - sub109693(Common::Point(_fieldA4 + arg1, _fieldA6 - (_fieldAC * arg1))); -} - -void Scene3500::Actor7::sub109693(Common::Point Pt) { - setPosition(Pt); -} - -int Scene3500::UnkObject3500::sub1097C9(int arg1) { - return (_field2A / 2) + arg1 - (arg1 % _field2A); -} - -int Scene3500::UnkObject3500::sub1097EF(int arg1) { - return (_field2C / 2) + arg1 - (arg1 % _field2C); -} - -int Scene3500::UnkObject3500::sub109C09(Common::Point pt) { - int vx = pt.x / _field2A; - int vy = pt.y / _field2C; - - if ((vx >= 0) && (_field26 > vx) && (_field28 > vy)) { - return _field16[((_field26 * vy) + vx) * 2]; - } else - return -1; -} - -int Scene3500::UnkObject3500::sub109C5E(int &x, int &y) { - int retVal = sub51AFD(Common::Point(x, y)); - x = _field2E; - y = _field30; - - return retVal; -} - -Scene3500::Scene3500() { - _fieldAF8 = 0; - _fieldB9E = 0; - _rotation = NULL; - _field126E = 0; - _field1270 = 0; - _field1272 = 0; - _field1274 = 0; - _field1276 = 0; - _field1278 = 0; - _field127A = 0; - _field127C = 0; - _field127E = 0; - _field1280 = 0; - _field1282 = 0; - _field1284 = 0; - _field1286 = 0; -} - -void Scene3500::synchronize(Serializer &s) { - SceneExt::synchronize(s); - SYNC_POINTER(_rotation); - - s.syncAsSint16LE(_fieldAF8); - s.syncAsSint16LE(_fieldB9E); - s.syncAsSint16LE(_field126E); - s.syncAsSint16LE(_field1270); - s.syncAsSint16LE(_field1272); - s.syncAsSint16LE(_field1274); - s.syncAsSint16LE(_field1276); - s.syncAsSint16LE(_field1278); - s.syncAsSint16LE(_field127A); - s.syncAsSint16LE(_field127C); - s.syncAsSint16LE(_field127E); - s.syncAsSint16LE(_field1280); - s.syncAsSint16LE(_field1282); - s.syncAsSint16LE(_field1284); - s.syncAsSint16LE(_field1286); -} - -void Scene3500::sub107F71(int arg1) { - switch (arg1) { - case -1: - _actor7.sub1094ED(); - if (_field1270 != 0) { - _field1270--; - _actor7.sub109663(_field1270); - } - if (_action1._field24 != 0) - _field1270 = 0; - break; - case 1: - _actor7.sub1094ED(); - if (_field1270 < 16) { - ++_field1270; - _actor7.sub109663(_field1270); - } - if (_action1._field24 != 0) - _field1270 = 0; - break; - case 88: - if ((_action == 0) || (_action1._field24 == 0)) { - // The original makes a second useless check on action, skipped - _action2.sub10831F(2); - if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != 2))) { - _action2.signal(); - } else { - _actor9.setAction(&_action2, &_actor9, NULL); - } - } - break; - case 96: - if ((_action) && (_action1._field24 != 0) && (_action2._field1E != 1)) { - _field1278 = 0; - _action1.sub108732(0); - } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) { - _field1278 = arg1; - } else if ((_action) && (_action1._field24 == 0)) { - _action1.sub108670(1); - _action1.signal(); - } else if (_action == 0) { - _action1.sub108670(1); - setAction(&_action1, &_actor1, NULL); - } - break; - case 104: - if ((_action == 0) || (_action1._field24 == 0)) { - _action2.sub10831F(-1); - if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != -1))) { - _action2.signal(); - } else { - _actor9.setAction(&_action2, &_actor9, NULL); - } - } - break; - case 112: - if ((_action) && (_action1._field24 != 0) && (_action2._field1E != -1)) { - _field1278 = 0; - _action1.sub108732(0); - } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) { - _field1278 = arg1; - } else if ((_action) && (_action1._field24 == 0)) { - _action1.sub108670(-1); - _action1.signal(); - } else if (_action == 0) { - _action1.sub108670(-1); - setAction(&_action1, &_actor1, NULL); - } - break; - default: - _field1270 = arg1; - _actor7.sub109663(arg1); - if (_action1._field24 != 0) { - _field1270 = 0; - } - break; - } -} - void Scene3500::Action1::signal() { Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene; @@ -3199,13 +2988,13 @@ void Scene3500::Action1::signal() { scene->_field1286 = 0; if (scene->_field1270 != 0) { scene->_field1270 = 0; - scene->_field126E = 0; + scene->_mazeChangeAmount = 0; scene->_field1272 = 0; scene->_rotation->_idxChange = 0; } break; case 1: - if ((scene->_actor1._frame % 2) == 0) { + if ((scene->_actor1._frame % 2) == 1) { setDelay(1); return; } @@ -3216,25 +3005,28 @@ void Scene3500::Action1::signal() { setDelay(1); break; case 4: { - int si = scene->_unkObj1.sub109C09(Common::Point(scene->_field127A + 70, scene->_field127C + 46)); - int var2 = scene->_unkObj1.sub1097C9(scene->_field127A + 70) - 70; - int var4 = scene->_unkObj1.sub1097EF(scene->_field127C + 46) - 46; - int di = abs(var2 - scene->_field127A); - int var6 = abs(var4 - scene->_field127C); + int si = scene->_mazeUI.getCellFromMapXY(Common::Point(scene->_mazePosition.x + 70, scene->_mazePosition.y + 46)); + int var2 = scene->_mazeUI.cellFromX(scene->_mazePosition.x + 70) - 70; + int var4 = scene->_mazeUI.cellFromY(scene->_mazePosition.y + 46) - 46; + int di = abs(var2 - scene->_mazePosition.x); + int var6 = abs(var4 - scene->_mazePosition.y); if ((scene->_actor1._frame % 2) != 0) { scene->_actor1._frameChange = _field1E; scene->_actor1.setFrame(scene->_actor1.changeFrame()); } - int var8 = (scene->_action1._field1E * 2 + scene->_field1276); - if (var8 > 7) - var8 = 1; - else if (var8 < 1) - var8 = 7; + // Get the new direction starting on + int var8 = (scene->_action1._field1E * 2 + scene->_mazeDirection); + if (var8 > MAZEDIR_NORTHWEST) + var8 = MAZEDIR_NORTH; + else if (var8 < MAZEDIR_NORTH) + var8 = MAZEDIR_WEST; + // Check whether movement is allowed in that direction. If so, then + // movement is started again switch (var8) { - case 0: + case MAZEDIR_NORTH: if ( ((si != 2) && (si != 3) && (si != 6) && (si != 1) && (si != 23) && (si != 24) && (si != 4) && (si != 11)) || (var6 != 0)) { if ((si != 25) && (si != 26) && (si != 5) && (si != 14) && (si != 15)) @@ -3246,7 +3038,7 @@ void Scene3500::Action1::signal() { } else _field20 = 1; break; - case 2: + case MAZEDIR_EAST: if ( ((si != 12) && (si != 13) && (si != 11) && (si != 16) && (si != 26) && (si != 24) && (si != 15) && (si != 6) && (si != 31)) || (di != 0)) { if ((si != 25) && (si != 23) && (si != 14) && (si != 5) && (si != 4)) @@ -3258,7 +3050,7 @@ void Scene3500::Action1::signal() { } else _field20 = 1; break; - case 4: + case MAZEDIR_SOUTH: if ( ((si != 2) && (si != 3) && (si != 6) && (si != 1) && (si != 25) && (si != 26) && (si != 5) && (si != 16) && (si != 31)) || (var6 != 0)) { if ((si != 23) && (si != 24) && (si != 4) && (si != 14) && (si != 15)) @@ -3270,7 +3062,7 @@ void Scene3500::Action1::signal() { } else _field20 = 1; break; - case 6: + case MAZEDIR_WEST: if ( ((si != 12) && (si != 13) && (si != 11) && (si != 16) && (si != 25) && (si != 23) && (si != 14) && (si != 1) && (si != 31)) || (var6 != 0)) { if ((si != 26) && (si != 24) && (si != 15) && (si != 5) && (si != 4)) @@ -3288,14 +3080,14 @@ void Scene3500::Action1::signal() { // No break on purpose case 2: { scene->_actor8.setPosition(Common::Point(160, 73)); - scene->_actor8._moveDiff.x = 160 - scene->_field126E; + scene->_actor8._moveDiff.x = 160 - scene->_mazeChangeAmount; scene->_fieldAF8 = 160 - ((_field1E * 2) * 160); Common::Point pt(scene->_fieldAF8, 73); NpcMover *mover = new NpcMover(); scene->_actor8.addMover(mover, &pt, this); scene->_actor9.setPosition(Common::Point(160 + ((_field1E * 2) * 160), 73)); - scene->_actor9._moveDiff.x = 160 - scene->_field126E; + scene->_actor9._moveDiff.x = 160 - scene->_mazeChangeAmount; scene->_fieldB9E = 160; Common::Point pt2(scene->_fieldB9E, 73); NpcMover *mover2 = new NpcMover(); @@ -3304,8 +3096,8 @@ void Scene3500::Action1::signal() { break; case 5: scene->_actor1._frameChange = _field1E; - scene->_field1276 = scene->_actor1.changeFrame(); - scene->_actor1.setFrame(scene->_field1276); + scene->_mazeDirection = scene->_actor1.changeFrame(); + scene->_actor1.setFrame(scene->_mazeDirection); setDelay(1); break; case 6: @@ -3325,8 +3117,8 @@ void Scene3500::Action1::signal() { case 7: if ((scene->_actor1._frame % 2) == 0) { scene->_actor1._frameChange = _field1E; - scene->_field1276 = scene->_actor1.changeFrame(); - scene->_actor1.setFrame(scene->_field1276); + scene->_mazeDirection = scene->_actor1.changeFrame(); + scene->_actor1.setFrame(scene->_mazeDirection); } setDelay(1); break; @@ -3342,7 +3134,7 @@ void Scene3500::Action1::signal() { // but it's clearly a cut and paste error from case 4. // The following code allows the switch to work properly. warning("Checkme: fix for dead code"); - int var_8 = (_field1E * 2 + scene->_field1276); + int var_8 = (_field1E * 2 + scene->_mazeDirection); if (var_8 > 7) var_8 = 1; else if (var_8 < 1) @@ -3353,12 +3145,12 @@ void Scene3500::Action1::signal() { case 0: // No break on purpose case 4: - scene->_field127A = scene->_unkObj1.sub1097C9(scene->_field127A + 70) - 70; + scene->_mazePosition.x = scene->_mazeUI.cellFromX(scene->_mazePosition.x + 70) - 70; break; case 2: // No break on purpose case 6: - scene->_field127C = scene->_unkObj1.sub1097EF(scene->_field127C + 46) - 46; + scene->_mazePosition.y = scene->_mazeUI.cellFromY(scene->_mazePosition.y + 46) - 46; break; default: break; @@ -3368,7 +3160,7 @@ void Scene3500::Action1::signal() { _field24 = 0; if (_field20 == 0) { scene->_actor7.sub1094ED(); - if (scene->_field126E == scene->_field1270) + if (scene->_mazeChangeAmount == scene->_field1270) scene->_aSound1.play(276); } break; @@ -3416,12 +3208,232 @@ void Scene3500::Action1::dispatch() { Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene; Action::dispatch(); - if ((_actionIndex == 1) && (scene->_field126E <= 4)) { + if ((_actionIndex == 1) && (scene->_mazeChangeAmount <= 4)) { scene->_rotation->_idxChange = 0; signal(); } } +/*--------------------------------------------------------------------------*/ + +Scene3500::Action2::Action2() { + _field1E = 0; +} + +void Scene3500::Action2::synchronize(Serializer &s) { + Action::synchronize(s); + + s.syncAsSint16LE(_field1E); +} + +/*--------------------------------------------------------------------------*/ + +Scene3500::Item4::Item4() { + _field34 = 0; +} + +void Scene3500::Item4::synchronize(Serializer &s) { + NamedHotspot::synchronize(s); + + s.syncAsSint16LE(_field34); +} + +/*--------------------------------------------------------------------------*/ + +Scene3500::Actor7::Actor7() { + _fieldA4 = 0; + _fieldA6 = 0; + _fieldA8 = 0; + _fieldAA = 0; + _fieldAC = 0; + _fieldAE = 0; +} + +void Scene3500::Actor7::synchronize(Serializer &s) { + SceneActor::synchronize(s); + + s.syncAsSint16LE(_fieldA4); + s.syncAsSint16LE(_fieldA6); + s.syncAsSint16LE(_fieldA8); + s.syncAsSint16LE(_fieldAA); + s.syncAsSint16LE(_fieldAC); + s.syncAsSint16LE(_fieldAE); +} + +void Scene3500::Actor7::sub109466(int arg1, int arg2, int arg3, int arg4, int arg5) { + _fieldAE = 0; + _fieldA4 = arg1; + _fieldA6 = arg2; + _fieldA8 = arg3; + _fieldAA = arg4; + _fieldAC = _fieldAA / _fieldA8; + + postInit(); + setup(1050, 3, 1); + fixPriority(255); + sub109663(arg5); +} + +void Scene3500::Actor7::sub1094ED() { + Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene; + + scene->_field1270 = _position.x - _fieldA4; +} + +void Scene3500::Actor7::sub109663(int arg1){ + sub109693(Common::Point(_fieldA4 + arg1, _fieldA6 - (_fieldAC * arg1))); +} + +void Scene3500::Actor7::sub109693(Common::Point Pt) { + setPosition(Pt); +} + +/*--------------------------------------------------------------------------*/ + +int Scene3500::MazeUI3500::cellFromX(int x) { + return (_cellSize.x / 2) + x - (x % _cellSize.x); +} + +int Scene3500::MazeUI3500::cellFromY(int y) { + return (_cellSize.y / 2) + y - (y % _cellSize.y) - 1; +} + +int Scene3500::MazeUI3500::getCellFromMapXY(Common::Point pt) { + int cellX = pt.x / _cellSize.x; + int cellY = pt.y / _cellSize.y; + + if ((cellX >= 0) && (cellY >= 0) && (cellX < _mapCells.x) && (cellY < _mapCells.y)) { + return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * cellY + cellX) * 2); + } else + return -1; +} + +bool Scene3500::MazeUI3500::setMazePosition2(Common::Point &p) { + bool retVal = setMazePosition(p); + p = _mapOffset; + + return retVal; +} + +Scene3500::Scene3500() { + _fieldAF8 = 0; + _fieldB9E = 0; + _rotation = NULL; + _mazeChangeAmount = 0; + _field1270 = 0; + _field1272 = 0; + _field1274 = 0; + _mazeDirection = MAZEDIR_NONE; + _field1278 = 0; + _mazePosition.x = 0; + _mazePosition.y = 0; + _field127E = 0; + _field1280 = 0; + _field1282 = 0; + _field1284 = 0; + _field1286 = 0; +} + +void Scene3500::synchronize(Serializer &s) { + SceneExt::synchronize(s); + SYNC_POINTER(_rotation); + + s.syncAsSint16LE(_fieldAF8); + s.syncAsSint16LE(_fieldB9E); + s.syncAsSint16LE(_mazeChangeAmount); + s.syncAsSint16LE(_field1270); + s.syncAsSint16LE(_field1272); + s.syncAsSint16LE(_field1274); + s.syncAsSint16LE(_mazeDirection); + s.syncAsSint16LE(_field1278); + s.syncAsSint16LE(_mazePosition.x); + s.syncAsSint16LE(_mazePosition.y); + s.syncAsSint16LE(_field127E); + s.syncAsSint16LE(_field1280); + s.syncAsSint16LE(_field1282); + s.syncAsSint16LE(_field1284); + s.syncAsSint16LE(_field1286); +} + +void Scene3500::sub107F71(int arg1) { + switch (arg1) { + case -1: + _actor7.sub1094ED(); + if (_field1270 != 0) { + _field1270--; + _actor7.sub109663(_field1270); + } + if (_action1._field24 != 0) + _field1270 = 0; + break; + case 1: + _actor7.sub1094ED(); + if (_field1270 < 16) { + ++_field1270; + _actor7.sub109663(_field1270); + } + if (_action1._field24 != 0) + _field1270 = 0; + break; + case 88: + if ((_action == 0) || (_action1._field24 == 0)) { + // The original makes a second useless check on action, skipped + _action2.sub10831F(2); + if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != 2))) { + _action2.signal(); + } else { + _actor9.setAction(&_action2, &_actor9, NULL); + } + } + break; + case 96: + if ((_action) && (_action1._field24 != 0) && (_action2._field1E != 1)) { + _field1278 = 0; + _action1.sub108732(0); + } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) { + _field1278 = arg1; + } else if ((_action) && (_action1._field24 == 0)) { + _action1.sub108670(1); + _action1.signal(); + } else if (_action == 0) { + _action1.sub108670(1); + setAction(&_action1, &_actor1, NULL); + } + break; + case 104: + if ((_action == 0) || (_action1._field24 == 0)) { + _action2.sub10831F(-1); + if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != -1))) { + _action2.signal(); + } else { + _actor9.setAction(&_action2, &_actor9, NULL); + } + } + break; + case 112: + if ((_action) && (_action1._field24 != 0) && (_action2._field1E != -1)) { + _field1278 = 0; + _action1.sub108732(0); + } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) { + _field1278 = arg1; + } else if ((_action) && (_action1._field24 == 0)) { + _action1.sub108670(-1); + _action1.signal(); + } else if (_action == 0) { + _action1.sub108670(-1); + setAction(&_action1, &_actor1, NULL); + } + break; + default: + _field1270 = arg1; + _actor7.sub109663(arg1); + if (_action1._field24 != 0) { + _field1270 = 0; + } + break; + } +} + void Scene3500::Action2::sub10831F(int arg1) { Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene; @@ -3452,17 +3464,17 @@ void Scene3500::Action2::signal() { di = scene->_fieldB9E; } - scene->_actor8._moveDiff.y = 9 - (scene->_field126E / 2); + scene->_actor8._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2); Common::Point pt(si, 73 - (_field1E * 12)); NpcMover *mover = new NpcMover(); scene->_actor8.addMover(mover, &pt, NULL); - scene->_actor9._moveDiff.y = 9 - (scene->_field126E / 2); + scene->_actor9._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2); Common::Point pt2(di, 73 - (_field1E * 12)); NpcMover *mover2 = new NpcMover(); scene->_actor9.addMover(mover2, &pt2, NULL); - scene->_field126E = (scene->_field126E / 2) + (scene->_field126E % 2); - setDelay(17 - scene->_field126E); + scene->_mazeChangeAmount = (scene->_mazeChangeAmount / 2) + (scene->_mazeChangeAmount % 2); + setDelay(17 - scene->_mazeChangeAmount); } break; case 1: { @@ -3477,12 +3489,12 @@ void Scene3500::Action2::signal() { scene->_actor7.sub1094ED(); - scene->_actor8._moveDiff.y = 9 - (scene->_field126E / 2); + scene->_actor8._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2); Common::Point pt(si, 73); NpcMover *mover = new NpcMover(); scene->_actor8.addMover(mover, &pt, NULL); - scene->_actor9._moveDiff.y = 9 - (scene->_field126E / 2); + scene->_actor9._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2); Common::Point pt2(di, 73); NpcMover *mover2 = new NpcMover(); scene->_actor9.addMover(mover2, &pt2, NULL); @@ -3559,7 +3571,6 @@ bool Scene3500::Actor7::startAction(CursorType action, Event &event) { void Scene3500::postInit(SceneObjectList *OwnerList) { byte tmpPal[768]; - Rect tmpRect; loadScene(1050); R2_GLOBALS._uiElements._active = false; @@ -3574,9 +3585,8 @@ void Scene3500::postInit(SceneObjectList *OwnerList) { _field1278 = 0; _field1272 = 1; _field1270 = 4; - _field126E = 4; - _field127A = 860; - _field127C = 891; + _mazeChangeAmount = 4; + _mazePosition = Common::Point(860, 891); _rotation = R2_GLOBALS._scenePalette.addRotation(240, 254, -1); _rotation->setDelay(0); _rotation->_idxChange = 1; @@ -3615,7 +3625,7 @@ void Scene3500::postInit(SceneObjectList *OwnerList) { _item7.setDetails(96, 3500, 12, 10, -1); _actor8.postInit(); - _actor8.setup(10501, 1, 1); + _actor8.setup(1050, 1, 1); _actor8.setPosition(Common::Point(160, 73)); _actor8.fixPriority(1); @@ -3630,8 +3640,8 @@ void Scene3500::postInit(SceneObjectList *OwnerList) { _item1.setDetails(Rect(0, 0, 320, 200), 3500, 0, -1, 2, 1, NULL); _actor1.postInit(); - _field1276 = 1; - _actor1.setup(1004, 1, _field1276); + _mazeDirection = MAZEDIR_NORTH; + _actor1.setup(1004, 1, _mazeDirection); _actor1.setPosition(Common::Point(230, 135)); _actor1.fixPriority(200); _actor1._frameChange = 1; @@ -3654,7 +3664,7 @@ void Scene3500::postInit(SceneObjectList *OwnerList) { _actor6.hide(); _actor2.postInit(); - _actor2.setup(1004, 4, _field126E + 1); + _actor2.setup(1004, 4, _mazeChangeAmount + 1); _actor2.setPosition(Common::Point(126, 137)); _actor2.fixPriority(200); @@ -3663,15 +3673,12 @@ void Scene3500::postInit(SceneObjectList *OwnerList) { _actor3.setPosition(Common::Point(126, 108)); _actor3.fixPriority(200); - tmpRect.set(160, 89, 299, 182); - _unkObj1.sub9EDE8(tmpRect); - _unkObj1.sub51AE9(2); - _unkObj1.sub51AFD(Common::Point(_field127A, _field127C)); + _mazeUI.setDisplayBounds(Rect(160, 89, 299, 182)); + _mazeUI.load(2); + _mazeUI.setMazePosition(_mazePosition); _action1._field24 = 0; - warning("gfx_set_pane_p()"); - _unkObj1.sub51B02(); - warning("gfx_set_pane_p()"); + _mazeUI.draw(); _field1286 = 1; R2_GLOBALS._player.postInit(); @@ -3682,7 +3689,6 @@ void Scene3500::postInit(SceneObjectList *OwnerList) { } void Scene3500::remove() { - _rotation->remove(); R2_GLOBALS._sound2.fadeOut2(NULL); SceneExt::remove(); } @@ -3699,64 +3705,58 @@ void Scene3500::process(Event &event) { if (event.eventType == EVENT_KEYPRESS) { switch (event.kbd.keycode) { - case Common::KEYCODE_1: - warning("FIXME: keycode = 0x4700"); + case Common::KEYCODE_KP7: R2_GLOBALS._sound2.play(338); sub107F71(16); event.handled = true; break; - case Common::KEYCODE_2: - warning("FIXME: keycode = 0x4800"); + case Common::KEYCODE_UP: + case Common::KEYCODE_KP8: R2_GLOBALS._sound2.play(14, NULL, 63); sub107F71(88); event.handled = true; break; - case Common::KEYCODE_3: - warning("FIXME: keycode = 0x4900"); + case Common::KEYCODE_KP9: if (_field1270 < 16) R2_GLOBALS._sound2.play(338); sub107F71(1); event.handled = true; break; - case Common::KEYCODE_4: - warning("FIXME: keycode = 0x4B00"); + case Common::KEYCODE_KP4: + case Common::KEYCODE_LEFT: R2_GLOBALS._sound2.play(14, NULL, 63); sub107F71(112); event.handled = true; break; - case Common::KEYCODE_5: - warning("FIXME: keycode = 0x4D00"); + case Common::KEYCODE_KP6: + case Common::KEYCODE_RIGHT: R2_GLOBALS._sound2.play(14, NULL, 63); sub107F71(96); event.handled = true; break; - case Common::KEYCODE_6: - warning("FIXME: keycode = 0x4F00"); + case Common::KEYCODE_KP1: R2_GLOBALS._sound2.play(338); sub107F71(0); event.handled = true; break; - case Common::KEYCODE_7: - warning("FIXME: keycode = 0x5000"); + case Common::KEYCODE_KP2: + case Common::KEYCODE_DOWN: R2_GLOBALS._sound2.play(14, NULL, 63); sub107F71(104); event.handled = true; break; - case Common::KEYCODE_8: - warning("FIXME: keycode = 0x5100"); + case Common::KEYCODE_KP3: if (_field1270 != 0) R2_GLOBALS._sound2.play(338); sub107F71(-1); event.handled = true; break; - case Common::KEYCODE_9: - warning("FIXME: keycode = 0x5200"); + case Common::KEYCODE_KP0: R2_GLOBALS._sound2.play(338); sub107F71(8); event.handled = true; break; - case Common::KEYCODE_0: - warning("FIXME: keycode = 0x5300"); + case Common::KEYCODE_KP_PERIOD: R2_GLOBALS._sound2.play(338); sub107F71(4); event.handled = true; @@ -3787,9 +3787,10 @@ void Scene3500::process(Event &event) { void Scene3500::dispatch() { Rect tmpRect; Scene::dispatch(); + if (((_actor1._frame % 2) == 0) && (_action1._field24 == 0)) { _actor1.setFrame(_actor1.changeFrame()); - _field1276 = _actor1._frame; + _mazeDirection = _actor1._frame; } int oldField1278; if ((_field1278 != 0) && (_action1._field24 == 0)) { @@ -3801,90 +3802,90 @@ void Scene3500::dispatch() { if (!_rotation) return; - int var_field127A = 0; - int di = 0; + int newMazeX = 0; + int newMazeY = 0; int var_4 = 0; int var_6 = 0; int var_8 = 0; int var_a = 0; int dx = 0; - int tmpVar = 0; + int cellId = 0; - if ((_field126E == 0) && (_field1282 == 0)) { + if ((_mazeChangeAmount == 0) && (_field1282 == 0)) { if (_field1284 == 2) R2_GLOBALS._sceneManager.changeScene(1000); } else { _field1282 = 0; tmpRect.set(160, 89, 299, 182); - var_field127A = _field127A; - di = _field127C; - var_4 = _unkObj1.sub1097C9(70) - 70; - var_6 = _unkObj1.sub1097EF(_field127C + 46) - 46; - var_8 = abs(var_4 - var_field127A); - var_a = abs(var_6 - di); + newMazeX = _mazePosition.x; + newMazeY = _mazePosition.y; + var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70; + var_6 = _mazeUI.cellFromY(_mazePosition.y + 46) - 46; + var_8 = abs(var_4 - newMazeX); + var_a = abs(var_6 - newMazeY); dx = 0; - switch (_field1276) { - case 0: - tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, 46)); - if ( ((tmpVar == 2) || (tmpVar == 3) || (tmpVar == 6) || (tmpVar == 1)) - || (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 > 3)) ) { + switch (_mazeDirection) { + case MAZEDIR_NORTH: + cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if (((cellId == 2) || (cellId == 3) || (cellId == 6) || (cellId == 1)) || + ((cellId == 25 || cellId == 26 || cellId == 5 || cellId == 14 || cellId == 15) && var_8 > 3)) { R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); } else { - var_6 = _unkObj1.sub1097EF(di + 46) - 46; - di = _field127C - _field126E; - dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4)) && (tmpVar != dx)) { - di = var_6; + var_6 = _mazeUI.cellFromY(newMazeY + 46) - 46; + newMazeY = _mazePosition.y - _mazeChangeAmount; + dx = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if (((cellId == 23) || (cellId == 24) || (cellId == 4)) && (cellId != dx)) { + newMazeY = var_6; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 11) && (tmpVar != dx)) { - di = var_6 + 3; + } else if ((cellId == 11) && (cellId != dx)) { + newMazeY = var_6 + 3; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); } else { - var_6 = _unkObj1.sub1097EF(di + 46) - 46; - var_a = abs(var_6 - di); - tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - - if ( (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4)) && (di <= var_6) && (_field127C>= var_6)) - || (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (_field126E >= var_a) && (_field126E > 3) && (_action1._field24 != 0)) ) { - di = var_6; - if ((tmpVar != 25) && (tmpVar != 26) && (tmpVar != 5) && (tmpVar != 14) && (tmpVar == 15)) + var_6 = _mazeUI.cellFromY(newMazeY + 46) - 46; + var_a = abs(var_6 - newMazeY); + cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + + if ( (((cellId == 23) || (cellId == 24) || (cellId == 4)) && (newMazeY <= var_6) && (_mazePosition.y>= var_6)) + || (((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)) && (_mazeChangeAmount >= var_a) && (_mazeChangeAmount > 3) && (_action1._field24 != 0)) ) { + newMazeY = var_6; + if ((cellId != 25) && (cellId != 26) && (cellId != 5) && (cellId != 14) && (cellId == 15)) R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 11) && (var_6 + 3 >= di) && (_field127C >= var_6 + 3)) { + } else if ((cellId == 11) && (var_6 + 3 >= newMazeY) && (_mazePosition.y >= var_6 + 3)) { R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 != 0) && (var_8 <= 3)) { - var_field127A = var_4; + } else if (((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)) && (var_8 != 0) && (var_8 <= 3)) { + newMazeX = var_4; R2_GLOBALS._sound2.play(339); } else { // Nothing @@ -3892,65 +3893,65 @@ void Scene3500::dispatch() { } } break; - case 2: - tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if ( ((tmpVar == 12) || (tmpVar == 13) || (tmpVar == 11) || (tmpVar == 16) || (tmpVar == 31)) - || (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (var_a > 3)) ) { + case MAZEDIR_EAST: + cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if ( ((cellId == 12) || (cellId == 13) || (cellId == 11) || (cellId == 16) || (cellId == 31)) + || (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (var_a > 3)) ) { R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); } else { - var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70; - var_field127A = _field127A + _field126E; - dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15)) && (tmpVar != dx)) { - var_field127A = var_4; + var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70; + newMazeX = _mazePosition.x + _mazeChangeAmount; + dx = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if (((cellId == 26) || (cellId == 24) || (cellId == 15)) && (cellId != dx)) { + newMazeX = var_4; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 6) && (tmpVar != dx)) { - var_field127A = var_4 - 5; + } else if ((cellId == 6) && (cellId != dx)) { + newMazeX = var_4 - 5; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); } else { - var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70; - var_8 = abs(var_field127A - var_4); - tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, tmpVar + 46)); - if ( (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15)) && (var_field127A >= var_4) && (_field127A <= var_4)) - || (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (_field126E >= var_8) && (_field126E <= 3) && (_action1._field24 != 0)) ) { - var_field127A = var_4; - if ((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) + var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70; + var_8 = abs(newMazeX - var_4); + cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if ( (((cellId == 26) || (cellId == 24) || (cellId == 15)) && (newMazeX >= var_4) && (_mazePosition.x <= var_4)) + || (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (_mazeChangeAmount >= var_8) && (_mazeChangeAmount <= 3) && (_action1._field24 != 0)) ) { + newMazeX = var_4; + if ((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 6) && (var_4 - 5 <= var_field127A) && (_field127A <= var_4 - 5)) { - var_field127A = var_4 - 5; + } else if ((cellId == 6) && (var_4 - 5 <= newMazeX) && (_mazePosition.x <= var_4 - 5)) { + newMazeX = var_4 - 5; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (var_a != 0) && (var_a <= 3)) { - di = var_6; + } else if (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (var_a != 0) && (var_a <= 3)) { + newMazeY = var_6; R2_GLOBALS._sound2.play(339); } else { // Nothing @@ -3958,84 +3959,87 @@ void Scene3500::dispatch() { } } break; - case 4: - tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if ( ((tmpVar == 2) || (tmpVar == 3) || (tmpVar == 6) || (tmpVar == 1)) - || (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 > 3)) ) { + case MAZEDIR_SOUTH: + cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if ( ((cellId == 2) || (cellId == 3) || (cellId == 6) || (cellId == 1)) + || (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (var_8 > 3)) ) { R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); } else { - var_6 = _unkObj1.sub1097EF(di + 46) - 46; - di = _field127C + _field126E; - dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5)) && (tmpVar == dx)) { + var_6 = _mazeUI.cellFromY(newMazeY + 46) - 46; + newMazeY = _mazePosition.y + _mazeChangeAmount; + dx = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + + if (((cellId == 25) || (cellId == 26) || (cellId == 5)) && (cellId != dx)) { R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 16) && (tmpVar == dx)) { - di = var_6 - 3; + } else if ((cellId == 16) && (cellId != dx)) { + newMazeY = var_6 - 3; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 31) && (tmpVar == dx)) { - di = var_6 + 4; + } else if ((cellId == 31) && (cellId != dx)) { + newMazeY = var_6 + 4; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); } else { - var_6 = _unkObj1.sub1097EF(di + 46) - 46; - var_a = abs(di - var_6); - tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if ( (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5)) && (di >= var_6) && (_field127C <= var_6)) - || (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (_field126E >= var_a) && (_field126E <= 3) && (_action1._field24 != 0)) ){ - if ((tmpVar != 23) && (tmpVar != 24) && (tmpVar != 4) && (tmpVar != 14) && (tmpVar != 15)) + var_6 = _mazeUI.cellFromY(newMazeY + 46) - 46; + var_a = abs(newMazeY - var_6); + cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if ( (((cellId == 25) || (cellId == 26) || (cellId == 5)) && (newMazeY >= var_6) && (_mazePosition.y <= var_6)) + || (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (_mazeChangeAmount >= var_a) && (_mazeChangeAmount <= 3) && (_action1._field24 != 0)) ){ + newMazeY = var_6; + + if ((cellId != 23) && (cellId != 24) && (cellId != 4) && (cellId != 14) && (cellId != 15)) R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 16) && (var_6 - 3 <= di) && (_field127C <= var_6 - 3)) { - di = var_6 - 3; + } else if ((cellId == 16) && (var_6 - 3 <= newMazeY) && (_mazePosition.y <= var_6 - 3)) { + newMazeY = var_6 - 3; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 31) && (var_6 + 4 <= di) && (_field127C <= var_6 + 4)) { - di = var_6 + 4; + } else if ((cellId == 31) && (var_6 + 4 <= newMazeY) && (_mazePosition.y <= var_6 + 4)) { + newMazeY = var_6 + 4; _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - if ((var_field127A == 660) && (_field126E + 306 <= di) && (di <= 307)) + if ((newMazeX == 660) && (_mazeChangeAmount + 306 <= newMazeY) && (newMazeY <= 307)) ++_field1284; else R2_GLOBALS._sound2.play(339); - } else if (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 != 0) && (var_8 <= 3)) { - var_field127A = var_4; + } else if (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (var_8 != 0) && (var_8 <= 3)) { + newMazeX = var_4; R2_GLOBALS._sound2.play(339); } else { // Nothing @@ -4043,65 +4047,65 @@ void Scene3500::dispatch() { } } break; - case 6: - tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if ( ((tmpVar == 12) || (tmpVar == 13) || (tmpVar == 11) || (tmpVar == 16) || (tmpVar == 31)) - || (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (var_a > 3)) ) { + case MAZEDIR_WEST: + cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if ( ((cellId == 12) || (cellId == 13) || (cellId == 11) || (cellId == 16) || (cellId == 31)) + || (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (var_a > 3)) ) { R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); } else { - var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70; - var_field127A = _field127A - _field126E; - dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14)) && (tmpVar != dx)) { - var_field127A = var_4; + var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70; + newMazeX = _mazePosition.x - _mazeChangeAmount; + dx = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if (((cellId == 25) || (cellId == 23) || (cellId == 14)) && (cellId != dx)) { + newMazeX = var_4; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 1) && (tmpVar != dx)) { - var_field127A = var_4 + 5; + } else if ((cellId == 1) && (cellId != dx)) { + newMazeX = var_4 + 5; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); } else { - var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70; - var_8 = abs(var_4 - var_field127A); - tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46)); - if ( (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14)) && (var_field127A <= var_4) && (_field127A >= var_4)) - || (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (_field126E >= var_8) && (_field126E <= 3) && (_action1._field24 != 0)) ) { - var_field127A = var_4; - if ((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) + var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70; + var_8 = abs(var_4 - newMazeX); + cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46)); + if ( (((cellId == 25) || (cellId == 23) || (cellId == 14)) && (newMazeX <= var_4) && (_mazePosition.x >= var_4)) + || (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (_mazeChangeAmount >= var_8) && (_mazeChangeAmount <= 3) && (_action1._field24 != 0)) ) { + newMazeX = var_4; + if ((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if ((tmpVar == 1) && (var_field127A >= var_4 + 5) && (_field127A >= var_4 + 5)) { - var_field127A = var_4 + 5; + } else if ((cellId == 1) && (newMazeX >= var_4 + 5) && (_mazePosition.x >= var_4 + 5)) { + newMazeX = var_4 + 5; R2_GLOBALS._sound2.play(339); _rotation->_idxChange = 0; _field1270 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1272 = 0; if (_action1._field24 == 0) _actor8.hide(); - } else if (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (var_a != 0) && (var_a <= 3)) { - di = var_6; + } else if (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (var_a != 0) && (var_a <= 3)) { + newMazeY = var_6; R2_GLOBALS._sound2.play(339); } else { // Nothing @@ -4114,49 +4118,49 @@ void Scene3500::dispatch() { } if (_field1284 < 2) { - _field127A = var_field127A; - _field127C = di; - if (_unkObj1.sub109C5E(_field127A, _field127C) != 0) { + _mazePosition.x = newMazeX; + _mazePosition.y = newMazeY; + if (_mazeUI.setMazePosition2(_mazePosition) != 0) { _field1272 = 0; - _field126E = 0; + _mazeChangeAmount = 0; _field1270 = 0; _rotation->setDelay(0); _rotation->_idxChange = 0; } - warning("gfx_set_pane_p"); - _unkObj1.sub51B02(); + + _mazeUI.draw(); if (_field1284 != 0) ++_field1284; } } if (_field1272 == 0) { - if (_field126E != _field1270) { - if (_field126E >= _field1270) { - if (_field126E == 1) { + if (_mazeChangeAmount != _field1270) { + if (_mazeChangeAmount >= _field1270) { + if (_mazeChangeAmount == 1) { if (_action1._field24 != 0) { - if ( ((_field1276 == 1) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15))) - || ((_field1276 == 3) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4))) - || ((_field1276 == 5) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15))) - || ((_field1276 == 7) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4))) ){ - _field126E = 1; + if ( ((_mazeDirection == 1) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15))) + || ((_mazeDirection == 3) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4))) + || ((_mazeDirection == 5) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15))) + || ((_mazeDirection == 7) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4))) ){ + _mazeChangeAmount = 1; } else - _field126E--; + _mazeChangeAmount--; } else - _field126E--; + _mazeChangeAmount--; } else - _field126E--; + _mazeChangeAmount--; } else - ++_field126E; + ++_mazeChangeAmount; _field1272 = 1; } - _actor2.setFrame2(_field126E); + _actor2.setFrame2(_mazeChangeAmount + 1); } if (_field1272 == 1) { - if (_field126E == 0) + if (_mazeChangeAmount == 0) _rotation->_idxChange = 0; - else if (_field126E > 8) + else if (_mazeChangeAmount > 8) _rotation->_idxChange = 2; else _rotation->_idxChange = 1; @@ -4165,9 +4169,9 @@ void Scene3500::dispatch() { if (_field1272 != 0) _field1272--; - if (_field126E != 0) { - R2_GLOBALS._player._uiEnabled = false; - if (_field126E != _field1270) + if (_mazeChangeAmount != 0) { + R2_GLOBALS._player._uiEnabled = false; + if (_mazeChangeAmount != _field1270) _aSound1.play(276); } else { R2_GLOBALS._player._uiEnabled = true; diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.h b/engines/tsage/ringworld2/ringworld2_scenes3.h index 44787b9eef..85e5674433 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes3.h +++ b/engines/tsage/ringworld2/ringworld2_scenes3.h @@ -633,12 +633,12 @@ class Scene3500 : public SceneExt { // TODO: double check if nothing specific is present, then remove this class }; - class UnkObject3500 : public UnkObject1200 { + class MazeUI3500 : public MazeUI { public: - int sub1097C9(int arg1); - int sub1097EF(int arg1); - int sub109C09(Common::Point pt); - int sub109C5E(int &x, int &y); + int cellFromX(int arg1); + int cellFromY(int arg1); + int getCellFromMapXY(Common::Point pt); + bool setMazePosition2(Common::Point &p); }; public: Action1 _action1; @@ -650,6 +650,7 @@ public: Item4 _item5; Item4 _item6; Item4 _item7; + // Glyph of vessel on top of the maze ui SceneActor _actor1; SceneActor _actor2; SceneActor _actor3; @@ -660,20 +661,19 @@ public: Actor8 _actor8; Actor8 _actor9; ASoundExt _aSound1; - UnkObject3500 _unkObj1; + MazeUI3500 _mazeUI; SequenceManager _sequenceManager; int _fieldAF8; int _fieldB9E; PaletteRotation *_rotation; - int _field126E; + int _mazeChangeAmount; int _field1270; int _field1272; int _field1274; - int _field1276; + int _mazeDirection; int _field1278; - int _field127A; - int _field127C; + Common::Point _mazePosition; int _field127E; int _field1280; int _field1282; diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp index da1449efdf..bff61bafc4 100644 --- a/engines/tsage/ringworld2/ringworld2_speakers.cpp +++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp @@ -40,7 +40,7 @@ VisualSpeaker::VisualSpeaker(): Speaker() { _color1 = 8; _color2 = 0; _displayMode = 0; - _fieldF6 = 0; + _speakerMode = 0; } void VisualSpeaker::remove() { @@ -49,27 +49,104 @@ void VisualSpeaker::remove() { _fieldF8 = 0; _object1.setStrip(_object1._strip - 1); _object1.setFrame(_object1.getFrameCount()); - _object1.animate(ANIM_MODE_6, (_fieldF6 == 0xff) ? this : NULL); + _object1.animate(ANIM_MODE_6, (_speakerMode == 0xff) ? this : NULL); } else { - _object1.animate(ANIM_MODE_6, (_fieldF6 == 0xff) ? this : NULL); + _object1.animate(ANIM_MODE_6, (_speakerMode == 0xff) ? this : NULL); } } Speaker::remove(); } +void VisualSpeaker::signal() { + // TODO: _action->_field18 = 1; + if (_speakerMode == 0xff) + proc16(); + + _speakerMode = 0; + if (_numFrames) { + if (_object2) { + _object1.setStrip(_object1._strip + 1); + _object1.animate(ANIM_MODE_2, NULL); + _fieldF8 = 1; + } + + if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || _soundId) + _sceneText.show(); + + if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && _soundId) { + // TODO: Check global that is passed + setFrame2(/* word_55F90 */ 0); + } + } else if (_action && _object2) { + _action->setDelay(1); + _sceneText.remove(); + + R2_GLOBALS._playStream.stop(); + } +} + +void VisualSpeaker::dispatch() { + uint32 frameNumber = R2_GLOBALS._events.getFrameNumber(); + + // Delay check for character animation + if (_delayAmount) { + if (frameNumber >= _frameNumber) { + _delayAmount = _delayAmount - (_frameNumber - frameNumber); + _frameNumber = frameNumber; + + if (_delayAmount <= 0) { + _delayAmount = 0; + _object1.animate(ANIM_MODE_NONE, NULL); + _object1.setFrame(1); + } + } + } + + // Delay check for voice + if (_delayAmount2) { + if (frameNumber >= _frameNumber2) { + _delayAmount2 = _delayAmount2 - (_frameNumber2 - frameNumber); + _frameNumber2 = frameNumber; + + if (_delayAmount2 <= 0) { + _delayAmount2 = 0; + if (R2_GLOBALS._playStream.play(0, NULL)) { + _numFrames = 2; + _soundId = 0; + } else { + _sceneText.show(); + } + } + } + } + + if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && (_numFrames == 2) && + !R2_GLOBALS._playStream.isPlaying()) { + _numFrames = 0; + _object1.animate(ANIM_MODE_NONE); + _object1.setFrame(1); + + if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) { + _action->setDelay(1); + } + } +} + void VisualSpeaker::synchronize(Serializer &s) { Speaker::synchronize(s); SYNC_POINTER(_object2); - s.syncAsSint16LE(_fieldF6); + s.syncAsSint16LE(_speakerMode); s.syncAsSint16LE(_fieldF8); s.syncAsSint16LE(_displayMode); s.syncAsSint16LE(_soundId); - s.syncAsSint16LE(_delayAmount); s.syncAsByte(_removeObject); - s.syncAsSint32LE(_frameNumber); s.syncAsSint16LE(_numFrames); + s.syncAsSint16LE(_delayAmount); + s.syncAsUint32LE(_frameNumber); + s.syncAsSint16LE(_delayAmount2); + s.syncAsUint32LE(_frameNumber2); } void VisualSpeaker::setText(const Common::String &msg) { @@ -159,8 +236,7 @@ void VisualSpeaker::setText(const Common::String &msg) { if (s.empty()) _numFrames = 0; - - if (_fieldF6) { + if (_speakerMode) { if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || !_soundId) _sceneText.hide(); } else { @@ -173,7 +249,7 @@ void VisualSpeaker::setText(const Common::String &msg) { void VisualSpeaker::proc16() { R2_GLOBALS._playStream.stop(); - _fieldF6 = 0; + _speakerMode = 0; _object1.remove(); assert(_object2); @@ -187,6 +263,11 @@ void VisualSpeaker::setFrame(int numFrames) { _frameNumber = R2_GLOBALS._events.getFrameNumber(); } +void VisualSpeaker::setFrame2(int numFrames) { + _delayAmount2 = numFrames; + _frameNumber2 = R2_GLOBALS._events.getFrameNumber(); +} + void VisualSpeaker::setDelay(int delay) { _delayAmount = delay; _frameNumber = R2_GLOBALS._events.getFrameNumber(); @@ -211,7 +292,7 @@ SpeakerCaptain3210::SpeakerCaptain3210() { _speakerName = "Captain"; _color1 = 5; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -220,7 +301,7 @@ SpeakerCaptain3210::SpeakerCaptain3210() { } void SpeakerCaptain3210::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -250,7 +331,7 @@ SpeakerCaretaker2450::SpeakerCaretaker2450() { _speakerName = "CARETAKER"; _color1 = 43; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -266,7 +347,7 @@ SpeakerChief1100::SpeakerChief1100() { _speakerName = "CHIEF"; _color1 = 8; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -275,7 +356,7 @@ SpeakerChief1100::SpeakerChief1100() { } void SpeakerChief1100::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -324,7 +405,7 @@ SpeakerGuard::SpeakerGuard() { _speakerName = "GUARD"; _color1 = 5; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -333,7 +414,7 @@ SpeakerGuard::SpeakerGuard() { } void SpeakerGuard2800::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -364,7 +445,7 @@ SpeakerJocko::SpeakerJocko() { _speakerName = "Jocko"; _color1 = 45; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -373,7 +454,7 @@ SpeakerJocko::SpeakerJocko() { } void SpeakerJocko3200::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -396,7 +477,7 @@ void SpeakerJocko3200::proc15() { } void SpeakerJocko3220::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -419,7 +500,7 @@ void SpeakerJocko3220::proc15() { } void SpeakerJocko3230::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -449,7 +530,7 @@ SpeakerMiranda::SpeakerMiranda(): VisualSpeaker() { _speakerName = "MIRANDA"; _color1 = 154; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -458,7 +539,7 @@ SpeakerMiranda::SpeakerMiranda(): VisualSpeaker() { } void SpeakerMiranda300::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 3) { @@ -498,7 +579,7 @@ void SpeakerMiranda300::proc15() { } void SpeakerMiranda1625::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene; @@ -521,7 +602,7 @@ void SpeakerMiranda1625::proc15() { } void SpeakerMiranda3255::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &R2_GLOBALS._player; @@ -544,7 +625,7 @@ void SpeakerMiranda3255::proc15() { void SpeakerMiranda3375::proc15() { Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 3) @@ -594,7 +675,7 @@ void SpeakerMiranda3375::proc15() { void SpeakerMiranda3385::proc15() { Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 3) @@ -643,7 +724,7 @@ void SpeakerMiranda3385::proc15() { void SpeakerMiranda3395::proc15() { Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 3) @@ -693,7 +774,7 @@ void SpeakerMiranda3395::proc15() { void SpeakerMiranda3400::proc15() { Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 3) @@ -737,7 +818,7 @@ void SpeakerMiranda3400::proc15() { void SpeakerMiranda3600::proc15() { Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 3) @@ -783,7 +864,7 @@ void SpeakerMiranda3600::proc15() { void SpeakerMiranda3700::proc15() { Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor3; @@ -840,7 +921,7 @@ SpeakerNej::SpeakerNej() { _speakerName = "NEJ"; _color1 = 171; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -849,7 +930,7 @@ SpeakerNej::SpeakerNej() { } void SpeakerNej2700::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -884,7 +965,7 @@ void SpeakerNej2700::proc15() { } void SpeakerNej2750::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -916,7 +997,7 @@ void SpeakerNej2750::proc15() { } void SpeakerNej2800::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -948,7 +1029,7 @@ SpeakerPharisha::SpeakerPharisha(): VisualSpeaker() { _speakerName = "PHARISHA"; _color1 = 151; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -957,7 +1038,7 @@ SpeakerPharisha::SpeakerPharisha(): VisualSpeaker() { } void SpeakerPharisha2435::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -984,7 +1065,7 @@ SpeakerPrivate3210::SpeakerPrivate3210() { _speakerName = "Private"; _color1 = 45; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -993,7 +1074,7 @@ SpeakerPrivate3210::SpeakerPrivate3210() { } void SpeakerPrivate3210::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -1023,7 +1104,7 @@ SpeakerProtector3600::SpeakerProtector3600() { _speakerName = "Protector"; _color1 = 170; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -1032,7 +1113,7 @@ SpeakerProtector3600::SpeakerProtector3600() { } void SpeakerProtector3600::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -1084,7 +1165,7 @@ SpeakerQuinn::SpeakerQuinn(): VisualSpeaker() { _speakerName = "QUINN"; _color1 = 60; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -1093,7 +1174,7 @@ SpeakerQuinn::SpeakerQuinn(): VisualSpeaker() { } void SpeakerQuinn300::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 3) { @@ -1140,7 +1221,7 @@ void SpeakerQuinn300::proc15() { } void SpeakerQuinn1100::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (v == 0) @@ -1188,7 +1269,7 @@ void SpeakerQuinn1100::proc15() { } void SpeakerQuinn2435::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 1) { @@ -1214,7 +1295,7 @@ void SpeakerQuinn2435::proc15() { } void SpeakerQuinn2450::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 1) { @@ -1242,7 +1323,7 @@ void SpeakerQuinn2450::proc15() { } void SpeakerQuinn2700::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &R2_GLOBALS._player; @@ -1273,7 +1354,7 @@ void SpeakerQuinn2700::proc15() { } void SpeakerQuinn2750::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &R2_GLOBALS._player; @@ -1304,7 +1385,7 @@ void SpeakerQuinn2750::proc15() { } void SpeakerQuinn2800::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &R2_GLOBALS._player; @@ -1345,7 +1426,7 @@ void SpeakerQuinn2800::proc15() { void SpeakerQuinn3255::proc15() { Scene3255 *scene = (Scene3255 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor4; @@ -1368,7 +1449,7 @@ void SpeakerQuinn3255::proc15() { void SpeakerQuinn3375::proc15() { Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 1) @@ -1419,7 +1500,7 @@ void SpeakerQuinn3375::proc15() { void SpeakerQuinn3385::proc15() { Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 1) @@ -1474,7 +1555,7 @@ void SpeakerQuinn3385::proc15() { void SpeakerQuinn3395::proc15() { Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 1) @@ -1529,7 +1610,7 @@ void SpeakerQuinn3395::proc15() { void SpeakerQuinn3400::proc15() { Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 1) @@ -1578,7 +1659,7 @@ void SpeakerQuinn3400::proc15() { void SpeakerQuinn3600::proc15() { Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 1) @@ -1626,7 +1707,7 @@ void SpeakerQuinn3600::proc15() { void SpeakerQuinn3700::setText(const Common::String &msg) { Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene; - switch (_fieldF6) { + switch (_speakerMode) { case 2: scene->_actor3.setup(30, 1, 1); R2_GLOBALS._sound2.play(44); @@ -1644,7 +1725,7 @@ void SpeakerQuinn3700::setText(const Common::String &msg) { void SpeakerQuinn3700::proc15() { Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor1; @@ -1701,7 +1782,7 @@ SpeakerQuinnL::SpeakerQuinnL(): VisualSpeaker() { _speakerName = "QUINNL"; _color1 = 35; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -1718,7 +1799,7 @@ SpeakerRalf3245::SpeakerRalf3245() { _speakerName = "Ralf"; _color1 = 5; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -1727,7 +1808,7 @@ SpeakerRalf3245::SpeakerRalf3245() { } void SpeakerRalf3245::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -1770,7 +1851,7 @@ SpeakerRocko::SpeakerRocko() { _speakerName = "Rocko"; _color1 = 5; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -1779,7 +1860,7 @@ SpeakerRocko::SpeakerRocko() { } void SpeakerRocko3200::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -1802,7 +1883,7 @@ void SpeakerRocko3200::proc15() { } void SpeakerRocko3220::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -1825,7 +1906,7 @@ void SpeakerRocko3220::proc15() { } void SpeakerRocko3230::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -1855,7 +1936,7 @@ SpeakerSeeker::SpeakerSeeker(): VisualSpeaker() { _speakerName = "SEEKER"; _color1 = 35; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -1864,7 +1945,7 @@ SpeakerSeeker::SpeakerSeeker(): VisualSpeaker() { } void SpeakerSeeker300::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 3) { @@ -1900,7 +1981,7 @@ void SpeakerSeeker300::proc15() { } void SpeakerSeeker1100::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (v == 0) @@ -1959,7 +2040,7 @@ void SpeakerSeeker1100::proc15() { } void SpeakerSeeker1900::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 2) { @@ -1989,7 +2070,7 @@ void SpeakerSeeker1900::proc15() { } void SpeakerSeeker2435::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 2) { @@ -2015,7 +2096,7 @@ void SpeakerSeeker2435::proc15() { } void SpeakerSeeker2450::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 2) { @@ -2042,7 +2123,7 @@ void SpeakerSeeker2450::proc15() { void SpeakerSeeker3375::proc15() { Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 2) @@ -2091,7 +2172,7 @@ void SpeakerSeeker3375::proc15() { void SpeakerSeeker3385::proc15() { Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 2) @@ -2140,7 +2221,7 @@ void SpeakerSeeker3385::proc15() { void SpeakerSeeker3395::proc15() { Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 2) @@ -2189,7 +2270,7 @@ void SpeakerSeeker3395::proc15() { void SpeakerSeeker3400::proc15() { Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 2) @@ -2248,7 +2329,7 @@ void SpeakerSeeker3400::proc15() { void SpeakerSeeker3600::proc15() { Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { if (R2_GLOBALS._player._characterIndex == 2) @@ -2295,7 +2376,7 @@ void SpeakerSeeker3600::proc15() { void SpeakerSeeker3700::setText(const Common::String &msg) { Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene; - if (_fieldF6 == 1) { + if (_speakerMode == 1) { R2_GLOBALS._sound2.play(44); scene->_actor3.setup(30, 8, 1); } else { @@ -2307,7 +2388,7 @@ void SpeakerSeeker3700::setText(const Common::String &msg) { void SpeakerSeeker3700::proc15() { Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor2; @@ -2359,7 +2440,7 @@ SpeakerSeekerL::SpeakerSeekerL(): VisualSpeaker() { _speakerName = "SEEKERL"; _color1 = 35; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -2376,7 +2457,7 @@ SpeakerSocko3200::SpeakerSocko3200() { _speakerName = "Socko"; _color1 = 10; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -2385,7 +2466,7 @@ SpeakerSocko3200::SpeakerSocko3200() { } void SpeakerSocko3200::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -2415,7 +2496,7 @@ SpeakerSoldier::SpeakerSoldier(int colour) { _speakerName = "SOLDIER"; _color1 = colour; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -2424,7 +2505,7 @@ SpeakerSoldier::SpeakerSoldier(int colour) { } void SpeakerSoldier300::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; @@ -2455,7 +2536,7 @@ SpeakerTeal::SpeakerTeal(): VisualSpeaker() { _speakerName = "TEAL"; _color1 = 22; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -2468,7 +2549,7 @@ SpeakerTealMode7::SpeakerTealMode7(): SpeakerTeal() { } void SpeakerTeal300::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; @@ -2492,7 +2573,7 @@ void SpeakerTeal300::proc15() { } void SpeakerTeal1625::proc15() { - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene; @@ -2516,7 +2597,7 @@ void SpeakerTeal1625::proc15() { } void SpeakerTeal3240::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -2541,7 +2622,7 @@ void SpeakerTeal3240::proc15() { void SpeakerTeal3400::proc15() { Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor4; @@ -2598,7 +2679,7 @@ void SpeakerTeal3400::proc15() { void SpeakerTeal3600::proc15() { Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor5; @@ -2659,7 +2740,7 @@ SpeakerTomko3245::SpeakerTomko3245() { _speakerName = "Tomko"; _color1 = 10; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -2668,7 +2749,7 @@ SpeakerTomko3245::SpeakerTomko3245() { } void SpeakerTomko3245::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -2711,7 +2792,7 @@ SpeakerWebbster::SpeakerWebbster(int colour) { _speakerName = "WEBBSTER"; _color1 = colour; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -2720,7 +2801,7 @@ SpeakerWebbster::SpeakerWebbster(int colour) { } void SpeakerWebbster3240::proc15() { - int v = _fieldF6; + int v = _speakerMode; Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene; if (!_object2) { @@ -2745,7 +2826,7 @@ void SpeakerWebbster3240::proc15() { void SpeakerWebbster3375::proc15() { Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor3; @@ -2789,7 +2870,7 @@ void SpeakerWebbster3375::proc15() { void SpeakerWebbster3385::proc15() { Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor3; @@ -2833,7 +2914,7 @@ void SpeakerWebbster3385::proc15() { void SpeakerWebbster3395::proc15() { Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor3; @@ -2877,7 +2958,7 @@ void SpeakerWebbster3395::proc15() { void SpeakerWebbster3400::proc15() { Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_actor3; @@ -2925,7 +3006,7 @@ SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() { _speakerName = "DUTYOFFICER"; _color1 = 5; _color2 = 0; - _fieldF6 = 0; + _speakerMode = 0; _textWidth = 300; _hideObjects = false; _object2 = NULL; @@ -2936,7 +3017,7 @@ SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() { void SpeakerDutyOfficer::proc15() { Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene; - int v = _fieldF6; + int v = _speakerMode; if (!_object2) { _object2 = &scene->_object2; diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h index fa2946d56c..532e02576c 100644 --- a/engines/tsage/ringworld2/ringworld2_speakers.h +++ b/engines/tsage/ringworld2/ringworld2_speakers.h @@ -41,21 +41,27 @@ class VisualSpeaker : public Speaker { public: SceneActor _object1; SceneObject *_object2; - int _fieldF6, _fieldF8; + int _speakerMode; + int _fieldF8; int _displayMode; int _soundId; int _delayAmount; bool _removeObject; - int _frameNumber; + uint32 _frameNumber; int _numFrames; + int _delayAmount2; + uint32 _frameNumber2; private: void setFrame(int numFrames); + void setFrame2(int numFrames); public: VisualSpeaker(); virtual Common::String getClassName() { return "VisualSpeaker"; } virtual void synchronize(Serializer &s); virtual void remove(); + virtual void signal(); + virtual void dispatch(); virtual void setText(const Common::String &msg); virtual void proc15() {} virtual void proc16(); diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h index 4126e31822..d43ef792bc 100644 --- a/engines/tsage/saveload.h +++ b/engines/tsage/saveload.h @@ -150,6 +150,16 @@ public: if (i != this->end()) ++i; this->insert(i, newItem); } + + bool contains(T item) { + typename SynchronizedList<T>::iterator i = this->begin(); + for (; i != this->end(); ++i) { + if (*i == item) + return true; + } + + return false; + } }; /** diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp index 4bd9e49875..c0ebb804d2 100644 --- a/engines/tsage/user_interface.cpp +++ b/engines/tsage/user_interface.cpp @@ -84,7 +84,10 @@ void UIQuestion::showDescription(CursorType cursor) { case GType_Ringworld2: if ((cursor == R2_COM_SCANNER) || (cursor == R2_COM_SCANNER_2)) { // Show communicator - warning("TODO: Communicator"); + Ringworld2::SceneExt *scene = static_cast<Ringworld2::SceneExt *> + (R2_GLOBALS._sceneManager._scene); + if (!scene->_sceneAreas.contains(R2_GLOBALS._scannerDialog)) + R2_GLOBALS._scannerDialog->proc12(4, 1, 1, 160, 125); } else { // Show object description SceneItem::display2(3, (int)cursor); @@ -399,7 +402,7 @@ void UIElements::setup(const Common::Point &pt) { } // Setup bottom-right hand buttons - xp += 62; + xp = (g_vm->getGameID() == GType_Ringworld2) ? 255 : 253; int yp = (g_vm->getGameID() == GType_BlueForce) ? 16 : 17; _question.setup(1, 4, 7, xp, yp, 255); _question.setEnabled(false); @@ -410,7 +413,7 @@ void UIElements::setup(const Common::Point &pt) { add(&_scrollLeft); _scrollLeft._isLeft = true; - xp += 22; + xp += (g_vm->getGameID() == GType_Ringworld2) ? 21 : 22; _scrollRight.setup(1, 4, 4, xp, yp, 255); add(&_scrollRight); _scrollRight._isLeft = false; diff --git a/engines/tucker/tucker.cpp b/engines/tucker/tucker.cpp index 2bd7c47b62..04e83efbe5 100644 --- a/engines/tucker/tucker.cpp +++ b/engines/tucker/tucker.cpp @@ -941,7 +941,7 @@ void TuckerEngine::fadeOutPalette(int colorsCount) { _system->getPaletteManager()->grabPalette(pal, 0, colorsCount); for (int color = 0; color < colorsCount; ++color) { for (int i = 0; i < 3; ++i) { - const int c = int(pal[color * 3 + i]) + kFadePaletteStep * 3; + const int c = int(pal[color * 3 + i]) + kFadePaletteStep * 4; pal[color * 3 + i] = MIN<int>(c, _currentPalette[color * 3 + i]); } } @@ -954,7 +954,7 @@ void TuckerEngine::fadeInPalette(int colorsCount) { _system->getPaletteManager()->grabPalette(pal, 0, colorsCount); for (int color = 0; color < colorsCount; ++color) { for (int i = 0; i < 3; ++i) { - const int c = int(pal[color * 3 + i]) - kFadePaletteStep * 3; + const int c = int(pal[color * 3 + i]) - kFadePaletteStep * 4; pal[color * 3 + i] = MAX<int>(c, 0); } } @@ -2991,6 +2991,7 @@ enum TableInstructionCode { kCode_gfg, kCode_gv, kCode_loc, + kCode_mof, kCode_opt, kCode_opf, kCode_ofg, @@ -3041,6 +3042,7 @@ static const struct { { "gfg", kCode_gfg }, { "gv", kCode_gv }, { "loc", kCode_loc }, + { "mof", kCode_mof }, { "opt", kCode_opt }, { "opf", kCode_opf }, { "ofg", kCode_ofg }, @@ -3062,8 +3064,9 @@ static const struct { int TuckerEngine::readTableInstructionCode(int *index) { bool match = false; + int nameLen = 0; for (int i = 0; _instructions[i].name; ++i) { - const int nameLen = strlen(_instructions[i].name); + nameLen = strlen(_instructions[i].name); if (_instructions[i].name[1] == '0') { if (_instructions[i].name[0] == _tableInstructionsPtr[0] && _instructions[i].name[2] == _tableInstructionsPtr[2]) { const char digit = _tableInstructionsPtr[1]; @@ -3083,6 +3086,7 @@ int TuckerEngine::readTableInstructionCode(int *index) { } } warning("Unhandled instruction '%c%c%c'", _tableInstructionsPtr[0], _tableInstructionsPtr[1], _tableInstructionsPtr[2]); + _tableInstructionsPtr += nameLen + 1; return kCode_invalid; } @@ -3232,6 +3236,9 @@ int TuckerEngine::executeTableInstruction() { case kCode_loc: _nextLocationNum = readTableInstructionParam(2); return 1; + case kCode_mof: + // TODO: Unknown opcode in Spanish version. Identify if this has any function. + return 0; case kCode_opt: _conversationOptionsCount = readTableInstructionParam(2); for (i = 0; i < _conversationOptionsCount; ++i) { diff --git a/engines/wintermute/ad/ad_response.cpp b/engines/wintermute/ad/ad_response.cpp index 4483bbc667..d59bcf363c 100644 --- a/engines/wintermute/ad/ad_response.cpp +++ b/engines/wintermute/ad/ad_response.cpp @@ -166,7 +166,7 @@ BaseFont *AdResponse::getFont() const { int32 AdResponse::getID() const { return _iD; } - + const char *AdResponse::getText() const { return _text; } diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp index 4d8e79b5c2..0594699edc 100644 --- a/engines/wintermute/base/base_game.cpp +++ b/engines/wintermute/base/base_game.cpp @@ -212,7 +212,7 @@ BaseGame::BaseGame(const Common::String &gameId) : BaseObject(this), _gameId(gam #else*/ _touchInterface = false; _constrainedMemory = false; - + _settings = new BaseGameSettings(this); //#endif @@ -3734,7 +3734,7 @@ bool BaseGame::onWindowClose() { bool BaseGame::displayDebugInfo() { const uint32 strLength = 100; char str[strLength]; - + if (_debugShowFPS) { sprintf(str, "FPS: %d", _gameRef->_fps); _systemFont->drawText((byte *)str, 0, 0, 100, TAL_LEFT); diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h index d51255d013..b821805ada 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -137,7 +137,7 @@ public: bool initialize2(); bool initialize3(); BaseTransitionMgr *_transMgr; - + // String Table void expandStringByStringTable(char **str) const; char *getKeyFromStringTable(const char *str) const; @@ -275,7 +275,7 @@ private: bool _mouseRightDown; bool _mouseMidlleDown; - + BaseGameSettings *_settings; int32 _soundBufferSizeSec; diff --git a/engines/wintermute/base/base_game_music.cpp b/engines/wintermute/base/base_game_music.cpp index ac23801e4c..eff5d47210 100644 --- a/engines/wintermute/base/base_game_music.cpp +++ b/engines/wintermute/base/base_game_music.cpp @@ -8,12 +8,12 @@ * 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. @@ -65,10 +65,10 @@ bool BaseGameMusic::playMusic(int channel, const char *filename, bool looping, u BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS); return STATUS_FAILED; } - + delete _music[channel]; _music[channel] = nullptr; - + _music[channel] = new BaseSound(_gameRef); if (_music[channel] && DID_SUCCEED(_music[channel]->setSound(filename, Audio::Mixer::kMusicSoundType, true))) { if (_musicStartTime[channel]) { @@ -93,7 +93,7 @@ bool BaseGameMusic::stopMusic(int channel) { BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS); return STATUS_FAILED; } - + if (_music[channel]) { _music[channel]->stop(); delete _music[channel]; @@ -111,7 +111,7 @@ bool BaseGameMusic::pauseMusic(int channel) { BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS); return STATUS_FAILED; } - + if (_music[channel]) { return _music[channel]->pause(); } else { @@ -126,7 +126,7 @@ bool BaseGameMusic::resumeMusic(int channel) { BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS); return STATUS_FAILED; } - + if (_music[channel]) { return _music[channel]->resume(); } else { @@ -141,7 +141,7 @@ bool BaseGameMusic::setMusicStartTime(int channel, uint32 time) { BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS); return STATUS_FAILED; } - + _musicStartTime[channel] = time; if (_music[channel] && _music[channel]->isPlaying()) { return _music[channel]->setPositionTime(time); @@ -153,14 +153,14 @@ bool BaseGameMusic::setMusicStartTime(int channel, uint32 time) { ////////////////////////////////////////////////////////////////////////// bool BaseGameMusic::updateMusicCrossfade() { /* byte globMusicVol = _soundMgr->getVolumePercent(SOUND_MUSIC); */ - + if (!_musicCrossfadeRunning) { return STATUS_OK; } if (_gameRef->_state == GAME_FROZEN) { return STATUS_OK; } - + if (_musicCrossfadeChannel1 < 0 || _musicCrossfadeChannel1 >= NUM_MUSIC_CHANNELS || !_music[_musicCrossfadeChannel1]) { _musicCrossfadeRunning = false; return STATUS_OK; @@ -169,34 +169,34 @@ bool BaseGameMusic::updateMusicCrossfade() { _musicCrossfadeRunning = false; return STATUS_OK; } - + if (!_music[_musicCrossfadeChannel1]->isPlaying()) { _music[_musicCrossfadeChannel1]->play(); } if (!_music[_musicCrossfadeChannel2]->isPlaying()) { _music[_musicCrossfadeChannel2]->play(); } - + uint32 currentTime = _gameRef->getLiveTimer()->getTime() - _musicCrossfadeStartTime; - + if (currentTime >= _musicCrossfadeLength) { _musicCrossfadeRunning = false; //_music[_musicCrossfadeChannel2]->setVolume(GlobMusicVol); _music[_musicCrossfadeChannel2]->setVolumePercent(100); - + _music[_musicCrossfadeChannel1]->stop(); //_music[_musicCrossfadeChannel1]->setVolume(GlobMusicVol); _music[_musicCrossfadeChannel1]->setVolumePercent(100); - - + + if (_musicCrossfadeSwap) { // swap channels BaseSound *dummy = _music[_musicCrossfadeChannel1]; int dummyInt = _musicStartTime[_musicCrossfadeChannel1]; - + _music[_musicCrossfadeChannel1] = _music[_musicCrossfadeChannel2]; _musicStartTime[_musicCrossfadeChannel1] = _musicStartTime[_musicCrossfadeChannel2]; - + _music[_musicCrossfadeChannel2] = dummy; _musicStartTime[_musicCrossfadeChannel2] = dummyInt; } @@ -205,10 +205,10 @@ bool BaseGameMusic::updateMusicCrossfade() { //_music[_musicCrossfadeChannel2]->setVolume((float)CurrentTime / (float)_musicCrossfadeLength * GlobMusicVol); _music[_musicCrossfadeChannel1]->setVolumePercent((int)(100.0f - (float)currentTime / (float)_musicCrossfadeLength * 100.0f)); _music[_musicCrossfadeChannel2]->setVolumePercent((int)((float)currentTime / (float)_musicCrossfadeLength * 100.0f)); - + //_gameRef->QuickMessageForm("%d %d", _music[_musicCrossfadeChannel1]->GetVolume(), _music[_musicCrossfadeChannel2]->GetVolume()); } - + return STATUS_OK; } @@ -242,15 +242,15 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this stack->correctParams(4); channel = stack->pop()->getInt(); } - + const char *filename = stack->pop()->getString(); ScValue *valLooping = stack->pop(); bool looping = valLooping->isNULL() ? true : valLooping->getBool(); - + ScValue *valLoopStart = stack->pop(); uint32 loopStart = (uint32)(valLoopStart->isNULL() ? 0 : valLoopStart->getInt()); - - + + if (DID_FAIL(playMusic(channel, filename, looping, loopStart))) { stack->pushBool(false); } else { @@ -258,20 +258,20 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this } return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // StopMusic / StopMusicChannel ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "StopMusic") == 0 || strcmp(name, "StopMusicChannel") == 0) { int channel = 0; - + if (strcmp(name, "StopMusic") == 0) { stack->correctParams(0); } else { stack->correctParams(1); channel = stack->pop()->getInt(); } - + if (DID_FAIL(stopMusic(channel))) { stack->pushBool(false); } else { @@ -279,20 +279,20 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this } return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // PauseMusic / PauseMusicChannel ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PauseMusic") == 0 || strcmp(name, "PauseMusicChannel") == 0) { int channel = 0; - + if (strcmp(name, "PauseMusic") == 0) { stack->correctParams(0); } else { stack->correctParams(1); channel = stack->pop()->getInt(); } - + if (DID_FAIL(pauseMusic(channel))) { stack->pushBool(false); } else { @@ -300,7 +300,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this } return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // ResumeMusic / ResumeMusicChannel ////////////////////////////////////////////////////////////////////////// @@ -312,7 +312,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this stack->correctParams(1); channel = stack->pop()->getInt(); } - + if (DID_FAIL(resumeMusic(channel))) { stack->pushBool(false); } else { @@ -320,7 +320,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this } return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // GetMusic / GetMusicChannel ////////////////////////////////////////////////////////////////////////// @@ -343,7 +343,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this } return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // SetMusicPosition / SetMusicChannelPosition ////////////////////////////////////////////////////////////////////////// @@ -355,18 +355,18 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this stack->correctParams(2); channel = stack->pop()->getInt(); } - + uint32 time = stack->pop()->getInt(); - + if (DID_FAIL(setMusicStartTime(channel, time))) { stack->pushBool(false); } else { stack->pushBool(true); } - + return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // GetMusicPosition / GetMusicChannelPosition ////////////////////////////////////////////////////////////////////////// @@ -378,7 +378,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this stack->correctParams(1); channel = stack->pop()->getInt(); } - + if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) { stack->pushInt(0); } else { @@ -386,7 +386,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this } return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // IsMusicPlaying / IsMusicChannelPlaying ////////////////////////////////////////////////////////////////////////// @@ -398,7 +398,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this stack->correctParams(1); channel = stack->pop()->getInt(); } - + if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) { stack->pushBool(false); } else { @@ -406,7 +406,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this } return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // SetMusicVolume / SetMusicChannelVolume ////////////////////////////////////////////////////////////////////////// @@ -418,7 +418,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this stack->correctParams(2); channel = stack->pop()->getInt(); } - + int volume = stack->pop()->getInt(); if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) { stack->pushBool(false); @@ -431,7 +431,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this } return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // GetMusicVolume / GetMusicChannelVolume ////////////////////////////////////////////////////////////////////////// @@ -443,16 +443,16 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this stack->correctParams(1); channel = stack->pop()->getInt(); } - + if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) { stack->pushInt(0); } else { stack->pushInt(_music[channel]->getVolumePercent()); } - + return STATUS_OK; } - + ////////////////////////////////////////////////////////////////////////// // MusicCrossfade ////////////////////////////////////////////////////////////////////////// @@ -462,34 +462,34 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this int channel2 = stack->pop()->getInt(0); uint32 fadeLength = (uint32)stack->pop()->getInt(0); bool swap = stack->pop()->getBool(true); - + if (_musicCrossfadeRunning) { script->runtimeError("Game.MusicCrossfade: Music crossfade is already in progress."); stack->pushBool(false); return STATUS_OK; } - + _musicCrossfadeStartTime = _gameRef->getLiveTimer()->getTime(); _musicCrossfadeChannel1 = channel1; _musicCrossfadeChannel2 = channel2; _musicCrossfadeLength = fadeLength; _musicCrossfadeSwap = swap; - + _musicCrossfadeRunning = true; - + stack->pushBool(true); return STATUS_OK; - } + } ////////////////////////////////////////////////////////////////////////// // GetSoundLength ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetSoundLength") == 0) { stack->correctParams(1); - + int length = 0; const char *filename = stack->pop()->getString(); - + BaseSound *sound = new BaseSound(_gameRef); if (sound && DID_SUCCEED(sound->setSound(filename, Audio::Mixer::kMusicSoundType, true))) { length = sound->getLength(); diff --git a/engines/wintermute/base/base_game_music.h b/engines/wintermute/base/base_game_music.h index 0ac904b8c1..150ea6200c 100644 --- a/engines/wintermute/base/base_game_music.h +++ b/engines/wintermute/base/base_game_music.h @@ -8,12 +8,12 @@ * 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. @@ -53,7 +53,7 @@ public: bool stopMusic(int channel); bool playMusic(int channel, const char *filename, bool looping = true, uint32 loopStart = 0); bool updateMusicCrossfade(); - + bool persistChannels(BasePersistenceManager *persistMgr); bool persistCrossfadeSettings(BasePersistenceManager *persistMgr); private: diff --git a/engines/wintermute/base/base_game_settings.cpp b/engines/wintermute/base/base_game_settings.cpp index 55fbe39fd2..9b5eb314bb 100644 --- a/engines/wintermute/base/base_game_settings.cpp +++ b/engines/wintermute/base/base_game_settings.cpp @@ -8,12 +8,12 @@ * 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. @@ -47,7 +47,7 @@ BaseGameSettings::BaseGameSettings(BaseGame *gameRef) { _allowAccessTab = true; _allowAboutTab = true; _allowDesktopRes = false; - + _compressedSavegames = true; _richSavedGames = false; _savedGameExt = "dsv"; @@ -101,21 +101,21 @@ bool BaseGameSettings::loadSettings(const char *filename) { TOKEN_TABLE(SAVED_GAME_EXT) TOKEN_TABLE(GUID) TOKEN_TABLE_END - - + + byte *origBuffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); if (origBuffer == nullptr) { BaseEngine::LOG(0, "BaseGame::LoadSettings failed for file '%s'", filename); return STATUS_FAILED; } - + bool ret = STATUS_OK; - + byte *buffer = origBuffer; byte *params; int cmd; BaseParser parser; - + if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_SETTINGS) { BaseEngine::LOG(0, "'SETTINGS' keyword expected in game settings file."); return STATUS_FAILED; @@ -130,61 +130,61 @@ bool BaseGameSettings::loadSettings(const char *filename) { strcpy(_gameFile, (char *)params); } break; - + case TOKEN_STRING_TABLE: if (DID_FAIL(_stringTable->loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; - + case TOKEN_RESOLUTION: parser.scanStr((char *)params, "%d,%d", &_resWidth, &_resHeight); break; - + case TOKEN_REQUIRE_3D_ACCELERATION: parser.scanStr((char *)params, "%b", &_requireAcceleration); break; - + case TOKEN_REQUIRE_SOUND: parser.scanStr((char *)params, "%b", &_requireSound); break; - + case TOKEN_HWTL_MODE: parser.scanStr((char *)params, "%d", &_TLMode); break; - + case TOKEN_ALLOW_WINDOWED_MODE: parser.scanStr((char *)params, "%b", &_allowWindowed); break; - + case TOKEN_ALLOW_DESKTOP_RES: parser.scanStr((char *)params, "%b", &_allowDesktopRes); break; - + case TOKEN_ALLOW_ADVANCED: parser.scanStr((char *)params, "%b", &_allowAdvanced); break; - + case TOKEN_ALLOW_ACCESSIBILITY_TAB: parser.scanStr((char *)params, "%b", &_allowAccessTab); break; - + case TOKEN_ALLOW_ABOUT_TAB: parser.scanStr((char *)params, "%b", &_allowAboutTab); break; - + case TOKEN_REGISTRY_PATH: //BaseEngine::instance().getRegistry()->setBasePath((char *)params); break; - + case TOKEN_RICH_SAVED_GAMES: parser.scanStr((char *)params, "%b", &_richSavedGames); break; - + case TOKEN_SAVED_GAME_EXT: _savedGameExt = (char *)params; break; - + case TOKEN_GUID: break; } @@ -197,12 +197,12 @@ bool BaseGameSettings::loadSettings(const char *filename) { BaseEngine::LOG(0, "Error loading game settings '%s'", filename); ret = STATUS_FAILED; } - + _allowWindowed = true; // TODO: These two settings should probably be cleaned out altogether. _compressedSavegames = true; - + delete[] origBuffer; - + return ret; } diff --git a/engines/wintermute/base/base_game_settings.h b/engines/wintermute/base/base_game_settings.h index 1dfb0b50cc..92c00ab0c2 100644 --- a/engines/wintermute/base/base_game_settings.h +++ b/engines/wintermute/base/base_game_settings.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/wintermute/base/base_keyboard_state.h b/engines/wintermute/base/base_keyboard_state.h index b62ece02b7..e321dfee16 100644 --- a/engines/wintermute/base/base_keyboard_state.h +++ b/engines/wintermute/base/base_keyboard_state.h @@ -61,7 +61,7 @@ private: bool _currentPrintable; uint32 _currentKeyData; uint32 _currentCharCode; - + bool _currentShift; bool _currentAlt; bool _currentControl; diff --git a/engines/wintermute/base/base_persistence_manager.cpp b/engines/wintermute/base/base_persistence_manager.cpp index 5dbacb157b..c46bb721fe 100644 --- a/engines/wintermute/base/base_persistence_manager.cpp +++ b/engines/wintermute/base/base_persistence_manager.cpp @@ -282,7 +282,7 @@ bool BasePersistenceManager::initSave(const char *desc) { } else { _saveStream->writeUint32LE(0); } - + thumbnailOK = true; } } diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp index e1424cea87..eca2998da5 100644 --- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp +++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp @@ -546,7 +546,7 @@ void BaseRenderOSystem::drawTickets() { // Revert the colorMod-state. _colorMod = oldColorMod; - + it = _renderQueue.begin(); // Clean out the old tickets decrement = 0; diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp index 0572ef2f6e..87bb2fdb53 100644 --- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp +++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp @@ -163,7 +163,7 @@ bool BaseSurfaceOSystem::finishLoad() { needsColorKey = true; } } - + if (needsColorKey) { TransparentSurface trans(*_surface); trans.applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha); diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp index 36c5d7b740..98c5be62a8 100644 --- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp +++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.h b/engines/wintermute/base/gfx/osystem/render_ticket.h index 968b42b5e1..64df3590a1 100644 --- a/engines/wintermute/base/gfx/osystem/render_ticket.h +++ b/engines/wintermute/base/gfx/osystem/render_ticket.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/wintermute/base/save_thumb_helper.cpp b/engines/wintermute/base/save_thumb_helper.cpp index bab29c5cf8..535648eddd 100644 --- a/engines/wintermute/base/save_thumb_helper.cpp +++ b/engines/wintermute/base/save_thumb_helper.cpp @@ -56,23 +56,23 @@ BaseImage *SaveThumbHelper::storeThumb(bool doFlip, int width, int height) { // works normally for direct3d _gameRef->displayContent(false); _gameRef->_renderer->flip(); - + _gameRef->displayContent(false); _gameRef->_renderer->flip(); } - + BaseImage *screenshot = _gameRef->_renderer->takeScreenshot(); if (!screenshot) { return nullptr; } - + // normal thumbnail if (_gameRef->getSaveThumbWidth() > 0 && _gameRef->getSaveThumbHeight() > 0) { thumbnail = new BaseImage(); thumbnail->copyFrom(screenshot, width, height); } - - + + delete screenshot; screenshot = nullptr; } @@ -99,7 +99,7 @@ bool SaveThumbHelper::storeThumbnail(bool doFlip) { bool SaveThumbHelper::storeScummVMThumbNail(bool doFlip) { delete _scummVMThumb; _scummVMThumb = nullptr; - + _scummVMThumb = storeThumb(doFlip, kThumbnailWidth, kThumbnailHeight2); if (!_scummVMThumb) { return STATUS_FAILED; diff --git a/engines/wintermute/base/timer.cpp b/engines/wintermute/base/timer.cpp index 5dfc117f48..96097c10d5 100644 --- a/engines/wintermute/base/timer.cpp +++ b/engines/wintermute/base/timer.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/wintermute/base/timer.h b/engines/wintermute/base/timer.h index ec5477ba2e..4099c6c825 100644 --- a/engines/wintermute/base/timer.h +++ b/engines/wintermute/base/timer.h @@ -8,12 +8,12 @@ * 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. @@ -51,7 +51,7 @@ public: void persist(BasePersistenceManager *persistMgr); }; - + } // End of namespace Wintermute #endif diff --git a/engines/wintermute/debugger.cpp b/engines/wintermute/debugger.cpp index 92b8e6251f..6e865befb9 100644 --- a/engines/wintermute/debugger.cpp +++ b/engines/wintermute/debugger.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/wintermute/debugger.h b/engines/wintermute/debugger.h index 588b81af97..6fbbb084f0 100644 --- a/engines/wintermute/debugger.h +++ b/engines/wintermute/debugger.h @@ -8,12 +8,12 @@ * 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. @@ -32,7 +32,7 @@ class Console : public GUI::Debugger { public: Console(WintermuteEngine *vm); virtual ~Console(); - + bool Cmd_ShowFps(int argc, const char **argv); bool Cmd_DumpFile(int argc, const char **argv); private: diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp index 8f9db8392f..ac24c6f15e 100644 --- a/engines/wintermute/video/video_theora_player.cpp +++ b/engines/wintermute/video/video_theora_player.cpp @@ -163,14 +163,14 @@ bool VideoTheoraPlayer::resetStream() { if (!_file) { return STATUS_FAILED; } - + #if defined (USE_THEORADEC) _theoraDecoder = new Video::TheoraDecoder(); #else return STATUS_FAILED; #endif _theoraDecoder->loadStream(_file); - + if (!_theoraDecoder->isVideoLoaded()) { return STATUS_FAILED; } diff --git a/engines/wintermute/video/video_theora_player.h b/engines/wintermute/video/video_theora_player.h index 364509a080..40b9ba104a 100644 --- a/engines/wintermute/video/video_theora_player.h +++ b/engines/wintermute/video/video_theora_player.h @@ -101,7 +101,7 @@ public: // video properties int32 _posX; int32 _posY; - + bool _dontDropFrames; private: int32 _state; diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp index 89a6f1b3e0..19848b002e 100644 --- a/engines/wintermute/wintermute.cpp +++ b/engines/wintermute/wintermute.cpp @@ -26,7 +26,6 @@ #include "common/debug.h" #include "common/debug-channels.h" #include "common/error.h" -#include "common/EventRecorder.h" #include "common/file.h" #include "common/fs.h" #include "common/tokenizer.h" diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp index c818101645..6825767dfd 100644 --- a/graphics/cursorman.cpp +++ b/graphics/cursorman.cpp @@ -48,6 +48,9 @@ bool CursorManager::isVisible() { bool CursorManager::showMouse(bool visible) { if (_cursorStack.empty()) return false; + if (_locked) { + return false; + } _cursorStack.top()->_visible = visible; @@ -225,6 +228,10 @@ void CursorManager::replaceCursorPalette(const byte *colors, uint start, uint nu } } +void CursorManager::lock(bool locked) { + _locked = locked; +} + CursorManager::Cursor::Cursor(const void *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { #ifdef USE_RGB_COLOR if (!format) diff --git a/graphics/cursorman.h b/graphics/cursorman.h index 66e8d1ba56..b4d8ad94ce 100644 --- a/graphics/cursorman.h +++ b/graphics/cursorman.h @@ -160,12 +160,15 @@ public: */ void replaceCursorPalette(const byte *colors, uint start, uint num); + void lock(bool locked); private: friend class Common::Singleton<SingletonBaseType>; // Even though this is basically the default constructor we implement it // ourselves, so it is private and thus there is no way to create this class // except from the Singleton code. - CursorManager() {} + CursorManager() { + _locked = false; + } ~CursorManager(); struct Cursor { @@ -198,6 +201,7 @@ private: }; Common::Stack<Cursor *> _cursorStack; Common::Stack<Palette *> _cursorPaletteStack; + bool _locked; }; } // End of namespace Graphics diff --git a/graphics/scaler.h b/graphics/scaler.h index 1e5b796631..54d022d202 100644 --- a/graphics/scaler.h +++ b/graphics/scaler.h @@ -89,4 +89,10 @@ extern bool createThumbnailFromScreen(Graphics::Surface *surf); */ extern bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h, const uint8 *palette); +/** + * Downscale screenshot to thumbnale size. + * + */ +extern bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in); + #endif diff --git a/graphics/scaler/thumbnail_intern.cpp b/graphics/scaler/thumbnail_intern.cpp index 88f3cc2077..8a98263eee 100644 --- a/graphics/scaler/thumbnail_intern.cpp +++ b/graphics/scaler/thumbnail_intern.cpp @@ -134,7 +134,7 @@ static bool grabScreen565(Graphics::Surface *surf) { return true; } -static bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in) { +bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in) { uint16 width = in.w; uint16 inHeight = in.h; @@ -206,7 +206,7 @@ static bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in) { return true; } -bool createThumbnailFromScreen(Graphics::Surface* surf) { +bool createThumbnailFromScreen(Graphics::Surface *surf) { assert(surf); Graphics::Surface screen; @@ -236,3 +236,31 @@ bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h, return createThumbnail(*surf, screen); } + +// this is somewhat awkward, but createScreenShot should logically be in graphics, +// but moving other functions in this file into that namespace breaks several engines +namespace Graphics { +bool createScreenShot(Graphics::Surface &surf) { + Graphics::PixelFormat screenFormat = g_system->getScreenFormat(); + //convert surface to 2 bytes pixel format to avoid problems with palette saving and loading + if ((screenFormat.bytesPerPixel == 1) || (screenFormat.bytesPerPixel == 2)) { + return grabScreen565(&surf); + } else { + Graphics::Surface *screen = g_system->lockScreen(); + if (!screen) { + return false; + } + surf.create(screen->w, screen->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); + for (uint y = 0; y < screen->h; ++y) { + for (uint x = 0; x < screen->w; ++x) { + byte r = 0, g = 0, b = 0, a = 0; + uint32 col = READ_UINT32(screen->getBasePtr(x, y)); + screenFormat.colorToARGB(col, a, r, g, b); + ((uint32 *)surf.pixels)[y * surf.w + x] = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(a, r, g, b); + } + } + g_system->unlockScreen(); + return true; + } +} +} // End of namespace Graphics diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp index ddb377306d..e3f368dffa 100644 --- a/graphics/thumbnail.cpp +++ b/graphics/thumbnail.cpp @@ -23,6 +23,7 @@ #include "graphics/scaler.h" #include "graphics/colormasks.h" #include "common/endian.h" +#include "common/algorithm.h" #include "common/system.h" #include "common/stream.h" #include "common/textconsole.h" @@ -42,7 +43,16 @@ struct ThumbnailHeader { #define ThumbnailHeaderSize (4+4+1+2+2+(1+4+4)) -bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool outputWarnings) { +enum HeaderState { + /// There is no header present + kHeaderNone, + /// The header present only has reliable values for version and size + kHeaderUnsupported, + /// The header is present and the version is supported + kHeaderPresent +}; + +HeaderState loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool outputWarnings) { header.type = in.readUint32BE(); // We also accept the bad 'BMHT' header here, for the sake of compatibility // with some older savegames which were written incorrectly due to a bug in @@ -50,16 +60,28 @@ bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool ou if (header.type != MKTAG('T','H','M','B') && header.type != MKTAG('B','M','H','T')) { if (outputWarnings) warning("couldn't find thumbnail header type"); - return false; + return kHeaderNone; } header.size = in.readUint32BE(); header.version = in.readByte(); + // Do a check whether any read errors had occured. If so we cannot use the + // values obtained for size and version because they might be bad. + if (in.err() || in.eos()) { + // TODO: We fake that there is no header. This is actually not quite + // correct since we found the start of the header and then things + // started to break. Right no we leave detection of this to the client. + // Since this case is caused by broken files, the client code should + // catch it anyway... If there is a nicer solution here, we should + // implement it. + return kHeaderNone; + } + if (header.version > THMB_VERSION) { if (outputWarnings) warning("trying to load a newer thumbnail version: %d instead of %d", header.version, THMB_VERSION); - return false; + return kHeaderUnsupported; } header.width = in.readUint16BE(); @@ -81,7 +103,15 @@ bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool ou header.format = createPixelFormat<565>(); } - return true; + if (in.err() || in.eos()) { + // When we reached this point we know that at least the size and + // version field was loaded successfully, thus we tell this header + // is not supported and silently hope that the client code is + // prepared to handle read errors. + return kHeaderUnsupported; + } else { + return kHeaderPresent; + } } } // end of anonymous namespace @@ -89,7 +119,12 @@ bool checkThumbnailHeader(Common::SeekableReadStream &in) { uint32 position = in.pos(); ThumbnailHeader header; - bool hasHeader = loadHeader(in, header, false); + // TODO: It is not clear whether this is the best semantics. Now + // checkThumbnailHeader will return true even when the thumbnail header + // found is actually not usable. However, most engines seem to use this + // to detect the presence of any header and if there is none it wont even + // try to skip it. Thus, this looks like the best solution for now... + bool hasHeader = (loadHeader(in, header, false) != kHeaderNone); in.seek(position, SEEK_SET); @@ -100,7 +135,9 @@ bool skipThumbnail(Common::SeekableReadStream &in) { uint32 position = in.pos(); ThumbnailHeader header; - if (!loadHeader(in, header, false)) { + // We can skip unsupported and supported headers. So we only seek back + // to the old position in case there is no header at all. + if (loadHeader(in, header, false) == kHeaderNone) { in.seek(position, SEEK_SET); return false; } @@ -110,10 +147,23 @@ bool skipThumbnail(Common::SeekableReadStream &in) { } Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) { + const uint32 position = in.pos(); ThumbnailHeader header; - - if (!loadHeader(in, header, true)) + HeaderState headerState = loadHeader(in, header, true); + + // Try to handle unsupported/broken headers gracefully. If there is no + // header at all, we seek back and return at this point. If there is an + // unsupported/broken header, we skip the actual data and return. The + // downside is that we might reset the end of stream flag with this and + // the client code would not be able to notice a read past the end of the + // stream at this point then. + if (headerState == kHeaderNone) { + in.seek(position, SEEK_SET); + return 0; + } else if (headerState == kHeaderUnsupported) { + in.seek(header.size - (in.pos() - position), SEEK_CUR); return 0; + } if (header.format.bytesPerPixel != 2 && header.format.bytesPerPixel != 4) { warning("trying to load thumbnail with unsupported bit depth %d", header.format.bytesPerPixel); @@ -143,7 +193,6 @@ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) { assert(0); } } - return to; } @@ -216,4 +265,55 @@ bool saveThumbnail(Common::WriteStream &out, const Graphics::Surface &thumb) { return true; } + +/** + * Returns an array indicating which pixels of a source image horizontally or vertically get + * included in a scaled image + */ +int *scaleLine(int size, int srcSize) { + int scale = 100 * size / srcSize; + assert(scale > 0); + int *v = new int[size]; + Common::fill(v, &v[size], 0); + + int distCtr = 0; + int *destP = v; + for (int distIndex = 0; distIndex < srcSize; ++distIndex) { + distCtr += scale; + while (distCtr >= 100) { + assert(destP < &v[size]); + *destP++ = distIndex; + distCtr -= 100; + } + } + + return v; +} + +Graphics::Surface *scale(const Graphics::Surface &srcImage, int xSize, int ySize) { + Graphics::Surface *s = new Graphics::Surface(); + s->create(xSize, ySize, srcImage.format); + + int *horizUsage = scaleLine(xSize, srcImage.w); + int *vertUsage = scaleLine(ySize, srcImage.h); + + // Loop to create scaled version + for (int yp = 0; yp < ySize; ++yp) { + const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]); + byte *destP = (byte *)s->getBasePtr(0, yp); + + for (int xp = 0; xp < xSize; ++xp) { + const byte *tempSrcP = srcP + (horizUsage[xp] * srcImage.format.bytesPerPixel); + for (int byteCtr = 0; byteCtr < srcImage.format.bytesPerPixel; ++byteCtr) { + *destP++ = *tempSrcP++; + } + } + } + + // Delete arrays and return surface + delete[] horizUsage; + delete[] vertUsage; + return s; +} + } // End of namespace Graphics diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h index 45a0fdbf07..c857809c91 100644 --- a/graphics/thumbnail.h +++ b/graphics/thumbnail.h @@ -64,6 +64,24 @@ bool saveThumbnail(Common::WriteStream &out); */ bool saveThumbnail(Common::WriteStream &out, const Graphics::Surface &thumb); +/** + * Grabs framebuffer into surface + * + * @param surf a surface + * @return false if a error occurred + */ +bool createScreenShot(Graphics::Surface &surf); + +/** + * Scales a passed surface, creating a new surface with the result + * @param srcImage Source image to scale + * @param xSize New surface width + * @param ySize New surface height + * @remarks Caller is responsible for freeing the returned surface + */ +Graphics::Surface *scale(const Graphics::Surface &srcImage, int xSize, int ySize); + + } // End of namespace Graphics #endif diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h index f785422c5a..a1e61ec705 100644 --- a/graphics/yuv_to_rgb.h +++ b/graphics/yuv_to_rgb.h @@ -22,10 +22,17 @@ /** * @file - * YUV to RGB conversion used in engines: - * - mohawk - * - scumm (he) - * - sword25 + * YUV to RGB conversion. + * + * Used in graphics: + * - JPEGDecoder + * + * Used in video: + * - BinkDecoder + * - Indeo3Decoder + * - PSXStreamDecoder + * - TheoraDecoder + * - SVQ1Decoder */ #ifndef GRAPHICS_YUV_TO_RGB_H diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp new file mode 100644 index 0000000000..fd0093d266 --- /dev/null +++ b/gui/EventRecorder.cpp @@ -0,0 +1,678 @@ +/* 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. + * + */ + + +#include "gui/EventRecorder.h" + +#ifdef ENABLE_EVENTRECORDER + +namespace Common { +DECLARE_SINGLETON(GUI::EventRecorder); +} + +#include "common/debug-channels.h" +#include "backends/timer/sdl/sdl-timer.h" +#include "backends/mixer/sdl/sdl-mixer.h" +#include "common/config-manager.h" +#include "common/md5.h" +#include "gui/gui-manager.h" +#include "gui/widget.h" +#include "gui/onscreendialog.h" +#include "common/random.h" +#include "common/savefile.h" +#include "common/textconsole.h" +#include "graphics/thumbnail.h" +#include "graphics/surface.h" +#include "graphics/scaler.h" + +namespace GUI { + + +const int kMaxRecordsNames = 0x64; +const int kDefaultScreenshotPeriod = 60000; +const int kDefaultBPP = 2; + +uint32 readTime(Common::ReadStream *inFile) { + uint32 d = inFile->readByte(); + if (d == 0xff) { + d = inFile->readUint32LE(); + } + + return d; +} + +void writeTime(Common::WriteStream *outFile, uint32 d) { + //Simple RLE compression + if (d >= 0xff) { + outFile->writeByte(0xff); + outFile->writeUint32LE(d); + } else { + outFile->writeByte(d); + } +} + +EventRecorder::EventRecorder() { + _timerManager = NULL; + _recordMode = kPassthrough; + _fakeMixerManager = NULL; + _initialized = false; + _needRedraw = false; + _fastPlayback = false; + + _fakeTimer = 0; + _savedState = false; + _needcontinueGame = false; + _temporarySlot = 0; + _realSaveManager = 0; + _realMixerManager = 0; + _controlPanel = 0; + _lastMillis = 0; + _lastScreenshotTime = 0; + _screenshotPeriod = 0; + _playbackFile = 0; + + DebugMan.addDebugChannel(kDebugLevelEventRec, "EventRec", "Event recorder debug level"); +} + +EventRecorder::~EventRecorder() { + if (_timerManager != NULL) { + delete _timerManager; + } +} + +void EventRecorder::deinit() { + if (!_initialized) { + return; + } + setFileHeader(); + _needRedraw = false; + _initialized = false; + _recordMode = kPassthrough; + delete _fakeMixerManager; + _fakeMixerManager = NULL; + _controlPanel->close(); + delete _controlPanel; + debugC(1, kDebugLevelEventRec, "playback:action=stopplayback"); + g_system->getEventManager()->getEventDispatcher()->unregisterSource(this); + _recordMode = kPassthrough; + _playbackFile->close(); + delete _playbackFile; + switchMixer(); + switchTimerManagers(); + DebugMan.disableDebugChannel("EventRec"); +} + +void EventRecorder::processMillis(uint32 &millis, bool skipRecord) { + if (!_initialized) { + return; + } + if (skipRecord) { + millis = _fakeTimer; + return; + } + if (_recordMode == kRecorderPlaybackPause) { + millis = _fakeTimer; + } + uint32 millisDelay; + Common::RecorderEvent timerEvent; + switch (_recordMode) { + case kRecorderRecord: + updateSubsystems(); + millisDelay = millis - _lastMillis; + _lastMillis = millis; + _fakeTimer += millisDelay; + _controlPanel->setReplayedTime(_fakeTimer); + timerEvent.recordedtype = Common::kRecorderEventTypeTimer; + timerEvent.time = _fakeTimer; + _playbackFile->writeEvent(timerEvent); + takeScreenshot(); + _timerManager->handler(); + break; + case kRecorderPlayback: + updateSubsystems(); + if (_nextEvent.recordedtype == Common::kRecorderEventTypeTimer) { + _fakeTimer = _nextEvent.time; + _nextEvent = _playbackFile->getNextEvent(); + _timerManager->handler(); + } else { + if (_nextEvent.type == Common::EVENT_RTL) { + error("playback:action=stopplayback"); + } else { + uint32 seconds = _fakeTimer / 1000; + Common::String screenTime = Common::String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60); + error("playback:action=error reason=\"synchronization error\" time = %s", screenTime.c_str()); + } + } + millis = _fakeTimer; + _controlPanel->setReplayedTime(_fakeTimer); + break; + case kRecorderPlaybackPause: + millis = _fakeTimer; + break; + default: + break; + } +} + +bool EventRecorder::processDelayMillis() { + return _fastPlayback; +} + +void EventRecorder::checkForKeyCode(const Common::Event &event) { + if ((event.type == Common::EVENT_KEYDOWN) && (event.kbd.flags & Common::KBD_CTRL) && (event.kbd.keycode == Common::KEYCODE_p) && (!event.synthetic)) { + togglePause(); + } +} + +bool EventRecorder::pollEvent(Common::Event &ev) { + if ((_recordMode != kRecorderPlayback) || !_initialized) + return false; + + if ((_nextEvent.recordedtype == Common::kRecorderEventTypeTimer) || (_nextEvent.type == Common::EVENT_INVALID)) { + return false; + } + + switch (_nextEvent.type) { + case Common::EVENT_MOUSEMOVE: + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONDOWN: + case Common::EVENT_RBUTTONUP: + case Common::EVENT_WHEELUP: + case Common::EVENT_WHEELDOWN: + g_system->warpMouse(_nextEvent.mouse.x, _nextEvent.mouse.y); + break; + default: + break; + } + ev = _nextEvent; + _nextEvent = _playbackFile->getNextEvent(); + return true; +} + +void EventRecorder::switchFastMode() { + if (_recordMode == kRecorderPlaybackPause) { + _fastPlayback = !_fastPlayback; + } +} + +void EventRecorder::togglePause() { + RecordMode oldState; + switch (_recordMode) { + case kRecorderPlayback: + case kRecorderRecord: + oldState = _recordMode; + _recordMode = kRecorderPlaybackPause; + _controlPanel->runModal(); + _recordMode = oldState; + _initialized = true; + break; + case kRecorderPlaybackPause: + _controlPanel->close(); + break; + default: + break; + } +} + +void EventRecorder::RegisterEventSource() { + g_system->getEventManager()->getEventDispatcher()->registerMapper(this, false); +} + +uint32 EventRecorder::getRandomSeed(const Common::String &name) { + uint32 result = g_system->getMillis(); + if (_recordMode == kRecorderRecord) { + _playbackFile->getHeader().randomSourceRecords[name] = result; + } else if (_recordMode == kRecorderPlayback) { + result = _playbackFile->getHeader().randomSourceRecords[name]; + } + return result; +} + +Common::String EventRecorder::generateRecordFileName(const Common::String &target) { + Common::String pattern(target+".r??"); + Common::StringArray files = g_system->getSavefileManager()->listSavefiles(pattern); + for (int i = 0; i < kMaxRecordsNames; ++i) { + Common::String recordName = Common::String::format("%s.r%02d", target.c_str(), i); + if (find(files.begin(), files.end(), recordName) != files.end()) { + continue; + } + return recordName; + } + return ""; +} + + +void EventRecorder::init(Common::String recordFileName, RecordMode mode) { + _fakeMixerManager = new NullSdlMixerManager(); + _fakeMixerManager->init(); + _fakeMixerManager->suspendAudio(); + _fakeTimer = 0; + _lastMillis = g_system->getMillis(); + _playbackFile = new Common::PlaybackFile(); + _lastScreenshotTime = 0; + _recordMode = mode; + _needcontinueGame = false; + if (ConfMan.hasKey("disable_display")) { + DebugMan.enableDebugChannel("EventRec"); + gDebugLevel = 1; + } + if (_recordMode == kRecorderPlayback) { + debugC(1, kDebugLevelEventRec, "playback:action=\"Load file\" filename=%s", recordFileName.c_str()); + } + g_system->getEventManager()->getEventDispatcher()->registerSource(this, false); + _screenshotPeriod = ConfMan.getInt("screenshot_period"); + if (_screenshotPeriod == 0) { + _screenshotPeriod = kDefaultScreenshotPeriod; + } + if (!openRecordFile(recordFileName)) { + deinit(); + error("playback:action=error reason=\"Record file loading error\""); + return; + } + if (_recordMode != kPassthrough) { + _controlPanel = new GUI::OnScreenDialog(_recordMode == kRecorderRecord); + } + if (_recordMode == kRecorderPlayback) { + applyPlaybackSettings(); + _nextEvent = _playbackFile->getNextEvent(); + } + if (_recordMode == kRecorderRecord) { + getConfig(); + } + + switchMixer(); + switchTimerManagers(); + _needRedraw = true; + _initialized = true; +} + + +/** + * Opens or creates file depend of recording mode. + * + *@param id of recording or playing back game + *@return true in case of success, false in case of error + * + */ +bool EventRecorder::openRecordFile(const Common::String &fileName) { + bool result; + switch (_recordMode) { + case kRecorderRecord: + return _playbackFile->openWrite(fileName); + case kRecorderPlayback: + _recordMode = kPassthrough; + result = _playbackFile->openRead(fileName); + _recordMode = kRecorderPlayback; + return result; + default: + return false; + } + return true; +} + +bool EventRecorder::checkGameHash(const ADGameDescription *gameDesc) { + if (_playbackFile->getHeader().hashRecords.size() != 0) { + warning("Engine doesn't contain description table"); + return false; + } + for (const ADGameFileDescription *fileDesc = gameDesc->filesDescriptions; fileDesc->fileName; fileDesc++) { + if (_playbackFile->getHeader().hashRecords.find(fileDesc->fileName) == _playbackFile->getHeader().hashRecords.end()) { + warning("MD5 hash for file %s not found in record file", fileDesc->fileName); + debugC(1, kDebugLevelEventRec, "playback:action=\"Check game hash\" filename=%s filehash=%s storedhash=\"\" result=different", fileDesc->fileName, fileDesc->md5); + return false; + } + if (_playbackFile->getHeader().hashRecords[fileDesc->fileName] != fileDesc->md5) { + warning("Incorrect version of game file %s. Stored MD5 is %s. MD5 of loaded game is %s", fileDesc->fileName, _playbackFile->getHeader().hashRecords[fileDesc->fileName].c_str(), fileDesc->md5); + debugC(1, kDebugLevelEventRec, "playback:action=\"Check game hash\" filename=%s filehash=%s storedhash=%s result=different", fileDesc->fileName, fileDesc->md5, _playbackFile->getHeader().hashRecords[fileDesc->fileName].c_str()); + return false; + } + debugC(1, kDebugLevelEventRec, "playback:action=\"Check game hash\" filename=%s filehash=%s storedhash=%s result=equal", fileDesc->fileName, fileDesc->md5, _playbackFile->getHeader().hashRecords[fileDesc->fileName].c_str()); + } + return true; +} + +void EventRecorder::registerMixerManager(SdlMixerManager *mixerManager) { + _realMixerManager = mixerManager; +} + +void EventRecorder::switchMixer() { + if (_recordMode == kPassthrough) { + _realMixerManager->resumeAudio(); + } else { + _realMixerManager->suspendAudio(); + _fakeMixerManager->resumeAudio(); + } +} + +SdlMixerManager *EventRecorder::getMixerManager() { + if (_recordMode == kPassthrough) { + return _realMixerManager; + } else { + return _fakeMixerManager; + } +} + +void EventRecorder::getConfigFromDomain(Common::ConfigManager::Domain *domain) { + for (Common::ConfigManager::Domain::iterator entry = domain->begin(); entry!= domain->end(); ++entry) { + _playbackFile->getHeader().settingsRecords[entry->_key] = entry->_value; + } +} + +void EventRecorder::getConfig() { + getConfigFromDomain(ConfMan.getDomain(ConfMan.kApplicationDomain)); + getConfigFromDomain(ConfMan.getActiveDomain()); + _playbackFile->getHeader().settingsRecords["save_slot"] = ConfMan.get("save_slot"); +} + + +void EventRecorder::applyPlaybackSettings() { + for (Common::StringMap::iterator i = _playbackFile->getHeader().settingsRecords.begin(); i != _playbackFile->getHeader().settingsRecords.end(); ++i) { + Common::String currentValue = ConfMan.get(i->_key); + if (currentValue != i->_value) { + ConfMan.set(i->_key, i->_value, ConfMan.kTransientDomain); + debugC(1, kDebugLevelEventRec, "playback:action=\"Apply settings\" key=%s storedvalue=%s currentvalue=%s result=different", i->_key.c_str(), i->_value.c_str(), currentValue.c_str()); + } else { + debugC(1, kDebugLevelEventRec, "playback:action=\"Apply settings\" key=%s storedvalue=%s currentvalue=%s result=equal", i->_key.c_str(), i->_value.c_str(), currentValue.c_str()); + } + } + removeDifferentEntriesInDomain(ConfMan.getDomain(ConfMan.kApplicationDomain)); + removeDifferentEntriesInDomain(ConfMan.getActiveDomain()); +} + +void EventRecorder::removeDifferentEntriesInDomain(Common::ConfigManager::Domain *domain) { + for (Common::ConfigManager::Domain::iterator entry = domain->begin(); entry!= domain->end(); ++entry) { + if (_playbackFile->getHeader().settingsRecords.find(entry->_key) == _playbackFile->getHeader().settingsRecords.end()) { + debugC(1, kDebugLevelEventRec, "playback:action=\"Apply settings\" checksettings:key=%s storedvalue=%s currentvalue="" result=different", entry->_key.c_str(), entry->_value.c_str()); + domain->erase(entry->_key); + } + } +} + +DefaultTimerManager *EventRecorder::getTimerManager() { + return _timerManager; +} + +void EventRecorder::registerTimerManager(DefaultTimerManager *timerManager) { + _timerManager = timerManager; +} + +void EventRecorder::switchTimerManagers() { + delete _timerManager; + if (_recordMode == kPassthrough) { + _timerManager = new SdlTimerManager(); + } else { + _timerManager = new DefaultTimerManager(); + } +} + +void EventRecorder::updateSubsystems() { + if (_recordMode == kPassthrough) { + return; + } + RecordMode oldRecordMode = _recordMode; + _recordMode = kPassthrough; + _fakeMixerManager->update(); + _recordMode = oldRecordMode; +} + +Common::List<Common::Event> EventRecorder::mapEvent(const Common::Event &ev, Common::EventSource *source) { + if ((!_initialized) && (_recordMode != kRecorderPlaybackPause)) { + return DefaultEventMapper::mapEvent(ev, source); + } + + checkForKeyCode(ev); + Common::Event evt = ev; + evt.mouse.x = evt.mouse.x * (g_system->getOverlayWidth() / g_system->getWidth()); + evt.mouse.y = evt.mouse.y * (g_system->getOverlayHeight() / g_system->getHeight()); + switch (_recordMode) { + case kRecorderPlayback: + if (ev.synthetic != true) { + return Common::List<Common::Event>(); + } + return Common::DefaultEventMapper::mapEvent(ev, source); + break; + case kRecorderRecord: + g_gui.processEvent(evt, _controlPanel); + if (((evt.type == Common::EVENT_LBUTTONDOWN) || (evt.type == Common::EVENT_LBUTTONUP) || (evt.type == Common::EVENT_MOUSEMOVE)) && _controlPanel->isMouseOver()) { + return Common::List<Common::Event>(); + } else { + Common::RecorderEvent e; + memcpy(&e, &ev, sizeof(ev)); + e.recordedtype = Common::kRecorderEventTypeNormal; + e.time = _fakeTimer; + _playbackFile->writeEvent(e); + return DefaultEventMapper::mapEvent(ev, source); + } + break; + case kRecorderPlaybackPause: { + Common::Event dialogEvent; + if (_controlPanel->isEditDlgVisible()) { + dialogEvent = ev; + } else { + dialogEvent = evt; + } + g_gui.processEvent(dialogEvent, _controlPanel->getActiveDlg()); + if (((dialogEvent.type == Common::EVENT_LBUTTONDOWN) || (dialogEvent.type == Common::EVENT_LBUTTONUP) || (dialogEvent.type == Common::EVENT_MOUSEMOVE)) && _controlPanel->isMouseOver()) { + return Common::List<Common::Event>(); + } + return Common::DefaultEventMapper::mapEvent(dialogEvent, source); + } + break; + default: + return Common::DefaultEventMapper::mapEvent(ev, source); + } +} + +void EventRecorder::setGameMd5(const ADGameDescription *gameDesc) { + for (const ADGameFileDescription *fileDesc = gameDesc->filesDescriptions; fileDesc->fileName; fileDesc++) { + if (fileDesc->md5 != NULL) { + _playbackFile->getHeader().hashRecords[fileDesc->fileName] = fileDesc->md5; + } + } +} + +void EventRecorder::processGameDescription(const ADGameDescription *desc) { + if (_recordMode == kRecorderRecord) { + setGameMd5(desc); + } + if ((_recordMode == kRecorderPlayback) && !checkGameHash(desc)) { + deinit(); + error("playback:action=error reason=\"\""); + } +} + +void EventRecorder::deleteRecord(const Common::String& fileName) { + g_system->getSavefileManager()->removeSavefile(fileName); +} + +void EventRecorder::takeScreenshot() { + if ((_fakeTimer - _lastScreenshotTime) > _screenshotPeriod) { + Graphics::Surface screen; + uint8 md5[16]; + if (grabScreenAndComputeMD5(screen, md5)) { + _lastScreenshotTime = _fakeTimer; + _playbackFile->saveScreenShot(screen, md5); + screen.free(); + } + } +} + +bool EventRecorder::grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5[16]) { + if (!createScreenShot(screen)) { + warning("Can't save screenshot"); + return false; + } + Common::MemoryReadStream bitmapStream((const byte*)screen.pixels, screen.w * screen.h * screen.format.bytesPerPixel); + computeStreamMD5(bitmapStream, md5); + return true; +} + +Common::SeekableReadStream *EventRecorder::processSaveStream(const Common::String &fileName) { + Common::InSaveFile *saveFile; + switch (_recordMode) { + case kRecorderPlayback: + debugC(1, kDebugLevelEventRec, "playback:action=\"Process save file\" filename=%s len=%d", fileName.c_str(), _playbackFile->getHeader().saveFiles[fileName].size); + return new Common::MemoryReadStream(_playbackFile->getHeader().saveFiles[fileName].buffer, _playbackFile->getHeader().saveFiles[fileName].size); + case kRecorderRecord: + saveFile = _realSaveManager->openForLoading(fileName); + if (saveFile != NULL) { + _playbackFile->addSaveFile(fileName, saveFile); + saveFile->seek(0); + } + return saveFile; + default: + return NULL; + break; + } +} + +Common::SaveFileManager *EventRecorder::getSaveManager(Common::SaveFileManager *realSaveManager) { + _realSaveManager = realSaveManager; + if (_recordMode != kPassthrough) { + return &_fakeSaveManager; + } else { + return realSaveManager; + } +} + +void EventRecorder::preDrawOverlayGui() { + if ((_initialized) || (_needRedraw)) { + RecordMode oldMode = _recordMode; + _recordMode = kPassthrough; + g_system->showOverlay(); + g_gui.theme()->clearAll(); + g_gui.theme()->openDialog(true, GUI::ThemeEngine::kShadingNone); + _controlPanel->drawDialog(); + g_gui.theme()->finishBuffering(); + g_gui.theme()->updateScreen(); + _recordMode = oldMode; + } +} + +void EventRecorder::postDrawOverlayGui() { + if ((_initialized) || (_needRedraw)) { + RecordMode oldMode = _recordMode; + _recordMode = kPassthrough; + g_system->hideOverlay(); + _recordMode = oldMode; + } +} + +Common::StringArray EventRecorder::listSaveFiles(const Common::String &pattern) { + if (_recordMode == kRecorderPlayback) { + Common::StringArray result; + for (Common::HashMap<Common::String, Common::PlaybackFile::SaveFileBuffer>::iterator i = _playbackFile->getHeader().saveFiles.begin(); i != _playbackFile->getHeader().saveFiles.end(); ++i) { + if (i->_key.matchString(pattern, false, true)) { + result.push_back(i->_key); + } + } + return result; + } else { + return _realSaveManager->listSavefiles(pattern); + } +} + +void EventRecorder::setFileHeader() { + if (_recordMode != kRecorderRecord) { + return; + } + TimeDate t; + const EnginePlugin *plugin = 0; + GameDescriptor desc = EngineMan.findGame(ConfMan.getActiveDomainName(), &plugin); + g_system->getTimeAndDate(t); + if (_author.empty()) { + setAuthor("Unknown Author"); + } + if (_name.empty()) { + g_eventRec.setName(Common::String::format("%.2d.%.2d.%.4d ", t.tm_mday, t.tm_mon, 1900 + t.tm_year) + desc.description()); + } + _playbackFile->getHeader().author = _author; + _playbackFile->getHeader().notes = _desc; + _playbackFile->getHeader().name = _name; +} + +SDL_Surface *EventRecorder::getSurface(int width, int height) { + // Create a RGB565 surface of the requested dimensions. + return SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 16, 0xF800, 0x07E0, 0x001F, 0x0000); +} + +bool EventRecorder::switchMode() { + const Common::String gameId = ConfMan.get("gameid"); + const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); + bool metaInfoSupport = (*plugin)->hasFeature(MetaEngine::kSavesSupportMetaInfo); + bool featuresSupport = metaInfoSupport && + g_engine->canSaveGameStateCurrently() && + (*plugin)->hasFeature(MetaEngine::kSupportsListSaves) && + (*plugin)->hasFeature(MetaEngine::kSupportsDeleteSave); + if (!featuresSupport) { + return false; + } + + int emptySlot = 1; + SaveStateList saveList = (*plugin)->listSaves(gameId.c_str()); + for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) { + int saveSlot = x->getSaveSlot(); + if (saveSlot == 0) { + continue; + } + if (emptySlot != saveSlot) { + break; + } + emptySlot++; + } + Common::String saveName; + if (emptySlot >= 0) { + saveName = Common::String::format("Save %d", emptySlot + 1); + Common::Error status = g_engine->saveGameState(emptySlot, saveName); + if (status.getCode() == Common::kNoError) { + Common::Event eventRTL; + eventRTL.type = Common::EVENT_RTL; + g_system->getEventManager()->pushEvent(eventRTL); + } + } + ConfMan.set("record_mode", "", Common::ConfigManager::kTransientDomain); + ConfMan.setInt("save_slot", emptySlot, Common::ConfigManager::kTransientDomain); + _needcontinueGame = true; + return true; +} + +bool EventRecorder::checkForContinueGame() { + bool result = _needcontinueGame; + _needcontinueGame = false; + return result; +} + +void EventRecorder::deleteTemporarySave() { + if (_temporarySlot == -1) return; + const Common::String gameId = ConfMan.get("gameid"); + const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); + (*plugin)->removeSaveState(gameId.c_str(), _temporarySlot); + _temporarySlot = -1; +} + +} // End of namespace GUI + +#endif // ENABLE_EVENTRECORDER + diff --git a/gui/EventRecorder.h b/gui/EventRecorder.h new file mode 100644 index 0000000000..68ffe16fbc --- /dev/null +++ b/gui/EventRecorder.h @@ -0,0 +1,238 @@ +/* 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. + * + */ + +#ifndef GUI_EVENTRECORDER_H +#define GUI_EVENTRECORDER_H + +#include "common/system.h" + +#include "common/events.h" +#include "common/savefile.h" +#include "common/singleton.h" + +#include "engines/advancedDetector.h" + +#ifdef ENABLE_EVENTRECORDER + +#include "common/mutex.h" +#include "common/array.h" +#include "common/memstream.h" +#include "backends/keymapper/keymapper.h" +#include "backends/mixer/sdl/sdl-mixer.h" +#include "common/hashmap.h" +#include "common/hash-str.h" +#include "backends/timer/sdl/sdl-timer.h" +#include "common/config-manager.h" +#include "common/recorderfile.h" +#include "backends/saves/recorder/recorder-saves.h" +#include "backends/mixer/nullmixer/nullsdl-mixer.h" +#include "backends/saves/default/default-saves.h" + + +#define g_eventRec (GUI::EventRecorder::instance()) + +namespace GUI { + class OnScreenDialog; +} + +namespace GUI { +class RandomSource; +class SeekableReadStream; +class WriteStream; + + +/** + * Our generic event recorder. + * + * TODO: Add more documentation. + */ +class EventRecorder : private Common::EventSource, public Common::Singleton<EventRecorder>, private Common::DefaultEventMapper { + friend class Common::Singleton<SingletonBaseType>; + EventRecorder(); + ~EventRecorder(); +public: + /** Specify operation mode of Event Recorder */ + enum RecordMode { + kPassthrough = 0, /**< kPassthrough, do nothing */ + kRecorderRecord = 1, /**< kRecorderRecord, do the recording */ + kRecorderPlayback = 2, /**< kRecorderPlayback, playback existing recording */ + kRecorderPlaybackPause = 3 /**< kRecordetPlaybackPause, interal state when user pauses the playback */ + }; + + void init(Common::String recordFileName, RecordMode mode); + void deinit(); + bool processDelayMillis(); + uint32 getRandomSeed(const Common::String &name); + void processMillis(uint32 &millis, bool skipRecord); + bool processAudio(uint32 &samples, bool paused); + void processGameDescription(const ADGameDescription *desc); + Common::SeekableReadStream *processSaveStream(const Common::String & fileName); + + /** Hooks for intercepting into GUI processing, so required events could be shoot + * or filtered out */ + void preDrawOverlayGui(); + void postDrawOverlayGui(); + + /** Set recording author + * + * @see getAuthor + */ + void setAuthor(const Common::String &author) { + _author = author; + } + + /** Set recording notes + * + * @see getNotes + */ + void setNotes(const Common::String &desc){ + _desc = desc; + } + + /** Set descriptive name of the recording + * + * @see getName + */ + void setName(const Common::String &name) { + _name = name; + } + + /** Get recording author + * + * @see getAuthor + */ + const Common::String getAuthor() { + return _author; + } + + /** Get recording notes + * + * @see setNotes + */ + const Common::String getNotes() { + return _desc; + } + + /** Get recording name + * + * @see setName + */ + const Common::String getName() { + return _name; + } + void setRedraw(bool redraw) { + _needRedraw = redraw; + } + + void registerMixerManager(SdlMixerManager *mixerManager); + void registerTimerManager(DefaultTimerManager *timerManager); + + SdlMixerManager *getMixerManager(); + DefaultTimerManager *getTimerManager(); + + void deleteRecord(const Common::String& fileName); + bool checkForContinueGame(); + + void suspendRecording() { + _savedState = _initialized; + _initialized = false; + } + + void resumeRecording() { + _initialized = _savedState; + } + + Common::StringArray listSaveFiles(const Common::String &pattern); + Common::String generateRecordFileName(const Common::String &target); + + Common::SaveFileManager *getSaveManager(Common::SaveFileManager *realSaveManager); + SDL_Surface *getSurface(int width, int height); + void RegisterEventSource(); + + /** Retrieve game screenshot and compute its checksum for comparison */ + bool grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5[16]); + + void updateSubsystems(); + bool switchMode(); + void switchFastMode(); + +private: + virtual Common::List<Common::Event> mapEvent(const Common::Event &ev, Common::EventSource *source); + bool notifyPoll(); + bool pollEvent(Common::Event &ev); + bool _initialized; + volatile uint32 _fakeTimer; + bool _savedState; + bool _needcontinueGame; + int _temporarySlot; + Common::String _author; + Common::String _desc; + Common::String _name; + + Common::SaveFileManager *_realSaveManager; + SdlMixerManager *_realMixerManager; + DefaultTimerManager *_timerManager; + RecorderSaveFileManager _fakeSaveManager; + NullSdlMixerManager *_fakeMixerManager; + GUI::OnScreenDialog *_controlPanel; + Common::RecorderEvent _nextEvent; + + void setFileHeader(); + void setGameMd5(const ADGameDescription *gameDesc); + void getConfig(); + void getConfigFromDomain(Common::ConfigManager::Domain *domain); + void removeDifferentEntriesInDomain(Common::ConfigManager::Domain *domain); + void applyPlaybackSettings(); + + void switchMixer(); + void switchTimerManagers(); + + void togglePause(); + + void takeScreenshot(); + + bool openRecordFile(const Common::String &fileName); + + bool checkGameHash(const ADGameDescription *desc); + + void checkForKeyCode(const Common::Event &event); + bool allowMapping() const { return false; } + + volatile uint32 _lastMillis; + uint32 _lastScreenshotTime; + uint32 _screenshotPeriod; + Common::PlaybackFile *_playbackFile; + + void saveScreenShot(); + void checkRecordedMD5(); + void deleteTemporarySave(); + volatile RecordMode _recordMode; + Common::String _recordFileName; + bool _fastPlayback; + bool _needRedraw; +}; + +} // End of namespace GUI + +#endif // ENABLE_EVENTRECORDER + +#endif diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index e2fa2580f5..3ce043cb39 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -50,6 +50,14 @@ const char * const ThemeEngine::kImageEraser = "eraser.bmp"; const char * const ThemeEngine::kImageDelbtn = "delbtn.bmp"; const char * const ThemeEngine::kImageList = "list.bmp"; const char * const ThemeEngine::kImageGrid = "grid.bmp"; +const char * const ThemeEngine::kImageStopbtn = "stopbtn.bmp"; +const char * const ThemeEngine::kImageEditbtn = "editbtn.bmp"; +const char * const ThemeEngine::kImageSwitchModebtn = "switchbtn.bmp"; +const char * const ThemeEngine::kImageFastReplaybtn = "fastreplay.bmp"; +const char * const ThemeEngine::kImageStopSmallbtn = "stopbtn_small.bmp"; +const char * const ThemeEngine::kImageEditSmallbtn = "editbtn_small.bmp"; +const char * const ThemeEngine::kImageSwitchModeSmallbtn = "switchbtn_small.bmp"; +const char * const ThemeEngine::kImageFastReplaySmallbtn = "fastreplay_small.bmp"; struct TextDrawData { const Graphics::Font *_fontPtr; @@ -465,11 +473,7 @@ void ThemeEngine::enable() { if (_enabled) return; - if (_useCursor) { - CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize); - CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true); - CursorMan.showMouse(true); - } + showCursor(); _system->showOverlay(); clearAll(); @@ -482,10 +486,8 @@ void ThemeEngine::disable() { _system->hideOverlay(); - if (_useCursor) { - CursorMan.popCursorPalette(); - CursorMan.popCursor(); - } + hideCursor(); + _enabled = false; } @@ -1787,5 +1789,20 @@ Common::String ThemeEngine::getThemeId(const Common::String &filename) { } } +void ThemeEngine::showCursor() { + if (_useCursor) { + CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize); + CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true); + CursorMan.showMouse(true); + } +} + +void ThemeEngine::hideCursor() { + if (_useCursor) { + CursorMan.popCursorPalette(); + CursorMan.popCursor(); + } +} + } // End of namespace GUI. diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 6e5fd291b7..160ceb3259 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -234,6 +234,14 @@ public: static const char *const kImageDelbtn; ///< Delete characters in the predictive dialog static const char *const kImageList; ///< List image used in save/load chooser selection static const char *const kImageGrid; ///< Grid image used in save/load chooser selection + static const char *const kImageStopbtn; ///< Stop recording button in recorder onscreen dialog + static const char *const kImageEditbtn; ///< Edit recording metadata in recorder onscreen dialog + static const char *const kImageSwitchModebtn; ///< Switch mode button in recorder onscreen dialog + static const char *const kImageFastReplaybtn; ///< Fast playback mode button in recorder onscreen dialog + static const char *const kImageStopSmallbtn; ///< Stop recording button in recorder onscreen dialog (for 320xY) + static const char *const kImageEditSmallbtn; ///< Edit recording metadata in recorder onscreen dialog (for 320xY) + static const char *const kImageSwitchModeSmallbtn; ///< Switch mode button in recorder onscreen dialog (for 320xY) + static const char *const kImageFastReplaySmallbtn; ///< Fast playback mode button in recorder onscreen dialog (for 320xY) /** * Graphics mode enumeration. @@ -275,8 +283,13 @@ public: void refresh(); void enable(); + + void showCursor(); + void hideCursor(); + void disable(); + /** * Query the set up pixel format. */ diff --git a/gui/about.cpp b/gui/about.cpp index 088971f273..20145886c6 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -46,7 +46,7 @@ enum { // 0 - 2 -- set a custom color: // 0 normal text // 1 highlighted text -// 2 disabled text +// 2 disabled text // TODO: Maybe add a tab/indent feature; that is, make it possible to specify // an amount by which that line shall be indented (the indent of course would have // to be considered while performing any word wrapping, too). @@ -139,7 +139,7 @@ void AboutDialog::addLine(const char *str) { } else { Common::String format(str, 2); str += 2; - + static Common::String asciiStr; if (format[0] == 'A') { bool useAscii = false; diff --git a/gui/chooser.cpp b/gui/chooser.cpp index 6ae08161df..c195e94c9b 100644 --- a/gui/chooser.cpp +++ b/gui/chooser.cpp @@ -67,6 +67,7 @@ void ChooserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data break; case kCloseCmd: setResult(-1); + // Fall through default: Dialog::handleCommand(sender, cmd, data); } diff --git a/gui/credits.h b/gui/credits.h index 81d46b2b73..70f79ac9a5 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -294,9 +294,6 @@ static const char *credits[] = { "C0""Andre Heider", "C0""Angus Lees", "", -"C1""BADA", -"C0""Chris Warren-Smith", -"", "C1""Dreamcast", "C0""Marcus Comstedt", "", @@ -352,6 +349,9 @@ static const char *credits[] = { "C0""Jurgen Braam", "C0""Lars Persson", "", +"C1""Tizen / BADA", +"C0""Chris Warren-Smith", +"", "C1""WebOS", "C0""Klaus Reimer", "", diff --git a/gui/dialog.h b/gui/dialog.h index 1773c6633e..d269a2f645 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -37,6 +37,8 @@ struct Event; namespace GUI { +class EventRecorder; + class Widget; // Some "common" commands sent to handleCommand() @@ -47,6 +49,7 @@ enum { class Dialog : public GuiObject { friend class GuiManager; + friend class EventRecorder; friend class Tooltip; protected: Widget *_mouseWidget; diff --git a/gui/editrecorddialog.cpp b/gui/editrecorddialog.cpp new file mode 100644 index 0000000000..cfcc747121 --- /dev/null +++ b/gui/editrecorddialog.cpp @@ -0,0 +1,87 @@ +/* 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. + * + */ + +#include "editrecorddialog.h" +#include "gui/widgets/edittext.h" +#include "common/translation.h" + + +namespace GUI { + +const Common::String EditRecordDialog::getAuthor() { + return _authorEdit->getEditString(); +} + +void EditRecordDialog::setAuthor(const Common::String &author) { + _authorEdit->setEditString(author); +} + +const Common::String EditRecordDialog::getNotes() { + return _notesEdit->getEditString(); +} + +void EditRecordDialog::setNotes(const Common::String &desc) { + _notesEdit->setEditString(desc); +} + +const Common::String EditRecordDialog::getName() { + return _nameEdit->getEditString(); +} + +void EditRecordDialog::setName(const Common::String &name) { + _nameEdit->setEditString(name); +} + +EditRecordDialog::~EditRecordDialog() { +} + +EditRecordDialog::EditRecordDialog(const Common::String author, const Common::String name, const Common::String notes) : Dialog("EditRecordDialog") { + new StaticTextWidget(this,"EditRecordDialog.AuthorLabel",_("Author:")); + new StaticTextWidget(this,"EditRecordDialog.NameLabel",_("Name:")); + new StaticTextWidget(this,"EditRecordDialog.NotesLabel",_("Notes:")); + _authorEdit = new EditTextWidget(this, "EditRecordDialog.AuthorEdit",""); + _notesEdit = new EditTextWidget(this, "EditRecordDialog.NotesEdit",""); + _nameEdit = new EditTextWidget(this, "EditRecordDialog.NameEdit",""); + _authorEdit->setEditString(author); + _notesEdit->setEditString(notes); + _nameEdit->setEditString(name); + new GUI::ButtonWidget(this, "EditRecordDialog.Cancel", _("Cancel"), 0, kCloseCmd); + new GUI::ButtonWidget(this, "EditRecordDialog.OK", _("Ok"), 0, kOKCmd); +} + +void EditRecordDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { + switch(cmd) { + case kCloseCmd: + setResult(kCloseCmd); + close(); + break; + case kOKCmd: + setResult(kOKCmd); + close(); + break; + default: + Dialog::handleCommand(sender, cmd, data); + break; + } +} + +} diff --git a/backends/platform/bada/application.h b/gui/editrecorddialog.h index 2b0d37f1ef..c8da4521ca 100644 --- a/backends/platform/bada/application.h +++ b/gui/editrecorddialog.h @@ -8,47 +8,49 @@ * 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 + * 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. * */ -#ifndef BADA_APPLICATION_H -#define BADA_APPLICATION_H +#ifndef GUI_EDITRECORDDIALOG_H +#define GUI_EDITRECORDDIALOG_H -#include <FBase.h> -#include <FApp.h> -#include <FGraphics.h> -#include <FUi.h> -#include <FSystem.h> +#include "gui/dialog.h" -#include "backends/platform/bada/system.h" +namespace GUI { -class BadaScummVM : public Osp::App::Application { +class EditTextWidget; +class StaticTextWidget; + +class EditRecordDialog : public Dialog { +private: + EditTextWidget *_notesEdit; + EditTextWidget *_nameEdit; + EditTextWidget *_authorEdit; + EditRecordDialog() : Dialog("EditRecordDialog") {}; public: - BadaScummVM(); - ~BadaScummVM(); + EditRecordDialog(const Common::String author, const Common::String name, const Common::String notes); + ~EditRecordDialog(); - static Osp::App::Application *createInstance(void); + const Common::String getAuthor(); + const Common::String getNotes(); + const Common::String getName(); - bool OnAppInitializing(Osp::App::AppRegistry &appRegistry); - bool OnAppTerminating(Osp::App::AppRegistry &appRegistry, bool forcedTermination = false); - void OnForeground(void); - void OnBackground(void); - void OnLowMemory(void); - void OnBatteryLevelChanged(Osp::System::BatteryLevel batteryLevel); - void OnUserEventReceivedN(RequestId requestId, Osp::Base::Collection::IList *pArgs); + void setAuthor(const Common::String &author); + void setNotes(const Common::String &desc); + void setName(const Common::String &name); -private: - void pauseGame(bool pause); - BadaAppForm *_appForm; + virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); }; +}// End of namespace GUI + #endif diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp index a0ef4216aa..1505c8c707 100644 --- a/gui/gui-manager.cpp +++ b/gui/gui-manager.cpp @@ -27,6 +27,7 @@ #include "common/rect.h" #include "common/textconsole.h" #include "common/translation.h" +#include "gui/EventRecorder.h" #include "backends/keymapper/keymapper.h" @@ -253,12 +254,15 @@ Dialog *GuiManager::getTopDialog() const { void GuiManager::runLoop() { Dialog * const activeDialog = getTopDialog(); bool didSaveState = false; - int button; - uint32 time; if (activeDialog == 0) return; +#ifdef ENABLE_EVENTRECORDER + // Suspend recording while GUI is shown + g_eventRec.suspendRecording(); +#endif + if (!_stateIsSaved) { saveState(); _theme->enable(); @@ -296,10 +300,10 @@ void GuiManager::runLoop() { // _theme->updateScreen(); // _system->updateScreen(); - if (lastRedraw + waitTime < _system->getMillis()) { + if (lastRedraw + waitTime < _system->getMillis(true)) { _theme->updateScreen(); _system->updateScreen(); - lastRedraw = _system->getMillis(); + lastRedraw = _system->getMillis(true); } Common::Event event; @@ -314,72 +318,21 @@ void GuiManager::runLoop() { if (activeDialog != getTopDialog() && event.type != Common::EVENT_SCREEN_CHANGED) continue; - Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); - - switch (event.type) { - case Common::EVENT_KEYDOWN: - activeDialog->handleKeyDown(event.kbd); - break; - case Common::EVENT_KEYUP: - activeDialog->handleKeyUp(event.kbd); - break; - case Common::EVENT_MOUSEMOVE: - activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); - - if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) { - _lastMousePosition.x = mouse.x; - _lastMousePosition.y = mouse.y; - _lastMousePosition.time = _system->getMillis(); - } + processEvent(event, activeDialog); + if (event.type == Common::EVENT_MOUSEMOVE) { tooltipCheck = true; - break; - // We don't distinguish between mousebuttons (for now at least) - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_RBUTTONDOWN: - button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2); - time = _system->getMillis(); - if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) - && ABS(_lastClick.x - event.mouse.x) < 3 - && ABS(_lastClick.y - event.mouse.y) < 3) { - _lastClick.count++; - } else { - _lastClick.x = event.mouse.x; - _lastClick.y = event.mouse.y; - _lastClick.count = 1; - } - _lastClick.time = time; - activeDialog->handleMouseDown(mouse.x, mouse.y, button, _lastClick.count); - break; - case Common::EVENT_LBUTTONUP: - case Common::EVENT_RBUTTONUP: - button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2); - activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count); - break; - case Common::EVENT_WHEELUP: - activeDialog->handleMouseWheel(mouse.x, mouse.y, -1); - break; - case Common::EVENT_WHEELDOWN: - activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); - break; - case Common::EVENT_SCREEN_CHANGED: - screenChange(); - break; - default: -#ifdef ENABLE_KEYMAPPER - activeDialog->handleOtherEvent(event); -#endif - break; } - if (lastRedraw + waitTime < _system->getMillis()) { + + if (lastRedraw + waitTime < _system->getMillis(true)) { _theme->updateScreen(); _system->updateScreen(); - lastRedraw = _system->getMillis(); + lastRedraw = _system->getMillis(true); } } - if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { + if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis(true)) { Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y); if (wdg && wdg->hasTooltip() && !(wdg->getFlags() & WIDGET_PRESSED)) { Tooltip *tooltip = new Tooltip(); @@ -409,6 +362,11 @@ void GuiManager::runLoop() { restoreState(); _useStdCursor = false; } + +#ifdef ENABLE_EVENTRECORDER + // Resume recording once GUI is shown + g_eventRec.resumeRecording(); +#endif } #pragma mark - @@ -492,7 +450,7 @@ void GuiManager::setupCursor() { // very much. We could plug in a different cursor here if we like to. void GuiManager::animateCursor() { - int time = _system->getMillis(); + int time = _system->getMillis(true); if (time > _cursorAnimateTimer + kCursorAnimateDelay) { for (int i = 0; i < 15; i++) { if ((i < 6) || (i > 8)) { @@ -537,4 +495,64 @@ void GuiManager::screenChange() { _system->updateScreen(); } +void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDialog) { + int button; + uint32 time; + Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); + switch (event.type) { + case Common::EVENT_KEYDOWN: + activeDialog->handleKeyDown(event.kbd); + break; + case Common::EVENT_KEYUP: + activeDialog->handleKeyUp(event.kbd); + break; + case Common::EVENT_MOUSEMOVE: + activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); + + if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) { + _lastMousePosition.x = mouse.x; + _lastMousePosition.y = mouse.y; + _lastMousePosition.time = _system->getMillis(true); + } + + break; + // We don't distinguish between mousebuttons (for now at least) + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2); + time = _system->getMillis(true); + if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) + && ABS(_lastClick.x - event.mouse.x) < 3 + && ABS(_lastClick.y - event.mouse.y) < 3) { + _lastClick.count++; + } else { + _lastClick.x = event.mouse.x; + _lastClick.y = event.mouse.y; + _lastClick.count = 1; + } + _lastClick.time = time; + activeDialog->handleMouseDown(mouse.x, mouse.y, button, _lastClick.count); + break; + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2); + activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count); + break; + case Common::EVENT_WHEELUP: + activeDialog->handleMouseWheel(mouse.x, mouse.y, -1); + break; + case Common::EVENT_WHEELDOWN: + activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); + break; + case Common::EVENT_SCREEN_CHANGED: + screenChange(); + break; + default: + #ifdef ENABLE_KEYMAPPER + activeDialog->handleOtherEvent(event); + #endif + break; + } +} + } // End of namespace GUI diff --git a/gui/gui-manager.h b/gui/gui-manager.h index 49542fd001..b52d91ba08 100644 --- a/gui/gui-manager.h +++ b/gui/gui-manager.h @@ -35,6 +35,10 @@ namespace Graphics { class Font; } +namespace Common { + struct Event; +} + namespace GUI { class Dialog; @@ -67,6 +71,8 @@ public: // until no dialogs are active anymore. void runLoop(); + void processEvent(const Common::Event &event, Dialog *const activeDialog); + bool isActive() const { return ! _dialogStack.empty(); } bool loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx = ThemeEngine::kGfxDisabled, bool force = false); diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 4e35b54db8..77d4cce794 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -37,6 +37,11 @@ #include "gui/message.h" #include "gui/gui-manager.h" #include "gui/options.h" +#ifdef ENABLE_EVENTRECORDER +#include "gui/onscreendialog.h" +#include "gui/recorderdialog.h" +#include "gui/EventRecorder.h" +#endif #include "gui/saveload.h" #include "gui/widgets/edittext.h" #include "gui/widgets/list.h" @@ -596,7 +601,6 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat LauncherDialog::LauncherDialog() : Dialog(0, 0, 320, 200) { _backgroundType = GUI::ThemeEngine::kDialogBackgroundMain; - const int screenW = g_system->getOverlayWidth(); const int screenH = g_system->getOverlayHeight(); @@ -779,10 +783,9 @@ void LauncherDialog::updateListing() { } void LauncherDialog::addGame() { - int modifiers = g_system->getEventManager()->getModifierState(); #ifndef DISABLE_MASS_ADD - const bool massAdd = (modifiers & Common::KBD_SHIFT) != 0; + const bool massAdd = checkModifier(Common::KBD_SHIFT); if (massAdd) { MessageDialog alert(_("Do you really want to run the mass game detector? " @@ -975,6 +978,49 @@ void LauncherDialog::editGame(int item) { } } +void LauncherDialog::loadGameButtonPressed(int item) { +#ifdef ENABLE_EVENTRECORDER + const bool shiftPressed = checkModifier(Common::KBD_SHIFT); + if (shiftPressed) { + recordGame(item); + } else { + loadGame(item); + } + updateButtons(); +#else + loadGame(item); +#endif +} + +#ifdef ENABLE_EVENTRECORDER +void LauncherDialog::recordGame(int item) { + RecorderDialog recorderDialog; + MessageDialog alert(_("Do you want to load savegame?"), + _("Yes"), _("No")); + switch(recorderDialog.runModal(_domains[item])) { + case RecorderDialog::kRecordDialogClose: + break; + case RecorderDialog::kRecordDialogPlayback: + ConfMan.setActiveDomain(_domains[item]); + close(); + ConfMan.set("record_mode", "playback", ConfigManager::kTransientDomain); + ConfMan.set("record_file_name", recorderDialog.getFileName(), ConfigManager::kTransientDomain); + break; + case RecorderDialog::kRecordDialogRecord: + ConfMan.setActiveDomain(_domains[item]); + if (alert.runModal() == GUI::kMessageOK) { + loadGame(item); + } + close(); + g_eventRec.setAuthor(recorderDialog._author); + g_eventRec.setName(recorderDialog._name); + g_eventRec.setNotes(recorderDialog._notes); + ConfMan.set("record_mode", "record", ConfigManager::kTransientDomain); + break; + } +} +#endif + void LauncherDialog::loadGame(int item) { String gameId = ConfMan.get("gameid", _domains[item]); if (gameId.empty()) @@ -1039,7 +1085,7 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat editGame(item); break; case kLoadGameCmd: - loadGame(item); + loadGameButtonPressed(item); break; case kOptionsCmd: { GlobalOptionsDialog options; @@ -1109,20 +1155,28 @@ void LauncherDialog::updateButtons() { _loadButton->setEnabled(en); _loadButton->draw(); } + switchButtonsText(_addButton, "~A~dd Game...", "Mass Add..."); +#ifdef ENABLE_EVENTRECORDER + switchButtonsText(_loadButton, "~L~oad...", "Record..."); +#endif +} - // Update the label of the "Add" button depending on whether shift is pressed or not - int modifiers = g_system->getEventManager()->getModifierState(); - const bool massAdd = (modifiers & Common::KBD_SHIFT) != 0; +// Update the label of the button depending on whether shift is pressed or not +void LauncherDialog::switchButtonsText(ButtonWidget *button, const char *normalText, const char *shiftedText) { + const bool shiftPressed = checkModifier(Common::KBD_SHIFT); const bool lowRes = g_system->getOverlayWidth() <= 320; - const char *newAddButtonLabel = massAdd - ? (lowRes ? _c("Mass Add...", "lowres") : _("Mass Add...")) - : (lowRes ? _c("~A~dd Game...", "lowres") : _("~A~dd Game...")); + const char *newAddButtonLabel = shiftPressed + ? (lowRes ? _c(shiftedText, "lowres") : _(shiftedText)) + : (lowRes ? _c(normalText, "lowres") : _(normalText)); - if (_addButton->getLabel() != newAddButtonLabel) - _addButton->setLabel(newAddButtonLabel); + if (button->getLabel() != newAddButtonLabel) + button->setLabel(newAddButtonLabel); } + + + void LauncherDialog::reflowLayout() { #ifndef DISABLE_FANCY_THEMES if (g_gui.xmlEval()->getVar("Globals.ShowLauncherLogo") == 1 && g_gui.theme()->supportsImages()) { @@ -1186,4 +1240,9 @@ void LauncherDialog::reflowLayout() { Dialog::reflowLayout(); } +bool LauncherDialog::checkModifier(int checkedModifier) { + int modifiers = g_system->getEventManager()->getModifierState(); + return (modifiers & checkedModifier) != 0; +} + } // End of namespace GUI diff --git a/gui/launcher.h b/gui/launcher.h index fc0484350a..2ab47be98d 100644 --- a/gui/launcher.h +++ b/gui/launcher.h @@ -56,7 +56,7 @@ protected: ListWidget *_list; ButtonWidget *_addButton; Widget *_startButton; - Widget *_loadButton; + ButtonWidget *_loadButton; Widget *_editButton; Widget *_removeButton; #ifndef DISABLE_FANCY_THEMES @@ -80,6 +80,7 @@ protected: void updateListing(); void updateButtons(); + void switchButtonsText(ButtonWidget *button, const char *normalText, const char *shiftedText); void open(); void close(); @@ -100,6 +101,16 @@ protected: void editGame(int item); /** + * Facade for "Load..."/"Record..." buttons. + */ + void loadGameButtonPressed(int item); + + /** + * Handle "Record..." button. + */ + void recordGame(int item); + + /** * Handle "Load..." button. */ void loadGame(int item); @@ -111,6 +122,8 @@ protected: * @target name of target to select */ void selectTarget(const String &target); +private: + bool checkModifier(int modifier); }; } // End of namespace GUI diff --git a/gui/module.mk b/gui/module.mk index bda3c88cd5..338e43c6a4 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -7,6 +7,7 @@ MODULE_OBJS := \ debugger.o \ dialog.o \ error.o \ + EventRecorder.o \ gui-manager.o \ launcher.o \ massadd.o \ @@ -38,6 +39,13 @@ MODULE_OBJS += \ browser.o endif +ifdef ENABLE_EVENTRECORDER +MODULE_OBJS += \ + editrecorddialog.o \ + onscreendialog.o \ + recorderdialog.o +endif + ifdef USE_FLUIDSYNTH MODULE_OBJS += \ fluidsynth-dialog.o diff --git a/gui/onscreendialog.cpp b/gui/onscreendialog.cpp new file mode 100644 index 0000000000..03a6f26ec0 --- /dev/null +++ b/gui/onscreendialog.cpp @@ -0,0 +1,233 @@ +/* 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. + * + */ + +#include "common/system.h" + +#include "gui/gui-manager.h" + +#include "gui/EventRecorder.h" + +#include "common/events.h" +#include "common/rect.h" +#include "common/translation.h" + +#include "graphics/cursorman.h" + +#include "gui/editrecorddialog.h" +#include "gui/ThemeEval.h" + +#include "gui/onscreendialog.h" + +namespace GUI { + +bool OnScreenDialog::isVisible() const { + return true; +} + +enum { + kStopCmd = 'STOP', + kEditCmd = 'EDIT', + kSwitchModeCmd = 'MODE', + kFastModeCmd = 'FAST' +}; + +void OnScreenDialog::reflowLayout() { + GuiObject::reflowLayout(); +} + +void OnScreenDialog::releaseFocus() { +} + +OnScreenDialog::OnScreenDialog(bool isRecord) : Dialog("OnScreenDialog") { + _x = _y = 0; + +#ifndef DISABLE_FANCY_THEMES + if (g_gui.xmlEval()->getVar("Globals.OnScreenDialog.ShowPics") == 1 && g_gui.theme()->supportsImages()) { + GUI::PicButtonWidget *btn; + btn = new PicButtonWidget(this, "OnScreenDialog.StopButton", 0, kStopCmd, 0); + btn->useThemeTransparency(true); + + if (g_system->getOverlayWidth() > 320) + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageStopbtn)); + else + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageStopSmallbtn)); + + if (isRecord) { + btn = new PicButtonWidget(this, "OnScreenDialog.EditButton", 0, kEditCmd, 0); + btn->useThemeTransparency(true); + + if (g_system->getOverlayWidth() > 320) + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEditbtn)); + else + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEditSmallbtn)); + } else { + btn = new PicButtonWidget(this, "OnScreenDialog.SwitchModeButton", 0, kSwitchModeCmd, 0); + btn->useThemeTransparency(true); + if (g_system->getOverlayWidth() > 320) + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageSwitchModebtn)); + else + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageSwitchModeSmallbtn)); + + btn = new PicButtonWidget(this, "OnScreenDialog.FastReplayButton", 0, kFastModeCmd, 0); + btn->useThemeTransparency(true); + if (g_system->getOverlayWidth() > 320) + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageFastReplaybtn)); + else + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageFastReplaySmallbtn)); + } + } else +#endif + { + if (g_system->getOverlayWidth() > 320) + new ButtonWidget(this, "OnScreenDialog.StopButton", "[ ]", _("Stop"), kStopCmd); + else + new ButtonWidget(this, "OnScreenDialog.StopButton", "[]", _("Stop"), kStopCmd); + + if (isRecord) { + new ButtonWidget(this, "OnScreenDialog.EditButton", "E", _("Edit record description"), kEditCmd); + } else { + new ButtonWidget(this, "OnScreenDialog.SwitchModeButton", "G", _("Switch to Game"), kSwitchModeCmd); + + new ButtonWidget(this, "OnScreenDialog.FastReplayButton", ">>", _("Fast replay"), kFastModeCmd); + } + } + + + _text = new GUI::StaticTextWidget(this, "OnScreenDialog.TimeLabel", "00:00:00"); + _enableDrag = false; + _mouseOver = false; + _editDlgShown = false; + + _lastTime = 0; + _dlg = 0; +} + +void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + Common::Event eventRTL; + switch (cmd) { + case kStopCmd: + eventRTL.type = Common::EVENT_RTL; + g_system->getEventManager()->pushEvent(eventRTL); + close(); + break; + case kEditCmd: + _dlg = new EditRecordDialog(g_eventRec.getAuthor(), g_eventRec.getName(), g_eventRec.getNotes()); + CursorMan.lock(false); + g_eventRec.setRedraw(false); + g_system->showOverlay(); + _editDlgShown = true; + _dlg->runModal(); + _editDlgShown = false; + g_system->hideOverlay(); + g_eventRec.setRedraw(true); + CursorMan.lock(true); + g_eventRec.setAuthor(((EditRecordDialog *)_dlg)->getAuthor()); + g_eventRec.setName(((EditRecordDialog *)_dlg)->getName()); + g_eventRec.setNotes(((EditRecordDialog *)_dlg)->getNotes()); + delete _dlg; + break; + case kSwitchModeCmd: + if (g_eventRec.switchMode()) { + close(); + } + break; + case kFastModeCmd: + g_eventRec.switchFastMode(); + break; + } +} + +void OnScreenDialog::setReplayedTime(uint32 newTime) { + if (newTime - _lastTime > 1000) { + uint32 seconds = newTime / 1000; + _text->setLabel(Common::String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60)); + _lastTime = newTime; + } +} + +OnScreenDialog::~OnScreenDialog() { +} + +void OnScreenDialog::handleMouseMoved(int x, int y, int button) { + if (_enableDrag) { + _x = _x + x - _dragPoint.x; + _y = _y + y - _dragPoint.y; + } + Dialog::handleMouseMoved(x, y, button); + if (isMouseOver(x, y)) { + if (_mouseOver == false) { + g_gui.theme()->showCursor(); + CursorMan.lock(true); + } + _mouseOver = true; + } else { + if (_mouseOver == true) { + CursorMan.lock(false); + g_gui.theme()->hideCursor(); + } + _mouseOver = false; + } +} + +void OnScreenDialog::handleMouseDown(int x, int y, int button, int clickCount) { + if (isMouseOver(x, y)) { + _dragPoint.x = x; + _dragPoint.y = y; + _enableDrag = true; + } + Dialog::handleMouseDown(x, y, button, clickCount); +} + +void OnScreenDialog::handleMouseUp(int x, int y, int button, int clickCount) { + if (isMouseOver(x, y)) { + + } + _enableDrag = false; + Dialog::handleMouseUp(x, y, button, clickCount); +} + +bool OnScreenDialog::isMouseOver(int x, int y) { + return (x >= 0 && x < _w && y >= 0 && y < _h); +} + +bool OnScreenDialog::isMouseOver() { + return _mouseOver; +} + +void OnScreenDialog::close() { + CursorMan.lock(false); + Dialog::close(); +} + +Dialog *OnScreenDialog::getActiveDlg() { + if (_editDlgShown) { + return _dlg; + } else { + return this; + } +} + +bool OnScreenDialog::isEditDlgVisible() { + return _editDlgShown; +} + +} diff --git a/gui/onscreendialog.h b/gui/onscreendialog.h new file mode 100644 index 0000000000..2fae14cbc6 --- /dev/null +++ b/gui/onscreendialog.h @@ -0,0 +1,66 @@ +/* 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. + * + */ + +#ifndef GUI_ONSCREENDIALOG_H +#define GUI_ONSCREENDIALOG_H + +#include "gui/dialog.h" +#include "gui/widget.h" + +namespace GUI { + +class OnScreenDialog : public Dialog { +private: + uint32 _lastTime; + bool _enableDrag; + bool _mouseOver; + bool _editDlgShown; + Common::Point _dragPoint; + GUI::StaticTextWidget *_text; + Dialog *_dlg; + + bool isMouseOver(int x, int y); + +public: + OnScreenDialog(bool recordingMode); + ~OnScreenDialog(); + virtual void close(); + virtual bool isVisible() const; + virtual void reflowLayout(); + + void setReplayedTime(uint32 newTime); + + virtual void handleMouseMoved(int x, int y, int button); + virtual void handleMouseDown(int x, int y, int button, int clickCount); + virtual void handleMouseUp(int x, int y, int button, int clickCount); + void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); + + bool isMouseOver(); + bool isEditDlgVisible(); + Dialog *getActiveDlg(); +protected: + virtual void releaseFocus(); +}; + +} // End of namespace GUI + +#endif diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp new file mode 100644 index 0000000000..1a11dbac65 --- /dev/null +++ b/gui/recorderdialog.cpp @@ -0,0 +1,298 @@ +/* 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. + */ + +#include "common/algorithm.h" +#include "common/bufferedstream.h" +#include "common/savefile.h" +#include "common/system.h" +#include "graphics/colormasks.h" +#include "graphics/palette.h" +#include "graphics/scaler.h" +#include "graphics/thumbnail.h" +#include "common/translation.h" +#include "gui/widgets/list.h" +#include "gui/editrecorddialog.h" +#include "gui/EventRecorder.h" +#include "gui/message.h" +#include "gui/saveload.h" +#include "common/system.h" +#include "gui/ThemeEval.h" +#include "gui/gui-manager.h" +#include "recorderdialog.h" + +#define MAX_RECORDS_NAMES 0xFF + +namespace GUI { + +enum { + kRecordCmd = 'RCRD', + kPlaybackCmd = 'PBCK', + kDeleteCmd = 'DEL ', + kNextScreenshotCmd = 'NEXT', + kPrevScreenshotCmd = 'PREV', + kEditRecordCmd = 'EDIT' +}; + +RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(0), _currentScreenshot(0) { + _firstScreenshotUpdate = false; + _screenShotsCount = 0; + _currentScreenshotText = 0; + _authorText = 0; + _notesText = 0; + + _backgroundType = ThemeEngine::kDialogBackgroundSpecial; + + new StaticTextWidget(this, "SaveLoadChooser.Title", _("Recorder or Playback Gameplay")); + + _list = new GUI::ListWidget(this, "RecorderDialog.List"); + _list->setNumberingMode(GUI::kListNumberingOff); + + _deleteButton = new GUI::ButtonWidget(this, "RecorderDialog.Delete", _("Delete"), 0, kDeleteCmd); + new GUI::ButtonWidget(this, "RecorderDialog.Cancel", _("Cancel"), 0, kCloseCmd); + new GUI::ButtonWidget(this, "RecorderDialog.Record", _("Record"), 0, kRecordCmd); + _playbackButton = new GUI::ButtonWidget(this, "RecorderDialog.Playback", _("Playback"), 0, kPlaybackCmd); + + _editButton = new GUI::ButtonWidget(this, "RecorderDialog.Edit", _("Edit"), 0, kEditRecordCmd); + + _editButton->setEnabled(false); + _deleteButton->setEnabled(false); + _playbackButton->setEnabled(false); + + _gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10); + _container = new GUI::ContainerWidget(this, 0, 0, 10, 10); + if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) { + new GUI::ButtonWidget(this,"RecorderDialog.NextScreenShotButton", "<", 0, kPrevScreenshotCmd); + new GUI::ButtonWidget(this, "RecorderDialog.PreviousScreenShotButton", ">", 0, kNextScreenshotCmd); + _currentScreenshotText = new StaticTextWidget(this, "RecorderDialog.currentScreenshot", "0/0"); + _authorText = new StaticTextWidget(this, "RecorderDialog.Author", _("Author: ")); + _notesText = new StaticTextWidget(this, "RecorderDialog.Notes", _("Notes: ")); + } + if (_gfxWidget) + _gfxWidget->setGfx(0); +} + + +void RecorderDialog::reflowLayout() { + if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) { + int16 x, y; + uint16 w, h; + + if (!g_gui.xmlEval()->getWidgetData("RecorderDialog.Thumbnail", x, y, w, h)) { + error("Error when loading position data for Recorder Thumbnails"); + } + + int thumbW = kThumbnailWidth; + int thumbH = kThumbnailHeight2; + int thumbX = x + (w >> 1) - (thumbW >> 1); + int thumbY = y + kLineHeight; + + _container->resize(x, y, w, h); + _gfxWidget->resize(thumbX, thumbY, thumbW, thumbH); + + _container->setVisible(true); + _gfxWidget->setVisible(true); + updateSelection(false); + } else { + _container->setVisible(false); + _gfxWidget->setVisible(false); + } + Dialog::reflowLayout(); +} + + + +void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + switch(cmd) { + case kEditRecordCmd: { + if (_list->getSelected() >= 0) { + EditRecordDialog editDlg(_fileHeaders[_list->getSelected()].author, _fileHeaders[_list->getSelected()].name, _fileHeaders[_list->getSelected()].notes); + if (editDlg.runModal() != kOKCmd) { + return; + } + _playbackFile.openRead(_fileHeaders[_list->getSelected()].fileName); + _playbackFile.getHeader().author = editDlg.getAuthor(); + _playbackFile.getHeader().name = editDlg.getName(); + _playbackFile.getHeader().notes = editDlg.getNotes(); + _playbackFile.updateHeader(); + _fileHeaders[_list->getSelected()] = _playbackFile.getHeader(); + int oldselection = _list->getSelected(); + updateList(); + _list->setSelected(oldselection); + updateSelection(true); + _playbackFile.close(); + } + } + break; + case kNextScreenshotCmd: + ++_currentScreenshot; + updateScreenshot(); + break; + case kPrevScreenshotCmd: + --_currentScreenshot; + updateScreenshot(); + break; + case kDeleteCmd: + if (_list->getSelected() >= 0) { + MessageDialog alert(_("Do you really want to delete this record?"), + _("Delete"), _("Cancel")); + if (alert.runModal() == GUI::kMessageOK) { + _playbackFile.close(); + g_eventRec.deleteRecord(_fileHeaders[_list->getSelected()].fileName); + _list->setSelected(-1); + updateList(); + } + } + break; + case GUI::kListSelectionChangedCmd: + updateSelection(true); + break; + case kRecordCmd: { + TimeDate t; + Common::String gameId = ConfMan.get("gameid", _target); + const EnginePlugin *plugin = 0; + GameDescriptor desc = EngineMan.findGame(gameId, &plugin); + g_system->getTimeAndDate(t); + EditRecordDialog editDlg("Unknown Author", Common::String::format("%.2d.%.2d.%.4d ", t.tm_mday, t.tm_mon, 1900 + t.tm_year) + desc.description(), ""); + if (editDlg.runModal() != kOKCmd) { + return; + } + _author = editDlg.getAuthor(); + _name = editDlg.getName(); + _notes = editDlg.getNotes(); + _filename = g_eventRec.generateRecordFileName(_target); + setResult(kRecordDialogRecord); + close(); + } + break; + case kPlaybackCmd: + if (_list->getSelected() >= 0) { + _filename = _fileHeaders[_list->getSelected()].fileName; + setResult(kRecordDialogPlayback); + close(); + } + break; + case kCloseCmd: + setResult(kRecordDialogClose); + // Fall through + default: + Dialog::handleCommand(sender, cmd, data); + } +} + +void RecorderDialog::updateList() { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::String pattern(_target+".r??"); + Common::StringArray files = saveFileMan->listSavefiles(pattern); + Common::PlaybackFile file; + Common::StringArray namesList; + _fileHeaders.clear(); + for (Common::StringArray::iterator i = files.begin(); i != files.end(); ++i) { + if (file.openRead(*i)) { + namesList.push_back(file.getHeader().name); + _fileHeaders.push_back(file.getHeader()); + } + file.close(); + } + _list->setList(namesList); + _list->draw(); +} + +int RecorderDialog::runModal(Common::String &target) { + _target = target; + updateList(); + return Dialog::runModal(); +} + +RecorderDialog::~RecorderDialog() { +} + +void RecorderDialog::updateSelection(bool redraw) { + if (_list->getSelected() >= 0) { + _editButton->setEnabled(true); + _deleteButton->setEnabled(true); + _playbackButton->setEnabled(true); + } + + if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") != 1) + return; + + _gfxWidget->setGfx(-1, -1, 0, 0, 0); + _screenShotsCount = 0; + _currentScreenshot = 0; + updateScreenShotsText(); + if (_list->getSelected() >= 0) { + _authorText->setLabel(_("Author: ") + _fileHeaders[_list->getSelected()].author); + _notesText->setLabel(_("Notes: ") + _fileHeaders[_list->getSelected()].notes); + + _firstScreenshotUpdate = true; + updateScreenshot(); + if ((_screenShotsCount) > 0) { + _currentScreenshot = 1; + } + updateScreenshot(); + } else { + _authorText->setLabel(_("Author: ")); + _notesText->setLabel(_("Notes: ")); + _screenShotsCount = -1; + _currentScreenshot = 0; + _gfxWidget->setGfx(-1, -1, 0, 0, 0); + _gfxWidget->draw(); + updateScreenShotsText(); + } +} + +void RecorderDialog::updateScreenshot() { + if (_list->getSelected() == -1) { + return; + } + if (_currentScreenshot < 1) { + _currentScreenshot = _screenShotsCount; + } + if (_currentScreenshot > _screenShotsCount) { + _currentScreenshot = 1; + } + if (_firstScreenshotUpdate) { + _playbackFile.openRead(_fileHeaders[_list->getSelected()].fileName); + _screenShotsCount = _playbackFile.getScreensCount(); + _firstScreenshotUpdate = false; + } + Graphics::Surface *srcsf = _playbackFile.getScreenShot(_currentScreenshot); + if (srcsf != NULL) { + Graphics::Surface *destsf = Graphics::scale(*srcsf, _gfxWidget->getWidth(), _gfxWidget->getHeight()); + _gfxWidget->setGfx(destsf); + updateScreenShotsText(); + delete destsf; + delete srcsf; + } else { + _gfxWidget->setGfx(-1, -1, 0, 0, 0); + } + _gfxWidget->draw(); +} + +void RecorderDialog::updateScreenShotsText() { + if (_screenShotsCount == -1) { + _currentScreenshotText->setLabel(Common::String::format("%d / ?", _currentScreenshot)); + } else { + _currentScreenshotText->setLabel(Common::String::format("%d / %d", _currentScreenshot, _screenShotsCount)); + } +} + +} // End of namespace GUI diff --git a/gui/recorderdialog.h b/gui/recorderdialog.h new file mode 100644 index 0000000000..eb690a4f38 --- /dev/null +++ b/gui/recorderdialog.h @@ -0,0 +1,81 @@ +/* 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. + */ + +#ifndef GUI_RECORDER_DIALOG_H +#define GUI_RECORDER_DIALOG_H +#include "common/stream.h" +#include "common/recorderfile.h" +#include "gui/dialog.h" +namespace GUI { + +class ListWidget; +class GraphicsWidget; +class ButtonWidget; +class CommandSender; +class ContainerWidget; +class StaticTextWidget; + +class RecorderDialog : public GUI::Dialog { +private: + bool _firstScreenshotUpdate; + Common::PlaybackFile _playbackFile; + Common::String _target; + Common::String _filename; + int _currentScreenshot; + int _screenShotsCount; + Common::Array<Common::PlaybackFile::PlaybackFileHeader> _fileHeaders; + GUI::ListWidget *_list; + GUI::ContainerWidget *_container; + GUI::GraphicsWidget *_gfxWidget; + GUI::StaticTextWidget *_currentScreenshotText; + GUI::StaticTextWidget *_authorText; + GUI::StaticTextWidget *_notesText; + GUI::ButtonWidget *_editButton; + GUI::ButtonWidget *_deleteButton; + GUI::ButtonWidget *_playbackButton; + + void updateList(); + void updateScreenShotsText(); + void updateSelection(bool redraw); + void updateScreenshot(); +public: + Common::String _author; + Common::String _name; + Common::String _notes; + enum DialogResult { + kRecordDialogClose, + kRecordDialogRecord, + kRecordDialogPlayback + }; + RecorderDialog(); + ~RecorderDialog(); + + virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); + virtual void reflowLayout(); + + int runModal(Common::String &target); + const Common::String getFileName() {return _filename;} +}; + +} // End of namespace GUI + + +#endif diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index c7dd62b6c6..585117fba4 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -286,6 +286,7 @@ void SaveLoadChooserSimple::handleCommand(CommandSender *sender, uint32 cmd, uin break; case kCloseCmd: setResult(-1); + // Fall through default: SaveLoadChooserDialog::handleCommand(sender, cmd, data); } @@ -595,6 +596,7 @@ void SaveLoadChooserGrid::handleCommand(CommandSender *sender, uint32 cmd, uint3 case kCloseCmd: setResult(-1); + // Fall through default: SaveLoadChooserDialog::handleCommand(sender, cmd, data); } diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 6d8e6baac7..1b6ae3ec27 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -610,50 +610,54 @@ "/> " "</drawdata> " "</render_info> " -"<layout_info resolution='y<400'> " +"<layout_info resolution='y>399'> " "<globals> " -"<def var='Line.Height' value='12' /> " -"<def var='Font.Height' value='10' /> " -"<def var='About.OuterBorder' value='10'/> " -"<def var='Layout.Spacing' value='8'/> " +"<def var='Line.Height' value='16' /> " +"<def var='Font.Height' value='16' /> " +"<def var='About.OuterBorder' value='80'/> " +"<def var='Layout.Spacing' value='8' /> " "<def var='ShowLauncherLogo' value='0'/> " "<def var='ShowGlobalMenuLogo' value='0'/> " "<def var='ShowSearchPic' value='0'/> " "<def var='ShowChooserPics' value='0'/> " -"<def var='ShowChooserPageDisplay' value='0'/> " -"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> " -"<def var='KeyMapper.Spacing' value='5'/> " -"<def var='KeyMapper.LabelWidth' value='80'/> " -"<def var='KeyMapper.ButtonWidth' value='60'/> " -"<def var='Tooltip.MaxWidth' value='70'/> " -"<def var='Tooltip.XDelta' value='8'/> " -"<def var='Tooltip.YDelta' value='8'/> " -"<def var='Predictive.Button.Width' value='45' /> " -"<def var='Predictive.Button.Height' value='15' /> " -"<widget name='Button' " -"size='72,16' " -"/> " -"<widget name='Slider' " -"size='85,12' " -"/> " +"<def var='ShowChooserPageDisplay' value='1'/> " +"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> " +"<def var='RecorderDialog.ExtInfo.Visible' value='1'/> " +"<def var='OnScreenDialog.ShowPics' value='0'/> " +"<def var='KeyMapper.Spacing' value='10'/> " +"<def var='KeyMapper.LabelWidth' value='100'/> " +"<def var='KeyMapper.ButtonWidth' value='80'/> " +"<def var='Tooltip.MaxWidth' value='200'/> " +"<def var='Tooltip.XDelta' value='16'/> " +"<def var='Tooltip.YDelta' value='16'/> " +"<def var='Predictive.Button.Width' value='60' /> " "<widget name='OptionsLabel' " "size='110,Globals.Line.Height' " "textalign='right' " "/> " "<widget name='SmallLabel' " -"size='18,Globals.Line.Height' " +"size='24,Globals.Line.Height' " +"/> " +"<widget name='ShortOptionsLabel' " +"size='60,Globals.Line.Height' " +"/> " +"<widget name='Button' " +"size='108,24' " +"/> " +"<widget name='Slider' " +"size='128,18' " "/> " "<widget name='PopUp' " -"size='-1,15' " +"size='-1,19' " "/> " "<widget name='Checkbox' " -"size='-1,Globals.Line.Height' " +"size='-1,14' " "/> " "<widget name='Radiobutton' " "size='-1,Globals.Line.Height' " "/> " "<widget name='ListWidget' " -"padding='5,0,0,0' " +"padding='5,0,8,0' " "/> " "<widget name='PopUpWidget' " "padding='7,5,0,0' " @@ -665,29 +669,35 @@ "padding='7,5,5,5' " "/> " "<widget name='Scrollbar' " -"size='9,0' " +"size='15,0' " "/> " "<widget name='TabWidget.Tab' " -"size='45,16' " -"padding='0,0,2,0' " +"size='75,27' " +"padding='0,0,8,0' " "/> " "<widget name='TabWidget.Body' " -"padding='0,0,0,-8' " +"padding='0,0,0,0' " "/> " "<widget name='TabWidget.NavButton' " -"size='32,18' " -"padding='0,0,1,0' " +"size='15,18' " +"padding='0,3,4,0' " +"/> " +"<widget name='EditRecordLabel' " +"size='60,25' " +"/> " +"<widget name='EditRecord' " +"size='240,25' " "/> " "</globals> " "<dialog name='Launcher' overlays='screen'> " -"<layout type='vertical' center='true' padding='6,6,2,2'> " +"<layout type='vertical' center='true' padding='16,16,8,8'> " "<widget name='Version' " "height='Globals.Line.Height' " "textalign='center' " "/> " -"<layout type='horizontal' spacing='5' padding='0,0,0,0'> " +"<layout type='horizontal' spacing='5' padding='10,0,0,0'> " "<widget name='SearchDesc' " -"width='50' " +"width='60' " "height='Globals.Line.Height' " "textalign='right' " "/> " @@ -702,38 +712,39 @@ "<space /> " "</layout> " "<widget name='GameList'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='LoadGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='AddGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='EditGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='RemoveGameButton' " -"height='12' " +"height='20' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<space size='4'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='QuitButton' " -"height='12' " +"height='20' " "/> " "<widget name='AboutButton' " -"height='12' " +"height='20' " "/> " "<widget name='OptionsButton' " -"height='12' " +"height='20' " "/> " "<widget name='StartButton' " -"height='12' " +"height='20' " "/> " "</layout> " "</layout> " "</dialog> " -"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,0,4'> " +"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<layout type='vertical' padding='8,8,8,8'> " "<widget name='Headline' " "height='Globals.Line.Height' " "/> " @@ -741,7 +752,7 @@ "height='Globals.Line.Height' " "/> " "<widget name='List'/> " -"<layout type='vertical' padding='0,0,8,0'> " +"<layout type='vertical' padding='0,0,16,0'> " "<widget name='Hidden' " "type='Checkbox' " "/> " @@ -760,10 +771,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> " +"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " "<layout type='vertical' padding='0,0,0,0'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='16,16,16,16'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -776,7 +787,7 @@ "</dialog> " "<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='grModePopupDesc' " "type='OptionsLabel' " "/> " @@ -784,7 +795,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='grRenderPopupDesc' " "type='OptionsLabel' " "/> " @@ -802,7 +813,7 @@ "</dialog> " "<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auMidiPopupDesc' " "type='OptionsLabel' " "/> " @@ -810,7 +821,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -818,7 +829,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auSampleRatePopupDesc' " "type='OptionsLabel' " "/> " @@ -826,7 +837,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " @@ -840,7 +851,7 @@ "type='Radiobutton' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -854,8 +865,9 @@ "</layout> " "</dialog> " "<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -866,7 +878,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -877,7 +889,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -888,8 +900,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " -"<space size='110' /> " +"</layout> " +"<layout type='vertical' padding='24,0,24,0' center='true'> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " "/> " @@ -897,8 +909,8 @@ "</layout> " "</dialog> " "<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='6'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auPrefGmPopupDesc' " "type='OptionsLabel' " "/> " @@ -906,7 +918,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='mcFontButton' " "type='Button' " "/> " @@ -921,7 +933,7 @@ "<widget name='mcMixedCheckbox' " "type='Checkbox' " "/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='mcMidiGainText' " "type='OptionsLabel' " "/> " @@ -934,14 +946,14 @@ "/> " "</layout> " "<widget name='mcFluidSynthSettings' " -"width='150' " +"width='200' " "height='Globals.Button.Height' " "/> " "</layout> " "</dialog> " "<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auPrefMt32PopupDesc' " "type='OptionsLabel' " "/> " @@ -959,7 +971,7 @@ "</dialog> " "<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='SaveButton' " "type='Button' " "/> " @@ -971,7 +983,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -983,7 +995,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ExtraButton' " "type='Button' " "/> " @@ -1007,7 +1019,7 @@ "</dialog> " "<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -1015,31 +1027,25 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='RendererPopupDesc' " -"width='80' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='RendererPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='AutosavePeriodPopupDesc' " -"width='80' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='AutosavePeriodPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='GuiLanguagePopupDesc' " -"width='80' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='GuiLanguagePopup' " "type='PopUp' " @@ -1074,10 +1080,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> " +"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " "<layout type='vertical' padding='0,0,0,0' spacing='16'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='16,16,16,4'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -1089,7 +1095,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1097,7 +1103,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1105,7 +1111,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1113,7 +1119,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1121,7 +1127,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1129,43 +1135,34 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='vertical' padding='16,16,16,16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Id' " -"width='35' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='Domain' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Name' " -"width='35' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='Desc' " "type='PopUp' " "/> " "</layout> " -"<space size='8'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='LangPopupDesc' " -"width='60' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='LangPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PlatformPopupDesc' " -"width='60' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='PlatformPopup' " "type='PopUp' " @@ -1174,8 +1171,8 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='vertical' padding='16,16,16,16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Savepath' " "type='Button' " "/> " @@ -1187,7 +1184,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Extrapath' " "type='Button' " "/> " @@ -1199,7 +1196,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Gamepath' " "type='Button' " "/> " @@ -1210,7 +1207,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " +"<layout type='vertical' padding='16,16,16,16'> " "<widget name='customOption1Checkbox' " "type='Checkbox' " "/> " @@ -1235,55 +1232,57 @@ "</layout> " "</dialog> " "<dialog name='GlobalMenu' overlays='screen_center'> " -"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' center='true'> " "<widget name='Title' " -"width='160' " -"height='4' " +"width='210' " +"height='Globals.Line.Height' " "/> " "<widget name='Version' " -"width='160' " -"height='4' " +"width='210' " +"height='Globals.Line.Height' " "/> " -"<space size='1'/> " +"<widget name='Resume' " +"width='150' " +"height='Globals.Button.Height' " +"/> " +"<space size='10'/> " "<widget name='Load' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='Save' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " -"<space size='1'/> " +"<space size='10'/> " "<widget name='Options' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='Help' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='About' " -"width='120' " -"height='12' " -"/> " -"<space size='1'/> " -"<widget name='Resume' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " +"<space size='10'/> " "<widget name='RTL' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='Quit' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "</layout> " "</dialog> " "<dialog name='GlobalConfig' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='vertical' padding='0,0,0,0' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -1294,7 +1293,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -1305,7 +1304,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -1316,34 +1315,33 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " -"<space size='110' /> " +"</layout> " +"<layout type='vertical' padding='24,24,24,24' center='true'> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " -"width='80' " +"width='80' " "/> " "</layout> " -"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> " +"</layout> " +"<space size='8' /> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subToggleSpeechOnly' " "type='Radiobutton' " -"width='90' " +"width='100' " "/> " "<widget name='subToggleSubOnly' " "type='Radiobutton' " -"width='90' " +"width='100' " "/> " "<widget name='subToggleSubBoth' " "type='Radiobutton' " -"width='90' " +"width='100' " "/> " "</layout> " -"</layout> " -"<space size='2' /> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -1354,8 +1352,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<space size='16'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='4'> " +"<space size='60'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='Keys' " "type='Button' " "/> " @@ -1372,7 +1370,7 @@ "<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'> " "<layout type='vertical' padding='0,0,0,0'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='16,16,16,16'> " "<space/> " "<widget name='ResetSettings' " "type='Button' " @@ -1387,7 +1385,7 @@ "</layout> " "</dialog> " "<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1450,7 +1448,7 @@ "</layout> " "</dialog> " "<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1505,7 +1503,7 @@ "</layout> " "</dialog> " "<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='InterpolationText' " "type='OptionsLabel' " @@ -1517,10 +1515,25 @@ "</layout> " "</dialog> " "<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8' center='true'> " -"<widget name='Title' height='Globals.Line.Height'/> " +"<layout type='vertical' padding='8,8,8,32' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " +"<widget name='Title' " +"height='Globals.Line.Height' " +"/> " +"<space/> " +"<widget name='PageDisplay' " +"width='200' " +"height='Globals.Line.Height' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,16' spacing='16'> " "<widget name='List' /> " -"<layout type='horizontal' padding='0,0,16,0'> " +"<widget name='Thumbnail' " +"width='180' " +"height='200' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='ListSwitch' " "height='Globals.Line.Height' " "width='Globals.Line.Height' " @@ -1533,7 +1546,7 @@ "<widget name='Delete' " "type='Button' " "/> " -"<space size='16'/> " +"<space size='32'/> " "<widget name='Cancel' " "type='Button' " "/> " @@ -1546,7 +1559,7 @@ "<dialog name='SavenameDialog' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " "<widget name='DescriptionText' " -"width='180' " +"width='320' " "height='Globals.Line.Height' " "/> " "<widget name='Description' " @@ -1556,22 +1569,139 @@ "<widget name='Cancel' " "type='Button' " "/> " +"<space size='96'/> " "<widget name='Ok' " "type='Button' " "/> " "</layout> " "</layout> " "</dialog> " -"<dialog name='ScummHelp' overlays='screen'> " -"<layout type='vertical' padding='8,8,8,8'> " +"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'> " +"<layout type='vertical' padding='8,8,8,32' center='true'> " "<widget name='Title' " +"height='Globals.Line.Height' " +"/> " +"<layout type='horizontal' padding='0,0,0,16' spacing='16'> " +"<widget name='List' /> " +"<layout type='vertical' padding='0,0,0,0'> " +"<widget name='Thumbnail' " "width='180' " +"height='170' " +"/> " +"<layout type='horizontal' padding='0,0,0,0'> " +"<widget name='NextScreenShotButton' " +"width='25' " +"height='25' " +"/> " +"<widget name='currentScreenshot' " +"width='125' " +"height='25' " +"textalign='center' " +"/> " +"<widget name='PreviousScreenShotButton' " +"width='25' " +"height='25' " +"/> " +"</layout> " +"<widget name='Author' height='Globals.Line.Height' /> " +"<widget name='Notes' height='Globals.Line.Height' /> " +"</layout> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0'> " +"<widget name='Delete' " +"type='Button' " +"/> " +"<space size='16'/> " +"<widget name='Cancel' " +"type='Button' " +"/> " +"<space size='16'/> " +"<widget name='Edit' " +"type='Button' " +"/> " +"<widget name='Record' " +"type='Button' " +"/> " +"<widget name='Playback' " +"type='Button' " +"/> " +"</layout> " +"</layout> " +"</dialog> " +"<dialog name='OnScreenDialog' overlays='screen_center'> " +"<layout type='horizontal' spacing='5' padding='5,3,5,3' center='true'> " +"<widget name='StopButton' " +"width='32' " +"height='32' " +"/> " +"<widget name='EditButton' " +"width='32' " +"height='32' " +"/> " +"<widget name='SwitchModeButton' " +"width='32' " +"height='32' " +"/> " +"<widget name='FastReplayButton' " +"width='32' " +"height='32' " +"/> " +"<widget name='TimeLabel' " +"width='50' " +"height='30' " +"/> " +"</layout> " +"</dialog> " +"<dialog name='EditRecordDialog' overlays='screen_center'> " +"<layout type='vertical' padding='8,8,8,8' center='true'> " +"<widget name='Title' " +"width='320' " +"height='Globals.Line.Height' " +"/> " +"<layout type='horizontal' spacing='5' padding='0,0,0,10'> " +"<widget name='AuthorLabel' " +"type='EditRecordLabel' " +"/> " +"<widget name='AuthorEdit' " +"type='EditRecord' " +"/> " +"</layout> " +"<layout type='horizontal' spacing='5' padding='0,0,0,10'> " +"<widget name='NameLabel' " +"type='EditRecordLabel' " +"/> " +"<widget name='NameEdit' " +"type='EditRecord' " +"/> " +"</layout> " +"<layout type='horizontal' spacing='5' padding='0,0,0,10'> " +"<widget name='NotesLabel' " +"type='EditRecordLabel' " +"/> " +"<widget name='NotesEdit' " +"type='EditRecord' " +"/> " +"</layout> " +"<layout type='horizontal' spacing='5' padding='0,0,0,10'> " +"<widget name='Cancel' " +"type='Button' " +"/> " +"<widget name='OK' " +"type='Button' " +"/> " +"</layout> " +"</layout> " +"</dialog> " +"<dialog name='ScummHelp' overlays='screen_center'> " +"<layout type='vertical' padding='8,8,8,8' center='true'> " +"<widget name='Title' " +"width='320' " "height='Globals.Line.Height' " "/> " "<widget name='HelpText' " -"height='140' " +"height='200' " "/> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,16,0'> " "<widget name='Prev' " "type='Button' " "/> " @@ -1588,7 +1718,7 @@ "<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8' center='true'> " "<widget name='Description1' " -"width='280' " +"width='320' " "height='Globals.Line.Height' " "/> " "<widget name='Description2' " @@ -1606,20 +1736,20 @@ "</layout> " "</dialog> " "<dialog name='MassAdd' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='4,4,16,4' center='true'> " +"<layout type='vertical' padding='8,8,32,8' center='true'> " "<widget name='DirProgressText' " -"width='280' " +"width='480' " "height='Globals.Line.Height' " "/> " "<widget name='GameProgressText' " -"width='280' " +"width='480' " "height='Globals.Line.Height' " "/> " "<widget name='GameList' " -"width='280' " -"height='100' " +"width='480' " +"height='250' " "/> " -"<layout type='horizontal' padding='4,4,4,4'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<widget name='Ok' " "type='Button' " "/> " @@ -1630,20 +1760,20 @@ "</layout> " "</dialog> " "<dialog name='KeyMapper' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PopupDesc' " "type='OptionsLabel' " "/> " "<widget name='Popup' " "type='PopUp' " -"width='150' " +"width='400' " "height='Globals.Line.Height' " "/> " "</layout> " "<widget name='KeymapArea' " -"width='300' " -"height='120' " +"width='600' " +"height='280' " "/> " "<widget name='Close' " "type='Button' " @@ -1651,142 +1781,144 @@ "</layout> " "</dialog> " "<dialog name='Predictive' overlays='screen_center'> " -"<layout type='vertical' padding='1,1,1,1' center='true'> " +"<layout type='vertical' padding='5,5,5,5' center='true'> " "<widget name='Headline' " "height='Globals.Line.Height' " -"width='150' " +"width='210' " "textalign='center' " "/> " -"<layout type='horizontal' padding='3,3,3,3'> " +"<layout type='horizontal' padding='5,5,5,5'> " "<widget name='Word' " -"width='120' " +"width='190' " "height='Globals.Button.Height' " "/> " "<widget name='Delete' " "width='20' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "</layout> " +"<space size='5' /> " "<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Button1' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='Button2' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='Button3' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "</layout> " "<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Button4' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='Button5' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='Button6' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "</layout> " "<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Button7' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='Button8' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='Button9' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='3,3,3,0'> " +"<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Pre' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='Button0' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='Next' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "</layout> " -"<space size='3' /> " -"<layout type='horizontal' padding='3,3,0,3'> " +"<space size='5' /> " +"<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Add' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " +"<space size='22'/> " "<widget name='Cancel' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "<widget name='OK' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Predictive.Button.Height' " +"height='Globals.Button.Height' " "/> " "</layout> " "</layout> " "</dialog> " "</layout_info> " -"<layout_info resolution='y>399'> " +"<layout_info resolution='y<400'> " "<globals> " -"<def var='Line.Height' value='16' /> " -"<def var='Font.Height' value='16' /> " -"<def var='About.OuterBorder' value='80'/> " -"<def var='Layout.Spacing' value='8' /> " +"<def var='Line.Height' value='12' /> " +"<def var='Font.Height' value='10' /> " +"<def var='About.OuterBorder' value='10'/> " +"<def var='Layout.Spacing' value='8'/> " "<def var='ShowLauncherLogo' value='0'/> " "<def var='ShowGlobalMenuLogo' value='0'/> " "<def var='ShowSearchPic' value='0'/> " "<def var='ShowChooserPics' value='0'/> " -"<def var='ShowChooserPageDisplay' value='1'/> " -"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> " -"<def var='KeyMapper.Spacing' value='10'/> " -"<def var='KeyMapper.LabelWidth' value='100'/> " -"<def var='KeyMapper.ButtonWidth' value='80'/> " -"<def var='Tooltip.MaxWidth' value='200'/> " -"<def var='Tooltip.XDelta' value='16'/> " -"<def var='Tooltip.YDelta' value='16'/> " -"<def var='Predictive.Button.Width' value='60' /> " +"<def var='ShowChooserPageDisplay' value='0'/> " +"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> " +"<def var='RecorderDialog.ExtInfo.Visible' value='0'/> " +"<def var='OnScreenDialog.ShowPics' value='0'/> " +"<def var='KeyMapper.Spacing' value='5'/> " +"<def var='KeyMapper.LabelWidth' value='80'/> " +"<def var='KeyMapper.ButtonWidth' value='60'/> " +"<def var='Tooltip.MaxWidth' value='70'/> " +"<def var='Tooltip.XDelta' value='8'/> " +"<def var='Tooltip.YDelta' value='8'/> " +"<def var='Predictive.Button.Width' value='45' /> " +"<def var='Predictive.Button.Height' value='15' /> " +"<widget name='Button' " +"size='72,16' " +"/> " +"<widget name='Slider' " +"size='85,12' " +"/> " "<widget name='OptionsLabel' " "size='110,Globals.Line.Height' " "textalign='right' " "/> " "<widget name='SmallLabel' " -"size='24,Globals.Line.Height' " -"/> " -"<widget name='ShortOptionsLabel' " -"size='60,Globals.Line.Height' " -"/> " -"<widget name='Button' " -"size='108,24' " -"/> " -"<widget name='Slider' " -"size='128,18' " +"size='18,Globals.Line.Height' " "/> " "<widget name='PopUp' " -"size='-1,19' " +"size='-1,15' " "/> " "<widget name='Checkbox' " -"size='-1,14' " +"size='-1,Globals.Line.Height' " "/> " "<widget name='Radiobutton' " "size='-1,Globals.Line.Height' " "/> " "<widget name='ListWidget' " -"padding='5,0,8,0' " +"padding='5,0,0,0' " "/> " "<widget name='PopUpWidget' " "padding='7,5,0,0' " @@ -1798,29 +1930,35 @@ "padding='7,5,5,5' " "/> " "<widget name='Scrollbar' " -"size='15,0' " +"size='9,0' " "/> " "<widget name='TabWidget.Tab' " -"size='75,27' " -"padding='0,0,8,0' " +"size='45,16' " +"padding='0,0,2,0' " "/> " "<widget name='TabWidget.Body' " -"padding='0,0,0,0' " +"padding='0,0,0,-8' " "/> " "<widget name='TabWidget.NavButton' " -"size='15,18' " -"padding='0,3,4,0' " +"size='32,18' " +"padding='0,0,1,0' " +"/> " +"<widget name='EditRecordLabel' " +"size='60,Globals.Line.Height' " +"/> " +"<widget name='EditRecord' " +"size='120,15' " "/> " "</globals> " "<dialog name='Launcher' overlays='screen'> " -"<layout type='vertical' center='true' padding='16,16,8,8'> " +"<layout type='vertical' center='true' padding='6,6,2,2'> " "<widget name='Version' " "height='Globals.Line.Height' " "textalign='center' " "/> " -"<layout type='horizontal' spacing='5' padding='10,0,0,0'> " +"<layout type='horizontal' spacing='5' padding='0,0,0,0'> " "<widget name='SearchDesc' " -"width='60' " +"width='50' " "height='Globals.Line.Height' " "textalign='right' " "/> " @@ -1835,39 +1973,38 @@ "<space /> " "</layout> " "<widget name='GameList'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='LoadGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='AddGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='EditGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='RemoveGameButton' " -"height='20' " +"height='12' " "/> " "</layout> " -"<space size='4'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='QuitButton' " -"height='20' " +"height='12' " "/> " "<widget name='AboutButton' " -"height='20' " +"height='12' " "/> " "<widget name='OptionsButton' " -"height='20' " +"height='12' " "/> " "<widget name='StartButton' " -"height='20' " +"height='12' " "/> " "</layout> " "</layout> " "</dialog> " -"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " +"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> " +"<layout type='vertical' padding='8,8,0,4'> " "<widget name='Headline' " "height='Globals.Line.Height' " "/> " @@ -1875,7 +2012,7 @@ "height='Globals.Line.Height' " "/> " "<widget name='List'/> " -"<layout type='vertical' padding='0,0,16,0'> " +"<layout type='vertical' padding='0,0,8,0'> " "<widget name='Hidden' " "type='Checkbox' " "/> " @@ -1894,10 +2031,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> " "<layout type='vertical' padding='0,0,0,0'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='16,16,16,16'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -1910,7 +2047,7 @@ "</dialog> " "<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='grModePopupDesc' " "type='OptionsLabel' " "/> " @@ -1918,7 +2055,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='grRenderPopupDesc' " "type='OptionsLabel' " "/> " @@ -1936,7 +2073,7 @@ "</dialog> " "<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auMidiPopupDesc' " "type='OptionsLabel' " "/> " @@ -1944,7 +2081,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -1952,7 +2089,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auSampleRatePopupDesc' " "type='OptionsLabel' " "/> " @@ -1960,7 +2097,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " @@ -1974,7 +2111,7 @@ "type='Radiobutton' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -1988,9 +2125,8 @@ "</layout> " "</dialog> " "<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='horizontal' padding='16,16,16,16' spacing='8'> " -"<layout type='vertical' padding='0,0,0,0' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -2001,7 +2137,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -2012,7 +2148,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -2023,8 +2159,8 @@ "type='SmallLabel' " "/> " "</layout> " -"</layout> " -"<layout type='vertical' padding='24,0,24,0' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<space size='110' /> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " "/> " @@ -2032,8 +2168,8 @@ "</layout> " "</dialog> " "<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='vertical' padding='16,16,16,16' spacing='6'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auPrefGmPopupDesc' " "type='OptionsLabel' " "/> " @@ -2041,7 +2177,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='mcFontButton' " "type='Button' " "/> " @@ -2056,7 +2192,7 @@ "<widget name='mcMixedCheckbox' " "type='Checkbox' " "/> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='mcMidiGainText' " "type='OptionsLabel' " "/> " @@ -2069,14 +2205,14 @@ "/> " "</layout> " "<widget name='mcFluidSynthSettings' " -"width='200' " +"width='150' " "height='Globals.Button.Height' " "/> " "</layout> " "</dialog> " "<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auPrefMt32PopupDesc' " "type='OptionsLabel' " "/> " @@ -2094,7 +2230,7 @@ "</dialog> " "<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='SaveButton' " "type='Button' " "/> " @@ -2106,7 +2242,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -2118,7 +2254,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ExtraButton' " "type='Button' " "/> " @@ -2142,7 +2278,7 @@ "</dialog> " "<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -2150,25 +2286,31 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='RendererPopupDesc' " -"type='OptionsLabel' " +"width='80' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='RendererPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='AutosavePeriodPopupDesc' " -"type='OptionsLabel' " +"width='80' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='AutosavePeriodPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='GuiLanguagePopupDesc' " -"type='OptionsLabel' " +"width='80' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='GuiLanguagePopup' " "type='PopUp' " @@ -2203,10 +2345,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> " "<layout type='vertical' padding='0,0,0,0' spacing='16'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='16,16,16,4'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -2218,7 +2360,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -2226,7 +2368,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -2234,7 +2376,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -2242,7 +2384,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -2250,7 +2392,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -2258,34 +2400,43 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='16,16,16,16'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='Id' " -"type='OptionsLabel' " +"width='35' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='Domain' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='Name' " -"type='OptionsLabel' " +"width='35' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='Desc' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<space size='8'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='LangPopupDesc' " -"type='OptionsLabel' " +"width='60' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='LangPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='PlatformPopupDesc' " -"type='OptionsLabel' " +"width='60' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='PlatformPopup' " "type='PopUp' " @@ -2294,8 +2445,8 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='16,16,16,16'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Savepath' " "type='Button' " "/> " @@ -2307,7 +2458,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Extrapath' " "type='Button' " "/> " @@ -2319,7 +2470,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Gamepath' " "type='Button' " "/> " @@ -2330,7 +2481,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='16,16,16,16'> " +"<layout type='vertical' padding='8,8,8,8'> " "<widget name='customOption1Checkbox' " "type='Checkbox' " "/> " @@ -2355,57 +2506,55 @@ "</layout> " "</dialog> " "<dialog name='GlobalMenu' overlays='screen_center'> " -"<layout type='vertical' padding='16,16,16,16' center='true'> " +"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> " "<widget name='Title' " -"width='210' " -"height='Globals.Line.Height' " +"width='160' " +"height='4' " "/> " "<widget name='Version' " -"width='210' " -"height='Globals.Line.Height' " -"/> " -"<widget name='Resume' " -"width='150' " -"height='Globals.Button.Height' " +"width='160' " +"height='4' " "/> " -"<space size='10'/> " +"<space size='1'/> " "<widget name='Load' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='Save' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " -"<space size='10'/> " +"<space size='1'/> " "<widget name='Options' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='Help' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='About' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " +"/> " +"<space size='1'/> " +"<widget name='Resume' " +"width='120' " +"height='12' " "/> " -"<space size='10'/> " "<widget name='RTL' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='Quit' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "</layout> " "</dialog> " "<dialog name='GlobalConfig' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0'> " -"<layout type='vertical' padding='0,0,0,0' center='true'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -2416,7 +2565,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -2427,7 +2576,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -2438,33 +2587,34 @@ "type='SmallLabel' " "/> " "</layout> " -"</layout> " -"<layout type='vertical' padding='24,24,24,24' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<space size='110' /> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " -"width='80' " +"width='80' " "/> " "</layout> " -"</layout> " -"<space size='8' /> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subToggleSpeechOnly' " "type='Radiobutton' " -"width='100' " +"width='90' " "/> " "<widget name='subToggleSubOnly' " "type='Radiobutton' " -"width='100' " +"width='90' " "/> " "<widget name='subToggleSubBoth' " "type='Radiobutton' " -"width='100' " +"width='90' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"</layout> " +"<space size='2' /> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -2475,8 +2625,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<space size='60'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<space size='16'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='4'> " "<widget name='Keys' " "type='Button' " "/> " @@ -2493,7 +2643,7 @@ "<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'> " "<layout type='vertical' padding='0,0,0,0'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='16,16,16,16'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<space/> " "<widget name='ResetSettings' " "type='Button' " @@ -2508,7 +2658,7 @@ "</layout> " "</dialog> " "<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -2571,7 +2721,7 @@ "</layout> " "</dialog> " "<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -2626,7 +2776,7 @@ "</layout> " "</dialog> " "<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='InterpolationText' " "type='OptionsLabel' " @@ -2638,25 +2788,10 @@ "</layout> " "</dialog> " "<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,8,32' center='true'> " -"<layout type='horizontal' padding='0,0,0,0'> " -"<widget name='Title' " -"height='Globals.Line.Height' " -"/> " -"<space/> " -"<widget name='PageDisplay' " -"width='200' " -"height='Globals.Line.Height' " -"/> " -"</layout> " -"<layout type='horizontal' padding='0,0,0,16' spacing='16'> " +"<layout type='vertical' padding='8,8,8,8' center='true'> " +"<widget name='Title' height='Globals.Line.Height'/> " "<widget name='List' /> " -"<widget name='Thumbnail' " -"width='180' " -"height='200' " -"/> " -"</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,16,0'> " "<widget name='ListSwitch' " "height='Globals.Line.Height' " "width='Globals.Line.Height' " @@ -2669,7 +2804,7 @@ "<widget name='Delete' " "type='Button' " "/> " -"<space size='32'/> " +"<space size='16'/> " "<widget name='Cancel' " "type='Button' " "/> " @@ -2682,7 +2817,7 @@ "<dialog name='SavenameDialog' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " "<widget name='DescriptionText' " -"width='320' " +"width='180' " "height='Globals.Line.Height' " "/> " "<widget name='Description' " @@ -2692,23 +2827,114 @@ "<widget name='Cancel' " "type='Button' " "/> " -"<space size='96'/> " "<widget name='Ok' " "type='Button' " "/> " "</layout> " "</layout> " "</dialog> " -"<dialog name='ScummHelp' overlays='screen_center'> " +"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'> " +"<layout type='vertical' padding='8,8,8,4' center='true'> " +"<widget name='Title' " +"height='Globals.Line.Height' " +"/> " +"<widget name='List' /> " +"<layout type='horizontal' padding='0,0,0,0' spacing='2'> " +"<widget name='Edit' " +"type='Button' " +"/> " +"<space /> " +"<widget name='Record' " +"type='Button' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0' spacing='2'> " +"<widget name='Delete' " +"type='Button' " +"/> " +"<space /> " +"<widget name='Cancel' " +"type='Button' " +"/> " +"<widget name='Playback' " +"type='Button' " +"/> " +"</layout> " +"</layout> " +"</dialog> " +"<dialog name='OnScreenDialog' overlays='screen_center'> " +"<layout type='horizontal' spacing='5' padding='3,2,3,2' center='true'> " +"<widget name='StopButton' " +"width='16' " +"height='16' " +"/> " +"<widget name='EditButton' " +"width='16' " +"height='16' " +"/> " +"<widget name='SwitchModeButton' " +"width='16' " +"height='16' " +"/> " +"<widget name='FastReplayButton' " +"width='16' " +"height='16' " +"/> " +"<widget name='TimeLabel' " +"width='50' " +"height='16' " +"/> " +"</layout> " +"</dialog> " +"<dialog name='EditRecordDialog' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8' center='true'> " "<widget name='Title' " -"width='320' " +"height='Globals.Line.Height' " +"/> " +"<layout type='horizontal' spacing='5' padding='0,0,0,10'> " +"<widget name='AuthorLabel' " +"type='EditRecordLabel' " +"/> " +"<widget name='AuthorEdit' " +"type='EditRecord' " +"/> " +"</layout> " +"<layout type='horizontal' spacing='5' padding='0,0,0,10'> " +"<widget name='NameLabel' " +"type='EditRecordLabel' " +"/> " +"<widget name='NameEdit' " +"type='EditRecord' " +"/> " +"</layout> " +"<layout type='horizontal' spacing='5' padding='0,0,0,10'> " +"<widget name='NotesLabel' " +"type='EditRecordLabel' " +"/> " +"<widget name='NotesEdit' " +"type='EditRecord' " +"/> " +"</layout> " +"<layout type='horizontal' spacing='5' padding='0,0,0,0'> " +"<widget name='Cancel' " +"type='Button' " +"/> " +"<widget name='OK' " +"type='Button' " +"/> " +"</layout> " +"</layout> " +"</dialog> " +"<dialog name='ScummHelp' overlays='screen'> " +"<layout type='vertical' padding='8,8,8,8'> " +"<widget name='Title' " +"width='180' " "height='Globals.Line.Height' " "/> " "<widget name='HelpText' " -"height='200' " +"height='140' " "/> " -"<layout type='horizontal' padding='0,0,16,0'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='Prev' " "type='Button' " "/> " @@ -2725,7 +2951,7 @@ "<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8' center='true'> " "<widget name='Description1' " -"width='320' " +"width='280' " "height='Globals.Line.Height' " "/> " "<widget name='Description2' " @@ -2743,20 +2969,20 @@ "</layout> " "</dialog> " "<dialog name='MassAdd' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,32,8' center='true'> " +"<layout type='vertical' padding='4,4,16,4' center='true'> " "<widget name='DirProgressText' " -"width='480' " +"width='280' " "height='Globals.Line.Height' " "/> " "<widget name='GameProgressText' " -"width='480' " +"width='280' " "height='Globals.Line.Height' " "/> " "<widget name='GameList' " -"width='480' " -"height='250' " +"width='280' " +"height='100' " "/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='4,4,4,4'> " "<widget name='Ok' " "type='Button' " "/> " @@ -2767,20 +2993,20 @@ "</layout> " "</dialog> " "<dialog name='KeyMapper' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PopupDesc' " "type='OptionsLabel' " "/> " "<widget name='Popup' " "type='PopUp' " -"width='400' " +"width='150' " "height='Globals.Line.Height' " "/> " "</layout> " "<widget name='KeymapArea' " -"width='600' " -"height='280' " +"width='300' " +"height='120' " "/> " "<widget name='Close' " "type='Button' " @@ -2788,93 +3014,91 @@ "</layout> " "</dialog> " "<dialog name='Predictive' overlays='screen_center'> " -"<layout type='vertical' padding='5,5,5,5' center='true'> " +"<layout type='vertical' padding='1,1,1,1' center='true'> " "<widget name='Headline' " "height='Globals.Line.Height' " -"width='210' " +"width='150' " "textalign='center' " "/> " -"<layout type='horizontal' padding='5,5,5,5'> " +"<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Word' " -"width='190' " +"width='120' " "height='Globals.Button.Height' " "/> " "<widget name='Delete' " "width='20' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "</layout> " -"<space size='5' /> " "<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Button1' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='Button2' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='Button3' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "</layout> " "<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Button4' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='Button5' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='Button6' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "</layout> " "<layout type='horizontal' padding='3,3,3,3'> " "<widget name='Button7' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='Button8' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='Button9' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='3,3,3,3'> " +"<layout type='horizontal' padding='3,3,3,0'> " "<widget name='Pre' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='Button0' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='Next' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "</layout> " -"<space size='5' /> " -"<layout type='horizontal' padding='3,3,3,3'> " +"<space size='3' /> " +"<layout type='horizontal' padding='3,3,0,3'> " "<widget name='Add' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " -"<space size='22'/> " "<widget name='Cancel' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "<widget name='OK' " "width='Globals.Predictive.Button.Width' " -"height='Globals.Button.Height' " +"height='Globals.Predictive.Button.Height' " "/> " "</layout> " "</layout> " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex 297ff20344..4154c6c33a 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index 180e8fba74..5fd2d6f835 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -36,6 +36,9 @@ <def var = 'ShowChooserPageDisplay' value = '1'/> <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '1'/> + <def var = 'RecorderDialog.ExtInfo.Visible' value = '1'/> + + <def var = 'OnScreenDialog.ShowPics' value = '0'/> <def var = 'KeyMapper.Spacing' value = '10'/> <def var = 'KeyMapper.LabelWidth' value = '100'/> @@ -101,6 +104,12 @@ size = '15, 18' padding = '0, 3, 4, 0' /> + <widget name = 'EditRecordLabel' + size = '60, 25' + /> + <widget name = 'EditRecord' + size = '240, 25' + /> </globals> <dialog name = 'Launcher' overlays = 'screen'> @@ -1019,6 +1028,125 @@ </layout> </dialog> + <dialog name = 'RecorderDialog' overlays = 'screen' inset = '8' shading = 'dim'> + <layout type = 'vertical' padding = '8, 8, 8, 32' center = 'true'> + <widget name = 'Title' + height = 'Globals.Line.Height' + /> + <layout type = 'horizontal' padding = '0, 0, 0, 16' spacing = '16'> + <widget name = 'List' /> + <layout type = 'vertical' padding = '0, 0, 0, 0'> + <widget name = 'Thumbnail' + width = '180' + height = '170' + /> + <layout type = 'horizontal' padding = '0, 0, 0, 0'> + <widget name = 'NextScreenShotButton' + width = '25' + height = '25' + /> + <widget name = 'currentScreenshot' + width = '125' + height = '25' + textalign = 'center' + /> + <widget name = 'PreviousScreenShotButton' + width = '25' + height = '25' + /> + </layout> + <widget name = 'Author' height = 'Globals.Line.Height' /> + <widget name = 'Notes' height = 'Globals.Line.Height' /> + </layout> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0'> + <widget name = 'Delete' + type = 'Button' + /> + <space size = '16'/> + <widget name = 'Cancel' + type = 'Button' + /> + <space size = '16'/> + <widget name = 'Edit' + type = 'Button' + /> + <widget name = 'Record' + type = 'Button' + /> + <widget name = 'Playback' + type = 'Button' + /> + </layout> + </layout> + </dialog> + + <dialog name = 'OnScreenDialog' overlays = 'screen_center'> + <layout type = 'horizontal' spacing = '5' padding = '5, 3, 5, 3' center = 'true'> + <widget name = 'StopButton' + width = '32' + height = '32' + /> + <widget name = 'EditButton' + width = '32' + height = '32' + /> + <widget name = 'SwitchModeButton' + width = '32' + height = '32' + /> + <widget name = 'FastReplayButton' + width = '32' + height = '32' + /> + <widget name = 'TimeLabel' + width = '50' + height = '30' + /> + </layout> + </dialog> + + <dialog name = 'EditRecordDialog' overlays = 'screen_center'> + <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'> + <widget name = 'Title' + width = '320' + height = 'Globals.Line.Height' + /> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'AuthorLabel' + type = 'EditRecordLabel' + /> + <widget name = 'AuthorEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'NameLabel' + type = 'EditRecordLabel' + /> + <widget name = 'NameEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'NotesLabel' + type = 'EditRecordLabel' + /> + <widget name = 'NotesEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'Cancel' + type = 'Button' + /> + <widget name = 'OK' + type = 'Button' + /> + </layout> + </layout> + </dialog> + <dialog name = 'ScummHelp' overlays = 'screen_center'> <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'> <widget name = 'Title' diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx index 8bb03dea17..802998df3c 100644 --- a/gui/themes/scummclassic/classic_layout_lowres.stx +++ b/gui/themes/scummclassic/classic_layout_lowres.stx @@ -37,6 +37,9 @@ <def var = 'ShowChooserPageDisplay' value = '0'/> <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '0'/> + <def var = 'RecorderDialog.ExtInfo.Visible' value = '0'/> + + <def var = 'OnScreenDialog.ShowPics' value = '0'/> <def var = 'KeyMapper.Spacing' value = '5'/> <def var = 'KeyMapper.LabelWidth' value = '80'/> @@ -99,6 +102,12 @@ size = '32, 18' padding = '0, 0, 1, 0' /> + <widget name = 'EditRecordLabel' + size = '60, Globals.Line.Height' + /> + <widget name = 'EditRecord' + size = '120, 15' + /> </globals> <dialog name = 'Launcher' overlays = 'screen'> @@ -1013,6 +1022,101 @@ </layout> </dialog> + <dialog name = 'RecorderDialog' overlays = 'screen' inset = '8' shading = 'dim'> + <layout type = 'vertical' padding = '8, 8, 8, 4' center = 'true'> + <widget name = 'Title' + height = 'Globals.Line.Height' + /> + <widget name = 'List' /> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '2'> + <widget name = 'Edit' + type = 'Button' + /> + <space /> + <widget name = 'Record' + type = 'Button' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '2'> + <widget name = 'Delete' + type = 'Button' + /> + <space /> + <widget name = 'Cancel' + type = 'Button' + /> + <widget name = 'Playback' + type = 'Button' + /> + </layout> + </layout> + </dialog> + + <dialog name = 'OnScreenDialog' overlays = 'screen_center'> + <layout type = 'horizontal' spacing = '5' padding = '3, 2, 3, 2' center = 'true'> + <widget name = 'StopButton' + width = '16' + height = '16' + /> + <widget name = 'EditButton' + width = '16' + height = '16' + /> + <widget name = 'SwitchModeButton' + width = '16' + height = '16' + /> + <widget name = 'FastReplayButton' + width = '16' + height = '16' + /> + <widget name = 'TimeLabel' + width = '50' + height = '16' + /> + </layout> + </dialog> + + <dialog name = 'EditRecordDialog' overlays = 'screen_center'> + <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'> + <widget name = 'Title' + height = 'Globals.Line.Height' + /> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'AuthorLabel' + type = 'EditRecordLabel' + /> + <widget name = 'AuthorEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'NameLabel' + type = 'EditRecordLabel' + /> + <widget name = 'NameEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'NotesLabel' + type = 'EditRecordLabel' + /> + <widget name = 'NotesEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 0'> + <widget name = 'Cancel' + type = 'Button' + /> + <widget name = 'OK' + type = 'Button' + /> + </layout> + </layout> + </dialog> + <dialog name = 'ScummHelp' overlays = 'screen'> <layout type = 'vertical' padding = '8, 8, 8, 8'> <widget name = 'Title' diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex dbd84992e6..0f10003e94 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/editbtn.bmp b/gui/themes/scummmodern/editbtn.bmp Binary files differnew file mode 100644 index 0000000000..49eb4035b5 --- /dev/null +++ b/gui/themes/scummmodern/editbtn.bmp diff --git a/gui/themes/scummmodern/editbtn_small.bmp b/gui/themes/scummmodern/editbtn_small.bmp Binary files differnew file mode 100644 index 0000000000..8a0357fc2e --- /dev/null +++ b/gui/themes/scummmodern/editbtn_small.bmp diff --git a/gui/themes/scummmodern/fastreplay.bmp b/gui/themes/scummmodern/fastreplay.bmp Binary files differnew file mode 100644 index 0000000000..35ad2b4444 --- /dev/null +++ b/gui/themes/scummmodern/fastreplay.bmp diff --git a/gui/themes/scummmodern/fastreplay_small.bmp b/gui/themes/scummmodern/fastreplay_small.bmp Binary files differnew file mode 100644 index 0000000000..8ef004c3bf --- /dev/null +++ b/gui/themes/scummmodern/fastreplay_small.bmp diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx index 4d449f50ec..1b3bcea0d6 100644 --- a/gui/themes/scummmodern/scummmodern_gfx.stx +++ b/gui/themes/scummmodern/scummmodern_gfx.stx @@ -103,6 +103,14 @@ <bitmap filename = 'delbtn.bmp'/> <bitmap filename = 'list.bmp'/> <bitmap filename = 'grid.bmp'/> + <bitmap filename = 'stopbtn.bmp'/> + <bitmap filename = 'editbtn.bmp'/> + <bitmap filename = 'switchbtn.bmp'/> + <bitmap filename = 'fastreplay.bmp'/> + <bitmap filename = 'stopbtn_small.bmp'/> + <bitmap filename = 'editbtn_small.bmp'/> + <bitmap filename = 'switchbtn_small.bmp'/> + <bitmap filename = 'fastreplay_small.bmp'/> </bitmaps> <fonts> diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx index 49c13cf1b0..b760e15919 100644 --- a/gui/themes/scummmodern/scummmodern_layout.stx +++ b/gui/themes/scummmodern/scummmodern_layout.stx @@ -43,6 +43,9 @@ <def var = 'ShowChooserPageDisplay' value = '1'/> <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '1'/> + <def var = 'RecorderDialog.ExtInfo.Visible' value = '1'/> + + <def var = 'OnScreenDialog.ShowPics' value = '1'/> <def var = 'KeyMapper.Spacing' value = '10'/> <def var = 'KeyMapper.LabelWidth' value = '100'/> @@ -106,6 +109,13 @@ size = '15, 18' padding = '0, 3, 4, 0' /> + + <widget name = 'EditRecordLabel' + size = '60, 25' + /> + <widget name = 'EditRecord' + size = '220, 25' + /> </globals> <dialog name = 'Launcher' overlays = 'screen'> @@ -1032,6 +1042,126 @@ </layout> </dialog> + <dialog name = 'RecorderDialog' overlays = 'screen' inset = '8' shading = 'dim'> + <layout type = 'vertical' padding = '8, 8, 8, 32' center = 'true'> + <widget name = 'Title' + height = 'Globals.Line.Height' + /> + <layout type = 'horizontal' padding = '0, 0, 0, 16' spacing = '16'> + <widget name = 'List' /> + <layout type = 'vertical' padding = '0, 0, 0, 0'> + <widget name = 'Thumbnail' + width = '180' + height = '170' + /> + <layout type = 'horizontal' padding = '0, 0, 0, 0'> + <widget name = 'NextScreenShotButton' + width = '25' + height = '25' + /> + <widget name = 'currentScreenshot' + width = '125' + height = '25' + textalign = 'center' + /> + <widget name = 'PreviousScreenShotButton' + width = '25' + height = '25' + /> + </layout> + <widget name = 'Author' height = 'Globals.Line.Height' /> + <widget name = 'Notes' height = 'Globals.Line.Height' /> + </layout> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0'> + <space/> + <widget name = 'Delete' + type = 'Button' + /> + <space size = '16'/> + <widget name = 'Cancel' + type = 'Button' + /> + <space size = '16'/> + <widget name = 'Edit' + type = 'Button' + /> + <widget name = 'Record' + type = 'Button' + /> + <widget name = 'Playback' + type = 'Button' + /> + </layout> + </layout> + </dialog> + + <dialog name = 'OnScreenDialog' overlays = 'screen_center'> + <layout type = 'horizontal' spacing = '5' padding = '5, 3, 5, 3' center = 'true'> + <widget name = 'StopButton' + width = '32' + height = '32' + /> + <widget name = 'EditButton' + width = '32' + height = '32' + /> + <widget name = 'SwitchModeButton' + width = '32' + height = '32' + /> + <widget name = 'FastReplayButton' + width = '32' + height = '32' + /> + <widget name = 'TimeLabel' + width = '50' + height = '30' + /> + </layout> + </dialog> + + <dialog name = 'EditRecordDialog' overlays = 'screen_center'> + <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'> + <widget name = 'Title' + width = '320' + height = 'Globals.Line.Height' + /> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'AuthorLabel' + type = 'EditRecordLabel' + /> + <widget name = 'AuthorEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'NameLabel' + type = 'EditRecordLabel' + /> + <widget name = 'NameEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'NotesLabel' + type = 'EditRecordLabel' + /> + <widget name = 'NotesEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'Cancel' + type = 'Button' + /> + <widget name = 'OK' + type = 'Button' + /> + </layout> + </layout> + </dialog> + <dialog name = 'ScummHelp' overlays = 'screen_center'> <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'> <widget name = 'Title' diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx index 9658402f82..cee1e4af2b 100644 --- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx +++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx @@ -35,6 +35,9 @@ <def var = 'ShowChooserPageDisplay' value = '0'/> <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '0'/> + <def var = 'RecorderDialog.ExtInfo.Visible' value = '0'/> + + <def var = 'OnScreenDialog.ShowPics' value = '1'/> <def var = 'Predictive.Button.Width' value = '45' /> <def var = 'Predictive.Button.Height' value = '15' /> @@ -97,6 +100,12 @@ size = '32, 18' padding = '0, 0, 2, 0' /> + <widget name = 'EditRecordLabel' + size = '60, Globals.Line.Height' + /> + <widget name = 'EditRecord' + size = '120, 15' + /> </globals> <dialog name = 'Launcher' overlays = 'screen'> @@ -1012,6 +1021,122 @@ </layout> </dialog> + <dialog name = 'SavenameDialog' overlays = 'screen_center'> + <layout type = 'vertical' padding = '8, 8, 8, 8'> + <widget name = 'DescriptionText' + width = '320' + height = 'Globals.Line.Height' + /> + <widget name = 'Description' + height = '19' + /> + <layout type = 'horizontal' padding = '0, 0, 16, 0'> + <widget name = 'Cancel' + type = 'Button' + /> + <space size = '96'/> + <widget name = 'Ok' + type = 'Button' + /> + </layout> + </layout> + </dialog> + + <dialog name = 'RecorderDialog' overlays = 'screen' inset = '8' shading = 'dim'> + <layout type = 'vertical' padding = '8, 8, 8, 4' center = 'true'> + <widget name = 'Title' + height = 'Globals.Line.Height' + /> + <widget name = 'List' /> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '2'> + <widget name = 'Edit' + type = 'Button' + /> + <space /> + <widget name = 'Record' + type = 'Button' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '2'> + <widget name = 'Delete' + type = 'Button' + /> + <space /> + <widget name = 'Cancel' + type = 'Button' + /> + <widget name = 'Playback' + type = 'Button' + /> + </layout> + </layout> + </dialog> + + <dialog name = 'OnScreenDialog' overlays = 'screen_center'> + <layout type = 'horizontal' spacing = '5' padding = '3, 2, 3, 2' center = 'true'> + <widget name = 'StopButton' + width = '16' + height = '16' + /> + <widget name = 'EditButton' + width = '16' + height = '16' + /> + <widget name = 'SwitchModeButton' + width = '16' + height = '16' + /> + <widget name = 'FastReplayButton' + width = '16' + height = '16' + /> + <widget name = 'TimeLabel' + width = '50' + height = '16' + /> + </layout> + </dialog> + + <dialog name = 'EditRecordDialog' overlays = 'screen_center'> + <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'> + <widget name = 'Title' + height = 'Globals.Line.Height' + /> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'AuthorLabel' + type = 'EditRecordLabel' + /> + <widget name = 'AuthorEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'NameLabel' + type = 'EditRecordLabel' + /> + <widget name = 'NameEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 10'> + <widget name = 'NotesLabel' + type = 'EditRecordLabel' + /> + <widget name = 'NotesEdit' + type = 'EditRecord' + /> + </layout> + <layout type = 'horizontal' spacing = '5' padding = '0, 0, 0, 0'> + <widget name = 'Cancel' + type = 'Button' + /> + <widget name = 'OK' + type = 'Button' + /> + </layout> + </layout> + </dialog> + <dialog name = 'ScummHelp' overlays = 'screen' inset = '8'> <layout type = 'vertical' padding = '8, 8, 8, 8'> <widget name = 'Title' diff --git a/gui/themes/scummmodern/stopbtn.bmp b/gui/themes/scummmodern/stopbtn.bmp Binary files differnew file mode 100644 index 0000000000..3575956694 --- /dev/null +++ b/gui/themes/scummmodern/stopbtn.bmp diff --git a/gui/themes/scummmodern/stopbtn_small.bmp b/gui/themes/scummmodern/stopbtn_small.bmp Binary files differnew file mode 100644 index 0000000000..ffd5025279 --- /dev/null +++ b/gui/themes/scummmodern/stopbtn_small.bmp diff --git a/gui/themes/scummmodern/switchbtn.bmp b/gui/themes/scummmodern/switchbtn.bmp Binary files differnew file mode 100644 index 0000000000..6bafa4a998 --- /dev/null +++ b/gui/themes/scummmodern/switchbtn.bmp diff --git a/gui/themes/scummmodern/switchbtn_small.bmp b/gui/themes/scummmodern/switchbtn_small.bmp Binary files differnew file mode 100644 index 0000000000..929b128884 --- /dev/null +++ b/gui/themes/scummmodern/switchbtn_small.bmp diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp index 4b266e8194..3677f02e47 100644 --- a/gui/widgets/edittext.cpp +++ b/gui/widgets/edittext.cpp @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "common/system.h" #include "gui/widgets/edittext.h" #include "gui/gui-manager.h" @@ -79,8 +80,13 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) { } if (setCaretPos(i)) draw(); -} +#ifdef TIZEN + // Display the virtual keypad to allow text entry. Samsung app-store testers expected + // the keypad to be displayed when clicking the filter edit control in the laucher gui. + g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); +#endif +} void EditTextWidget::drawWidget() { g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x+_w, _y+_h), 0, ThemeEngine::kWidgetBackgroundEditText); diff --git a/po/POTFILES b/po/POTFILES index c2f67e288b..b812620c25 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -48,6 +48,8 @@ engines/groovie/script.cpp engines/kyra/detection.cpp engines/kyra/lol.cpp engines/kyra/sound_midi.cpp +engines/neverhood/detection.cpp +engines/neverhood/menumodule.cpp engines/queen/queen.cpp engines/sky/compact.cpp engines/sky/detection.cpp @@ -139,6 +139,10 @@ ifdef USE_FAAD OSX_STATIC_LIBS += $(STATICLIBPATH)/lib/libfaad.a endif +ifdef USE_MPEG2 +OSX_STATIC_LIBS += $(STATICLIBPATH)/lib/libmpeg2.a +endif + ifdef USE_ZLIB OSX_ZLIB ?= $(STATICLIBPATH)/lib/libz.a endif diff --git a/test/common/hash-str.h b/test/common/hash-str.h new file mode 100644 index 0000000000..0391e7167f --- /dev/null +++ b/test/common/hash-str.h @@ -0,0 +1,164 @@ +#include <cxxtest/TestSuite.h> +#include "common/hash-str.h" + +/** + * Test suite for common/hash-str.h + * We test a number of case sensitive/insensitive hash and compare functions + * using example strings and known hashes, trying to tackle + * as much edge cases as possible. + */ +class HashStrTestSuite : public CxxTest::TestSuite { + + public: + void test_case_sensitive_string_equal_to() { + + // Name says it all. + // This verifies that the function returns true + // for exactly the same string, false for the same + // string in mixed case and false for some edge cases + // with various spacings plus one character replaced + // by itself+128 (if there's some processing done after + // conversion to 7-bit ASCII this might yield funny results). + + const Common::String lower("test"); + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const Common::String spaced("test "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + const Common::String plus128("t\345est"); + // 'e'+128 = 0xE5 = 0o345 + + Common::CaseSensitiveString_EqualTo css_et; + TS_ASSERT_EQUALS(css_et(lower, mixed), false); + TS_ASSERT_EQUALS(css_et(lower, lower1), true); + TS_ASSERT_EQUALS(css_et(lower, lower), true); + + // Different sorts of whitespace are to be treated differently. + TS_ASSERT_EQUALS(css_et(lower, spaced), false); + TS_ASSERT_EQUALS(css_et(lower, tabbed), false); + TS_ASSERT_EQUALS(css_et(spaced, tabbed), false); + TS_ASSERT_EQUALS(css_et(spaced, doublespaced), false); + TS_ASSERT_EQUALS(css_et(lower, plus128), false); + } + + void test_ignore_case_equal_to() { + + // This should be probably called case_insensitive_string_equal_to + // or something,but it's basically the same thing as + // test_case_sensitive_string_equal_to, only it's case + // insensitive. + + const Common::String lower("test"); + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const Common::String spaced("test "); + const Common::String mixedspaced("tESt "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + const Common::String plus128("t\345est"); + + Common::IgnoreCase_EqualTo ic_et; + TS_ASSERT_EQUALS(ic_et(lower, mixed), true); + TS_ASSERT_EQUALS(ic_et(lower, lower1), true); + TS_ASSERT_EQUALS(ic_et(lower, lower), true); + // Edge case: + TS_ASSERT_EQUALS(ic_et(spaced, mixedspaced), true); + + // Different sorts of whitespace are to be treated differently. + TS_ASSERT_EQUALS(ic_et(lower, spaced), false); + TS_ASSERT_EQUALS(ic_et(lower, tabbed), false); + TS_ASSERT_EQUALS(ic_et(spaced, tabbed), false); + TS_ASSERT_EQUALS(ic_et(spaced, doublespaced), false); + TS_ASSERT_EQUALS(ic_et(lower, plus128), false); + } + + void test_case_sensitive_string_hash() { + + // Here we compute string hashes for different + // strings and see that the functor is case sensitive + // and does not ignore spaces. + + const Common::String lower("test"); + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const Common::String spaced("test "); + const Common::String mixedspaced("tESt "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + + Common::CaseSensitiveString_Hash css_h; + TS_ASSERT_EQUALS(css_h(lower), css_h(lower1)); + TS_ASSERT_DIFFERS(css_h(mixed), css_h(lower)); + TS_ASSERT_DIFFERS(css_h(spaced), css_h(lower)); + TS_ASSERT_DIFFERS(css_h(tabbed), css_h(spaced)); + TS_ASSERT_DIFFERS(css_h(spaced), css_h(doublespaced)); + } + + void test_ignore_case_hash() { + // Same as test_case_sensitive_string_hash, but case insensitive. + const Common::String lower("test"); + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const Common::String spaced("test "); + const Common::String mixedspaced("tESt "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + + Common::IgnoreCase_Hash ic_h; + TS_ASSERT_EQUALS(ic_h(lower), ic_h(lower1)); + TS_ASSERT_EQUALS(ic_h(mixed), ic_h(lower)); + TS_ASSERT_EQUALS(ic_h(spaced), ic_h(mixedspaced)); + TS_ASSERT_DIFFERS(ic_h(tabbed), ic_h(lower)); + TS_ASSERT_DIFFERS(ic_h(spaced), ic_h(doublespaced)); + } + + void test_cpp_string_hash() + { + // We run the same tests with Hash<String>, + // a template specialization of Hash, also a functor. + // It is supposed to be case sensitive. + + const Common::String lower("test"); + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const Common::String spaced("test "); + const Common::String mixedspaced("tESt "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + + Common::Hash<Common::String> h; + TS_ASSERT_EQUALS(h(lower), h(lower1)); + TS_ASSERT_DIFFERS(h(mixed), h(lower)); + TS_ASSERT_DIFFERS(h(spaced), h(lower)); + TS_ASSERT_DIFFERS(h(tabbed), h(spaced)); + TS_ASSERT_DIFFERS(h(spaced), h(doublespaced)); + } + + void test_c_style_string_hash() + { + // Same as test_cpp_string_hash but with Hash<const char*>, + // a template specialization of Hash, also a functor, + // that works with C-Style strings. + // It is supposed to be case sensitive. + + char lower[] = "test"; + char lower1[] = "test"; + char mixed[] = "tESt"; + char spaced[] = "test "; + char mixedspaced[] = "tESt "; + char doublespaced[] = "test "; + char tabbed[] = "test\t"; + + Common::Hash<const char *> h; + TS_ASSERT_EQUALS(h(lower), h(lower1)); + TS_ASSERT_DIFFERS(h(mixed), h(lower)); + TS_ASSERT_DIFFERS(h(spaced), h(lower)); + TS_ASSERT_DIFFERS(h(spaced), h(mixedspaced)); + TS_ASSERT_DIFFERS(h(tabbed), h(spaced)); + TS_ASSERT_DIFFERS(h(spaced), h(doublespaced)); + + } + + +}; diff --git a/test/common/huffman.h b/test/common/huffman.h new file mode 100644 index 0000000000..53353aaa60 --- /dev/null +++ b/test/common/huffman.h @@ -0,0 +1,144 @@ +#include <cxxtest/TestSuite.h> +#include "common/huffman.h" +#include "common/bitstream.h" +#include "common/memstream.h" + +/** +* A test suite for the Huffman decoder in common/huffman.h +* The encoding used comes from the example on the Wikipedia page +* for Huffman. +* TODO: It could be improved by generating one at runtime. +*/ +class HuffmanTestSuite : public CxxTest::TestSuite { + public: + void test_get_with_full_symbols() { + + /* + * The class can be initialized with or without providing + * a max_length and a symbol table. + * We test with a table. + * + * Encoding (arbitrary, for testing purpouses): + * 0xA=010 + * 0xB=011 + * 0xC=11 + * 0xD=00 + * 0xE=10 + */ + + uint32 codeCount = 5; + uint8 maxLength = 3; + const uint8 lengths[] = {3,3,2,2,2}; + const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2}; + const uint32 symbols[] = {0xA, 0xB, 0xC, 0xD, 0xE}; + + Common::Huffman h(maxLength, codeCount, codes, lengths, symbols); + + byte input[] = {0x4F, 0x20}; + // Provided input... + uint32 expected[] = {0xA, 0xB, 0xC, 0xD, 0xE, 0xD, 0xD}; + // ..and expected output. + + /* + * What should be going on: + * 010 011 11 00 10 00 00 = A B C D E D D + * = 0100 1111 0010 0000 = 0x4F20 + */ + + Common::MemoryReadStream ms(input, sizeof(input)); + Common::BitStream8MSB bs(ms); + + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[0]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[1]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[2]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[3]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[4]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[5]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[6]); + } + + void test_get_without_symbols() { + + /* + * This is basically the same as test_get_with_full_symbols, but + * I only pass the minimal required arguments. + * Specifically, I avoid passing the symbols table, so that + * array indices are used instead. + * + * Encoding becomes: + * + * 0=010 + * 1=011 + * 2=11 + * 3=00 + * 4=10 + */ + + uint32 codeCount = 5; + const uint8 lengths[] = {3,3,2,2,2}; + const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2}; + + Common::Huffman h(0, codeCount, codes, lengths, 0); + + byte input[] = {0x4F, 0x20}; + uint32 expected[] = {0, 1, 2, 3, 4, 3 ,3}; + + Common::MemoryReadStream ms(input, sizeof(input)); + Common::BitStream8MSB bs(ms); + + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[0]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[1]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[2]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[3]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[4]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[5]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[6]); + } + + void test_get_after_set_symbols() { + + /* + * Another variation of test_get_with_full_symbols. + * I use the setSymbols method to define, a posteriori, + * an alphabet to be used in place of array indices. + * The encoding is, at first, + * 0=010 + * 1=011 + * 2=11 + * 3=00 + * 4=10 + * (=array indices). + */ + + uint32 codeCount = 5; + const uint8 lengths[] = {3,3,2,2,2}; + const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2}; + + Common::Huffman h(0, codeCount, codes, lengths, 0); + + const uint32 symbols[] = {0xA, 0xB, 0xC, 0xD, 0xE}; + h.setSymbols(symbols); + + byte input[] = {0x4F, 0x20}; + uint32 expected[] = {0xA, 0xB, 0xC, 0xD, 0xE, 0xD, 0xD}; + + Common::MemoryReadStream ms(input, sizeof(input)); + Common::BitStream8MSB bs(ms); + + /* New symbols: + * A=010 + * B=011 + * C=11 + * D=00 + * E=10 + */ + + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[0]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[1]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[2]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[3]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[4]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[5]); + TS_ASSERT_EQUALS(h.getSymbol(bs), expected[6]); + } +}; diff --git a/test/common/rendermode.h b/test/common/rendermode.h new file mode 100644 index 0000000000..e5e277f16b --- /dev/null +++ b/test/common/rendermode.h @@ -0,0 +1,84 @@ +#include <cxxtest/TestSuite.h> +#include "common/rendermode.h" +#include "common/gui_options.h" +#include "common/str.h" + +class RenderModeTestSuite : public CxxTest::TestSuite { + public: + void test_parse_render_mode_good() { + /* + * Tests for parseRenderMode. + * It takes a code (case-insensitive) and spits a RenderMode back at you. + * These cases should work - the inputs are standard, there's just some + * fun with caps being had in here. + */ + TS_ASSERT_EQUALS(Common::parseRenderMode("fMTOwNs"), Common::kRenderFMTowns); + TS_ASSERT_EQUALS(Common::parseRenderMode("hercGrEen"), Common::kRenderHercG); + TS_ASSERT_EQUALS(Common::parseRenderMode("hercAmbeR"), Common::kRenderHercA); + TS_ASSERT_EQUALS(Common::parseRenderMode("CgA"), Common::kRenderCGA); + TS_ASSERT_EQUALS(Common::parseRenderMode("ega"), Common::kRenderEGA); + TS_ASSERT_EQUALS(Common::parseRenderMode("Vga"), Common::kRenderVGA); + TS_ASSERT_EQUALS(Common::parseRenderMode("AmigA"), Common::kRenderAmiga); + TS_ASSERT_EQUALS(Common::parseRenderMode("pc9821"), Common::kRenderPC9821); + TS_ASSERT_EQUALS(Common::parseRenderMode("PC9801"), Common::kRenderPC9801); + TS_ASSERT_EQUALS(Common::parseRenderMode("0"), Common::kRenderDefault); + } + + + void test_parse_render_mode_bad() { + /* + * These cases, according to the specification, should return the default. + * It is only mentioned that the function must be case insensitive. + * Whitespaces, in particular, should not be automatically trimmed. + */ + TS_ASSERT_EQUALS(Common::parseRenderMode("fmtowns "), Common::kRenderDefault); + TS_ASSERT_EQUALS(Common::parseRenderMode("FM-TOWNS "), Common::kRenderDefault); + TS_ASSERT_EQUALS(Common::parseRenderMode(" cga"), Common::kRenderDefault); + TS_ASSERT_EQUALS(Common::parseRenderMode("\tC g A"), Common::kRenderDefault); + TS_ASSERT_EQUALS(Common::parseRenderMode("\t"), Common::kRenderDefault); + // This is the only interesting bit: if the function was really, really + // broken it could be tempted to test for +-0x20. + TS_ASSERT_EQUALS(Common::parseRenderMode("pc Y8 21 "), Common::kRenderDefault); + TS_ASSERT_EQUALS(Common::parseRenderMode(" PC\t9801 "), Common::kRenderDefault); + TS_ASSERT_EQUALS(Common::parseRenderMode("0"), Common::kRenderDefault); + } + + void test_get_render_mode_code_back_and_forth() { + /* + * What does getRenderModeCode return? + * Notably, the output should not be in mixed case. + */ + TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("FMTOWNS")), "fmtowns", 7); + TS_ASSERT_DIFFERS(Common::getRenderModeCode(Common::parseRenderMode("FMTOWNS")), "fmtowns"); + TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("CGA")), "cga", 3); + TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("vga")), "vga", 3); + TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("Ega")), "ega", 3); + TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("AmiGa")), "amiga", 5); + TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("PC9821")), "pc9821", 6); + TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("PC9801")), "pc9801", 6); + // Slightly more interesting: + // Make sure that we get a null pointer for 0 (and not the "0" string or stuff) + char *null_p = 0; + TS_ASSERT_EQUALS(Common::getRenderModeCode(Common::kRenderDefault), null_p); + } + + void test_render_2_guio() { + /* + * Verify that a rendermode is taken and the corresponding + * GUIO_xxxxx is returned. + */ + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderHercG), GUIO_RENDERHERCGREEN); + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderHercA), GUIO_RENDERHERCAMBER); + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderCGA), GUIO_RENDERCGA); + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderEGA), GUIO_RENDEREGA); + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderVGA), GUIO_RENDERVGA); + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderAmiga), GUIO_RENDERAMIGA); + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderFMTowns), GUIO_RENDERFMTOWNS); + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderPC9821), GUIO_RENDERPC9821); + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderPC9801), GUIO_RENDERPC9801); + // renderMode2GUIO is supposed to return an empty string + // if given kRenderDefault as an argument + Common::String empty; + TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderDefault), empty); + } +}; diff --git a/test/common/str.h b/test/common/str.h index 2c563f3132..adc6a099e4 100644 --- a/test/common/str.h +++ b/test/common/str.h @@ -243,6 +243,14 @@ class StringTestSuite : public CxxTest::TestSuite TS_ASSERT_EQUALS(str, "012345678923456789012345678901"); } + void test_erase() { + Common::String str("01234567890123456789012345678901"); + str.erase(18); + TS_ASSERT_EQUALS(str, "012345678901234567"); + str.erase(7, 5); + TS_ASSERT_EQUALS(str, "0123456234567"); + } + void test_sharing() { Common::String str("01234567890123456789012345678901"); Common::String str2(str); diff --git a/test/common/util.h b/test/common/util.h new file mode 100644 index 0000000000..cd65307612 --- /dev/null +++ b/test/common/util.h @@ -0,0 +1,237 @@ +#include <cxxtest/TestSuite.h> +#include "common/util.h" + +/** + * Test suite for the functions in common/util.h + */ +class UtilTestSuite : public CxxTest::TestSuite { + public: + void test_parsebool_yesno() { + + // First test for the parseBool function. + // These are the mixed case yes/no cases that must work + + bool valasbool; + bool success; + + Common::String string_1("Yes"); + success = Common::parseBool(string_1, valasbool); + TS_ASSERT_EQUALS(success, 1); + TS_ASSERT_EQUALS(valasbool, 1); + + Common::String string_2("nO"); + success = Common::parseBool(string_2, valasbool); + TS_ASSERT_EQUALS(success, 1); + TS_ASSERT_EQUALS(valasbool, 0); + } + + void test_parsebool_truefalse() { + + // First test for the parseBool function. + // These are the mixed case true/false cases that must work + + bool valasbool; + bool success; + + Common::String string_3("tRuE"); + success = Common::parseBool(string_3, valasbool); + TS_ASSERT_EQUALS(success, 1); + TS_ASSERT_EQUALS(valasbool, 1); + + Common::String string_4("fAlSe"); + success = Common::parseBool(string_4, valasbool); + TS_ASSERT_EQUALS(success, 1); + TS_ASSERT_EQUALS(valasbool, 0); + } + + void test_parsebool_onezero() { + + // Third test for the parseBool function. + // These are the 1/0 cases that must work. + // Note that while 'a-z'+0x20 must work just fine, + // '0-1'+0x20 should NOT; this is addressed in + // parsebool_bad + + bool valasbool; + bool success; + + Common::String string_5("1"); + success = Common::parseBool(string_5, valasbool); + TS_ASSERT_EQUALS(success, 1); + TS_ASSERT_EQUALS(valasbool, 1); + + Common::String string_6("0"); + success = Common::parseBool(string_6, valasbool); + TS_ASSERT_EQUALS(success, 1); + TS_ASSERT_EQUALS(valasbool, 0); + + } + + void test_parsebool_bad() { + + bool valasbool; + bool success; + + // Bad cases that should not return success #1: + // Random string + Common::String string_1("u_f1ght_l1k3_a_c0w"); + success = Common::parseBool(string_1, valasbool); + TS_ASSERT_EQUALS(success, 0); + + // Bad cases that should not return success #2, #3: + // The function should NOT accept trailing whitespaces: + Common::String string_2(" yes"); + success = Common::parseBool(string_2, valasbool); + TS_ASSERT_EQUALS(success, 0); + + Common::String string_3("yes "); + success = Common::parseBool(string_3, valasbool); + TS_ASSERT_EQUALS(success, 0); + + // While 'a-z'+0x20 must work just fine, + // '0-1'+0x20 should NOT. '2' is not good either. + + Common::String string_4("\x50"); + success = Common::parseBool(string_4, valasbool); + TS_ASSERT_EQUALS(success, 0); + + Common::String string_5("\x51"); + success = Common::parseBool(string_5, valasbool); + TS_ASSERT_EQUALS(success, 0); + + Common::String string_6("2"); + success = Common::parseBool(string_6, valasbool); + TS_ASSERT_EQUALS(success, 0); + } + + void test_is_al_num() { + + // Test the isAlnum function + // Should return true if and only if the input is an alphanumeric char + + TS_ASSERT_EQUALS(Common::isAlnum('a'), 1); + TS_ASSERT_EQUALS(Common::isAlnum('A'), 1); + TS_ASSERT_EQUALS(Common::isAlnum('z'), 1); + TS_ASSERT_EQUALS(Common::isAlnum('Z'), 1); + TS_ASSERT_EQUALS(Common::isAlnum('1'), 1); + TS_ASSERT_EQUALS(Common::isAlnum('0'), 1); + TS_ASSERT_EQUALS(Common::isAlnum('§'), 0); + TS_ASSERT_EQUALS(Common::isAlnum('$'), 0); + TS_ASSERT_EQUALS(Common::isAlnum(' '), 0); + TS_ASSERT_EQUALS(Common::isAlnum('\n'), 0); + TS_ASSERT_EQUALS(Common::isAlnum('\b'), 0); + TS_ASSERT_EQUALS(Common::isAlnum(0), 0); + TS_ASSERT_EQUALS(Common::isAlnum(255), 0); + + } + + void test_is_alpha() { + + // Test the isAlpha function + // Should return true if and only if the input is an alphanumeric char + + TS_ASSERT_EQUALS(Common::isAlpha('a'), 1); + TS_ASSERT_EQUALS(Common::isAlpha('A'), 1); + TS_ASSERT_EQUALS(Common::isAlpha('z'), 1); + TS_ASSERT_EQUALS(Common::isAlpha('Z'), 1); + TS_ASSERT_EQUALS(Common::isAlpha('1'), 0); + TS_ASSERT_EQUALS(Common::isAlpha('0'), 0); + TS_ASSERT_EQUALS(Common::isAlpha('§'), 0); + TS_ASSERT_EQUALS(Common::isAlpha('$'), 0); + TS_ASSERT_EQUALS(Common::isAlpha(' '), 0); + TS_ASSERT_EQUALS(Common::isAlpha('\n'), 0); + TS_ASSERT_EQUALS(Common::isAlpha('\b'), 0); + TS_ASSERT_EQUALS(Common::isAlpha(0), 0); + TS_ASSERT_EQUALS(Common::isAlpha(255), 0); + + } + + void test_is_digit() { + + // Test the isDigit function + // Should return true if and only if the input is a single digit + + TS_ASSERT_EQUALS(Common::isDigit('a'), 0); + TS_ASSERT_EQUALS(Common::isDigit('A'), 0); + TS_ASSERT_EQUALS(Common::isDigit('z'), 0); + TS_ASSERT_EQUALS(Common::isDigit('Z'), 0); + TS_ASSERT_EQUALS(Common::isDigit('1'), 1); + TS_ASSERT_EQUALS(Common::isDigit('0'), 1); + TS_ASSERT_EQUALS(Common::isDigit('§'), 0); + TS_ASSERT_EQUALS(Common::isDigit('$'), 0); + TS_ASSERT_EQUALS(Common::isDigit(' '), 0); + TS_ASSERT_EQUALS(Common::isDigit('\n'), 0); + TS_ASSERT_EQUALS(Common::isDigit('\b'), 0); + TS_ASSERT_EQUALS(Common::isDigit(0), 0); + TS_ASSERT_EQUALS(Common::isDigit(255), 0); + + } + + void test_is_lower() { + + // Test the isLower function + // Should return true if and only if the input is a lowercase char + + TS_ASSERT_EQUALS(Common::isLower('a'), 1); + TS_ASSERT_EQUALS(Common::isLower('A'), 0); + TS_ASSERT_EQUALS(Common::isLower('z'), 1); + TS_ASSERT_EQUALS(Common::isLower('Z'), 0); + TS_ASSERT_EQUALS(Common::isLower('1'), 0); + TS_ASSERT_EQUALS(Common::isLower('0'), 0); + TS_ASSERT_EQUALS(Common::isLower('§'), 0); + TS_ASSERT_EQUALS(Common::isLower('$'), 0); + TS_ASSERT_EQUALS(Common::isLower(' '), 0); + TS_ASSERT_EQUALS(Common::isLower('\n'), 0); + TS_ASSERT_EQUALS(Common::isLower('\b'), 0); + TS_ASSERT_EQUALS(Common::isLower(0), 0); + TS_ASSERT_EQUALS(Common::isLower(255), 0); + + } + + + void test_is_upper() { + + // Test the isUpper function + // Should return true if and only if the input is an uppercase char + + TS_ASSERT_EQUALS(Common::isUpper('a'), 0); + TS_ASSERT_EQUALS(Common::isUpper('A'), 1); + TS_ASSERT_EQUALS(Common::isUpper('z'), 0); + TS_ASSERT_EQUALS(Common::isUpper('Z'), 1); + TS_ASSERT_EQUALS(Common::isUpper('1'), 0); + TS_ASSERT_EQUALS(Common::isUpper('0'), 0); + TS_ASSERT_EQUALS(Common::isUpper('§'), 0); + TS_ASSERT_EQUALS(Common::isUpper('$'), 0); + TS_ASSERT_EQUALS(Common::isUpper(' '), 0); + TS_ASSERT_EQUALS(Common::isUpper('\n'), 0); + TS_ASSERT_EQUALS(Common::isUpper('\b'), 0); + TS_ASSERT_EQUALS(Common::isUpper(0), 0); + TS_ASSERT_EQUALS(Common::isUpper(255), 0); + + } + void test_is_space() { + // isSpace should return true iff the character is some kind of whitespace + // or tab character + for (int c = 0; c < 255; c++) { + if (c == ' ' || c == '\t' || + c == '\r' || c == '\n' || + c == '\v' || c == '\f') { + TS_ASSERT_EQUALS(Common::isSpace(c), 1); + } else { + TS_ASSERT_EQUALS(Common::isSpace(c), 0); + } + } + } + + void test_is_print() { + // isPrint should return true iff the input is a printable ascii char. + // That is to say, 0x20 to 0x7E. + for (int c = 0; c < 255; c++) { + if (c >= 0x20 && c <= 0x7E) { + TS_ASSERT_EQUALS(Common::isPrint(c), 1); + } else { + TS_ASSERT_EQUALS(Common::isPrint(c), 0); + } + } + } +}; diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index 6fe9c773b8..ff728a8437 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -36,6 +36,7 @@ // Video Codecs #include "video/codecs/cinepak.h" #include "video/codecs/indeo3.h" +#include "video/codecs/mpeg.h" #include "video/codecs/msvideo1.h" #include "video/codecs/msrle.h" #include "video/codecs/truemotion1.h" @@ -64,8 +65,8 @@ namespace Video { #define ID_VEDT MKTAG('v','e','d','t') #define ID_IDX1 MKTAG('i','d','x','1') #define ID_STRD MKTAG('s','t','r','d') -#define ID_00AM MKTAG('0','0','A','M') //#define ID_INFO MKTAG('I','N','F','O') +#define ID_ISFT MKTAG('I','S','F','T') // Codec tags #define ID_RLE MKTAG('R','L','E',' ') @@ -75,6 +76,7 @@ namespace Video { #define ID_CVID MKTAG('c','v','i','d') #define ID_IV32 MKTAG('i','v','3','2') #define ID_DUCK MKTAG('D','U','C','K') +#define ID_MPG2 MKTAG('m','p','g','2') static byte char2num(char c) { c = tolower((byte)c); @@ -89,17 +91,27 @@ static uint16 getStreamType(uint32 tag) { return tag & 0xffff; } -AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _soundType(soundType) { - _decodedHeader = false; - _fileStream = 0; - memset(&_ixInfo, 0, sizeof(_ixInfo)); - memset(&_header, 0, sizeof(_header)); +AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _frameRateOverride(0), _soundType(soundType) { + initCommon(); +} + +AVIDecoder::AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType) + : _frameRateOverride(frameRateOverride), _soundType(soundType) { + initCommon(); } AVIDecoder::~AVIDecoder() { close(); } +void AVIDecoder::initCommon() { + _decodedHeader = false; + _foundMovieList = false; + _fileStream = 0; + memset(&_ixInfo, 0, sizeof(_ixInfo)); + memset(&_header, 0, sizeof(_header)); +} + void AVIDecoder::runHandle(uint32 tag) { assert(_fileStream); if (_fileStream->eos()) @@ -137,6 +149,7 @@ void AVIDecoder::runHandle(uint32 tag) { case ID_STRD: // Extra stream info, safe to ignore case ID_VEDT: // Unknown, safe to ignore case ID_JUNK: // Alignment bytes, should be ignored + case ID_ISFT: // Metadata, safe to ignore { uint32 junkSize = _fileStream->readUint32LE(); _fileStream->skip(junkSize + (junkSize & 1)); // Alignment @@ -165,6 +178,13 @@ void AVIDecoder::handleList() { debug(0, "Found LIST of type %s", tag2str(listType)); + if (listType == ID_MOVI) { + // Found the 'movi' list + // We're done parsing everything + _foundMovieList = true; + return; + } + while ((_fileStream->pos() - curPos) < listSize) runHandle(_fileStream->readUint32BE()); @@ -203,6 +223,11 @@ void AVIDecoder::handleStreamHeader() { uint32 startPos = _fileStream->pos(); if (sHeader.streamType == ID_VIDS) { + if (_frameRateOverride != 0) { + sHeader.rate = _frameRateOverride.getNumerator(); + sHeader.scale = _frameRateOverride.getDenominator(); + } + BitmapInfoHeader bmInfo; bmInfo.size = _fileStream->readUint32LE(); bmInfo.width = _fileStream->readUint32LE(); @@ -263,26 +288,24 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { _fileStream = stream; _decodedHeader = false; + _foundMovieList = false; // Read chunks until we have decoded the header - while (!_decodedHeader) + while (!_decodedHeader && _fileStream->pos() < _fileStream->size()) runHandle(_fileStream->readUint32BE()); - uint32 nextTag = _fileStream->readUint32BE(); - - // Throw out any JUNK section - if (nextTag == ID_JUNK) { - runHandle(ID_JUNK); - nextTag = _fileStream->readUint32BE(); + if (_fileStream->pos() >= _fileStream->size()) { + warning("Failed to find AVI header"); + return false; } - // Ignore the 'movi' LIST - if (nextTag == ID_LIST) { - _fileStream->readUint32BE(); // Skip size - if (_fileStream->readUint32BE() != ID_MOVI) - error("Expected 'movi' LIST"); - } else { - error("Expected 'movi' LIST"); + // Then read until we find the movie list + while (!_foundMovieList && _fileStream->pos() < _fileStream->size()) + runHandle(_fileStream->readUint32BE()); + + if (_fileStream->pos() >= _fileStream->size()) { + warning("Failed to find AVI 'movi' LIST"); + return false; } return true; @@ -294,6 +317,7 @@ void AVIDecoder::close() { delete _fileStream; _fileStream = 0; _decodedHeader = false; + _foundMovieList = false; delete[] _ixInfo.indices; memset(&_ixInfo, 0, sizeof(_ixInfo)); @@ -428,6 +452,10 @@ Codec *AVIDecoder::AVIVideoTrack::createCodec() { case ID_DUCK: return new TrueMotion1Decoder(_bmInfo.width, _bmInfo.height); #endif +#ifdef USE_MPEG2 + case ID_MPG2: + return new MPEGDecoder(); +#endif default: warning("Unknown/Unhandled compression format \'%s\'", tag2str(_vidsHeader.streamHandler)); } diff --git a/video/avi_decoder.h b/video/avi_decoder.h index 34a67f4c28..6082232464 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -52,10 +52,13 @@ class Codec; * * Video decoder used in engines: * - sci + * - sword1 + * - sword2 */ class AVIDecoder : public VideoDecoder { public: AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); + AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); virtual ~AVIDecoder(); bool loadStream(Common::SeekableReadStream *stream); @@ -219,9 +222,11 @@ private: AVIHeader _header; Common::SeekableReadStream *_fileStream; - bool _decodedHeader; + bool _decodedHeader, _foundMovieList; Audio::Mixer::SoundType _soundType; + Common::Rational _frameRateOverride; + void initCommon(); void runHandle(uint32 tag); void handleList(); diff --git a/video/codecs/codec.h b/video/codecs/codec.h index c1194e461b..a4ad786bb0 100644 --- a/video/codecs/codec.h +++ b/video/codecs/codec.h @@ -51,7 +51,7 @@ public: * containing the decoded frame. * * @return a pointer to the decoded frame - * @note stream is not deleted + * @note stream is not deleted */ virtual const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream) = 0; diff --git a/video/codecs/indeo3.cpp b/video/codecs/indeo3.cpp index 7bf7fc8235..28e1a9c620 100644 --- a/video/codecs/indeo3.cpp +++ b/video/codecs/indeo3.cpp @@ -32,8 +32,9 @@ #include "common/endian.h" #include "common/stream.h" #include "common/textconsole.h" +#include "common/util.h" -#include "graphics/conversion.h" +#include "graphics/yuv_to_rgb.h" #include "video/codecs/indeo3.h" @@ -260,91 +261,61 @@ const Graphics::Surface *Indeo3Decoder::decodeImage(Common::SeekableReadStream * delete[] inData; - // Blit the frame onto the surface const byte *srcY = _cur_frame->Ybuf; const byte *srcU = _cur_frame->Ubuf; const byte *srcV = _cur_frame->Vbuf; - byte *dest = (byte *)_surface->pixels; - - const byte *srcUP = srcU; - const byte *srcVP = srcV; - const byte *srcUN = srcU + chromaWidth; - const byte *srcVN = srcV + chromaWidth; - - uint32 scaleWidth = _surface->w / fWidth; - uint32 scaleHeight = _surface->h / fHeight; - for (uint32 y = 0; y < fHeight; y++) { - byte *rowDest = dest; - - for (uint32 sH = 0; sH < scaleHeight; sH++) { - for (uint32 x = 0; x < fWidth; x++) { - uint32 xP = MAX<int32>((x >> 2) - 1, 0); - uint32 xN = MIN<int32>((x >> 2) + 1, chromaWidth - 1); - - byte cY = srcY[x]; - byte cU = srcU[x >> 2]; - byte cV = srcV[x >> 2]; - - if (((x % 4) == 0) && ((y % 4) == 0)) { - cU = (((uint32) cU) + ((uint32) srcUP[xP])) / 2; - cV = (((uint32) cV) + ((uint32) srcVP[xP])) / 2; - } else if (((x % 4) == 3) && ((y % 4) == 0)) { - cU = (((uint32) cU) + ((uint32) srcUP[xN])) / 2; - cV = (((uint32) cV) + ((uint32) srcVP[xN])) / 2; - } else if (((x % 4) == 0) && ((y % 4) == 3)) { - cU = (((uint32) cU) + ((uint32) srcUN[xP])) / 2; - cV = (((uint32) cV) + ((uint32) srcVN[xP])) / 2; - } else if (((x % 4) == 3) && ((y % 4) == 3)) { - cU = (((uint32) cU) + ((uint32) srcUN[xN])) / 2; - cV = (((uint32) cV) + ((uint32) srcVN[xN])) / 2; - } else if ( (x % 4) == 0) { - cU = (((uint32) cU) + ((uint32) srcU[xP])) / 2; - cV = (((uint32) cV) + ((uint32) srcV[xP])) / 2; - } else if ( (x % 4) == 3) { - cU = (((uint32) cU) + ((uint32) srcU[xN])) / 2; - cV = (((uint32) cV) + ((uint32) srcV[xN])) / 2; - } else if ( (y % 4) == 0) { - cU = (((uint32) cU) + ((uint32) srcUP[x >> 2])) / 2; - cV = (((uint32) cV) + ((uint32) srcVP[x >> 2])) / 2; - } else if ( (y % 4) == 3) { - cU = (((uint32) cU) + ((uint32) srcUN[x >> 2])) / 2; - cV = (((uint32) cV) + ((uint32) srcVN[x >> 2])) / 2; - } + // Create buffers for U/V with an extra row/column copied from the second-to-last + // row/column. + byte *tempU = new byte[(chromaWidth + 1) * (chromaHeight + 1)]; + byte *tempV = new byte[(chromaWidth + 1) * (chromaHeight + 1)]; - byte r = 0, g = 0, b = 0; - Graphics::YUV2RGB(cY, cU, cV, r, g, b); + for (uint i = 0; i < chromaHeight; i++) { + memcpy(tempU + (chromaWidth + 1) * i, srcU + chromaWidth * i, chromaWidth); + memcpy(tempV + (chromaWidth + 1) * i, srcV + chromaWidth * i, chromaWidth); + tempU[(chromaWidth + 1) * i + chromaWidth] = srcU[chromaWidth * (i + 1) - 1]; + tempV[(chromaWidth + 1) * i + chromaWidth] = srcV[chromaWidth * (i + 1) - 1]; + } - const uint32 color = _pixelFormat.RGBToColor(r, g, b); + memcpy(tempU + (chromaWidth + 1) * chromaHeight, tempU + (chromaWidth + 1) * (chromaHeight - 1), + chromaWidth + 1); + memcpy(tempV + (chromaWidth + 1) * chromaHeight, tempV + (chromaWidth + 1) * (chromaHeight - 1), + chromaWidth + 1); - for (uint32 sW = 0; sW < scaleWidth; sW++, rowDest += _surface->format.bytesPerPixel) { - if (_surface->format.bytesPerPixel == 1) - *((uint8 *)rowDest) = (uint8)color; - else if (_surface->format.bytesPerPixel == 2) - *((uint16 *)rowDest) = (uint16)color; - } - } + // Blit the frame onto the surface + uint32 scaleWidth = _surface->w / fWidth; + uint32 scaleHeight = _surface->h / fHeight; - dest += _surface->pitch; + if (scaleWidth == 1 && scaleHeight == 1) { + // Shortcut: Don't need to scale so we can decode straight to the surface + YUVToRGBMan.convert410(_surface, Graphics::YUVToRGBManager::kScaleITU, srcY, tempU, tempV, + fWidth, fHeight, fWidth, chromaWidth + 1); + } else { + // Need to upscale, so decode to a temp surface first + Graphics::Surface tempSurface; + tempSurface.create(fWidth, fHeight, _surface->format); + + YUVToRGBMan.convert410(&tempSurface, Graphics::YUVToRGBManager::kScaleITU, srcY, tempU, tempV, + fWidth, fHeight, fWidth, chromaWidth + 1); + + // Upscale + for (int y = 0; y < _surface->h; y++) { + for (int x = 0; x < _surface->w; x++) { + if (_surface->format.bytesPerPixel == 1) + *((byte *)_surface->getBasePtr(x, y)) = *((byte *)tempSurface.getBasePtr(x / scaleWidth, y / scaleHeight)); + else if (_surface->format.bytesPerPixel == 2) + *((uint16 *)_surface->getBasePtr(x, y)) = *((uint16 *)tempSurface.getBasePtr(x / scaleWidth, y / scaleHeight)); + else if (_surface->format.bytesPerPixel == 4) + *((uint32 *)_surface->getBasePtr(x, y)) = *((uint32 *)tempSurface.getBasePtr(x / scaleWidth, y / scaleHeight)); + } } - srcY += fWidth; - - if ((y & 3) == 3) { - srcU += chromaWidth; - srcV += chromaWidth; - - if (y > 0) { - srcUP += chromaWidth; - srcVP += chromaWidth; - } - if (y < (fHeight - 4U)) { - srcUN += chromaWidth; - srcVN += chromaWidth; - } - } + tempSurface.free(); } + delete[] tempU; + delete[] tempV; + return _surface; } diff --git a/video/codecs/mpeg.cpp b/video/codecs/mpeg.cpp new file mode 100644 index 0000000000..4540b4182e --- /dev/null +++ b/video/codecs/mpeg.cpp @@ -0,0 +1,107 @@ +/* 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. + * + */ + +#include "common/debug.h" +#include "common/stream.h" +#include "common/system.h" +#include "common/textconsole.h" +#include "graphics/surface.h" +#include "graphics/yuv_to_rgb.h" + +#include "video/codecs/mpeg.h" + +namespace Video { + +MPEGDecoder::MPEGDecoder() : Codec() { + _pixelFormat = g_system->getScreenFormat(); + _surface = 0; + + _mpegDecoder = mpeg2_init(); + + if (!_mpegDecoder) + error("Could not initialize libmpeg2"); + + _mpegInfo = mpeg2_info(_mpegDecoder); +} + +MPEGDecoder::~MPEGDecoder() { + mpeg2_close(_mpegDecoder); + + if (_surface) { + _surface->free(); + delete _surface; + } +} + +const Graphics::Surface *MPEGDecoder::decodeImage(Common::SeekableReadStream *stream) { + uint32 framePeriod; + decodePacket(stream, framePeriod); + return _surface; +} + +bool MPEGDecoder::decodePacket(Common::SeekableReadStream *packet, uint32 &framePeriod, Graphics::Surface *dst) { + // Decode as much as we can out of this packet + uint32 size = 0xFFFFFFFF; + mpeg2_state_t state; + bool foundFrame = false; + framePeriod = 0; + + do { + state = mpeg2_parse(_mpegDecoder); + + switch (state) { + case STATE_BUFFER: + size = packet->read(_buffer, BUFFER_SIZE); + mpeg2_buffer(_mpegDecoder, _buffer, _buffer + size); + break; + case STATE_SLICE: + case STATE_END: + if (_mpegInfo->display_fbuf) { + foundFrame = true; + const mpeg2_sequence_t *sequence = _mpegInfo->sequence; + + framePeriod += sequence->frame_period; + + if (!dst) { + // If no destination is specified, use our internal storage + if (!_surface) { + _surface = new Graphics::Surface(); + _surface->create(sequence->picture_width, sequence->picture_height, _pixelFormat); + } + + dst = _surface; + } + + YUVToRGBMan.convert420(dst, Graphics::YUVToRGBManager::kScaleITU, _mpegInfo->display_fbuf->buf[0], + _mpegInfo->display_fbuf->buf[1], _mpegInfo->display_fbuf->buf[2], sequence->picture_width, + sequence->picture_height, sequence->width, sequence->chroma_width); + } + break; + default: + break; + } + } while (size != 0); + + return foundFrame; +} + +} // End of namespace Video diff --git a/video/codecs/mpeg.h b/video/codecs/mpeg.h new file mode 100644 index 0000000000..0082844537 --- /dev/null +++ b/video/codecs/mpeg.h @@ -0,0 +1,98 @@ +/* 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. + * + */ + +#ifdef USE_MPEG2 + +#ifndef VIDEO_CODECS_MPEG_H +#define VIDEO_CODECS_MPEG_H + +#include "video/codecs/codec.h" +#include "graphics/pixelformat.h" + +#if defined(__PLAYSTATION2__) + typedef uint8 uint8_t; + typedef uint16 uint16_t; + typedef uint32 uint32_t; +#elif defined(_WIN32_WCE) + typedef signed char int8_t; + typedef signed short int16_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; +#elif defined(_MSC_VER) + typedef signed char int8_t; + typedef signed short int16_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + #if !defined(SDL_COMPILEDVERSION) || (SDL_COMPILEDVERSION < 1210) + typedef signed long int32_t; + typedef unsigned long uint32_t; + #endif +#else +# include <inttypes.h> +#endif + +extern "C" { + #include <mpeg2dec/mpeg2.h> +} + +namespace Common { +class SeekableReadStream; +} + +namespace Graphics { +struct Surface; +} + +namespace Video { + +// MPEG 1/2 video decoder + +class MPEGDecoder : public Codec { +public: + MPEGDecoder(); + ~MPEGDecoder(); + + // Codec interface + const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream); + Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; } + + // MPEGPSDecoder call + bool decodePacket(Common::SeekableReadStream *packet, uint32 &framePeriod, Graphics::Surface *dst = 0); + +private: + Graphics::PixelFormat _pixelFormat; + Graphics::Surface *_surface; + + enum { + BUFFER_SIZE = 4096 + }; + + byte _buffer[BUFFER_SIZE]; + mpeg2dec_t *_mpegDecoder; + const mpeg2_info_t *_mpegInfo; +}; + +} // End of namespace Video + +#endif // VIDEO_CODECS_MPEG_H + +#endif // USE_MPEG2 diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp index d24a021f3b..4c3b6f8414 100644 --- a/video/coktel_decoder.cpp +++ b/video/coktel_decoder.cpp @@ -2426,8 +2426,10 @@ void VMDDecoder::blit16(const Graphics::Surface &srcSurf, Common::Rect &rect) { if ((r == 0) && (g == 0) && (b == 0)) c = 0; - if (_surface.format.bytesPerPixel == 2) + if (_surface.format.bytesPerPixel == 2) *((uint16 *)dstRow) = (uint16) c; + else if (_surface.format.bytesPerPixel == 4) + *((uint32 *)dstRow) = (uint32) c; } src += srcSurf .pitch; @@ -2462,8 +2464,10 @@ void VMDDecoder::blit24(const Graphics::Surface &srcSurf, Common::Rect &rect) { if ((r == 0) && (g == 0) && (b == 0)) c = 0; - if (_surface.format.bytesPerPixel == 2) + if (_surface.format.bytesPerPixel == 2) *((uint16 *)dstRow) = (uint16) c; + else if (_surface.format.bytesPerPixel == 4) + *((uint32 *)dstRow) = (uint32) c; } src += srcSurf .pitch; diff --git a/video/module.mk b/video/module.mk index 287e14ce18..a491947aaf 100644 --- a/video/module.mk +++ b/video/module.mk @@ -31,5 +31,10 @@ MODULE_OBJS += \ theora_decoder.o endif +ifdef USE_MPEG2 +MODULE_OBJS += \ + codecs/mpeg.o +endif + # Include common rules include $(srcdir)/rules.mk |