diff --git a/.clang-format b/.clang-format index c950f944452..8a5739e47f1 100644 --- a/.clang-format +++ b/.clang-format @@ -19,4 +19,5 @@ SpacesInAngles: false, SpacesInParentheses: false, SpacesInSquareBrackets: false, + Standard: c++03, } diff --git a/Makefile b/Makefile index 1ad720a7dd1..0b022e33c42 100644 --- a/Makefile +++ b/Makefile @@ -32,11 +32,8 @@ ifeq "$(HAVE_GCC)" "1" # being helpful. #CXXFLAGS+= -Wmissing-format-attribute -ifneq "$(BACKEND)" "tizen" - # Disable exceptions. This setting causes tizen apps to crash - # TODO: Does this still apply after enabling RTTI again? + # Disable exceptions. CXXFLAGS+= -fno-exceptions -endif ifneq "$(HAVE_CLANG)" "1" # enable checking of pointers returned by "new", but only when we do not diff --git a/audio/decoders/flac.cpp b/audio/decoders/flac.cpp index e0205a40b58..6acf18ef964 100644 --- a/audio/decoders/flac.cpp +++ b/audio/decoders/flac.cpp @@ -355,8 +355,7 @@ int FLACStream::readBuffer(int16 *buffer, const int numSamples) { break; default: decoderOk = false; - warning("FLACStream: An error occurred while decoding. DecoderState is: %s", - FLAC__StreamDecoderStateString[getStreamDecoderState()]); + warning("FLACStream: An error occurred while decoding. DecoderState is: %d", getStreamDecoderState()); } // Compute how many samples we actually produced @@ -668,8 +667,7 @@ inline void FLACStream::callbackMetadata(const ::FLAC__StreamMetadata *metadata) } inline void FLACStream::callbackError(::FLAC__StreamDecoderErrorStatus status) { // some of these are non-critical-Errors - debug(1, "FLACStream: An error occurred while decoding. DecoderState is: %s", - FLAC__StreamDecoderErrorStatusString[status]); + debug(1, "FLACStream: An error occurred while decoding. DecoderStateError is: %d", status); } /* Static Callback Wrappers */ diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp index 4791de5485c..420ee011a83 100644 --- a/audio/mididrv.cpp +++ b/audio/mididrv.cpp @@ -109,6 +109,7 @@ static const struct { { MT_APPLEIIGS, GUIO_MIDIAPPLEIIGS }, { MT_TOWNS, GUIO_MIDITOWNS }, { MT_PC98, GUIO_MIDIPC98 }, + { MT_SEGACD, GUIO_MIDISEGACD }, { MT_GM, GUIO_MIDIGM }, { MT_MT32, GUIO_MIDIMT32 }, { 0, 0 }, @@ -229,6 +230,11 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { reslt = hdl; break; + case MT_SEGACD: + if (flags & MDT_SEGACD) + reslt = hdl; + break; + case MT_GM: case MT_GS: case MT_MT32: @@ -363,6 +369,9 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { } else if (flags & MDT_PC98) { tp = MT_PC98; flags &= ~MDT_PC98; + } else if (flags & MDT_SEGACD) { + tp = MT_SEGACD; + flags &= ~MDT_SEGACD; } else if (flags & MDT_ADLIB) { tp = MT_ADLIB; flags &= ~MDT_ADLIB; @@ -564,6 +573,10 @@ void MidiDriver_BASE::send(int8 source, byte status, byte firstOp, byte secondOp send(source, status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16)); } +void MidiDriver_BASE::stopAllNotes(bool stopSustainedNotes) { +// ResidualVM - not used +} + void MidiDriver::midiDriverCommonSend(uint32 b) { // ResidualVM - not used } diff --git a/audio/mididrv.h b/audio/mididrv.h index 6c8a2f2d5db..6f37125cd79 100644 --- a/audio/mididrv.h +++ b/audio/mididrv.h @@ -47,6 +47,7 @@ enum MusicType { MT_APPLEIIGS, // Apple IIGS MT_TOWNS, // FM-TOWNS MT_PC98, // PC98 + MT_SEGACD, // SegaCD MT_GM, // General MIDI MT_MT32, // MT-32 MT_GS // Roland GS @@ -77,11 +78,12 @@ enum MidiDriverFlags { MDT_AMIGA = 1 << 5, MDT_APPLEIIGS = 1 << 6, MDT_TOWNS = 1 << 7, // FM-TOWNS: Maps to MT_TOWNS - MDT_PC98 = 1 << 8, // FM-TOWNS: Maps to MT_PC98 - MDT_MIDI = 1 << 9, // Real MIDI - MDT_PREFER_MT32 = 1 << 10, // MT-32 output is preferred - MDT_PREFER_GM = 1 << 11, // GM output is preferred - MDT_PREFER_FLUID= 1 << 12 // FluidSynth driver is preferred + MDT_PC98 = 1 << 8, // PC-98: Maps to MT_PC98 + MDT_SEGACD = 1 << 9, + MDT_MIDI = 1 << 10, // Real MIDI + MDT_PREFER_MT32 = 1 << 11, // MT-32 output is preferred + MDT_PREFER_GM = 1 << 12, // GM output is preferred + MDT_PREFER_FLUID= 1 << 13 // FluidSynth driver is preferred }; /** @@ -159,6 +161,32 @@ public: * ignored. */ virtual void metaEvent(int8 source, byte type, byte *data, uint16 length) { metaEvent(type, data, length); } + + /** + * Stops all currently active notes. Specify stopSustainedNotes if + * the MIDI data makes use of the sustain controller to also stop + * sustained notes. + * + * Usually, the MIDI parser tracks active notes and terminates them + * when playback is stopped. This method should be used as a backup + * to silence the MIDI output in case the MIDI parser makes a + * mistake when tracking acive notes. It can also be used when + * quitting or pausing a game. + * + * By default, this method sends an All Notes Off message and, if + * stopSustainedNotes is true, a Sustain off message on all MIDI + * channels. Driver implementations can override this if they want + * to implement this functionality in a different way. + */ + virtual void stopAllNotes(bool stopSustainedNotes = false); + + /** + * A driver implementation might need time to prepare playback of + * a track. Use this function to check if the driver is ready to + * receive MIDI events. + */ + virtual bool isReady() { return true; } + protected: /** diff --git a/backends/dialogs/gtk/gtk-dialogs.cpp b/backends/dialogs/gtk/gtk-dialogs.cpp index 727308f2bb3..79f4f918a2e 100644 --- a/backends/dialogs/gtk/gtk-dialogs.cpp +++ b/backends/dialogs/gtk/gtk-dialogs.cpp @@ -59,8 +59,13 @@ Common::DialogManager::DialogResult GtkDialogManager::showFileBrowser(const char if (isDirBrowser) { action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; } +#if GTK_CHECK_VERSION(3,20,0) GtkFileChooserNative *native = gtk_file_chooser_native_new(utf8Title, NULL, action, utf8Choose, utf8Cancel); GtkFileChooser *chooser = GTK_FILE_CHOOSER(native); +#else + GtkWidget *dialog = gtk_file_chooser_dialog_new(utf8Title, NULL, action, utf8Choose, GTK_RESPONSE_ACCEPT, utf8Cancel, GTK_RESPONSE_CANCEL, NULL); + GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog); +#endif free(utf8Cancel); free(utf8Choose); free(utf8Title); @@ -73,7 +78,11 @@ Common::DialogManager::DialogResult GtkDialogManager::showFileBrowser(const char // Show dialog beginDialog(); +#if GTK_CHECK_VERSION(3,20,0) int res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native)); +#else + int res = gtk_dialog_run(GTK_DIALOG(dialog)); +#endif if (res == GTK_RESPONSE_ACCEPT) { // Get the selection from the user char *path = gtk_file_chooser_get_filename(chooser); @@ -87,7 +96,11 @@ Common::DialogManager::DialogResult GtkDialogManager::showFileBrowser(const char g_free(last); } +#if GTK_CHECK_VERSION(3,20,0) g_object_unref(native); +#else + gtk_widget_destroy(dialog); +#endif while (gtk_events_pending()) gtk_main_iteration(); diff --git a/backends/modular-backend.h b/backends/modular-backend.h index 81cd7eecbd3..fe958340b61 100644 --- a/backends/modular-backend.h +++ b/backends/modular-backend.h @@ -63,59 +63,59 @@ public: /** @name Graphics */ //@{ - virtual GraphicsManager *getGraphicsManager(); + GraphicsManager *getGraphicsManager(); virtual const GraphicsMode *getSupportedGraphicsModes() const override; virtual int getDefaultGraphicsMode() const override; virtual bool setGraphicsMode(int mode) override; virtual int getGraphicsMode() const override; - virtual const GraphicsMode *getSupportedShaders() const override; - virtual int getDefaultShader() const override; - virtual int getShader() const override; - virtual bool setShader(int id) override; - virtual const GraphicsMode *getSupportedStretchModes() const override; - virtual int getDefaultStretchMode() const override; - virtual bool setStretchMode(int mode) override; - virtual int getStretchMode() const override; - virtual void resetGraphicsScale() override; + virtual const GraphicsMode *getSupportedShaders() const override final; + virtual int getDefaultShader() const override final; + virtual int getShader() const override final; + virtual bool setShader(int id) override final; + virtual const GraphicsMode *getSupportedStretchModes() const override final; + virtual int getDefaultStretchMode() const override final; + virtual bool setStretchMode(int mode) override final; + virtual int getStretchMode() const override final; + virtual void resetGraphicsScale() override final; #ifdef USE_RGB_COLOR - virtual Graphics::PixelFormat getScreenFormat() const override; - virtual Common::List getSupportedFormats() const override; + virtual Graphics::PixelFormat getScreenFormat() const override final; + virtual Common::List getSupportedFormats() const override final; #endif - virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) override; + virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) override final; virtual void setupScreen(uint screenW, uint screenH, bool fullscreen, bool accel3d); // ResidualVM specific method virtual Graphics::PixelBuffer getScreenPixelBuffer(); // ResidualVM specific method virtual void suggestSideTextures(Graphics::Surface *left, Graphics::Surface *right); // ResidualVM specific method - virtual void initSizeHint(const Graphics::ModeList &modes) override; - virtual int getScreenChangeID() const override; + virtual void initSizeHint(const Graphics::ModeList &modes) override final; + virtual int getScreenChangeID() const override final; - virtual void beginGFXTransaction() override; - virtual OSystem::TransactionError endGFXTransaction() override; + virtual void beginGFXTransaction() override final; + virtual OSystem::TransactionError endGFXTransaction() override final; - virtual int16 getHeight() override; - virtual int16 getWidth() override; - virtual PaletteManager *getPaletteManager() override; - virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override; - virtual Graphics::Surface *lockScreen() override; - virtual void unlockScreen() override; - virtual void fillScreen(uint32 col) override; - virtual void updateScreen() override; - virtual void setShakePos(int shakeXOffset, int shakeYOffset) override; - virtual void setFocusRectangle(const Common::Rect& rect) override; - virtual void clearFocusRectangle() override; + virtual int16 getHeight() override final; + virtual int16 getWidth() override final; + virtual PaletteManager *getPaletteManager() override final; + virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override final; + virtual Graphics::Surface *lockScreen() override final; + virtual void unlockScreen() override final; + virtual void fillScreen(uint32 col) override final; + virtual void updateScreen() override final; + virtual void setShakePos(int shakeXOffset, int shakeYOffset) override final; + virtual void setFocusRectangle(const Common::Rect& rect) override final; + virtual void clearFocusRectangle() override final; - virtual void showOverlay() override; - virtual void hideOverlay() override; - virtual Graphics::PixelFormat getOverlayFormat() const override; - virtual void clearOverlay() override; - virtual void grabOverlay(void *buf, int pitch) override; - virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override; - virtual int16 getOverlayHeight() override; - virtual int16 getOverlayWidth() override; + virtual void showOverlay() override final; + virtual void hideOverlay() override final; + virtual Graphics::PixelFormat getOverlayFormat() const override final; + virtual void clearOverlay() override final; + virtual void grabOverlay(void *buf, int pitch) override final; + virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override final; + virtual int16 getOverlayHeight() override final; + virtual int16 getOverlayWidth() override final; - virtual bool showMouse(bool visible) override; - virtual void warpMouse(int x, int y) override; - virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override; - virtual void setCursorPalette(const byte *colors, uint start, uint num) override; + virtual bool showMouse(bool visible) override final; + virtual void warpMouse(int x, int y) override final; + virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override final; + virtual void setCursorPalette(const byte *colors, uint start, uint num) override final; virtual bool lockMouse(bool lock); // ResidualVM specific method //@} @@ -123,10 +123,10 @@ public: /** @name Mutex handling */ //@{ - virtual MutexRef createMutex() override; - virtual void lockMutex(MutexRef mutex) override; - virtual void unlockMutex(MutexRef mutex) override; - virtual void deleteMutex(MutexRef mutex) override; + virtual MutexRef createMutex() override final; + virtual void lockMutex(MutexRef mutex) override final; + virtual void unlockMutex(MutexRef mutex) override final; + virtual void deleteMutex(MutexRef mutex) override final; //@} @@ -140,8 +140,8 @@ public: /** @name Miscellaneous */ //@{ - virtual void displayMessageOnOSD(const char *msg) override; - virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override; + virtual void displayMessageOnOSD(const char *msg) override final; + virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override final; //@} diff --git a/backends/module.mk b/backends/module.mk index 5c0037f373d..1451e0329f7 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -232,11 +232,6 @@ MODULE_OBJS += \ audiocd/linux/linux-audiocd.o endif -ifeq ($(BACKEND),tizen) -MODULE_OBJS += \ - timer/tizen/timer.o -endif - ifeq ($(BACKEND),3ds) MODULE_OBJS += \ plugins/3ds/3ds-provider.o @@ -281,13 +276,6 @@ MODULE_OBJS += \ graphics/openpandora/op-graphics.o endif -ifeq ($(BACKEND),ps2) -MODULE_OBJS += \ - fs/ps2/ps2-fs.o \ - fs/ps2/ps2-fs-factory.o \ - plugins/ps2/ps2-provider.o -endif - ifeq ($(BACKEND),psp) MODULE_OBJS += \ fs/psp/psp-fs.o \ @@ -312,11 +300,6 @@ MODULE_OBJS += \ events/samsungtvsdl/samsungtvsdl-events.o endif -ifeq ($(BACKEND),webos) -MODULE_OBJS += \ - events/webossdl/webossdl-events.o -endif - ifeq ($(BACKEND),wii) MODULE_OBJS += \ fs/wii/wii-fs.o \ diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp index 736af75b8ed..92e4acae153 100644 --- a/backends/platform/sdl/posix/posix-main.cpp +++ b/backends/platform/sdl/posix/posix-main.cpp @@ -22,7 +22,7 @@ #include "common/scummsys.h" -#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(ANDROIDSDL) && !defined(NINTENDO_SWITCH) +#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(ANDROIDSDL) && !defined(NINTENDO_SWITCH) #include "backends/platform/sdl/posix/posix.h" #include "backends/plugins/sdl/sdl-provider.h" diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp index 352281cb974..ff59a1c32ee 100644 --- a/backends/platform/sdl/sdl-window.cpp +++ b/backends/platform/sdl/sdl-window.cpp @@ -39,13 +39,19 @@ SdlWindow::SdlWindow() #endif { -#if !SDL_VERSION_ATLEAST(2, 0, 0) +#if SDL_VERSION_ATLEAST(2, 0, 0) +#elif SDL_VERSION_ATLEAST(1, 2, 10) // Query the desktop resolution. We simply hope nothing tried to change // the resolution so far. const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); if (videoInfo && videoInfo->current_w > 0 && videoInfo->current_h > 0) { _desktopRes = Common::Rect(videoInfo->current_w, videoInfo->current_h); } +#elif defined(MAEMO) + // All supported Maemo devices have a display resolution of 800x480 + _desktopRes = Common::Rect(800, 480); +#else +#error Unable to detect screen resolution #endif } diff --git a/backends/text-to-speech/linux/linux-text-to-speech.cpp b/backends/text-to-speech/linux/linux-text-to-speech.cpp index 5bfb25766d0..674ccaa5445 100644 --- a/backends/text-to-speech/linux/linux-text-to-speech.cpp +++ b/backends/text-to-speech/linux/linux-text-to-speech.cpp @@ -33,7 +33,6 @@ #include "common/ustr.h" #include "common/config-manager.h" #include "common/encoding.h" -#include SPDConnection *_connection; diff --git a/backends/text-to-speech/linux/linux-text-to-speech.h b/backends/text-to-speech/linux/linux-text-to-speech.h index c67e22aa746..0e0c8d2f4de 100644 --- a/backends/text-to-speech/linux/linux-text-to-speech.h +++ b/backends/text-to-speech/linux/linux-text-to-speech.h @@ -32,6 +32,8 @@ #include "common/list.h" #include "common/mutex.h" +#include + struct StartSpeechParams { pthread_mutex_t *mutex; Common::List *speechQueue; diff --git a/backends/text-to-speech/windows/windows-text-to-speech.cpp b/backends/text-to-speech/windows/windows-text-to-speech.cpp index 97f7777a742..534759d0c36 100644 --- a/backends/text-to-speech/windows/windows-text-to-speech.cpp +++ b/backends/text-to-speech/windows/windows-text-to-speech.cpp @@ -462,7 +462,11 @@ void WindowsTextToSpeechManager::updateVoices() { ISpObjectTokenCategory *cpCategory; HRESULT hr = CoCreateInstance(CLSID_SpObjectTokenCategory, NULL, CLSCTX_ALL, IID_ISpObjectTokenCategory, (void**)&cpCategory); if (SUCCEEDED(hr)) { - hr = cpCategory->SetId(SPCAT_VOICES, FALSE); + hr = cpCategory->SetId(L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech_OneCore\\Voices", FALSE); + if (!SUCCEEDED(hr)) { + hr = cpCategory->SetId(SPCAT_VOICES, FALSE); + } + if (SUCCEEDED(hr)) { hr = cpCategory->EnumTokens(NULL, NULL, &cpEnum); } diff --git a/backends/timer/sdl/sdl-timer.cpp b/backends/timer/sdl/sdl-timer.cpp index 22d4bb985fc..66031cd4ba9 100644 --- a/backends/timer/sdl/sdl-timer.cpp +++ b/backends/timer/sdl/sdl-timer.cpp @@ -29,7 +29,12 @@ #include "common/textconsole.h" +static volatile bool timerInstalled = false; + static Uint32 timer_handler(Uint32 interval, void *param) { + if (!timerInstalled) + return interval; + ((DefaultTimerManager *)param)->handler(); return interval; } @@ -40,11 +45,14 @@ SdlTimerManager::SdlTimerManager() { error("Could not initialize SDL: %s", SDL_GetError()); } + timerInstalled = true; + // Creates the timer callback _timerID = SDL_AddTimer(10, &timer_handler, this); } SdlTimerManager::~SdlTimerManager() { + timerInstalled = false; // Removes the timer callback SDL_RemoveTimer(_timerID); } diff --git a/base/version.cpp b/base/version.cpp index 911560a89ad..56c188fe67e 100644 --- a/base/version.cpp +++ b/base/version.cpp @@ -59,15 +59,9 @@ const char *gScummVMVersion = SCUMMVM_VERSION SCUMMVM_REVISION; #ifdef __amigaos4__ static const char *version_cookie __attribute__((used)) = "$VER: ResidualVM " SCUMMVM_VERSION SCUMMVM_REVISION " (" AMIGA_DATE ")"; #endif -#ifdef __PLAYSTATION2__ -const char *gScummVMBuildDate = "Git Master"; /* ScummVM Git Master */ -const char *gScummVMVersionDate = SCUMMVM_VERSION SCUMMVM_REVISION " - PlayStation2"; -const char *gScummVMFullVersion = "ResidualVM " SCUMMVM_VERSION SCUMMVM_REVISION " - PlayStation2"; -#else const char *gScummVMBuildDate = __DATE__ " " __TIME__; const char *gScummVMVersionDate = SCUMMVM_VERSION SCUMMVM_REVISION " (" __DATE__ " " __TIME__ ")"; const char *gScummVMFullVersion = "ResidualVM " SCUMMVM_VERSION SCUMMVM_REVISION " (" __DATE__ " " __TIME__ ")"; -#endif const char *gScummVMFeatures = "" #ifdef TAINTED_BUILD // TAINTED means the build contains engines/subengines not enabled by default diff --git a/common/gui_options.cpp b/common/gui_options.cpp index 2786701c858..e568230705b 100644 --- a/common/gui_options.cpp +++ b/common/gui_options.cpp @@ -53,6 +53,7 @@ const struct GameOpt { { GUIO_MIDIAPPLEIIGS,"midiAppleIIgs" }, { GUIO_MIDITOWNS, "midiTowns" }, { GUIO_MIDIPC98, "midiPC98" }, + { GUIO_MIDISEGACD, "midiSegaCD" }, { GUIO_MIDIMT32, "midiMt32" }, { GUIO_MIDIGM, "midiGM" }, diff --git a/common/gui_options.h b/common/gui_options.h index 00d08cfea56..eca75e6877a 100644 --- a/common/gui_options.h +++ b/common/gui_options.h @@ -41,6 +41,7 @@ #define GUIO_MIDIAPPLEIIGS "\015" #define GUIO_MIDITOWNS "\016" #define GUIO_MIDIPC98 "\017" +#define GUIO_MIDISEGACD "\018" #define GUIO_MIDIMT32 "\020" #define GUIO_MIDIGM "\021" diff --git a/common/hashmap.h b/common/hashmap.h index 82dcbe4dd24..861f0556628 100644 --- a/common/hashmap.h +++ b/common/hashmap.h @@ -304,15 +304,7 @@ public: * Base constructor, creates an empty hashmap. */ template -HashMap::HashMap() -// -// We have to skip _defaultVal() on PS2 to avoid gcc 3.2.2 ICE -// -#ifdef __PLAYSTATION2__ - { -#else - : _defaultVal() { -#endif +HashMap::HashMap() : _defaultVal() { _mask = HASHMAP_MIN_CAPACITY - 1; _storage = new Node *[HASHMAP_MIN_CAPACITY]; assert(_storage != nullptr); diff --git a/common/inttypes.h b/common/inttypes.h index 7a39a3d8b13..11eb61e5bee 100644 --- a/common/inttypes.h +++ b/common/inttypes.h @@ -23,11 +23,7 @@ #ifndef COMMON_INTTYPES_H #define COMMON_INTTYPES_H -#if defined(__PLAYSTATION2__) - typedef uint8 uint8_t; - typedef uint16 uint16_t; - typedef uint32 uint32_t; -#elif defined(_MSC_VER) || defined (__SYMBIAN32__) +#if defined(_MSC_VER) || defined (__SYMBIAN32__) typedef signed char int8_t; typedef signed short int16_t; typedef unsigned char uint8_t; diff --git a/common/json.h b/common/json.h index 7b7c6b8d588..a55594a7ad6 100644 --- a/common/json.h +++ b/common/json.h @@ -53,7 +53,7 @@ #include "common/str.h" // Win32 incompatibilities -#if (defined(WIN32) && !defined(__GNUC__)) || defined(__PLAYSTATION2__) +#if (defined(WIN32) && !defined(__GNUC__)) static inline bool isnan(double x) { return x != x; } diff --git a/common/macresman.cpp b/common/macresman.cpp index 7f12f3207bd..917bb278543 100644 --- a/common/macresman.cpp +++ b/common/macresman.cpp @@ -37,7 +37,6 @@ namespace Common { -#define MBI_INFOHDR 128 #define MBI_ZERO1 0 #define MBI_NAMELEN 1 #define MBI_ZERO2 74 @@ -386,10 +385,11 @@ bool MacResManager::isMacBinary(SeekableReadStream &stream) { uint32 rsrcSize = READ_BE_UINT32(infoHeader + MBI_RFLEN); uint32 dataSizePad = (((dataSize + 127) >> 7) << 7); - uint32 rsrcSizePad = (((rsrcSize + 127) >> 7) << 7); + // Files produced by ISOBuster are not padded, thus, compare with the actual size + //uint32 rsrcSizePad = (((rsrcSize + 127) >> 7) << 7); // Length check - if (MBI_INFOHDR + dataSizePad + rsrcSizePad == (uint32)stream.size()) { + if (MBI_INFOHDR + dataSizePad + rsrcSize <= (uint32)stream.size()) { resForkOffset = MBI_INFOHDR + dataSizePad; } } @@ -425,10 +425,11 @@ bool MacResManager::loadFromMacBinary(SeekableReadStream &stream) { uint32 rsrcSize = READ_BE_UINT32(infoHeader + MBI_RFLEN); uint32 dataSizePad = (((dataSize + 127) >> 7) << 7); - uint32 rsrcSizePad = (((rsrcSize + 127) >> 7) << 7); + // Files produced by ISOBuster are not padded, thus, compare with the actual size + //uint32 rsrcSizePad = (((rsrcSize + 127) >> 7) << 7); // Length check - if (MBI_INFOHDR + dataSizePad + rsrcSizePad == (uint32)stream.size()) { + if (MBI_INFOHDR + dataSizePad + rsrcSize <= (uint32)stream.size()) { _resForkOffset = MBI_INFOHDR + dataSizePad; _resForkSize = rsrcSize; } @@ -751,4 +752,28 @@ void MacResManager::dumpRaw() { } } +MacResManager::MacVers *MacResManager::parseVers(SeekableReadStream *vvers) { + MacVers *v = new MacVers; + + v->majorVer = vvers->readByte(); + v->minorVer = vvers->readByte(); + byte devStage = vvers->readByte(); + const char *s; + switch (devStage) { + case 0x20: s = "Prealpha"; break; + case 0x40: s = "Alpha"; break; + case 0x60: s = "Beta"; break; + case 0x80: s = "Final"; break; + default: s = ""; + } + v->devStr = s; + + v->preReleaseVer = vvers->readByte(); + v->region = vvers->readUint16BE(); + v->str = vvers->readPascalString(); + v->msg = vvers->readPascalString(); + + return v; +} + } // End of namespace Common diff --git a/common/macresman.h b/common/macresman.h index 48850ee92db..6ae3fd36dcd 100644 --- a/common/macresman.h +++ b/common/macresman.h @@ -49,6 +49,8 @@ typedef Array MacResTagArray; */ class MacResManager { +#define MBI_INFOHDR 128 + public: MacResManager(); ~MacResManager(); @@ -139,6 +141,8 @@ public: */ SeekableReadStream *getDataFork(); + static int getDataForkOffset() { return MBI_INFOHDR; } + /** * Get the name of a given resource * @param typeID FourCC of the type @@ -188,6 +192,24 @@ public: */ void dumpRaw(); + /** + * Check if the given stream is in the MacBinary format. + * @param stream The stream we're checking + */ + static bool isMacBinary(SeekableReadStream &stream); + + struct MacVers { + byte majorVer; + byte minorVer; + byte devStage; + String devStr; + byte preReleaseVer; + uint16 region; + String str; + String msg; + }; + static MacVers *parseVers(SeekableReadStream *vvers); + private: SeekableReadStream *_stream; String _baseFileName; @@ -200,12 +222,6 @@ private: static String constructAppleDoubleName(String name); static String disassembleAppleDoubleName(String name, bool *isAppleDouble); - /** - * Check if the given stream is in the MacBinary format. - * @param stream The stream we're checking - */ - static bool isMacBinary(SeekableReadStream &stream); - /** * Do a sanity check whether the given stream is a raw resource fork. * diff --git a/common/memstream.h b/common/memstream.h index 187b562b2ff..00ae80950c4 100644 --- a/common/memstream.h +++ b/common/memstream.h @@ -78,10 +78,17 @@ public: * This is a MemoryReadStream subclass which adds non-endian * read methods whose endianness is set on the stream creation. */ -class MemoryReadStreamEndian : public MemoryReadStream, public ReadStreamEndian { +class MemoryReadStreamEndian : public MemoryReadStream, public SeekableReadStreamEndian { public: MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian) - : MemoryReadStream(buf, len), ReadStreamEndian(bigEndian) {} + : MemoryReadStream(buf, len), SeekableReadStreamEndian(bigEndian), ReadStreamEndian(bigEndian) {} + + int32 pos() const { return MemoryReadStream::pos(); } + int32 size() const { return MemoryReadStream::size(); } + + bool seek(int32 offs, int whence = SEEK_SET) { return MemoryReadStream::seek(offs, whence); } + + bool skip(uint32 offset) { return MemoryReadStream::seek(offset, SEEK_CUR); } }; /** diff --git a/common/scummsys.h b/common/scummsys.h index eb9088f85d0..82b67b47cdc 100644 --- a/common/scummsys.h +++ b/common/scummsys.h @@ -272,7 +272,6 @@ defined(__DS__) || \ defined(__3DS__) || \ defined(IPHONE) || \ - defined(__PLAYSTATION2__) || \ defined(__PSP__) || \ defined(__SYMBIAN32__) @@ -443,13 +442,8 @@ typedef unsigned int uint32; typedef signed int int32; typedef unsigned int uint; - #ifdef __PLAYSTATION2__ - typedef signed long int64; - typedef unsigned long uint64; - #else typedef signed long long int64; typedef unsigned long long uint64; - #endif #endif // @@ -462,7 +456,8 @@ defined(_M_X64) || \ defined(__ppc64__) || \ defined(__powerpc64__) || \ - defined(__LP64__) + defined(__LP64__) || \ + defined(_M_ARM64) typedef uint64 uintptr; diff --git a/common/str.cpp b/common/str.cpp index 77a50bd768f..535cf438767 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -284,7 +284,7 @@ String &String::operator=(char c) { } String &String::operator+=(const char *str) { - if (_str <= str && str <= _str + _size) + if (pointerInOwnBuffer(str)) return operator+=(String(str)); int len = strlen(str); @@ -297,6 +297,16 @@ String &String::operator+=(const char *str) { return *this; } +bool String::pointerInOwnBuffer(const char *str) const { + //compared pointers must be in the same array or UB + //cast to intptr however is IB + //which includes comparision of the values + uintptr ownBuffStart = (uintptr)_str; + uintptr ownBuffEnd = (uintptr)(_str + _size); + uintptr candidateAddr = (uintptr)str; + return ownBuffStart <= candidateAddr && candidateAddr <= ownBuffEnd; +} + String &String::operator+=(const String &str) { if (&str == this) return operator+=(String(str)); diff --git a/common/str.h b/common/str.h index bce55fd2103..0b2a9f6b89e 100644 --- a/common/str.h +++ b/common/str.h @@ -398,6 +398,8 @@ protected: void decRefCount(int *oldRefCount); void initWithCStr(const char *str, uint32 len); + bool pointerInOwnBuffer(const char *str) const; + void decodeUTF8(U32String &dst) const; void decodeOneByte(U32String &dst, CodePage page) const; }; diff --git a/common/stream.h b/common/stream.h index a3843290e20..1da3cba5609 100644 --- a/common/stream.h +++ b/common/stream.h @@ -279,6 +279,8 @@ public: */ class ReadStream : virtual public Stream { public: + ReadStream() {} + /** * Returns true if a read failed because the stream end has been reached. * This flag is cleared by clearErr(). @@ -707,7 +709,7 @@ public: * This is a SeekableReadStream subclass which adds non-endian read * methods whose endianness is set during the stream creation. */ -class SeekableReadStreamEndian : public SeekableReadStream, public ReadStreamEndian { +class SeekableReadStreamEndian : virtual public SeekableReadStream, virtual public ReadStreamEndian { public: SeekableReadStreamEndian(bool bigEndian) : ReadStreamEndian(bigEndian) {} }; diff --git a/common/substream.h b/common/substream.h index e3161c0a53f..8bc68cc8a99 100644 --- a/common/substream.h +++ b/common/substream.h @@ -66,7 +66,7 @@ public: * Manipulating the parent stream directly /will/ mess up a substream. * @see SubReadStream */ -class SeekableSubReadStream : public SubReadStream, public SeekableReadStream { +class SeekableSubReadStream : public SubReadStream, virtual public SeekableReadStream { protected: SeekableReadStream *_parentStream; uint32 _begin; @@ -86,12 +86,20 @@ public: * Manipulating the parent stream directly /will/ mess up a substream. * @see SubReadStream */ -class SeekableSubReadStreamEndian : public SeekableSubReadStream, public ReadStreamEndian { +class SeekableSubReadStreamEndian : virtual public SeekableSubReadStream, virtual public SeekableReadStreamEndian { public: SeekableSubReadStreamEndian(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool bigEndian, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO) : SeekableSubReadStream(parentStream, begin, end, disposeParentStream), + SeekableReadStreamEndian(bigEndian), ReadStreamEndian(bigEndian) { } + + virtual int32 pos() const { return SeekableSubReadStream::pos(); } + virtual int32 size() const { return SeekableSubReadStream::size(); } + + virtual bool seek(int32 offset, int whence = SEEK_SET) { return SeekableSubReadStream::seek(offset, whence); } + void hexdump(int len, int bytesPerLine = 16, int startOffset = 0) { SeekableSubReadStream::hexdump(len, bytesPerLine, startOffset); } + bool skip(uint32 offset) { return SeekableSubReadStream::seek(offset, SEEK_CUR); } }; /** diff --git a/common/unicode-bidi.cpp b/common/unicode-bidi.cpp index c6b2642b9bd..44f8ca2cc19 100644 --- a/common/unicode-bidi.cpp +++ b/common/unicode-bidi.cpp @@ -64,7 +64,7 @@ void UnicodeBiDiText::initWithU32String(const U32String &input) { FriBidiChar *visual_str = new FriBidiChar[buff_length * sizeof(FriBidiChar)]; _log_to_vis_index = new uint32[input_size]; _vis_to_log_index = new uint32[input_size]; - FriBidiCharType pbase_dir = FRIBIDI_TYPE_ON; + FriBidiParType pbase_dir = FRIBIDI_PAR_ON; if (!fribidi_log2vis( /* input */ @@ -89,7 +89,11 @@ void UnicodeBiDiText::initWithU32String(const U32String &input) { delete[] visual_str; } #else - warning("initWithU32String: Fribidi not available, using input string as fallback"); + static bool fribidiWarning = true; + if (fribidiWarning) { + warning("initWithU32String: Fribidi not available, will use input strings as fallback."); + fribidiWarning = false; + } visual = input; #endif diff --git a/common/winexe.cpp b/common/winexe.cpp index ad6ff965058..d853df01cff 100644 --- a/common/winexe.cpp +++ b/common/winexe.cpp @@ -23,6 +23,7 @@ #include "common/file.h" #include "common/memstream.h" #include "common/str.h" +#include "common/ustr.h" #include "common/winexe.h" #include "common/winexe_ne.h" #include "common/winexe_pe.h" @@ -183,4 +184,59 @@ WinResources *WinResources::createFromEXE(const String &fileName) { return nullptr; } +WinResources::VersionHash *WinResources::parseVersionInfo(SeekableReadStream *res) { + VersionHash *versionMap = new VersionHash; + + while (res->pos() < res->size() && !res->eos()) { + while (res->pos() % 4 && !res->eos()) // Pad to 4 + res->readByte(); + + /* uint16 len = */ res->readUint16LE(); + uint16 valLen = res->readUint16LE(); + uint16 type = res->readUint16LE(); + uint16 c; + + Common::U32String info; + while ((c = res->readUint16LE()) != 0 && !res->eos()) + info += c; + + while (res->pos() % 4 && !res->eos()) // Pad to 4 + res->readByte(); + + if (res->eos()) + break; + + if (type != 0) { // text + Common::U32String value; + for (int j = 0; j < valLen; j++) + value += res->readUint16LE(); + + versionMap->setVal(info.encode(), value); + } else { + if (info == "VS_VERSION_INFO") { + uint16 pos2 = res->pos() + valLen; + + res->readUint32LE(); + res->readUint32LE(); + uint16 fileB = res->readUint16LE(); + uint16 fileA = res->readUint16LE(); + uint16 fileD = res->readUint16LE(); + uint16 fileC = res->readUint16LE(); + uint16 prodB = res->readUint16LE(); + uint16 prodA = res->readUint16LE(); + uint16 prodD = res->readUint16LE(); + uint16 prodC = res->readUint16LE(); + + versionMap->setVal("File:", Common::String::format("%d.%d.%d.%d", fileA, fileB, fileC, fileD)); + versionMap->setVal("Prod:", Common::String::format("%d.%d.%d.%d", prodA, prodB, prodC, prodD)); + + while (res->pos() != pos2 && !res->eos()) + res->readByte(); + } + } + } + + return versionMap; +} + } // End of namespace Common diff --git a/common/winexe.h b/common/winexe.h index 2b81a33261f..cab08675878 100644 --- a/common/winexe.h +++ b/common/winexe.h @@ -130,6 +130,10 @@ public: } static WinResources *createFromEXE(const String &fileName); + + typedef Common::HashMap VersionHash; + + static VersionHash *parseVersionInfo(SeekableReadStream *stream); }; } // End of namespace Common diff --git a/configure b/configure index 630f9ff39e1..a8fc098aab1 100755 --- a/configure +++ b/configure @@ -178,6 +178,7 @@ _iconv=auto _tts=no _gtk=auto _fribidi=auto +_test_cxx11=no # Default option behavior yes/no _debug_build=auto _release_build=auto @@ -542,7 +543,7 @@ get_system_exe_extension() { riscos) _exeext=",e1f" ;; - 3ds | dreamcast | ds | gamecube | n64 | ps2 | psp | switch | wii) + 3ds | dreamcast | ds | gamecube | n64 | psp | switch | wii) _exeext=".elf" ;; gph-linux) @@ -1716,14 +1717,6 @@ ppc-amigaos) _host_cpu=powerpc _host_alias=$_host ;; -ps2) - _host_os=ps2 - _host_cpu=mips64r5900el - _host_alias=ee - # PS2 bogus dirs: they actually depend on launch medium - datadir='host:data' - docdir='host:docs' - ;; ps3) _host_os=ps3 _host_cpu=powerpc @@ -1777,26 +1770,6 @@ switch) # Switch SDK has C++11 constructs so we must enable it _use_cxx11=yes ;; -tizen) - _host_os=tizen - _host_cpu=arm - _host_alias=arm-linux-gnueabi - ;; -webos) - _host_os=webos - _host_cpu=arm - _host_alias=arm-none-linux-gnueabi - # The prefix is always the same on WebOS so we hardcode the default - # here. It is still possible to define a custom prefix which is - # needed when packaging the app with a user-specific app ID. - test "x$prefix" = xNONE && prefix=/media/cryptofs/apps/usr/palm/applications/org.residualvm.residualvm - # WebOS apps are installed into app-specific directories. The - # default directory structure of ScummVM makes no sense here so we - # hardcode WebOS specific directories here. - datarootdir='${prefix}/data' - datadir='${datarootdir}' - docdir='${prefix}/doc' - ;; wii) _host_os=wii _host_cpu=powerpc @@ -1825,7 +1798,7 @@ else fi case $_host in -arm-*riscos | caanoo | gp2x | gp2xwiz | openpandora | ps2 | psp | psp2 | switch) +arm-*riscos | caanoo | gp2x | gp2xwiz | openpandora | psp | psp2 | switch) if test "$_debug_build" = auto; then # If you want to debug one of these platforms, use '--disable-optimizations --enable-debug' _debug_build=no @@ -1894,12 +1867,6 @@ n64) exit 1 fi ;; -ps2) - if test -z "$PS2SDK"; then - echo "Please set PS2SDK in your environment. export PS2SDK=" - exit 1 - fi - ;; ps3) if test -z "$PS3DEV"; then echo "Please set PS3DEV in your environment. export PS3DEV=" @@ -1955,22 +1922,6 @@ riscos) add_line_to_config_mk "BINDHELP := bindhelp" fi ;; -tizen) - if test -z "$TIZEN_ROOTSTRAP"; then - echo "Please set TIZEN_ROOTSTRAP in your environment. export TIZEN_ROOTSTRAP=" - exit 1 - fi - ;; -webos) - if test -z "$WEBOS_SDK"; then - echo "Please set WEBOS_SDK in your environment. export WEBOS_SDK=" - exit 1 - fi - if test -z "$WEBOS_PDK"; then - echo "Please set WEBOS_PDK in your environment. export WEBOS_PDK=" - exit 1 - fi - ;; *) ;; esac @@ -2269,7 +2220,7 @@ fi # However, some platforms use GNU extensions in system header files, so # for these we must not use -pedantic. case $_host_os in -3ds | android | androidsdl | gamecube | ps2 | psp | switch | tizen | wii | webos) +3ds | android | androidsdl | gamecube | psp | switch | wii) ;; *) # ICC does not support pedantic, while GCC and clang do. @@ -2509,7 +2460,7 @@ case $_host_cpu in openpandora) define_in_config_if_yes yes 'USE_ARM_NEON_ASPECT_CORRECTOR' ;; - androidsdl-armeabi | arm-*riscos | caanoo | ds | gp2x | gp2xwiz | maemo | tizen) + androidsdl-armeabi | arm-*riscos | caanoo | ds | gp2x | gp2xwiz | maemo ) define_in_config_if_yes yes 'USE_ARM_SCALER_ASM' # FIXME: The following feature exhibits a bug. It produces distorted # sound since 9003ce517ff9906b0288f9f7c02197fd091d4554. The ARM @@ -2944,14 +2895,6 @@ EOF add_line_to_config_mk 'N64 = 1' _nuked_opl=no ;; - ps2) - append_var CXXFLAGS "-G2" - append_var DEFINES "-D_EE" - append_var DEFINES "-D__PLAYSTATION2__" - if test -z "$PS2SDK_OLD"; then - append_var DEFINES "-D__NEW_PS2SDK__" - fi - ;; ps3) # Force use of SDL and freetype from the ps3 toolchain _sdlpath="$PS3DEV/portlibs/ppu:$PS3DEV/portlibs/ppu/bin" @@ -3056,28 +2999,6 @@ EOF _optimization_level=-O3 fi ;; - tizen) - add_line_to_config_mk "TIZEN_ROOTSTRAP = $TIZEN_ROOTSTRAP" - append_var LDFLAGS "--sysroot=${TIZEN_ROOTSTRAP}" - append_var LDFLAGS "-L${TIZEN_LIBS}/lib" - append_var CXXFLAGS "-I${TIZEN_LIBS}/include" - ;; - webos) - append_var CXXFLAGS "--sysroot=$WEBOS_PDK/arm-gcc/sysroot" - append_var CXXFLAGS "-I$WEBOS_PDK/include" - append_var CXXFLAGS "-I$WEBOS_PDK/include/SDL" - append_var CXXFLAGS "-I$WEBOS_PDK/device/usr/include" - # These compiler options are needed to support the Palm Pixi - append_var CXXFLAGS "-mcpu=arm1136jf-s" - append_var CXXFLAGS "-mfpu=vfp " - append_var CXXFLAGS "-mfloat-abi=softfp" - append_var LDFLAGS "-L$WEBOS_PDK/device/lib" - append_var LDFLAGS "-L$WEBOS_PDK/device/usr/lib" - append_var LDFLAGS "-Wl,--allow-shlib-undefined" - append_var LDFLAGS "--sysroot=$WEBOS_PDK/arm-gcc/sysroot" - add_line_to_config_mk "WEBOS_SDK = $WEBOS_SDK" - _seq_midi=no - ;; wii) _optimization_level=-Os append_var CXXFLAGS "-mrvl" @@ -3432,47 +3353,6 @@ if test -n "$_host"; then _port_mk="backends/platform/sdl/amigaos/amigaos.mk" ;; - ps2) - append_var DEFINES "-DDISABLE_TEXT_CONSOLE" - append_var DEFINES "-DDISABLE_COMMAND_LINE" - append_var DEFINES "-DDISABLE_DOSBOX_OPL" - append_var DEFINES "-DDISABLE_SID" - append_var DEFINES "-DDISABLE_NES_APU" - append_var CXXFLAGS "-fno-exceptions" - append_var CXXFLAGS "-fno-rtti" - _backend="ps2" - _build_scalers=no - _mt32emu=no - _nuked_opl=no - # HACK to enable mad & zlib (they are not properly detected due to linker issues). - # This trick doesn't work for tremor right now, as the PS2 port the resulting library - # libtremor, while our code later on expects it to be called libvorbisidec. - # TODO: Enable tremor, e.g. by adding -ltremor or by renaming the lib. - # Disable this for older SDK as this breaks the build otherwise... - if test -z "$PS2SDK_OLD" && test "$_tremor" = auto; then - _tremor=yes - fi - _mad=yes - _zlib=yes - # HACK to fix compilation of C source files for now. - add_line_to_config_mk 'CC := ee-gcc' - add_line_to_config_mk 'CFLAGS := -std=c99 -W -Wno-unused-parameter -Wconversion -pedantic -G2 -s -O2 -Wuninitialized' - # HACK to fix linking for now. It seems ee-g++ does not handle linking correctly. - LD=ee-gcc - - if test "$_debug_build" = yes; then - # TODO: Setup debug build properly - append_var DEFINES "-D__PS2_DEBUG__" - #append_var INCLUDES "-I$(PS2GDB)/ee" - #append_var LDFLAGS "-L$(PS2GDB)/lib" - append_var LDFLAGS "-lps2gdbStub" - append_var LDFLAGS "-lps2ip" - append_var LDFLAGS "-ldebug" - else - # If not building for debug mode, strip binaries. - append_var CXXFLAGS "-s" - fi - ;; ps3) _timidity=no _vkeybd=yes @@ -3515,29 +3395,6 @@ if test -n "$_host"; then _vkeybd=yes _port_mk="backends/platform/sdl/switch/switch.mk" ;; - tizen) - _unix=yes - _backend="tizen" - _port_mk="backends/platform/tizen/tizen.mk" - _build_scalers=no - _seq_midi=no - _mt32emu=no - _timidity=no - _vkeybd=yes - # Tizen relies on the OpenGL ES output thus we always enable it. - _opengl_mode=gles - ;; - webos) - _backend="webos" - _port_mk="backends/platform/webos/webos.mk" - _build_scalers=yes - _build_hq_scalers=no - _timidity=no - _mt32emu=no - _seq_midi=no - _vkeybd=no - add_line_to_config_mk "HOST_COMPILER = `uname`" - ;; wii) _backend="wii" _build_scalers=no @@ -3651,6 +3508,7 @@ case $_backend in ;; null) append_var DEFINES "-DUSE_NULL_DRIVER" + _text_console=yes ;; openpandora) append_var DEFINES "-DOPENPANDORA" @@ -3660,26 +3518,6 @@ case $_backend in fi _sdl=auto ;; - ps2) - append_var DEFINES "-D_EE" - append_var DEFINES "-DFORCE_RETURN_TO_LAUNCHER" - append_var INCLUDES "-I$PS2SDK/ee/include" - append_var INCLUDES "-I$PS2SDK/common/include" - append_var INCLUDES "-I$PS2SDK/ports/include" - if test "$_dynamic_modules" = no ; then - append_var LDFLAGS "-mno-crt0" - append_var LDFLAGS "$PS2SDK/ee/startup/crt0.o" - append_var LDFLAGS "-T $PS2SDK/ee/startup/linkfile" - fi - append_var LDFLAGS "-L$PS2SDK/ee/lib" - append_var LDFLAGS "-L$PS2SDK/ports/lib" - if test -d "$PS2DEV/isjpcm"; then - append_var INCLUDES "-I$PS2DEV/isjpcm/include" - append_var LDFLAGS "-L$PS2DEV/isjpcm/lib" - fi - append_var LIBS "-lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm" - append_var LIBS "-lm -lc -lfileXio -lkernel -lstdc++" - ;; psp) append_var DEFINES "-D__PSP__" append_var DEFINES "-DDISABLE_COMMAND_LINE" @@ -3712,34 +3550,6 @@ case $_backend in _sdl=auto append_var MODULES "backends/platform/sdl" ;; - tizen) - # dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included - append_var DEFINES "-DTIZEN -DDISABLE_STDIO_FILESTREAM -DNONSTANDARD_PORT" - append_var DEFINES "-DNO_STDERR_STDOUT" - append_var DEFINES "-DDISABLE_COMMAND_LINE" - append_var INCLUDES '-I$(srcdir)/backends/platform/tizen' - append_var INCLUDES '-I$(TIZEN_ROOTSTRAP)/usr/include' - append_var INCLUDES '-I$(TIZEN_ROOTSTRAP)/usr/include/osp' - if test "$_debug_build" = yes; then - append_var CXXFLAGS "-D_DEBUG -DBUILD_DLL -O0 -g3" - fi - # created a shared library for inclusion via the eclipse build - append_var CXXFLAGS "-Wno-psabi" - append_var CXXFLAGS "--sysroot=${TIZEN_ROOTSTRAP}" - append_var CXXFLAGS "-fmessage-length=0" - append_var 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. - append_var LIBS "-lSDL -lpdl" - append_var DEFINES "-DWEBOS" - append_var MODULES "backends/platform/sdl" - _sdl=yes - _sdlversion=1.2.0 - ;; wii) append_var DEFINES "-D__WII__" append_var DEFINES "-DGEKKO" @@ -3883,7 +3693,7 @@ fi # Enable 16bit support only for backends which support it # case $_backend in - 3ds | android | androidsdl | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | psp2 | samsungtv | sdl | switch | tizen | webos | wii) + 3ds | android | androidsdl | dingux | dc | gph | iphone | ios7 | maemo | null | openpandora | psp | psp2 | samsungtv | sdl | switch | wii) if test "$_16bit" = auto ; then _16bit=yes else @@ -3956,10 +3766,10 @@ esac # echo_n "Checking if host is POSIX compliant... " case $_host_os in - amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp2 | psp | riscos | wii) + amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps3 | psp2 | psp | riscos | wii) _posix=no ;; - 3ds | android | androidsdl | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | switch | uclinux* | webos) + 3ds | android | androidsdl | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | switch | uclinux*) _posix=yes ;; os2-emx*) @@ -4165,14 +3975,6 @@ PLUGIN_EXTRA_DEPS = $(EXECUTABLE) PLUGIN_LDFLAGS := -Wl,--enable-auto-import -shared ./libresidualvm.a PRE_OBJS_FLAGS := -Wl,--whole-archive POST_OBJS_FLAGS := -Wl,--export-all-symbols -Wl,--no-whole-archive -Wl,--out-implib,./libresidualvm.a -' - ;; - ps2) - _elf_loader=yes - append_var DEFINES "-DUNCACHED_PLUGINS" -_mak_plugins=' -LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-T$(srcdir)/backends/plugins/ps2/main_prog.ld -PLUGIN_LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-T$(srcdir)/backends/plugins/ps2/plugin.ld -lstdc++ -lc ' ;; psp) @@ -4181,18 +3983,6 @@ PLUGIN_LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-T$(srcdir)/backend _mak_plugins=' LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/psp/main_prog.ld PLUGIN_LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/psp/plugin.ld -lstdc++ -lc -' - ;; - webos) - _plugin_prefix="lib" - _plugin_suffix=".so" - append_var CXXFLAGS "-fpic" - append_var LIBS "-ldl" -_mak_plugins=' -PLUGIN_EXTRA_DEPS = -PLUGIN_LDFLAGS += -shared $(LDFLAGS) -PRE_OBJS_FLAGS := -Wl,-export-dynamic -Wl,-whole-archive -POST_OBJS_FLAGS := -Wl,-no-whole-archive ' ;; *) @@ -4310,7 +4100,7 @@ int main(void) { return 0; } EOF cc_check -lsapi -lole32 && _tts=yes ;; - linux*) + linux* | freebsd*) cat > $TMPC << EOF #include int main(void) { return 0; } @@ -4385,8 +4175,6 @@ if test "$_tremor" = yes && test "$_vorbis" = no; then if test "$_tremolo" = yes ; then add_line_to_config_h '#define USE_TREMOLO' append_var LIBS "$TREMOR_LIBS -ltremolo" - elif test "$_host" = ps2 ; then - LIBS="-ltremor $LIBS" else append_var LIBS "$TREMOR_LIBS -lvorbisidec" fi @@ -4977,6 +4765,10 @@ if test "$_fluidsynth" = auto; then int main(void) { delete_fluid_settings(new_fluid_settings()); return 0; } EOF cc_check_no_clean $FLUIDSYNTH_CFLAGS $FLUIDSYNTH_LIBS && _fluidsynth=yes + if test "$_fluidsynth" != yes && test "$_pkg_config" = "yes" && $_pkgconfig --exists fluidsynth; then + FLUIDSYNTH_LIBS="`$_pkgconfig --static --libs fluidsynth`" + cc_check_no_clean $FLUIDSYNTH_CFLAGS $FLUIDSYNTH_LIBS && _fluidsynth=yes + fi if test "$_fluidsynth" != yes; then FLUIDSYNTH_LIBS="$FLUIDSYNTH_STATIC_LIBS" cc_check_no_clean $FLUIDSYNTH_CFLAGS $FLUIDSYNTH_LIBS && _fluidsynth=yes @@ -5495,6 +5287,7 @@ case $_host_os in linuxcd=no cat > $TMPC << EOF #include +#include #include int main(void) { int x = CDROMREADAUDIO; @@ -5732,8 +5525,8 @@ if test "$_tts" = "no"; then echo "no" else case $_host_os in - linux*) - echo "linux" + linux* | freebsd*) + echo "speech dispatcher" _tts=yes define_in_config_if_yes $_tts 'USE_SPEECH_DISPATCHER' append_var LIBS '-lspeechd -lpthread' @@ -5814,15 +5607,11 @@ case $_backend in # Add ../plugins as a path so plugins can be found when running from a .PND. append_var DEFINES "-DPLUGIN_DIRECTORY=\\\"../plugins\\\"" ;; - maemo | webos) - # The WebOS and Maemo apps want the plugins in the "lib" directory + maemo) + # The Maemo apps want the plugins in the "lib" directory # without a scummvm sub directory. append_var DEFINES "-DPLUGIN_DIRECTORY=\\\"$libdir\\\"" ;; - ps2) - # PS2 bogus dir: it actually depends on launch medium - append_var DEFINES "-DPLUGIN_DIRECTORY=\\\"host:plugins\\\"" - ;; *) append_var DEFINES "-DPLUGIN_DIRECTORY=\\\"$libdir/residualvm\\\"" ;; @@ -5849,7 +5638,7 @@ echo "$_enable_asan" echo_n "Backend... " echo_n "$_backend" -if test "$_backend" = "sdl" -a -n "$_sdlversion"; then +if test "$_sdl" = yes -a -n "$_sdlversion"; then echo_n " ($_sdlversion)" fi diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp index 09592a40b5b..0661dd94c08 100644 --- a/devtools/create_project/create_project.cpp +++ b/devtools/create_project/create_project.cpp @@ -28,26 +28,27 @@ #undef main #endif // main -#include "config.h" #include "create_project.h" +#include "config.h" #include "cmake.h" #include "codeblocks.h" +#include "msbuild.h" #include "msvc.h" #include "visualstudio.h" -#include "msbuild.h" #include "xcode.h" +#include #include +#include #include +#include #include #include -#include -#include -#include +#include -#include #include +#include #include #if (defined(_WIN32) || defined(WIN32)) && !defined(__GNUC__) @@ -57,11 +58,11 @@ #if (defined(_WIN32) || defined(WIN32)) #include #else +#include +#include #include #include #include -#include -#include #endif namespace { @@ -133,7 +134,7 @@ int main(int argc, char *argv[]) { setup.features = getAllFeatures(); ProjectType projectType = kProjectNone; - const MSVCVersion* msvc = NULL; + const MSVCVersion *msvc = NULL; int msvcVersion = 0; // Parse command line arguments @@ -141,7 +142,7 @@ int main(int argc, char *argv[]) { for (int i = 2; i < argc; ++i) { if (!std::strcmp(argv[i], "--list-engines")) { cout << " The following enables are available in the " PROJECT_DESCRIPTION " source distribution\n" - " located at \"" << srcDir << "\":\n"; + << " located at \"" << srcDir << "\":\n"; cout << " state | name | description\n\n"; cout.setf(std::ios_base::left, std::ios_base::adjustfield); @@ -275,7 +276,7 @@ int main(int argc, char *argv[]) { } else if (!std::strcmp(argv[i], "--build-events")) { setup.runBuildEvents = true; } else if (!std::strcmp(argv[i], "--installer")) { - setup.runBuildEvents = true; + setup.runBuildEvents = true; setup.createInstaller = true; } else if (!std::strcmp(argv[i], "--tools")) { setup.devTools = true; @@ -283,6 +284,8 @@ int main(int argc, char *argv[]) { setup.tests = true; } else if (!std::strcmp(argv[i], "--sdl1")) { setup.useSDL2 = false; + } else if (!std::strcmp(argv[i], "--use-canonical-lib-names")) { + setup.useCanonicalLibNames = true; } else { std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n"; return -1; @@ -431,6 +434,12 @@ int main(int argc, char *argv[]) { setup.libraries.push_back("sdl2"); } + if (setup.useCanonicalLibNames) { + for (StringList::iterator lib = setup.libraries.begin(); lib != setup.libraries.end(); ++lib) { + *lib = getCanonicalLibName(*lib); + } + } + // Add additional project-specific library #ifdef ADDITIONAL_LIBRARY setup.libraries.push_back(ADDITIONAL_LIBRARY); @@ -475,7 +484,6 @@ int main(int argc, char *argv[]) { provider = new CreateProjectTool::CodeBlocksProvider(globalWarnings, projectWarnings); - // Those libraries are automatically added by MSVC, but we need to add them manually with mingw setup.libraries.push_back("ole32"); setup.libraries.push_back("uuid"); @@ -665,11 +673,11 @@ int main(int argc, char *argv[]) { } // Setup project name and description - setup.projectName = PROJECT_NAME; + setup.projectName = PROJECT_NAME; setup.projectDescription = PROJECT_DESCRIPTION; if (setup.devTools) { - setup.projectName += "-tools"; + setup.projectName += "-tools"; setup.projectDescription += "Tools"; } @@ -704,49 +712,52 @@ void displayHelp(const char *exe) { " Additionally there are the following switches for changing various settings:\n" "\n" "Project specific settings:\n" - " --cmake build CMake 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" - " MSVC project files. By default the prefix is the\n" - " \"path\\to\\source\" argument\n" - " --output-dir path overwrite path, where the project files are placed\n" - " By default this is \".\", i.e. the current working\n" - " directory\n" + " --cmake build CMake 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" + " MSVC project files. By default the prefix is the\n" + " \"path\\to\\source\" argument\n" + " --output-dir path overwrite path, where the project files are placed\n" + " By default this is \".\", i.e. the current working\n" + " directory\n" "\n" "MSVC specific settings:\n" - " --msvc-version version set the targeted MSVC version. Possible values:\n"; + " --msvc-version version set the targeted MSVC version. Possible values:\n"; const MSVCList msvc = getAllMSVCVersions(); for (MSVCList::const_iterator i = msvc.begin(); i != msvc.end(); ++i) cout << " " << i->version << " stands for \"" << i->name << "\"\n"; - cout << " If no version is set, the latest installed version is used\n" - " --build-events Run custom build events as part of the build\n" - " (default: false)\n" - " --installer Create 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" - " --tests Create project files for the tests\n" - " (ignores --build-events and --installer, as well as engine settings)\n" - " (default: false)\n" + cout << " If no version is set, the latest installed version is used\n" + " --build-events Run custom build events as part of the build\n" + " (default: false)\n" + " --installer Create 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" + " --tests Create project files for the tests\n" + " (ignores --build-events and --installer, as well as engine settings)\n" + " (default: false)\n" + " --use-canonical-lib-names Use canonical library names for linking. This makes it easy to use\n" + " e.g. vcpkg-provided libraries\n" + " (default: false)\n" "\n" "Engines settings:\n" - " --list-engines list all available engines and their default state\n" - " --enable-engine= enable building of the engine with the name \"name\"\n" - " --disable-engine= disable building of the engine with the name \"name\"\n" - " --enable-all-engines enable building of all engines\n" - " --disable-all-engines disable building of all engines\n" + " --list-engines list all available engines and their default state\n" + " --enable-engine= enable building of the engine with the name \"name\"\n" + " --disable-engine= disable building of the engine with the name \"name\"\n" + " --enable-all-engines enable building of all engines\n" + " --disable-all-engines disable building of all engines\n" "\n" "Optional features settings:\n" - " --enable- enable inclusion of the feature \"name\"\n" - " --disable- disable inclusion of the feature \"name\"\n" + " --enable- enable inclusion of the feature \"name\"\n" + " --disable- disable inclusion of the feature \"name\"\n" "\n" "SDL settings:\n" - " --sdl1 link to SDL 1.2, instead of SDL 2.0\n" + " --sdl1 link to SDL 1.2, instead of SDL 2.0\n" "\n" " There are the following features available:\n" "\n"; @@ -952,9 +963,12 @@ bool parseEngine(const std::string &line, EngineDesc &engine) { return false; ++token; - engine.name = *token; ++token; - engine.desc = *token; ++token; - engine.enable = (*token == "yes"); ++token; + engine.name = *token; + ++token; + engine.desc = *token; + ++token; + engine.enable = (*token == "yes"); + ++token; if (token != tokens.end()) { engine.subEngines = tokenize(*token); ++token; @@ -1043,6 +1057,7 @@ TokenList tokenize(const std::string &input, char separator) { } namespace { +// clang-format off const Feature s_features[] = { // Libraries { "libz", "USE_ZLIB", "zlib", true, "zlib (compression) support" }, @@ -1085,6 +1100,7 @@ const Feature s_features[] = { { "langdetect", "USE_DETECTLANG", "", true, "System language detection support" }, // This feature actually depends on "translation", there // is just no current way of properly detecting this... { "text-console", "USE_TEXT_CONSOLE_FOR_DEBUGGER", "", false, "Text console debugger" }, // This feature is always applied in xcode projects +// { "tts", "USE_TTS", "", true, "Text to speech support"} // ResidualVM change }; const Tool s_tools[] = { @@ -1101,8 +1117,46 @@ const MSVCVersion s_msvc[] = { { 15, "Visual Studio 2017", "12.00", "15", "15.0", "v141", "llvm" }, { 16, "Visual Studio 2019", "12.00", "Version 16", "16.0", "v142", "llvm" } }; + +const std::pair s_canonical_lib_name_map[] = { + std::make_pair("jpeg-static", "jpeg"), + std::make_pair("libfaad", "faad"), + std::make_pair("libFLAC_static", "FLAC"), + std::make_pair("libfluidsynth", "fluidsynth"), + std::make_pair("libmad", "mad"), + std::make_pair("libmpeg2", "mpeg2"), + std::make_pair("libogg_static", "ogg"), + std::make_pair("libtheora_static", "theora"), + std::make_pair("libvorbis_static", "vorbis"), + std::make_pair("libvorbisfile_static", "vorbisfile"), + std::make_pair("SDL_net", "SDL2_net"), // Only support SDL2 + std::make_pair("win_utf8_io_static", "FLAC") // This is some FLAC-specific library not needed with vcpkg, but as there's '.lib' appended to each library, we can't set it to empty, so set it to FLAC again instead +}; + +const char *s_msvc_arch_names[] = {"arm64", "x86", "x64"}; +const char *s_msvc_config_names[] = {"arm64", "Win32", "x64"}; +// clang-format on } // End of anonymous namespace +std::string getMSVCArchName(MSVC_Architecture arch) { + return s_msvc_arch_names[arch]; +} + +std::string getMSVCConfigName(MSVC_Architecture arch) { + return s_msvc_config_names[arch]; +} + +std::string getCanonicalLibName(const std::string &lib) { + const size_t libCount = sizeof(s_canonical_lib_name_map) / sizeof(s_canonical_lib_name_map[0]); + + for (size_t i = 0; i < libCount; ++i) { + if (s_canonical_lib_name_map[i].first == lib) { + return s_canonical_lib_name_map[i].second; + } + } + return lib; +} + FeatureList getAllFeatures() { const size_t featureCount = sizeof(s_features) / sizeof(s_features[0]); @@ -1124,15 +1178,30 @@ StringList getFeatureDefines(const FeatureList &features) { return defines; } +StringList getFeatureLibraries(const Feature &feature) { + StringList libraries; + + if (feature.enable && feature.libraries && feature.libraries[0]) { + StringList fLibraries = tokenize(feature.libraries); + libraries.splice(libraries.end(), fLibraries); + } + // The libraries get sorted as they can get used in algorithms where ordering is a + // precondition, e.g. merge() + libraries.sort(); + + return libraries; +} + StringList getFeatureLibraries(const FeatureList &features) { StringList libraries; for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i) { - if (i->enable && i->libraries && i->libraries[0]) { - StringList fLibraries = tokenize(i->libraries); - libraries.splice(libraries.end(), fLibraries); + StringList fl = getFeatureLibraries(*i); + for (StringList::const_iterator flit = fl.begin(); flit != fl.end(); ++flit) { + libraries.push_back(*flit); } } + libraries.sort(); return libraries; } @@ -1156,6 +1225,27 @@ bool getFeatureBuildState(const std::string &name, FeatureList &features) { } } +BuildSetup removeFeatureFromSetup(BuildSetup setup, const std::string &feature) { + // TODO: use const_iterator in C++11 + for (FeatureList::iterator i = setup.features.begin(); i != setup.features.end(); ++i) { + if (i->enable && feature == i->name) { + StringList feature_libs = getFeatureLibraries(*i); + for (StringList::iterator lib = feature_libs.begin(); lib != feature_libs.end(); ++lib) { + if (setup.useCanonicalLibNames) { + *lib = getCanonicalLibName(*lib); + } + setup.libraries.remove(*lib); + } + if (i->define && i->define[0]) { + setup.defines.remove(i->define); + } + setup.features.erase(i); + break; + } + } + return setup; +} + ToolList getAllTools() { const size_t toolCount = sizeof(s_tools) / sizeof(s_tools[0]); @@ -1250,7 +1340,8 @@ void splitFilename(const std::string &fileName, std::string &name, std::string & std::string basename(const std::string &fileName) { const std::string::size_type slash = fileName.find_last_of('/'); - if (slash == std::string::npos) return fileName; + if (slash == std::string::npos) + return fileName; return fileName.substr(slash + 1); } @@ -1410,7 +1501,6 @@ void createDirectory(const std::string &dir) { } } #endif - } /** @@ -1475,7 +1565,7 @@ FileNode *scanFiles(const std::string &dir, const StringList &includeList, const // Project Provider methods ////////////////////////////////////////////////////////////////////////// ProjectProvider::ProjectProvider(StringList &global_warnings, std::map &project_warnings, const int version) - : _version(version), _globalWarnings(global_warnings), _projectWarnings(project_warnings) { + : _version(version), _globalWarnings(global_warnings), _projectWarnings(project_warnings) { } void ProjectProvider::createProject(BuildSetup &setup) { @@ -1501,7 +1591,8 @@ void ProjectProvider::createProject(BuildSetup &setup) { if (i->first == setup.projectName) continue; // Retain the files between engines if we're creating a single project - in.clear(); ex.clear(); + in.clear(); + ex.clear(); const std::string moduleDir = setup.srcDir + targetFolder + i->first; @@ -1511,7 +1602,8 @@ void ProjectProvider::createProject(BuildSetup &setup) { if (setup.tests) { // Create the main project file. - in.clear(); ex.clear(); + in.clear(); + ex.clear(); 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); @@ -1525,7 +1617,8 @@ void ProjectProvider::createProject(BuildSetup &setup) { 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(); + in.clear(); + ex.clear(); // File list for the Project file createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex); createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex); @@ -1620,8 +1713,10 @@ std::string ProjectProvider::createUUID() const { for (int i = 0; i < kUUIDLen; ++i) uuid[i] = (unsigned char)((std::rand() / (double)(RAND_MAX)) * 0xFF); - uuid[8] &= 0xBF; uuid[8] |= 0x80; - uuid[6] &= 0x4F; uuid[6] |= 0x40; + uuid[8] &= 0xBF; + uuid[8] |= 0x80; + uuid[6] &= 0x4F; + uuid[6] |= 0x40; return UUIDToString(uuid); #endif @@ -1633,7 +1728,7 @@ std::string ProjectProvider::createUUID(const std::string &name) const { if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { error("CryptAcquireContext failed"); } - + // Use MD5 hashing algorithm HCRYPTHASH hHash = NULL; if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { @@ -1643,7 +1738,7 @@ std::string ProjectProvider::createUUID(const std::string &name) const { // Hash unique ScummVM namespace {5f5b43e8-35ff-4f1e-ad7e-a2a87e9b5254} const BYTE uuidNs[kUUIDLen] = - { 0x5f, 0x5b, 0x43, 0xe8, 0x35, 0xff, 0x4f, 0x1e, 0xad, 0x7e, 0xa2, 0xa8, 0x7e, 0x9b, 0x52, 0x54 }; + {0x5f, 0x5b, 0x43, 0xe8, 0x35, 0xff, 0x4f, 0x1e, 0xad, 0x7e, 0xa2, 0xa8, 0x7e, 0x9b, 0x52, 0x54}; if (!CryptHashData(hHash, uuidNs, kUUIDLen, 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); @@ -1667,8 +1762,10 @@ std::string ProjectProvider::createUUID(const std::string &name) const { } // Add version and variant - uuid[6] &= 0x0F; uuid[6] |= 0x30; - uuid[8] &= 0x3F; uuid[8] |= 0x80; + uuid[6] &= 0x0F; + uuid[6] |= 0x30; + uuid[8] &= 0x3F; + uuid[8] |= 0x80; CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); @@ -1719,7 +1816,8 @@ void ProjectProvider::addFilesToProject(const std::string &dir, std::ofstream &p continue; // Search for duplicates - StringList::const_iterator j = i; ++j; + StringList::const_iterator j = i; + ++j; for (; j != includeList.end(); ++j) { std::string candidateFileName = getLastPathComponent(*j); std::transform(candidateFileName.begin(), candidateFileName.end(), candidateFileName.begin(), tolower); @@ -1990,7 +2088,7 @@ void ProjectProvider::createEnginePluginsTable(const BuildSetup &setup) { << "#endif\n"; } } -} // End of anonymous namespace +} // namespace CreateProjectTool void error(const std::string &message) { std::cerr << "ERROR: " << message << "!" << std::endl; diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h index 19c2ba094be..56eec932052 100644 --- a/devtools/create_project/create_project.h +++ b/devtools/create_project/create_project.h @@ -23,12 +23,12 @@ #ifndef TOOLS_CREATE_PROJECT_H #define TOOLS_CREATE_PROJECT_H -#ifndef __has_feature // Optional of course. -#define __has_feature(x) 0 // Compatibility with non-clang compilers. +#ifndef __has_feature // Optional of course. +#define __has_feature(x) 0 // Compatibility with non-clang compilers. #endif -#include #include +#include #include #include @@ -156,12 +156,12 @@ StringList getEngineDefines(const EngineDescList &engines); * used to build ScummVM. */ struct Feature { - const char *name; ///< Name of the feature - const char *define; ///< Define of the feature + const char *name; ///< Name of the feature + const char *define; ///< Define of the feature - const char *libraries; ///< Libraries, which need to be linked, for the feature + const char *libraries; ///< Libraries, which need to be linked, for the feature - bool enable; ///< Whether the feature is enabled or not + bool enable; ///< Whether the feature is enabled or not const char *description; ///< Human readable description of the feature @@ -172,8 +172,8 @@ struct Feature { typedef std::list FeatureList; struct Tool { - const char *name; ///< Name of the tools - bool enable; ///< Whether the tools is enabled or not + const char *name; ///< Name of the tools + bool enable; ///< Whether the tools is enabled or not }; typedef std::list ToolList; @@ -200,6 +200,14 @@ StringList getFeatureDefines(const FeatureList &features); */ StringList getFeatureLibraries(const FeatureList &features); +/** + * Returns a list of all external library files, according to the + * feature passed. + * + * @param features Feature for the build (this may contain features, which are *not* enabled!) + */ +StringList getFeatureLibraries(const Feature &feature); + /** * Sets the state of a given feature. This can be used to * either include or exclude an feature. @@ -228,8 +236,8 @@ bool getFeatureBuildState(const std::string &name, FeatureList &features); * It also contains the path to the project source root. */ struct BuildSetup { - std::string projectName; ///< Project name - std::string projectDescription; ///< Project description + std::string projectName; ///< Project name + std::string projectDescription; ///< Project description std::string srcDir; ///< Path to the sources. std::string filePrefix; ///< Prefix for the relative path arguments in the project files. @@ -242,18 +250,20 @@ struct BuildSetup { 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 installer after the build - bool useSDL2; ///< Whether to use SDL2 or not. + 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 installer after the build + bool useSDL2; ///< Whether to use SDL2 or not. + bool useCanonicalLibNames; ///< Whether to use canonical libraries names or default ones BuildSetup() { - devTools = false; - tests = false; - runBuildEvents = false; + devTools = false; + tests = false; + runBuildEvents = false; createInstaller = false; - useSDL2 = true; + useSDL2 = true; + useCanonicalLibNames = false; } }; @@ -263,17 +273,17 @@ struct BuildSetup { * @param message The error message to print to stderr. */ #if defined(__GNUC__) - #define NORETURN_POST __attribute__((__noreturn__)) +#define NORETURN_POST __attribute__((__noreturn__)) #elif defined(_MSC_VER) - #define NORETURN_PRE __declspec(noreturn) +#define NORETURN_PRE __declspec(noreturn) #endif #ifndef NORETURN_PRE -#define NORETURN_PRE +#define NORETURN_PRE #endif #ifndef NORETURN_POST -#define NORETURN_POST +#define NORETURN_POST #endif void NORETURN_PRE error(const std::string &message) NORETURN_POST; @@ -294,6 +304,15 @@ struct MSVCVersion { }; typedef std::list MSVCList; +enum MSVC_Architecture { + ARCH_ARM64, + ARCH_X86, + ARCH_AMD64 +}; + +std::string getMSVCArchName(MSVC_Architecture arch); +std::string getMSVCConfigName(MSVC_Architecture arch); + /** * Creates a list of all supported versions of Visual Studio. * @@ -316,6 +335,23 @@ const MSVCVersion *getMSVCVersion(int version); */ int getInstalledMSVC(); +/** + * Return a "canonical" library name, so it is easier to integrate other providers of dependencies. + * + * @param lib The link library as provided by ScummVM libs. + * @return Canonical link library. + */ +std::string getCanonicalLibName(const std::string &lib); + +/** + * Removes given feature from setup. + * + * @param setup The setup to be processed. + * @param feature The feature to be removed + * @return A copy of setup less feature. + */ +BuildSetup removeFeatureFromSetup(BuildSetup setup, const std::string &feature); + namespace CreateProjectTool { /** @@ -464,11 +500,11 @@ public: static std::string getLastPathComponent(const std::string &path); protected: - const int _version; ///< Target project version - StringList &_globalWarnings; ///< Global warnings - std::map &_projectWarnings; ///< Per-project warnings + const int _version; ///< Target project version + StringList &_globalWarnings; ///< Global warnings + std::map &_projectWarnings; ///< Per-project warnings - UUIDMap _uuidMap; ///< List of (project name, UUID) pairs + UUIDMap _uuidMap; ///< List of (project name, UUID) pairs /** * Create workspace/solution file @@ -590,7 +626,6 @@ protected: std::string createUUID(const std::string &name) const; private: - /** * Returns the string representation of an existing UUID. * @@ -608,6 +643,6 @@ private: void createEnginePluginsTable(const BuildSetup &setup); }; -} // End of CreateProjectTool namespace +} // namespace CreateProjectTool #endif // TOOLS_CREATE_PROJECT_H diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp index f72bec9ceaa..34a1212425c 100644 --- a/devtools/create_project/msbuild.cpp +++ b/devtools/create_project/msbuild.cpp @@ -20,11 +20,11 @@ * */ -#include "config.h" #include "msbuild.h" +#include "config.h" -#include #include +#include namespace CreateProjectTool { @@ -32,8 +32,12 @@ namespace CreateProjectTool { // MSBuild Provider (Visual Studio 2010 and later) ////////////////////////////////////////////////////////////////////////// -MSBuildProvider::MSBuildProvider(StringList &global_warnings, std::map &project_warnings, const int version, const MSVCVersion& msvc) - : MSVCProvider(global_warnings, project_warnings, version, msvc) { +MSBuildProvider::MSBuildProvider(StringList &global_warnings, std::map &project_warnings, const int version, const MSVCVersion &msvc) + : MSVCProvider(global_warnings, project_warnings, version, msvc) { + + _archs.push_back(ARCH_X86); + _archs.push_back(ARCH_AMD64); + _archs.push_back(ARCH_ARM64); } const char *MSBuildProvider::getProjectExtension() { @@ -48,23 +52,23 @@ namespace { inline void outputConfiguration(std::ostream &project, const std::string &config, const std::string &platform) { project << "\t\t\n" - "\t\t\t" << config << "\n" - "\t\t\t" << platform << "\n" - "\t\t\n"; + << "\t\t\t" << config << "\n" + << "\t\t\t" << platform << "\n" + << "\t\t\n"; } inline void outputConfigurationType(const BuildSetup &setup, std::ostream &project, const std::string &name, const std::string &config, const std::string &toolset) { project << "\t\n" - "\t\t" << ((name == setup.projectName || setup.devTools || setup.tests) ? "Application" : "StaticLibrary") << "\n" - "\t\t" << toolset << "\n" - "\t\n"; + << "\t\t" << ((name == setup.projectName || setup.devTools || setup.tests) ? "Application" : "StaticLibrary") << "\n" + << "\t\t" << toolset << "\n" + << "\t\n"; } inline void outputProperties(std::ostream &project, const std::string &config, const std::string &properties) { project << "\t\n" - "\t\t\n" - "\t\t\n" - "\t\n"; + << "\t\t\n" + << "\t\t\n" + << "\t\n"; } } // End of anonymous namespace @@ -73,68 +77,73 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri const StringList &includeList, const StringList &excludeList) { const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension(); std::ofstream project(projectFile.c_str()); - if (!project) + if (!project || !project.is_open()) { error("Could not open \"" + projectFile + "\" for writing"); + return; + } project << "\n" - "\n" - "\t\n"; - - outputConfiguration(project, "Debug", "Win32"); - outputConfiguration(project, "Debug", "x64"); - outputConfiguration(project, "Analysis", "Win32"); - outputConfiguration(project, "Analysis", "x64"); - outputConfiguration(project, "LLVM", "Win32"); - outputConfiguration(project, "LLVM", "x64"); - outputConfiguration(project, "Release", "Win32"); - outputConfiguration(project, "Release", "x64"); + << "\n" + << "\t\n"; + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + outputConfiguration(project, "Debug", getMSVCConfigName(*arch)); + outputConfiguration(project, "Analysis", getMSVCConfigName(*arch)); + outputConfiguration(project, "LLVM", getMSVCConfigName(*arch)); + outputConfiguration(project, "Release", getMSVCConfigName(*arch)); + } project << "\t\n"; // Project name & Guid project << "\t\n" - "\t\t{" << uuid << "}\n" - "\t\t" << name << "\n" - "\t\tWin32Proj\n" - "\t\t$(VCTargetsPath" << _version << ")\n" - "\t\n"; + << "\t\t{" << uuid << "}\n" + << "\t\t" << name << "\n" + << "\t\tWin32Proj\n" + << "\t\t$(VCTargetsPath" << _version << ")\n"; + + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + project << "\t\t" << getMSVCArchName(*arch) << "-windows\n"; + } + + project << "\t\n"; // Shared configuration project << "\t\n"; - outputConfigurationType(setup, project, name, "Release|Win32", _msvcVersion.toolsetMSVC); - outputConfigurationType(setup, project, name, "Analysis|Win32", _msvcVersion.toolsetMSVC); - outputConfigurationType(setup, project, name, "LLVM|Win32", _msvcVersion.toolsetLLVM); - outputConfigurationType(setup, project, name, "Debug|Win32", _msvcVersion.toolsetMSVC); - outputConfigurationType(setup, project, name, "Release|x64", _msvcVersion.toolsetMSVC); - outputConfigurationType(setup, project, name, "LLVM|x64", _msvcVersion.toolsetLLVM); - outputConfigurationType(setup, project, name, "Analysis|x64", _msvcVersion.toolsetMSVC); - outputConfigurationType(setup, project, name, "Debug|x64", _msvcVersion.toolsetMSVC); + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + outputConfigurationType(setup, project, name, "Release|" + getMSVCConfigName(*arch), _msvcVersion.toolsetMSVC); + outputConfigurationType(setup, project, name, "Analysis" + getMSVCConfigName(*arch), _msvcVersion.toolsetMSVC); + outputConfigurationType(setup, project, name, "LLVM|" + getMSVCConfigName(*arch), _msvcVersion.toolsetLLVM); + outputConfigurationType(setup, project, name, "Debug|" + getMSVCConfigName(*arch), _msvcVersion.toolsetMSVC); + } project << "\t\n" - "\t\n" - "\t\n"; + << "\t\n" + << "\t\n"; - outputProperties(project, "Release|Win32", setup.projectDescription + "_Release.props"); - outputProperties(project, "Analysis|Win32", setup.projectDescription + "_Analysis.props"); - outputProperties(project, "LLVM|Win32", setup.projectDescription + "_LLVM.props"); - outputProperties(project, "Debug|Win32", setup.projectDescription + "_Debug.props"); - outputProperties(project, "Release|x64", setup.projectDescription + "_Release64.props"); - outputProperties(project, "Analysis|x64", setup.projectDescription + "_Analysis64.props"); - outputProperties(project, "LLVM|x64", setup.projectDescription + "_LLVM64.props"); - outputProperties(project, "Debug|x64", setup.projectDescription + "_Debug64.props"); + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + outputProperties(project, "Release|" + getMSVCConfigName(*arch), setup.projectDescription + "_Release" + getMSVCArchName(*arch) + ".props"); + outputProperties(project, "Analysis|" + getMSVCConfigName(*arch), setup.projectDescription + "_Analysis" + getMSVCArchName(*arch) + ".props"); + outputProperties(project, "LLVM|" + getMSVCConfigName(*arch), setup.projectDescription + "_LLVM" + getMSVCArchName(*arch) + ".props"); + outputProperties(project, "Debug|" + getMSVCConfigName(*arch), setup.projectDescription + "_Debug" + getMSVCArchName(*arch) + ".props"); + } project << "\t\n"; // Project-specific settings (analysis uses debug properties) - outputProjectSettings(project, name, setup, false, true, "Debug"); - outputProjectSettings(project, name, setup, false, true, "Analysis"); - outputProjectSettings(project, name, setup, false, true, "LLVM"); - outputProjectSettings(project, name, setup, true, true, "Release"); - outputProjectSettings(project, name, setup, false, false, "Debug"); - outputProjectSettings(project, name, setup, false, false, "Analysis"); - outputProjectSettings(project, name, setup, false, false, "LLVM"); - outputProjectSettings(project, name, setup, true, false, "Release"); + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + BuildSetup archsetup = setup; + std::map::const_iterator disabled_features_it = _arch_disabled_features.find(*arch); + if (disabled_features_it != _arch_disabled_features.end()) { + for (StringList::const_iterator j = disabled_features_it->second.begin(); j != disabled_features_it->second.end(); ++j) { + archsetup = removeFeatureFromSetup(archsetup, *j); + } + } + outputProjectSettings(project, name, archsetup, false, *arch, "Debug"); + outputProjectSettings(project, name, archsetup, false, *arch, "Analysis"); + outputProjectSettings(project, name, archsetup, false, *arch, "LLVM"); + outputProjectSettings(project, name, archsetup, true, *arch, "Release"); + } // Files std::string modulePath; @@ -200,18 +209,20 @@ void MSBuildProvider::createFiltersFile(const BuildSetup &setup, const std::stri const std::string filtersFile = setup.outputDir + '/' + name + getProjectExtension() + ".filters"; std::ofstream filters(filtersFile.c_str()); - if (!filters) + if (!filters || !filters.is_open()) { error("Could not open \"" + filtersFile + "\" for writing"); + return; + } filters << "\n" - "\n"; + << "\n"; // Output the list of filters filters << "\t\n"; for (std::list::iterator filter = _filters.begin(); filter != _filters.end(); ++filter) { filters << "\t\t\n" - "\t\t\t" << createUUID() << "\n" - "\t\t\n"; + << "\t\t\t" << createUUID() << "\n" + << "\t\t\n"; } filters << "\t\n"; @@ -231,8 +242,8 @@ void MSBuildProvider::outputFilter(std::ostream &filters, const FileEntries &fil for (FileEntries::const_iterator entry = files.begin(), end = files.end(); entry != end; ++entry) { if ((*entry).filter != "") { filters << "\t\t<" << action << " Include=\"" << (*entry).path << "\">\n" - "\t\t\t" << (*entry).filter << "\n" - "\t\t\n"; + << "\t\t\t" << (*entry).filter << "\n" + << "\t\t\n"; } else { filters << "\t\t<" << action << " Include=\"" << (*entry).path << "\" />\n"; } @@ -249,14 +260,14 @@ void MSBuildProvider::writeReferences(const BuildSetup &setup, std::ofstream &ou continue; output << "\tfirst << ".vcxproj\">\n" - "\t\t{" << i->second << "}\n" - "\t\n"; + << "\t\t{" << i->second << "}\n" + << "\t\n"; } output << "\t\n"; } -void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) { +void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, MSVC_Architecture arch, const std::string &configuration) { // Check for project-specific warnings: std::map::iterator warningsIterator = _projectWarnings.find(name); bool enableLanguageExtensions = true; // ResidualVM @@ -269,10 +280,10 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s std::string warnings = ""; if (warningsIterator != _projectWarnings.end()) for (StringList::const_iterator i = warningsIterator->second.begin(); i != warningsIterator->second.end(); ++i) - warnings += *i + ';'; + warnings += *i + ';'; - project << "\t\n" - "\t\t\n"; + project << "\t\n" + << "\t\t\n"; // Language Extensions if (setup.devTools || setup.tests || name == setup.projectName || enableLanguageExtensions) { @@ -298,37 +309,37 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s libraries += *i + ".lib;"; project << "\t\t\n" - "\t\t\t$(OutDir)" << ((setup.devTools || setup.tests) ? name : setup.projectName) << ".exe\n" - "\t\t\t" << libraries << "%(AdditionalDependencies)\n" - "\t\t\n"; + << "\t\t\t$(OutDir)" << ((setup.devTools || setup.tests) ? name : setup.projectName) << ".exe\n" + << "\t\t\t" << libraries << "%(AdditionalDependencies)\n" + << "\t\t\n"; if (!setup.devTools && !setup.tests && setup.runBuildEvents) { project << "\t\t\n" - "\t\t\tGenerate revision\n" - "\t\t\t" << getPreBuildEvent() << "\n" - "\t\t\n"; + << "\t\t\tGenerate revision\n" + << "\t\t\t" << getPreBuildEvent() << "\n" + << "\t\t\n"; // Copy data files to the build folder project << "\t\t\n" - "\t\t\tCopy data files to the build folder\n" - "\t\t\t" << getPostBuildEvent(isWin32, setup) << "\n" - "\t\t\n"; + << "\t\t\tCopy data files to the build folder\n" + << "\t\t\t" << getPostBuildEvent(arch, setup) << "\n" + << "\t\t\n"; } else if (setup.tests) { project << "\t\t\n" - "\t\t\tGenerate runner.cpp\n" - "\t\t\t" << getTestPreBuildEvent(setup) << "\n" - "\t\t\n"; + << "\t\t\tGenerate runner.cpp\n" + << "\t\t\t" << getTestPreBuildEvent(setup) << "\n" + << "\t\t\n"; } } project << "\t\n"; } -void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents) { +void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, MSVC_Architecture arch, const StringList &defines, const std::string &prefix, bool runBuildEvents) { std::string warnings; for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) - warnings += *i + ';'; + warnings += *i + ';'; std::string definesList; for (StringList::const_iterator i = defines.begin(); i != defines.end(); ++i) @@ -339,22 +350,22 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea definesList += REVISION_DEFINE ";"; properties << "\n" - "\n" - "\t\n" - "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_Global\n" - "\t\t$(" << LIBS_DEFINE << ")\\bin;$(" << LIBS_DEFINE << ")\\bin\\" << (bits == 32 ? "x86" : "x64") << ";$(ExecutablePath)\n" - "\t\t$(" << LIBS_DEFINE << ")\\lib\\" << (bits == 32 ? "x86" : "x64") << ";$(" << LIBS_DEFINE << ")\\lib\\" << (bits == 32 ? "x86" : "x64") << "\\$(Configuration);$(LibraryPath)\n" - "\t\t$(" << LIBS_DEFINE << ")\\include;$(" << LIBS_DEFINE << ")\\include\\" << (setup.useSDL2 ? "SDL2" : "SDL") << ";$(IncludePath)\n" - "\t\t$(Configuration)" << bits << "\\\n" - "\t\t$(Configuration)" << bits << "\\$(ProjectName)\\\n" - "\t\n" - "\t\n" - "\t\t\n" - "\t\t\ttrue\n" - "\t\t\t" << warnings << ";%(DisableSpecificWarnings)\n" - "\t\t\t.;" << prefix << ";" << prefix << "\\engines;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "%(AdditionalIncludeDirectories)\n" - "\t\t\t" << definesList << "%(PreprocessorDefinitions)\n" - "\t\t\t" << ((setup.devTools || setup.tests) ? "Sync" : "") << "\n"; + << "\n" + << "\t\n" + << "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_Global\n" + << "\t\t$(" << LIBS_DEFINE << ")\\bin;$(" << LIBS_DEFINE << ")\\bin\\" << getMSVCArchName(arch) << ";$(" << LIBS_DEFINE << ")\\$(Configuration)\\bin;$(ExecutablePath)\n" + << "\t\t$(" << LIBS_DEFINE << ")\\lib\\" << getMSVCArchName(arch) << ";$(" << LIBS_DEFINE << ")\\lib\\" << getMSVCArchName(arch) << "\\$(Configuration);$(" << LIBS_DEFINE << ")\\lib;$(" << LIBS_DEFINE << ")\\$(Configuration)\\lib;$(LibraryPath)\n" + << "\t\t$(" << LIBS_DEFINE << ")\\include;$(" << LIBS_DEFINE << ")\\include\\" << (setup.useSDL2 ? "SDL2" : "SDL") << ";$(IncludePath)\n" + << "\t\t$(Configuration)" << getMSVCArchName(arch) << "\\\n" + << "\t\t$(Configuration)" << getMSVCArchName(arch) << "\\$(ProjectName)\\\n" + << "\t\n" + << "\t\n" + << "\t\t\n" + << "\t\t\ttrue\n" + << "\t\t\t" << warnings << ";%(DisableSpecificWarnings)\n" + << "\t\t\t.;" << prefix << ";" << prefix << "\\engines;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "%(AdditionalIncludeDirectories)\n" + << "\t\t\t" << definesList << "%(PreprocessorDefinitions)\n" + << "\t\t\t" << ((setup.devTools || setup.tests) ? "Sync" : "") << "\n"; #if NEEDS_RTTI properties << "\t\t\ttrue\n"; @@ -363,98 +374,99 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea #endif properties << "\t\t\tLevel4\n" - "\t\t\tfalse\n" - "\t\t\tDefault\n" - "\t\t\ttrue\n" - "\t\t\ttrue\n" - "\t\t\t/utf-8 %(AdditionalOptions)\n" - "\t\t\n" - "\t\t\n" - "\t\t\t%(IgnoreSpecificDefaultLibraries)\n" - "\t\t\tConsole\n"; + << "\t\t\tfalse\n" + << "\t\t\tDefault\n" + << "\t\t\ttrue\n" + << "\t\t\ttrue\n" + << "\t\t\t/utf-8 %(AdditionalOptions)\n" + << "\t\t\n" + << "\t\t\n" + << "\t\t\t%(IgnoreSpecificDefaultLibraries)\n" + << "\t\t\tConsole\n"; if (!setup.devTools && !setup.tests) properties << "\t\t\tWinMainCRTStartup\n"; properties << "\t\t\n" - "\t\t\n" - "\t\t\t.;" << prefix << ";%(AdditionalIncludeDirectories)\n" - "\t\t\t" << definesList << "%(PreprocessorDefinitions)\n" - "\t\t\n" - "\t\n" - "\n"; + << "\t\t\n" + << "\t\t\t.;" << prefix << ";%(AdditionalIncludeDirectories)\n" + << "\t\t\t" << definesList << "%(PreprocessorDefinitions)\n" + << "\t\t\n" + << "\t\n" + << "\n"; properties.flush(); } -void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) { - const std::string outputBitness = (isWin32 ? "32" : "64"); - - std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); - if (!properties) - error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); +void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, MSVC_Architecture arch, const std::string &configuration) { + std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + configuration + getMSVCArchName(arch) + getPropertiesExtension()).c_str()); + if (!properties || !properties.is_open()) { + error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + getMSVCArchName(arch) + getPropertiesExtension() + "\" for writing"); + return; + } properties << "\n" - "\n" - "\t\n" - "\t\t\n" - "\t\n" - "\t\n" - "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << configuration << outputBitness << "\n" - "\t\t" << (isRelease ? "false" : "true") << "\n" - "\t\tfalse\n" - "\t\n" - "\t\n" - "\t\t\n"; + << "\n" + << "\t\n" + << "\t\t\n" + << "\t\n" + << "\t\n" + << "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << configuration << getMSVCArchName(arch) << "\n" + << "\t\t" << (isRelease ? "false" : "true") << "\n" + << "\t\tfalse\n" + << "\t\n" + << "\t\n" + << "\t\t\n"; if (isRelease) { properties << "\t\t\ttrue\n" - "\t\t\ttrue\n" - "\t\t\tWIN32;RELEASE_BUILD;%(PreprocessorDefinitions)\n" - "\t\t\ttrue\n" - "\t\t\tfalse\n" - "\t\t\t\n" - "\t\t\tMultiThreadedDLL\n" - "\t\t\t" << (configuration == "Analysis" ? "true" : "false") << "\n" - "\t\t\n" - "\t\t\n" - "\t\t\ttrue\n" - "\t\t\n" - "\t\t\n" - "\t\t\tUseLinkTimeCodeGeneration\n" - "\t\t\t%(IgnoreSpecificDefaultLibraries)\n" - "\t\t\ttrue\n"; + << "\t\t\ttrue\n" + << "\t\t\tWIN32;RELEASE_BUILD;%(PreprocessorDefinitions)\n" + << "\t\t\ttrue\n" + << "\t\t\tfalse\n" + << "\t\t\t\n" + << "\t\t\tMultiThreadedDLL\n" + << "\t\t\t" << (configuration == "Analysis" ? "true" : "false") << "\n" + << "\t\t\n" + << "\t\t\n" + << "\t\t\ttrue\n" + << "\t\t\n" + << "\t\t\n" + << "\t\t\tUseLinkTimeCodeGeneration\n" + << "\t\t\t%(IgnoreSpecificDefaultLibraries)\n" + << "\t\t\ttrue\n"; } else { properties << "\t\t\tDisabled\n" - "\t\t\tWIN32;" << (configuration == "LLVM" ? "_CRT_SECURE_NO_WARNINGS;" : "") << "%(PreprocessorDefinitions)\n" - "\t\t\tEnableFastChecks\n" - "\t\t\tMultiThreadedDebugDLL\n" - "\t\t\ttrue\n" - "\t\t\tfalse\n"; + << "\t\t\tWIN32;" << (configuration == "LLVM" ? "_CRT_SECURE_NO_WARNINGS;" : "") << "%(PreprocessorDefinitions)\n" + << "\t\t\tEnableFastChecks\n" + << "\t\t\tMultiThreadedDebugDLL\n" + << "\t\t\ttrue\n" + << "\t\t\tfalse\n"; if (_version >= 14) { - // Since MSVC 2015 Edit and Continue is support for x64 too. - properties << "\t\t\t" << "EditAndContinue" << "\n"; + // Since<" << (arch != ARCH_ARM64 ? "EditAndContinue" : "ProgramDatabase") << "\n"; } else { // Older MSVC versions did not support Edit and Continue for x64, thus we do not use it. - properties << "\t\t\t" << (isWin32 ? "EditAndContinue" : "ProgramDatabase") << "\n"; + properties << "\t\t\t" << (arch == ARCH_X86 ? "EditAndContinue" : "ProgramDatabase") << "\n"; } properties << "\t\t\t" << (configuration == "Analysis" ? "true" : "false") << "\n"; if (configuration == "LLVM") { // FIXME The LLVM cl wrapper does not seem to work properly with the $(TargetDir) path so we hard-code the build folder until the issue is resolved - properties << "\t\t\t" << configuration << outputBitness <<";%(AdditionalIncludeDirectories)\n" - "\t\t\t-Wno-microsoft -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -Wpointer-arith -Wcast-qual -Wshadow -Wnon-virtual-dtor -Wwrite-strings -Wno-conversion -Wno-shorten-64-to-32 -Wno-sign-compare -Wno-four-char-constants -Wno-nested-anon-types -Qunused-arguments %(AdditionalOptions)\n"; + const std::string outputBitness = (arch == ARCH_X86 ? "32" : "64"); + properties << "\t\t\t" << configuration << outputBitness << ";%(AdditionalIncludeDirectories)\n" + << "\t\t\t-Wno-microsoft -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -Wpointer-arith -Wcast-qual -Wshadow -Wnon-virtual-dtor -Wwrite-strings -Wno-conversion -Wno-shorten-64-to-32 -Wno-sign-compare -Wno-four-char-constants -Wno-nested-anon-types -Qunused-arguments %(AdditionalOptions)\n"; } properties << "\t\t\n" - "\t\t\n" - "\t\t\ttrue\n" - "\t\t\tfalse\n"; + << "\t\t\n" + << "\t\t\ttrue\n" + << "\t\t\tfalse\n"; } properties << "\t\t\n" - "\t\n" - "\n"; + << "\t\n" + << "\n"; properties.flush(); properties.close(); @@ -462,7 +474,7 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b bool hasEnding(std::string const &fullString, std::string const &ending) { if (fullString.length() > ending.length()) { - return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending)); + return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); } else { return false; } @@ -472,7 +484,7 @@ namespace { inline void outputNasmCommand(std::ostream &projectFile, const std::string &config, const std::string &prefix) { projectFile << "\t\t\tnasm.exe -f win32 -g -o \"$(IntDir)" << prefix << "%(Filename).obj\" \"%(FullPath)\"\n" - "\t\t\t$(IntDir)" << prefix << "%(Filename).obj;%(Outputs)\n"; + << "\t\t\t$(IntDir)" << prefix << "%(Filename).obj;%(Outputs)\n"; } } // End of anonymous namespace @@ -490,7 +502,7 @@ void MSBuildProvider::writeFileListToProject(const FileNode &dir, std::ofstream // Compute the list of files _filters.push_back(""); // init filters computeFileList(dir, duplicate, objPrefix, filePrefix); - _filters.pop_back(); // remove last empty filter + _filters.pop_back(); // remove last empty filter // Output compile files if (!_compileFiles.empty()) { @@ -503,7 +515,7 @@ void MSBuildProvider::writeFileListToProject(const FileNode &dir, std::ofstream // Deal with duplicated file names if (isDuplicate) { projectFile << "\t\t\n" - "\t\t\t$(IntDir)" << (*entry).prefix << "%(Filename).obj\n"; + << "\t\t\t$(IntDir)" << (*entry).prefix << "%(Filename).obj\n"; projectFile << "\t\t\n"; } else { @@ -526,7 +538,7 @@ void MSBuildProvider::writeFileListToProject(const FileNode &dir, std::ofstream const bool isDuplicate = (std::find(duplicate.begin(), duplicate.end(), (*entry).name + ".o") != duplicate.end()); projectFile << "\t\t\n" - "\t\t\tDocument\n"; + << "\t\t\tDocument\n"; outputNasmCommand(projectFile, "Debug", (isDuplicate ? (*entry).prefix : "")); outputNasmCommand(projectFile, "Analysis", (isDuplicate ? (*entry).prefix : "")); @@ -587,4 +599,4 @@ void MSBuildProvider::computeFileList(const FileNode &dir, const StringList &dup } } -} // End of CreateProjectTool namespace +} // namespace CreateProjectTool diff --git a/devtools/create_project/msbuild.h b/devtools/create_project/msbuild.h index cb01059f3f2..12c2b25e579 100644 --- a/devtools/create_project/msbuild.h +++ b/devtools/create_project/msbuild.h @@ -35,16 +35,16 @@ protected: void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, const StringList &includeList, const StringList &excludeList); - void outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration); + void outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, MSVC_Architecture arch, const std::string &configuration); void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); void writeReferences(const BuildSetup &setup, std::ofstream &output); - void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents); + void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, MSVC_Architecture arch, const StringList &defines, const std::string &prefix, bool runBuildEvents) override; - void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration); + void createBuildProp(const BuildSetup &setup, bool isRelease, MSVC_Architecture arch, const std::string &configuration) override; const char *getProjectExtension(); const char *getPropertiesExtension(); @@ -56,8 +56,8 @@ private: std::string filter; std::string prefix; - bool operator<(const FileEntry& rhs) const { - return path.compare(rhs.path) == -1; // Not exactly right for alphabetical order, but good enough + bool operator<(const FileEntry &rhs) const { + return path.compare(rhs.path) == -1; // Not exactly right for alphabetical order, but good enough } }; typedef std::list FileEntries; @@ -76,6 +76,6 @@ private: void outputFiles(std::ostream &projectFile, const FileEntries &files, const std::string &action); }; -} // End of CreateProjectTool namespace +} // namespace CreateProjectTool #endif // TOOLS_CREATE_PROJECT_MSBUILD_H diff --git a/devtools/create_project/msvc.cpp b/devtools/create_project/msvc.cpp index fad2650a0f7..701173aee66 100644 --- a/devtools/create_project/msvc.cpp +++ b/devtools/create_project/msvc.cpp @@ -20,12 +20,12 @@ * */ -#include "config.h" #include "msvc.h" +#include "config.h" -#include #include #include +#include namespace CreateProjectTool { @@ -33,10 +33,24 @@ namespace CreateProjectTool { // MSVC Provider (Base class) ////////////////////////////////////////////////////////////////////////// MSVCProvider::MSVCProvider(StringList &global_warnings, std::map &project_warnings, const int version, const MSVCVersion &msvc) - : ProjectProvider(global_warnings, project_warnings, version), _msvcVersion(msvc) { + : ProjectProvider(global_warnings, project_warnings, version), _msvcVersion(msvc) { _enableLanguageExtensions = tokenize(ENABLE_LANGUAGE_EXTENSIONS, ','); - _disableEditAndContinue = tokenize(DISABLE_EDIT_AND_CONTINUE, ','); + _disableEditAndContinue = tokenize(DISABLE_EDIT_AND_CONTINUE, ','); + + // NASM not supported for Windows on AMD64 target + StringList amd64_disabled_features; + amd64_disabled_features.push_back("nasm"); + _arch_disabled_features[ARCH_AMD64] = amd64_disabled_features; + // NASM not supported for WoA target + // No OpenGL, OpenGL ES on Windows on ARM + // https://github.com/microsoft/vcpkg/issues/11248 [fribidi] Fribidi doesn't cross-compile on x86-64 to target arm/arm64 + StringList arm64_disabled_features; + arm64_disabled_features.push_back("nasm"); + arm64_disabled_features.push_back("opengl"); + arm64_disabled_features.push_back("opengles"); + arm64_disabled_features.push_back("fribidi"); + _arch_disabled_features[ARCH_ARM64] = arm64_disabled_features; } void MSVCProvider::createWorkspace(const BuildSetup &setup) { @@ -50,8 +64,10 @@ void MSVCProvider::createWorkspace(const BuildSetup &setup) { std::string solutionUUID = createUUID(setup.projectName + ".sln"); std::ofstream solution((setup.outputDir + '/' + setup.projectName + ".sln").c_str()); - if (!solution) + if (!solution || !solution.is_open()) { error("Could not open \"" + setup.outputDir + '/' + setup.projectName + ".sln\" for writing"); + return; + } solution << "Microsoft Visual Studio Solution File, Format Version " << _msvcVersion.solutionFormat << "\n"; solution << "# Visual Studio " << _msvcVersion.solutionVersion << "\n"; @@ -77,42 +93,36 @@ void MSVCProvider::createWorkspace(const BuildSetup &setup) { } solution << "Global\n" - "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" - "\t\tDebug|Win32 = Debug|Win32\n" - "\t\tAnalysis|Win32 = Analysis|Win32\n" - "\t\tLLVM|Win32 = LLVM|Win32\n" - "\t\tRelease|Win32 = Release|Win32\n" - "\t\tDebug|x64 = Debug|x64\n" - "\t\tAnalysis|x64 = Analysis|x64\n" - "\t\tLLVM|x64 = LLVM|x64\n" - "\t\tRelease|x64 = Release|x64\n" - "\tEndGlobalSection\n" - "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"; + "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n"; - for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { - solution << "\t\t{" << i->second << "}.Debug|Win32.ActiveCfg = Debug|Win32\n" - "\t\t{" << i->second << "}.Debug|Win32.Build.0 = Debug|Win32\n" - "\t\t{" << i->second << "}.Analysis|Win32.ActiveCfg = Analysis|Win32\n" - "\t\t{" << i->second << "}.Analysis|Win32.Build.0 = Analysis|Win32\n" - "\t\t{" << i->second << "}.LLVM|Win32.ActiveCfg = LLVM|Win32\n" - "\t\t{" << i->second << "}.LLVM|Win32.Build.0 = LLVM|Win32\n" - "\t\t{" << i->second << "}.Release|Win32.ActiveCfg = Release|Win32\n" - "\t\t{" << i->second << "}.Release|Win32.Build.0 = Release|Win32\n" - "\t\t{" << i->second << "}.Debug|x64.ActiveCfg = Debug|x64\n" - "\t\t{" << i->second << "}.Debug|x64.Build.0 = Debug|x64\n" - "\t\t{" << i->second << "}.Analysis|x64.ActiveCfg = Analysis|x64\n" - "\t\t{" << i->second << "}.Analysis|x64.Build.0 = Analysis|x64\n" - "\t\t{" << i->second << "}.LLVM|x64.ActiveCfg = LLVM|x64\n" - "\t\t{" << i->second << "}.LLVM|x64.Build.0 = LLVM|x64\n" - "\t\t{" << i->second << "}.Release|x64.ActiveCfg = Release|x64\n" - "\t\t{" << i->second << "}.Release|x64.Build.0 = Release|x64\n"; + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + solution << "\t\tDebug|" << getMSVCConfigName(*arch) << " = Debug|" << getMSVCConfigName(*arch) << "\n" + << "\t\tAnalysis|" << getMSVCConfigName(*arch) << " = Analysis|" << getMSVCConfigName(*arch) << "\n" + << "\t\tLLVM|" << getMSVCConfigName(*arch) << " = LLVM|" << getMSVCConfigName(*arch) << "\n" + << "\t\tRelease|" << getMSVCConfigName(*arch) << " = Release|" << getMSVCConfigName(*arch) << "\n"; } solution << "\tEndGlobalSection\n" - "\tGlobalSection(SolutionProperties) = preSolution\n" - "\t\tHideSolutionNode = FALSE\n" - "\tEndGlobalSection\n" - "EndGlobal\n"; + "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"; + + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + solution << "\t\t{" << i->second << "}.Debug|" << getMSVCConfigName(*arch) << ".ActiveCfg = Debug|" << getMSVCConfigName(*arch) << "\n" + << "\t\t{" << i->second << "}.Debug|" << getMSVCConfigName(*arch) << ".Build.0 = Debug|" << getMSVCConfigName(*arch) << "\n" + << "\t\t{" << i->second << "}.Analysis|" << getMSVCConfigName(*arch) << ".ActiveCfg = Analysis|" << getMSVCConfigName(*arch) << "\n" + << "\t\t{" << i->second << "}.Analysis|" << getMSVCConfigName(*arch) << ".Build.0 = Analysis|" << getMSVCConfigName(*arch) << "\n" + << "\t\t{" << i->second << "}.LLVM|" << getMSVCConfigName(*arch) << ".ActiveCfg = LLVM|" << getMSVCConfigName(*arch) << "\n" + << "\t\t{" << i->second << "}.LLVM|" << getMSVCConfigName(*arch) << ".Build.0 = LLVM|" << getMSVCConfigName(*arch) << "\n" + << "\t\t{" << i->second << "}.Release|" << getMSVCConfigName(*arch) << ".ActiveCfg = Release|" << getMSVCConfigName(*arch) << "\n" + << "\t\t{" << i->second << "}.Release|" << getMSVCConfigName(*arch) << ".Build.0 = Release|" << getMSVCConfigName(*arch) << "\n"; + } + } + + solution << "\tEndGlobalSection\n" + << "\tGlobalSection(SolutionProperties) = preSolution\n" + << "\t\tHideSolutionNode = FALSE\n" + << "\tEndGlobalSection\n" + << "EndGlobal\n"; } void MSVCProvider::createOtherBuildFiles(const BuildSetup &setup) { @@ -121,14 +131,12 @@ void MSVCProvider::createOtherBuildFiles(const BuildSetup &setup) { // Create the configuration property files (for Debug and Release with 32 and 64bits versions) // Note: we use the debug properties for the analysis configuration - createBuildProp(setup, true, false, "Release"); - createBuildProp(setup, true, true, "Release"); - createBuildProp(setup, false, false, "Debug"); - createBuildProp(setup, false, true, "Debug"); - createBuildProp(setup, false, false, "Analysis"); - createBuildProp(setup, false, true, "Analysis"); - createBuildProp(setup, false, false, "LLVM"); - createBuildProp(setup, false, true, "LLVM"); + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + createBuildProp(setup, true, *arch, "Release"); + createBuildProp(setup, false, *arch, "Debug"); + createBuildProp(setup, false, *arch, "Analysis"); + createBuildProp(setup, false, *arch, "LLVM"); + } } void MSVCProvider::addResourceFiles(const BuildSetup &setup, StringList &includeList, StringList &excludeList) { @@ -137,27 +145,22 @@ void MSVCProvider::addResourceFiles(const BuildSetup &setup, StringList &include } void MSVCProvider::createGlobalProp(const BuildSetup &setup) { - std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_Global" + getPropertiesExtension()).c_str()); - if (!properties) - error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_Global" + getPropertiesExtension() + "\" for writing"); + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_Global" + getMSVCArchName(*arch) + getPropertiesExtension()).c_str()); + if (!properties) + error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_Global" + getMSVCArchName(*arch) + getPropertiesExtension() + "\" for writing"); - outputGlobalPropFile(setup, properties, 32, setup.defines, convertPathToWin(setup.filePrefix), setup.runBuildEvents); - properties.close(); - - properties.open((setup.outputDir + '/' + setup.projectDescription + "_Global64" + getPropertiesExtension()).c_str()); - if (!properties) - error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_Global64" + getPropertiesExtension() + "\" for writing"); - - // HACK: We must disable the "nasm" feature for x64. To achieve that we must recreate the define list. - StringList x64Defines = setup.defines; - for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) { - if (i->enable && i->define && i->define[0] && !strcmp(i->name, "nasm")) { - x64Defines.remove(i->define); - break; + BuildSetup archSetup = setup; + std::map::const_iterator arch_disabled_features_it = _arch_disabled_features.find(*arch); + if (arch_disabled_features_it != _arch_disabled_features.end()) { + for (StringList::const_iterator feature = arch_disabled_features_it->second.begin(); feature != arch_disabled_features_it->second.end(); ++feature) { + archSetup = removeFeatureFromSetup(archSetup, *feature); + } } - } - outputGlobalPropFile(setup, properties, 64, x64Defines, convertPathToWin(setup.filePrefix), setup.runBuildEvents); + outputGlobalPropFile(archSetup, properties, *arch, archSetup.defines, convertPathToWin(archSetup.filePrefix), archSetup.runBuildEvents); + properties.close(); + } } std::string MSVCProvider::getPreBuildEvent() const { @@ -182,7 +185,7 @@ std::string MSVCProvider::getTestPreBuildEvent(const BuildSetup &setup) const { return ""$(SolutionDir)../../test/cxxtest/cxxtestgen.py" --runner=ParenPrinter --no-std --no-eh -o "$(SolutionDir)test_runner.cpp"" + target; } -std::string MSVCProvider::getPostBuildEvent(bool isWin32, const BuildSetup &setup) const { +std::string MSVCProvider::getPostBuildEvent(MSVC_Architecture arch, const BuildSetup &setup) const { std::string cmdLine = ""; cmdLine = "@echo off\n" @@ -193,7 +196,7 @@ std::string MSVCProvider::getPostBuildEvent(bool isWin32, const BuildSetup &setu cmdLine += (setup.useSDL2) ? "SDL2" : "SDL"; cmdLine += " "%" LIBS_DEFINE "%/lib/"; - cmdLine += (isWin32) ? "x86" : "x64"; + cmdLine += getMSVCArchName(arch); cmdLine += "/$(Configuration)" "; // Specify if installer needs to be built or not @@ -205,4 +208,4 @@ std::string MSVCProvider::getPostBuildEvent(bool isWin32, const BuildSetup &setu return cmdLine; } -} // End of CreateProjectTool namespace +} // namespace CreateProjectTool diff --git a/devtools/create_project/msvc.h b/devtools/create_project/msvc.h index b10cb569d47..f711f165f49 100644 --- a/devtools/create_project/msvc.h +++ b/devtools/create_project/msvc.h @@ -37,6 +37,9 @@ protected: StringList _enableLanguageExtensions; StringList _disableEditAndContinue; + std::list _archs; + std::map _arch_disabled_features; + void createWorkspace(const BuildSetup &setup); void createOtherBuildFiles(const BuildSetup &setup); @@ -64,17 +67,17 @@ protected: * @param prefix File prefix, used to add additional include paths. * @param runBuildEvents true if generating a revision number, false otherwise */ - virtual void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents) = 0; + virtual void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, MSVC_Architecture arch, const StringList &defines, const std::string &prefix, bool runBuildEvents) = 0; /** * Generates the project properties for debug and release settings. * * @param setup Description of the desired build setup. * @param isRelease Type of property file - * @param isWin32 Bitness of property file + * @param arch Target architecture * @param configuration Name of property file */ - virtual void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) = 0; + virtual void createBuildProp(const BuildSetup &setup, bool isRelease, MSVC_Architecture arch, const std::string &configuration) = 0; /** * Get the file extension for property files @@ -96,14 +99,14 @@ protected: /** * Get the command line for copying data files to the build directory. * - * @param isWin32 Bitness of property file. + * @param arch Target architecture * @param setup Description of the desired build setup. * * @return The post build event. */ - std::string getPostBuildEvent(bool isWin32, const BuildSetup &setup) const; + std::string getPostBuildEvent(MSVC_Architecture arch, const BuildSetup &setup) const; }; -} // End of CreateProjectTool namespace +} // namespace CreateProjectTool #endif // TOOLS_CREATE_PROJECT_MSVC_H diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp index 2515ef31d9b..4cf36fd6463 100644 --- a/devtools/create_project/visualstudio.cpp +++ b/devtools/create_project/visualstudio.cpp @@ -20,11 +20,11 @@ * */ -#include "config.h" #include "visualstudio.h" +#include "config.h" -#include #include +#include namespace CreateProjectTool { @@ -32,8 +32,11 @@ namespace CreateProjectTool { // Visual Studio Provider (Visual Studio 2008) ////////////////////////////////////////////////////////////////////////// -VisualStudioProvider::VisualStudioProvider(StringList &global_warnings, std::map &project_warnings, const int version, const MSVCVersion& msvc) - : MSVCProvider(global_warnings, project_warnings, version, msvc) { +VisualStudioProvider::VisualStudioProvider(StringList &global_warnings, std::map &project_warnings, const int version, const MSVCVersion &msvc) + : MSVCProvider(global_warnings, project_warnings, version, msvc) { + + _archs.push_back(ARCH_X86); + _archs.push_back(ARCH_AMD64); } const char *VisualStudioProvider::getProjectExtension() { @@ -48,29 +51,32 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: const StringList &includeList, const StringList &excludeList) { const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension(); std::ofstream project(projectFile.c_str()); - if (!project) + if (!project || !project.is_open()) { error("Could not open \"" + projectFile + "\" for writing"); + return; + } project << "\n" - "\n" - "\t\n" - "\t\t\n" - "\t\t\n" - "\t\n" - "\t\n"; + "\t\n"; + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + project << "\t\t\n"; + } + project << "\t\n" + << "\t\n"; // Check for project-specific warnings: - std::map< std::string, std::list >::iterator warningsIterator = _projectWarnings.find(name); + std::map >::iterator warningsIterator = _projectWarnings.find(name); if (setup.devTools || setup.tests || name == setup.projectName) { std::string libraries; @@ -78,20 +84,15 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) libraries += ' ' + *i + ".lib"; - // Win32 - outputConfiguration(project, setup, libraries, "Debug", "Win32", "", true); - outputConfiguration(project, setup, libraries, "Analysis", "Win32", "", true); - outputConfiguration(project, setup, libraries, "LLVM", "Win32", "", true); - outputConfiguration(project, setup, libraries, "Release", "Win32", "", true); - - // x64 // For 'x64' we must disable NASM support. Usually we would need to disable the "nasm" feature for that and // re-create the library list, BUT since NASM doesn't link any additional libraries, we can just use the // libraries list created for IA-32. If that changes in the future, we need to adjust this part! - outputConfiguration(project, setup, libraries, "Debug", "x64", "64", false); - outputConfiguration(project, setup, libraries, "Analysis", "x64", "64", false); - outputConfiguration(project, setup, libraries, "LLVM", "Win32", "64", false); - outputConfiguration(project, setup, libraries, "Release", "x64", "64", false); + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + outputConfiguration(project, setup, libraries, "Debug", *arch); + outputConfiguration(project, setup, libraries, "Analysis", *arch); + outputConfiguration(project, setup, libraries, "LLVM", *arch); + outputConfiguration(project, setup, libraries, "Release", *arch); + } } else { bool enableLanguageExtensions = true; // ResidualVM @@ -100,26 +101,23 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: std::string warnings = ""; if (warningsIterator != _projectWarnings.end()) for (StringList::const_iterator i = warningsIterator->second.begin(); i != warningsIterator->second.end(); ++i) - warnings += *i + ';'; + warnings += *i + ';'; std::string toolConfig; - toolConfig = (!warnings.empty() ? "DisableSpecificWarnings=\"" + warnings + "\"" : ""); - toolConfig += (disableEditAndContinue ? "DebugInformationFormat=\"3\" " : ""); + toolConfig = (!warnings.empty() ? "DisableSpecificWarnings=\"" + warnings + "\"" : ""); + toolConfig += (disableEditAndContinue ? "DebugInformationFormat=\"3\" " : ""); toolConfig += (enableLanguageExtensions ? "DisableLanguageExtensions=\"false\" " : ""); - // Win32 - outputConfiguration(setup, project, toolConfig, "Debug", "Win32", ""); - outputConfiguration(setup, project, toolConfig, "Analysis", "Win32", ""); - outputConfiguration(setup, project, toolConfig, "LLVM", "Win32", ""); - outputConfiguration(setup, project, toolConfig, "Release", "Win32", ""); - outputConfiguration(setup, project, toolConfig, "Debug", "x64", "64"); - outputConfiguration(setup, project, toolConfig, "Analysis", "x64", "64"); - outputConfiguration(setup, project, toolConfig, "LLVM", "x64", "64"); - outputConfiguration(setup, project, toolConfig, "Release", "x64", "64"); + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + outputConfiguration(setup, project, toolConfig, "Debug", *arch); + outputConfiguration(setup, project, toolConfig, "Analysis", *arch); + outputConfiguration(setup, project, toolConfig, "LLVM", *arch); + outputConfiguration(setup, project, toolConfig, "Release", *arch); + } } project << "\t\n" - "\t\n"; + << "\t\n"; std::string modulePath; if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) { @@ -139,44 +137,44 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: } project << "\t\n" - "\n"; + << "\n"; } -void VisualStudioProvider::outputConfiguration(std::ostream &project, const BuildSetup &setup, const std::string &libraries, const std::string &config, const std::string &platform, const std::string &props, const bool isWin32) { - project << "\t\t\n" - "\t\t\t\n" - "\t\t\t\n"; - outputBuildEvents(project, setup, isWin32); +void VisualStudioProvider::outputConfiguration(std::ostream &project, const BuildSetup &setup, const std::string &libraries, const std::string &config, const MSVC_Architecture arch) { + project << "\t\t\n" + << "\t\t\t\n" + << "\t\t\t\n"; + outputBuildEvents(project, setup, arch); project << "\t\t\n"; } -void VisualStudioProvider::outputConfiguration(const BuildSetup &setup, std::ostream &project, const std::string &toolConfig, const std::string &config, const std::string &platform, const std::string &props) { - project << "\t\t\n" - "\t\t\t\n" - "\t\t\n"; +void VisualStudioProvider::outputConfiguration(const BuildSetup &setup, std::ostream &project, const std::string &toolConfig, const std::string &config, const MSVC_Architecture arch) { + project << "\t\t\n" + << "\t\t\t\n" + << "\t\t\n"; } -void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildSetup &setup, const bool isWin32) { +void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildSetup &setup, const MSVC_Architecture arch) { if (!setup.devTools && !setup.tests && setup.runBuildEvents) { project << "\t\t\t\n" - "\t\t\t\n"; + << "\t\t\t\tCommandLine=\"" << getPreBuildEvent() << "\"\n" + << "\t\t\t/>\n" + << "\t\t\t\n"; } // Generate runner file before build for tests if (setup.tests) { project << "\t\t\t\n"; + << "\t\t\t\tCommandLine=\"" << getTestPreBuildEvent(setup) << "\"\n" + << "\t\t\t/>\n"; project << "\t\t\t\n"; + << "\t\t\t\tCommandLine=\"$(TargetPath)\" IgnoreExitCode=\"true\"\n" + << "\t\t\t/>\n"; } } @@ -193,10 +191,10 @@ void VisualStudioProvider::writeReferences(const BuildSetup &setup, std::ofstrea output << "\tEndProjectSection\n"; } -void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents) { +void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, MSVC_Architecture arch, const StringList &defines, const std::string &prefix, bool runBuildEvents) { std::string warnings; for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) - warnings += *i + ';'; + warnings += *i + ';'; std::string definesList; for (StringList::const_iterator i = defines.begin(); i != defines.end(); ++i) { @@ -210,20 +208,20 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of definesList += REVISION_DEFINE ";"; properties << "\n" - "\n" - "\t\n" + << "\t\n" - "\t\n" - "\t\n" + << "\t\n" + << "\t\n" - "\t\n" - "\n"; + properties << "\t\tAdditionalLibraryDirectories=\"$(" << LIBS_DEFINE << ")\\lib\\" << getMSVCArchName(arch) << "\"\n" + << "\t/>\n" + << "\t\n" + << "\n"; properties.flush(); } -void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) { - const std::string outputBitness = (isWin32 ? "32" : "64"); +void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelease, MSVC_Architecture arch, const std::string &configuration) { - std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); - if (!properties) - error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); + std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + configuration + getMSVCArchName(arch) + getPropertiesExtension()).c_str()); + if (!properties || !properties.is_open()) { + error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + getMSVCArchName(arch) + getPropertiesExtension() + "\" for writing"); + return; + } properties << "\n" - "\n" - "\t\n" + << "\t\n" - "\t\n" + << "\t\n" - "\t\n" + << "\t\n" - "\n"; + << "\n"; properties.flush(); properties.close(); @@ -337,6 +336,7 @@ void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofst name += ".o"; std::transform(name.begin(), name.end(), name.begin(), tolower); const bool isDuplicate = (std::find(duplicate.begin(), duplicate.end(), name) != duplicate.end()); + std::string filePath = convertPathToWin(filePrefix + node->name); if (ext == "asm") { std::string objFileName = "$(IntDir)\\"; @@ -347,41 +347,14 @@ void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofst const std::string toolLine = indentString + "\t\t\n"; // NASM is not supported for x64, thus we do not need to add additional entries here :-). - projectFile << indentString << "name) << "\">\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\n"; + writeFileToProject(projectFile, filePath, ARCH_X86, indentString, toolLine); } else { if (isDuplicate) { const std::string toolLine = indentString + "\t\t\n"; - projectFile << indentString << "name) << "\">\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\t\n" - << toolLine - << indentString << "\t\n" - << indentString << "\n"; + for (std::list::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) { + writeFileToProject(projectFile, filePath, *arch, indentString, toolLine); + } } else { projectFile << indentString << "name) << "\" />\n"; } @@ -396,4 +369,22 @@ void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofst projectFile << getIndent(indentation + 1) << "\n"; } -} // End of CreateProjectTool namespace +void VisualStudioProvider::writeFileToProject(std::ofstream &projectFile, const std::string &filePath, MSVC_Architecture arch, + const std::string &indentString, const std::string &toolLine) { + projectFile << indentString << "\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\n"; +} + +} // namespace CreateProjectTool diff --git a/devtools/create_project/visualstudio.h b/devtools/create_project/visualstudio.h index 29ef9da8353..6d9f37fac90 100644 --- a/devtools/create_project/visualstudio.h +++ b/devtools/create_project/visualstudio.h @@ -29,7 +29,7 @@ namespace CreateProjectTool { class VisualStudioProvider : public MSVCProvider { public: - VisualStudioProvider(StringList &global_warnings, std::map &project_warnings, const int version, const MSVCVersion& msvc); + VisualStudioProvider(StringList &global_warnings, std::map &project_warnings, const int version, const MSVCVersion &msvc); protected: void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, @@ -38,20 +38,23 @@ protected: void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); + void writeFileToProject(std::ofstream &projectFile, const std::string &filePath, MSVC_Architecture arch, + const std::string &indentString, const std::string &toolLine); + void writeReferences(const BuildSetup &setup, std::ofstream &output); - void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents); + void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, MSVC_Architecture arch, const StringList &defines, const std::string &prefix, bool runBuildEvents); - void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration); + void createBuildProp(const BuildSetup &setup, bool isRelease, MSVC_Architecture arch, const std::string &configuration); const char *getProjectExtension(); const char *getPropertiesExtension(); - void outputConfiguration(std::ostream &project, const BuildSetup &setup, const std::string &libraries, const std::string &config, const std::string &platform, const std::string &props, const bool isWin32); - void outputConfiguration(const BuildSetup &setup, std::ostream &project, const std::string &toolConfig, const std::string &config, const std::string &platform, const std::string &props); - void outputBuildEvents(std::ostream &project, const BuildSetup &setup, const bool isWin32); + void outputConfiguration(std::ostream &project, const BuildSetup &setup, const std::string &libraries, const std::string &config, const MSVC_Architecture arch); + void outputConfiguration(const BuildSetup &setup, std::ostream &project, const std::string &toolConfig, const std::string &config, const MSVC_Architecture arch); + void outputBuildEvents(std::ostream &project, const BuildSetup &setup, const MSVC_Architecture arch); }; -} // End of CreateProjectTool namespace +} // namespace CreateProjectTool #endif // TOOLS_CREATE_PROJECT_VISUALSTUDIO_H diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp index b8c2246653b..3c02d4ff806 100644 --- a/devtools/create_project/xcode.cpp +++ b/devtools/create_project/xcode.cpp @@ -745,7 +745,7 @@ void XcodeProvider::setupProject() { Object *project = new Object(this, "PBXProject", "PBXProject", "PBXProject", "", "Project object"); - project->addProperty("buildConfigurationList", getHash("XCConfigurationList_scummvm"), "Build configuration list for PBXProject \"" PROJECT_NAME "\"", kSettingsNoValue); + project->addProperty("buildConfigurationList", getHash("XCConfigurationList_" PROJECT_NAME), "Build configuration list for PBXProject \"" PROJECT_NAME "\"", kSettingsNoValue); project->addProperty("compatibilityVersion", "Xcode 3.2", "", kSettingsNoValue | kSettingsQuoteVariable); project->addProperty("developmentRegion", "English", "", kSettingsNoValue); project->addProperty("hasScannedForEncodings", "1", "", kSettingsNoValue); diff --git a/devtools/credits.pl b/devtools/credits.pl index da49a797905..e27a25c5ee1 100755 --- a/devtools/credits.pl +++ b/devtools/credits.pl @@ -58,7 +58,7 @@ if ($mode eq "") { $Text::Wrap::unexpand = 0; if ($mode eq "TEXT") { $Text::Wrap::columns = 78; - $max_name_width = 28; # The maximal width of a name. + $max_name_width = 29; # The maximal width of a name. } elsif ($mode eq "CPP") { $Text::Wrap::columns = 48; # Approx. } diff --git a/devtools/encode-macbinary.sh b/devtools/encode-macbinary.sh index 0655fc92427..e9465c10d7f 100755 --- a/devtools/encode-macbinary.sh +++ b/devtools/encode-macbinary.sh @@ -1,25 +1,141 @@ #!/bin/bash -# -# Iterates over current directory, encodes all files with -# MacBinary but ensures that the dates are preserved -for i in * -do - if test -d "$i" ; then - cd "$i" - if [ "$(ls -A .)" ] ; then # directory is not empty - bash $0 "$1/$i" +usage() { + cat << EOF +Usage: $0 [OPTIONS]... + +Dumping Mac files into MacBinary format + +There are 2 operation modes. Direct MacBinary encoding (Mac-only) and dumping ISO +contents with hfsutils. + +Mode 1: + $0 macbinary + Operate in MacBinary encoding mode + +Mode 2: + $0 + Operate in disk dumping mode + +Miscellaneous: + -h, --help display this help and exit +EOF +} + +path= + +macbinarydump() { + mypath=`realpath $0` + + for i in * + do + if test -d "$i" ; then + cd "$i" + if [ "$(ls -A .)" ] ; then # directory is not empty + bash $mypath macbinary-phase2 "$path/$i" + fi + cd .. + else + echo -ne "$path/$i... \r" + macbinary encode "$i" + touch -r "$i" "$i.bin" + mv "$i.bin" "$i" fi - cd .. - else - echo -ne "$1/$i... \r" - macbinary encode "$i" - touch -r "$i" "$i.bin" - mv "$i.bin" "$i" - fi -done + done +} -# on the top level we want to print a new line -if test -z "$1" ; then +hfsdump() { + IFS=$'\n' + mypath=`realpath $0` + + for i in `hls -F1a` + do + if [[ "$i" =~ ":" ]] ; then + dir="${i%?}" + hcd "$dir" + mkdir "$dir" + cd "$dir" + bash $mypath hfsutils-phase2 "$path:$i" + hcd :: + cd .. + else + echo -ne "$path$i... \r" + # Executable files have star at their end. Strip it + if [[ "$i" =~ \*$ ]] ; then + file="${i%?}" + else + file="$i" + fi + fileunix="$file" + # Files count contain stars + file="${file//\*/\\*}" + hcopy -m "$file" "./$fileunix" + fi + done +} + +for parm in "$@" ; do + if test "$parm" = "--help" || test "$parm" = "-help" || test "$parm" = "-h" ; then + usage + exit 0 + fi +done # for parm in ... + +if [[ $1 == "macbinary" ]] ; then + if test ! `type macbinary >/dev/null 2>/dev/null` ; then + echo "macbinary not found. Exiting" + exit 1 + fi + macbinarydump echo + exit 0 fi + +if [[ $1 == "macbinary-phase2" ]] ; then + path=$2 + macbinarydump + exit 0 +fi + +########### +# hfsutils mode +if [ "$#" -lt 1 ] ; then + usage + exit 1 +fi + +if [[ $1 == "hfsutils-phase2" ]] ; then + path=$2 + hfsdump + exit 0 +fi + +if ! `type hmount >/dev/null 2>/dev/null` ; then + echo "hfsutils not found. Exiting" + exit 1 +fi + +isofile="$1" + +echo -n "Mounting ISO..." +hmount "$isofile" >/dev/null 2>/dev/null +if test -z $? ; then + echo error + exit 1 +fi + +echo done + +echo "Dumping..." + +hfsdump +echo + +echo -n "Unmounting ISO..." +humount >/dev/null 2>/dev/null +if test -z $? ; then + echo error + exit 1 +fi + +echo done diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp index d7076e34204..f4e85b5d096 100644 --- a/engines/dialogs.cpp +++ b/engines/dialogs.cpp @@ -205,11 +205,6 @@ void MainMenuDialog::reflowLayout() { void MainMenuDialog::save() { int slot = _saveDialog->runModalWithCurrentTarget(); - #if defined(__PLAYSTATION2__) && defined(DYNAMIC_MODULES) - char pokeme[32]; - snprintf(pokeme,32,"hack"); - #endif - if (slot >= 0) { Common::String result(_saveDialog->getResultString()); if (result.empty()) { diff --git a/engines/engine.cpp b/engines/engine.cpp index c1792b69421..b7c8ad86b30 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -590,12 +590,13 @@ void Engine::openMainMenuDialog() { } } - applyGameSettings(); - syncSoundSettings(); #ifdef USE_TTS if (ttsMan != nullptr) ttsMan->popState(); #endif + + applyGameSettings(); + syncSoundSettings(); } bool Engine::warnUserAboutUnsupportedGame() { diff --git a/engines/wintermute/ad/ad_game.cpp b/engines/wintermute/ad/ad_game.cpp index 2d386b5b8fb..36e51e6cfdc 100644 --- a/engines/wintermute/ad/ad_game.cpp +++ b/engines/wintermute/ad/ad_game.cpp @@ -46,6 +46,7 @@ #include "engines/wintermute/base/font/base_font.h" #include "engines/wintermute/base/base_object.h" #include "engines/wintermute/base/base_parser.h" +#include "engines/wintermute/base/base_region.h" #include "engines/wintermute/base/sound/base_sound.h" #include "engines/wintermute/base/base_surface_storage.h" #include "engines/wintermute/base/base_transition_manager.h" @@ -64,6 +65,7 @@ #include "engines/wintermute/video/video_player.h" #include "engines/wintermute/video/video_theora_player.h" #include "engines/wintermute/platform_osystem.h" +#include "common/config-manager.h" #include "common/str.h" namespace Wintermute { @@ -1597,6 +1599,119 @@ bool AdGame::scheduleChangeScene(const char *filename, bool fadeIn) { } +////////////////////////////////////////////////////////////////////////// +bool AdGame::handleCustomActionStart(BaseGameCustomAction action) { + bool isCorrosion = BaseEngine::instance().getGameId() == "corrosion"; + + if (isCorrosion) { + // Corrosion Enhanced Edition contain city map screen, which is + // mouse controlled and conflicts with those custom actions + const char *m = "items\\street_map\\windows\\street_map_window.script"; + if (_scEngine->isRunningScript(m)) { + return false; + } + } + + int xLeft = 30; + int xCenter = _renderer->getWidth() / 2; + int xRight = _renderer->getWidth() - 30; + + int yTop = 35; + int yCenter = _renderer->getHeight() / 2; + int yBottom = _renderer->getHeight() - 35; + if (isCorrosion && !(ConfMan.get("extra").contains("Enhanced"))) { + // original version of Corrosion has a toolbar under the game screen + yBottom -= 60; + } + + BaseArray objects; + + Point32 p; + int distance = xCenter * xCenter + yCenter * yCenter; + + switch (action) { + case kClickAtCenter: + p.x = xCenter; + p.y = yCenter; + break; + case kClickAtLeft: + p.x = xLeft; + p.y = yCenter; + break; + case kClickAtRight: + p.x = xRight; + p.y = yCenter; + break; + case kClickAtTop: + p.x = xCenter; + p.y = yTop; + break; + case kClickAtBottom: + p.x = xCenter; + p.y = yBottom; + break; + case kClickAtEntityNearestToCenter: + p.x = xCenter; + p.y = yCenter; + // Looking through all objects for entities near to the center + if (_scene && _scene->getSceneObjects(objects, true)) { + for (uint32 i = 0; i < objects.size(); i++) { + BaseRegion *region; + if (objects[i]->getType() != OBJECT_ENTITY || + !objects[i]->_active || + !objects[i]->_registrable || + (!(region = ((AdEntity *)objects[i])->_region)) + ) { + continue; + } + + // Something exactly at center? Great! + if (region->pointInRegion(xCenter, yCenter)) { + distance = 0; + p.x = xCenter; + p.y = yCenter; + break; + } + + // Something at the edge? Available with other actions. + if (region->pointInRegion(xLeft, yCenter) || + region->pointInRegion(xRight, yCenter) || + region->pointInRegion(xCenter, yBottom) || + region->pointInRegion(xCenter, yTop) + ) { + continue; + } + + // Keep entities that has less distance to center + int x = ((AdEntity *)objects[i])->_posX; + int y = ((AdEntity *)objects[i])->_posY - ((AdEntity *)objects[i])->getHeight() / 2; + int d = (x - xCenter) * (x - xCenter) + (y - yCenter) * (y - yCenter); + if (distance > d) { + distance = d; + p.x = x; + p.y = y; + } + } + } + break; + default: + return false; + } + + BasePlatform::setCursorPos(p.x, p.y); + setActiveObject(_gameRef->_renderer->getObjectAt(p.x, p.y)); + onMouseLeftDown(); + onMouseLeftUp(); + return true; +} + + +////////////////////////////////////////////////////////////////////////// +bool AdGame::handleCustomActionEnd(BaseGameCustomAction action) { + return false; +} + + ////////////////////////////////////////////////////////////////////////// bool AdGame::getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *extMinor) const { BaseGame::getVersion(verMajor, verMinor, nullptr, nullptr); diff --git a/engines/wintermute/ad/ad_game.h b/engines/wintermute/ad/ad_game.h index bc39fb7871a..fc42754b9ae 100644 --- a/engines/wintermute/ad/ad_game.h +++ b/engines/wintermute/ad/ad_game.h @@ -52,6 +52,9 @@ public: bool onMouseRightDown() override; bool onMouseRightUp() override; + bool handleCustomActionStart(BaseGameCustomAction action) override; + bool handleCustomActionEnd(BaseGameCustomAction action) override; + bool displayDebugInfo() override; bool addSpeechDir(const char *dir); diff --git a/engines/wintermute/base/base_engine.h b/engines/wintermute/base/base_engine.h index 901a678ed17..5888b84a5e4 100644 --- a/engines/wintermute/base/base_engine.h +++ b/engines/wintermute/base/base_engine.h @@ -66,6 +66,7 @@ enum WMETargetExecutable { WME_1_7_1, // DEAD:CODE 2007 WME_1_7_2, // DEAD:CODE 2007 WME_1_7_3, // DEAD:CODE 2007 + WME_1_7_93, // DEAD:CODE 2007 WME_1_7_94, // DEAD:CODE 2007 WME_1_8_0, // DEAD:CODE 2007 WME_1_8_1, // DEAD:CODE 2007 diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp index ebb39a27362..ad49c11b5a3 100644 --- a/engines/wintermute/base/base_game.cpp +++ b/engines/wintermute/base/base_game.cpp @@ -79,6 +79,9 @@ #if EXTENDED_DEBUGGER_ENABLED #include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" +#endif + +#ifdef ENABLE_WME3D #include "graphics/renderer.h" #endif @@ -4011,50 +4014,6 @@ bool BaseGame::handleMouseWheel(int32 delta) { ////////////////////////////////////////////////////////////////////////// bool BaseGame::handleCustomActionStart(BaseGameCustomAction action) { - if (BaseEngine::instance().getGameId() == "corrosion") { - // Keyboard walking is added, for both original game & Enhanced Edition - - // However, Enhanced Edition contain city map screen, which is - // mouse controlled and conflicts with those custom actions - const char *m = "items\\street_map\\windows\\street_map_window.script"; - if (_scEngine->isRunningScript(m)) { - return false; - } - - Point32 p; - switch (action) { - case kClickAtCenter: - p.x = _renderer->getWidth() / 2; - p.y = _renderer->getHeight() / 2; - break; - case kClickAtLeft: - p.x = 30; - p.y = _renderer->getHeight() / 2; - break; - case kClickAtRight: - p.x = _renderer->getWidth() - 30; - p.y = _renderer->getHeight() / 2; - break; - case kClickAtTop: - p.x = _renderer->getWidth() / 2; - p.y = 10; - break; - case kClickAtBottom: - p.x = _renderer->getWidth() / 2; - p.y = _renderer->getHeight(); - p.y -= ConfMan.get("extra").contains("Enhanced") ? 35 : 90; - break; - default: - return false; - } - - BasePlatform::setCursorPos(p.x, p.y); - setActiveObject(_gameRef->_renderer->getObjectAt(p.x, p.y)); - onMouseLeftDown(); - onMouseLeftUp(); - return true; - } - return false; } diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h index d2ab79f71f3..f975da4f540 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -222,8 +222,8 @@ public: bool handleKeypress(Common::Event *event, bool printable = false) override; virtual void handleKeyRelease(Common::Event *event); - bool handleCustomActionStart(BaseGameCustomAction action); - bool handleCustomActionEnd(BaseGameCustomAction action); + virtual bool handleCustomActionStart(BaseGameCustomAction action); + virtual bool handleCustomActionEnd(BaseGameCustomAction action); bool unfreeze(); bool freeze(bool includingMusic = true); diff --git a/engines/wintermute/base/base_game_custom_actions.h b/engines/wintermute/base/base_game_custom_actions.h index f717771c35b..fe0c34c4406 100644 --- a/engines/wintermute/base/base_game_custom_actions.h +++ b/engines/wintermute/base/base_game_custom_actions.h @@ -36,7 +36,8 @@ enum BaseGameCustomAction { kClickAtLeft = 1, kClickAtRight = 2, kClickAtTop = 3, - kClickAtBottom = 4 + kClickAtBottom = 4, + kClickAtEntityNearestToCenter = 5 }; } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_persistence_manager.cpp b/engines/wintermute/base/base_persistence_manager.cpp index 5c7e3b4c10e..f8d32d1339c 100644 --- a/engines/wintermute/base/base_persistence_manager.cpp +++ b/engines/wintermute/base/base_persistence_manager.cpp @@ -36,7 +36,6 @@ #include "engines/wintermute/base/gfx/base_image.h" #include "engines/wintermute/base/save_thumb_helper.h" #include "engines/wintermute/base/sound/base_sound.h" -#include "graphics/transparent_surface.h" #include "engines/wintermute/wintermute.h" #include "graphics/scaler.h" #include "image/bmp.h" @@ -179,11 +178,9 @@ void BasePersistenceManager::getSaveStateDesc(int slot, SaveStateDescriptor &des Image::BitmapDecoder bmpDecoder; if (bmpDecoder.loadStream(thumbStream)) { const Graphics::Surface *bmpSurface = bmpDecoder.getSurface(); - Graphics::TransparentSurface *scaleableSurface = new Graphics::TransparentSurface(*bmpSurface, false); - Graphics::Surface *scaled = scaleableSurface->scale(kThumbnailWidth, kThumbnailHeight2); + Graphics::Surface *scaled = bmpSurface->scale(kThumbnailWidth, kThumbnailHeight2); Graphics::Surface *thumb = scaled->convertTo(g_system->getOverlayFormat()); desc.setThumbnail(thumb); - delete scaleableSurface; scaled->free(); delete scaled; } diff --git a/engines/wintermute/base/gfx/base_image.cpp b/engines/wintermute/base/gfx/base_image.cpp index a1548b83ead..963de43fc8f 100644 --- a/engines/wintermute/base/gfx/base_image.cpp +++ b/engines/wintermute/base/gfx/base_image.cpp @@ -28,7 +28,6 @@ #include "engines/wintermute/base/gfx/base_image.h" #include "engines/wintermute/base/base_file_manager.h" -#include "graphics/transparent_surface.h" #include "graphics/surface.h" #include "image/png.h" #include "image/jpeg.h" @@ -112,14 +111,13 @@ bool BaseImage::saveBMPFile(const Common::String &filename) const { ////////////////////////////////////////////////////////////////////////// bool BaseImage::resize(int newWidth, int newHeight) { // WME Lite used FILTER_BILINEAR with FreeImage_Rescale here. - Graphics::TransparentSurface temp(*_surface, true); + Graphics::Surface *temp = _surface->scale((uint16)newWidth, (uint16)newHeight); if (_deletableSurface) { _deletableSurface->free(); delete _deletableSurface; _deletableSurface = nullptr; } - _surface = _deletableSurface = temp.scale((uint16)newWidth, (uint16)newHeight); - temp.free(); + _surface = _deletableSurface = temp; return true; } @@ -216,13 +214,13 @@ bool BaseImage::writeBMPToStream(Common::WriteStream *stream) const { bool BaseImage::copyFrom(BaseImage *origImage, int newWidth, int newHeight) { // WME Lite used FILTER_BILINEAR with FreeImage_Rescale here. - Graphics::TransparentSurface temp(*origImage->_surface, false); + Graphics::Surface *temp = origImage->_surface->scale((uint16)newWidth, (uint16)newHeight); if (_deletableSurface) { _deletableSurface->free(); delete _deletableSurface; _deletableSurface = nullptr; } - _surface = _deletableSurface = temp.scale((uint16)newWidth, (uint16)newHeight); + _surface = _deletableSurface = temp; return true; } diff --git a/engines/wintermute/base/gfx/opengl/render_ticket.cpp b/engines/wintermute/base/gfx/opengl/render_ticket.cpp index 0ee3562308a..a9c2a7aa6a9 100644 --- a/engines/wintermute/base/gfx/opengl/render_ticket.cpp +++ b/engines/wintermute/base/gfx/opengl/render_ticket.cpp @@ -72,13 +72,7 @@ RenderTicketOpenGL::RenderTicketOpenGL(BaseSurfaceOpenGLTexture *owner, const Gr } else if ((dstRect->width() != srcRect->width() || dstRect->height() != srcRect->height()) && _transform._numTimesX * _transform._numTimesY == 1) { - Graphics::TransparentSurface src(*_surface, false); - Graphics::Surface *temp; - if (owner->_gameRef->getBilinearFiltering()) { - temp = src.scaleT(dstRect->width(), dstRect->height()); - } else { - temp = src.scaleT(dstRect->width(), dstRect->height()); - } + Graphics::Surface *temp = _surface->scale(dstRect->width(), dstRect->height(), owner->_gameRef->getBilinearFiltering()); _surface->free(); delete _surface; _surface = temp; diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp index e092e3cf173..d5297d6529c 100644 --- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp +++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp @@ -72,13 +72,7 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s } else if ((dstRect->width() != srcRect->width() || dstRect->height() != srcRect->height()) && _transform._numTimesX * _transform._numTimesY == 1) { - Graphics::TransparentSurface src(*_surface, false); - Graphics::Surface *temp; - if (owner->_gameRef->getBilinearFiltering()) { - temp = src.scaleT(dstRect->width(), dstRect->height()); - } else { - temp = src.scaleT(dstRect->width(), dstRect->height()); - } + Graphics::Surface *temp = _surface->scale(dstRect->width(), dstRect->height(), owner->_gameRef->getBilinearFiltering()); _surface->free(); delete _surface; _surface = temp; diff --git a/engines/wintermute/base/scriptables/dcscript.h b/engines/wintermute/base/scriptables/dcscript.h index 96bea233753..aa56d889cb2 100644 --- a/engines/wintermute/base/scriptables/dcscript.h +++ b/engines/wintermute/base/scriptables/dcscript.h @@ -113,8 +113,9 @@ typedef enum { // operation code types typedef enum { - OPCODES_UNCHANGED = 0, + OPCODES_UNCHANGED = 0 #ifdef ENABLE_FOXTAIL + , OPCODES_FOXTAIL_1_2_896, OPCODES_FOXTAIL_1_2_902 #endif diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h index f5d99374829..4b9ba0e5ac6 100644 --- a/engines/wintermute/detection_tables.h +++ b/engines/wintermute/detection_tables.h @@ -130,6 +130,8 @@ static const PlainGameDescriptor wintermuteGames[] = { {"sofiasdebt", "Sofia's Debt"}, {"sotv1", "Shadows on the Vatican - Act I: Greed"}, {"sotv2", "Shadows on the Vatican - Act II: Wrath"}, + {"strangechange", "Strange Change"}, + {"sunrise", "Sunrise: The game"}, {"tanya1", "Tanya Grotter and the Magical Double Bass"}, {"tanya2", "Tanya Grotter and the Disappearing Floor"}, {"tehran1933", "Murder In Tehran's Alleys 1933"}, @@ -591,7 +593,7 @@ static const WMEGameDescription gameDescriptions[] = { // Conspiracao Dumont (Demo) WME_WINENTRY("conspiracao", "Demo", - WME_ENTRY1s("ConspiracaoDumont.exe", "106f3f2c8f18bb5ffffeed634ace256c", 32908032), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), + WME_ENTRY1s("ConspiracaoDumont.exe", "106f3f2c8f18bb5ffffeed634ace256c", 32908032), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, WME_1_7_0), // Corrosion: Cold Winter Waiting WME_WINENTRY("corrosion", "", @@ -1404,7 +1406,7 @@ static const WMEGameDescription gameDescriptions[] = { // Life In 3 Minutes WME_WINENTRY("lifein3minutes", "", - WME_ENTRY1s("data.dcp", "c6368950e37a95bf098b02b4eaa5b929", 141787214), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), + WME_ENTRY1s("data.dcp", "c6368950e37a95bf098b02b4eaa5b929", 141787214), Common::EN_ANY, ADGF_UNSTABLE, WME_1_9_1), // Looky Demo (English) WME_WINENTRY("looky", "Demo", @@ -4865,6 +4867,16 @@ static const WMEGameDescription gameDescriptions[] = { WME_ENTRY2s("data.dcp", "5c88a51d010ad24225dee432ed38b238", 25987377, "lang-german.dcp", "78d06de2b4a8c68517eb6df3ded86d82", 1524330), Common::DE_DEU, ADGF_UNSTABLE, WME_1_9_1), + // Strange Change + // NOTE: This is a 2.5D game that is out of ScummVM scope + WME_WINENTRY("strangechange", "", + WME_ENTRY1s("data.dcp", "818e53c1584dac28f336195d7dcfb97d", 3762512), Common::EN_ANY, ADGF_UNSTABLE | GF_3D, WME_1_8_6), + + // Sunrise: The game (Demo) (German) + // NOTE: This is a 2.5D game that is out of ScummVM scope + WME_WINENTRY("sunrise", "", + WME_ENTRY1s("data.dcp", "3bac4da87472d2e7676e9548970d521a", 52095549), Common::DE_DEU, ADGF_UNSTABLE | GF_3D, WME_1_7_93), + // Tanya Grotter and the Magical Double Bass WME_WINENTRY("tanya1", "", WME_ENTRY1s("data.dcp", "035bbdaff078cc4053ecf4b518c0d0fd", 1007507786), Common::RU_RUS, ADGF_UNSTABLE, WME_1_8_0), @@ -5000,7 +5012,7 @@ static const WMEGameDescription gameDescriptions[] = { // War WME_WINENTRY("war", "", - WME_ENTRY1s("data.dcp", "003e317cda6d0137bbd5e5d7f089ee4d", 32591890), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), + WME_ENTRY1s("data.dcp", "003e317cda6d0137bbd5e5d7f089ee4d", 32591890), Common::EN_ANY, ADGF_UNSTABLE, WME_1_9_1), // Wintermute Engine Technology Demo (1.2) WME_WINENTRY("wmedemo", "1.2", @@ -5025,11 +5037,11 @@ static const WMEGameDescription gameDescriptions[] = { // Zilm: A Game of Reflex WME_WINENTRY("zilm", "", - WME_ENTRY1s("data.dcp", "81cece0c8105b4725fc35064a32b4b52", 351726), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), + WME_ENTRY1s("data.dcp", "81cece0c8105b4725fc35064a32b4b52", 351726), Common::EN_ANY, ADGF_UNSTABLE, WME_1_9_3), // Zilm: A Game of Reflex 1.0 WME_WINENTRY("zilm", "1.0", - WME_ENTRY1s("data.dcp", "098dffaf03d8adbb4cb5633e4733e63c", 351726), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), + WME_ENTRY1s("data.dcp", "098dffaf03d8adbb4cb5633e4733e63c", 351726), Common::EN_ANY, ADGF_UNSTABLE, WME_1_9_3), // Zbang! The Game (Demo) // NOTE: This is a 2.5D game that is out of ScummVM scope diff --git a/engines/wintermute/keymapper_tables.h b/engines/wintermute/keymapper_tables.h index 258195cf2fc..f65030661f7 100644 --- a/engines/wintermute/keymapper_tables.h +++ b/engines/wintermute/keymapper_tables.h @@ -35,6 +35,8 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common using namespace Common; Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "wintermute", "Wintermute engine"); + Keymap *gameKeyMap = new Keymap(Keymap::kKeymapTypeGame, gameId, gameDescr); + Keymap *extraKeyMap = new Keymap(Keymap::kKeymapTypeGame, "extras", "ScummVM extra actions"); Action *act; @@ -70,7 +72,12 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common gameId == "agustin" || gameId == "bickadoodle" || gameId == "bthreshold" || + gameId == "carolreed6" || + gameId == "carolreed7" || + gameId == "carolreed8" || gameId == "colorsoncanvas" || + gameId == "conspiracao" || + gameId == "corrosion" || gameId == "deadcity" || gameId == "darkfallls" || gameId == "drbohus" || @@ -84,6 +91,7 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common gameId == "hamlet" || gameId == "hor" || gameId == "juliauntold" || + gameId == "lifein3minutes" || gameId == "lonelyrobot" || gameId == "machumayu" || gameId == "mirage" || @@ -94,20 +102,18 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common gameId == "sofiasdebt" || gameId == "spaceinvaders" || gameId == "spacemadness" || + gameId == "strangechange" || gameId == "tanya1" || gameId == "tanya2" || gameId == "theancientmark1" || gameId == "thebox" || gameId == "thekite" || gameId == "tradestory" || + gameId == "war" || gameId == "wmedemo" ) { - return Keymap::arrayOf(engineKeyMap); - } - - Keymap *gameKeyMap = new Keymap(Keymap::kKeymapTypeGame, gameId, gameDescr); - - if (gameId == "dfafadventure" || + /* no game-specific keymap */ + } else if (gameId == "dfafadventure" || gameId == "dreamcat" || gameId == "openquest" ) { @@ -215,7 +221,12 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common act->addDefaultInputMapping("JOY_Y"); // extra joy gameKeyMap->addAction(act); } else if (gameId == "drdoylemotch" || + gameId == "carolreed9" || + gameId == "carolreed10" || + gameId == "carolreed11" || + gameId == "carolreed12" || gameId == "kulivocko" || + gameId == "sunrise" || gameId == "rebeccacarlson1" ) { act = new Action("HINT", _("Show hints")); @@ -239,7 +250,56 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common act->setMiddleClickEvent(); act->addDefaultInputMapping("MOUSE_MIDDLE"); // original mouse act->addDefaultInputMapping("JOY_Y"); // extra joy - engineKeyMap->addAction(act); + gameKeyMap->addAction(act); + } else if (gameId == "qajarycat") { + act = new Action("HINT", _("Show hints")); + act->setKeyEvent(KeyState(KEYCODE_SPACE, ASCII_SPACE)); + act->addDefaultInputMapping("SPACE"); // original keyboard + act->addDefaultInputMapping("MOUSE_MIDDLE"); // extra mouse + act->addDefaultInputMapping("JOY_Y"); // extra joy + gameKeyMap->addAction(act); + + act = new Action("GUIA", _("GUI variant A")); + act->setKeyEvent(KEYCODE_F10); + act->addDefaultInputMapping("F10"); // original keyboard + act->addDefaultInputMapping("MOUSE_WHEEL_UP"); // extra mouse + act->addDefaultInputMapping("JOY_LEFT"); // extra joy + gameKeyMap->addAction(act); + + act = new Action("GUIB", _("GUI variant B")); + act->setKeyEvent(KEYCODE_F11); + act->addDefaultInputMapping("F11"); // original keyboard + act->addDefaultInputMapping("MOUSE_WHEEL_DOWN"); // extra mouse + act->addDefaultInputMapping("JOY_RIGHT"); // extra joy + gameKeyMap->addAction(act); + + act = new Action("PHONEX", _("Phone cancel button")); + act->setKeyEvent(KeyState(KEYCODE_BACKSPACE, ASCII_BACKSPACE)); + act->addDefaultInputMapping("BACKSPACE"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("PHONEU", _("Phone up button")); + act->setKeyEvent(KEYCODE_UP); + act->addDefaultInputMapping("UP"); // original keyboard + act->addDefaultInputMapping("JOY_UP"); // extra joy + gameKeyMap->addAction(act); + + act = new Action("PHONED", _("Phone down button")); + act->setKeyEvent(KEYCODE_DOWN); + act->addDefaultInputMapping("DOWN"); // original keyboard + act->addDefaultInputMapping("JOY_DOWN"); // extra joy + gameKeyMap->addAction(act); + + act = new Action("MCLK", _("Middle Click")); + act->setMiddleClickEvent(); + act->addDefaultInputMapping("MOUSE_MIDDLE"); // original mouse + gameKeyMap->addAction(act); + + act = new Action("WTF", _("???")); + act->setKeyEvent(KEYCODE_HOME); + act->addDefaultInputMapping("HOME"); // original keyboard + //TODO: extra joy control, e.g. "JOY_R+JOY_B" + gameKeyMap->addAction(act); } else if (gameId == "alimardan1") { act = new Action("HINT", _("Show hints")); act->setKeyEvent(KeyState(KEYCODE_SPACE, ASCII_SPACE)); @@ -510,43 +570,22 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common act = new Action("VOLMAX", _("Volume max")); act->setMouseWheelUpEvent(); act->addDefaultInputMapping("MOUSE_WHEEL_UP"); // original mouse - act->addDefaultInputMapping("UP"); // extra keyboard - act->addDefaultInputMapping("JOY_UP"); // extra joy + act->addDefaultInputMapping("PAGEUP"); // extra keyboard + //TODO: extra joy control, e.g. "JOY_R+JOY_UP" gameKeyMap->addAction(act); act = new Action("VOLOFF", _("Volume off")); act->setMouseWheelDownEvent(); act->addDefaultInputMapping("MOUSE_WHEEL_DOWN"); // original mouse - act->addDefaultInputMapping("DOWN"); // extra keyboard - act->addDefaultInputMapping("JOY_DOWN"); // extra joy + act->addDefaultInputMapping("PAGEDOWN"); // extra keyboard + //TODO: extra joy control, e.g. "JOY_R+JOY_DOWN" gameKeyMap->addAction(act); - } else if (gameId == "corrosion") { - act = new Action(kStandardActionMoveUp, _("Walk forward")); - act->setCustomEngineActionEvent(kClickAtCenter); - act->addDefaultInputMapping("UP"); // extra keyboard - act->addDefaultInputMapping("KP8"); // extra keyboard - act->addDefaultInputMapping("JOY_UP"); // extra joy - gameKeyMap->addAction(act); - - act = new Action(kStandardActionMoveDown, _("Walk backward")); - act->setCustomEngineActionEvent(kClickAtBottom); - act->addDefaultInputMapping("DOWN"); // extra keyboard - act->addDefaultInputMapping("KP2"); // extra keyboard - act->addDefaultInputMapping("JOY_DOWN"); // extra joy - gameKeyMap->addAction(act); - - act = new Action(kStandardActionMoveLeft, _("Turn left")); - act->setCustomEngineActionEvent(kClickAtLeft); - act->addDefaultInputMapping("LEFT"); // extra keyboard - act->addDefaultInputMapping("KP4"); // extra keyboard - act->addDefaultInputMapping("JOY_LEFT"); // extra joy - gameKeyMap->addAction(act); - - act = new Action(kStandardActionMoveRight, _("Turn right")); - act->setCustomEngineActionEvent(kClickAtRight); - act->addDefaultInputMapping("RIGHT"); // extra keyboard - act->addDefaultInputMapping("KP6"); // extra keyboard - act->addDefaultInputMapping("JOY_RIGHT"); // extra joy + } else if (gameId == "carolreed5") { + act = new Action("HINT", _("Show hints")); + act->setKeyEvent(KeyState(KEYCODE_TAB, ASCII_TAB)); + act->addDefaultInputMapping("TAB"); // original keyboard + act->addDefaultInputMapping("MOUSE_MIDDLE"); // extra mouse + act->addDefaultInputMapping("JOY_Y"); // extra joy gameKeyMap->addAction(act); } else if (gameId == "erinmyers") { act = new Action("GUIB", _("Change font size")); @@ -1434,6 +1473,51 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common act->addDefaultInputMapping("MOUSE_MIDDLE"); // extra mouse act->addDefaultInputMapping("JOY_DOWN"); // extra joy gameKeyMap->addAction(act); + } else if (gameId == "zilm") { + act = new Action("P1UP", _("Player 1: Up")); + act->setKeyEvent(KeyState(KEYCODE_w, 'w')); + act->addDefaultInputMapping("w"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("P1LT", _("Player 1: Left")); + act->setKeyEvent(KeyState(KEYCODE_a, 'a')); + act->addDefaultInputMapping("a"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("P1DN", _("Player 1: Down")); + act->setKeyEvent(KeyState(KEYCODE_s, 's')); + act->addDefaultInputMapping("s"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("P1RT", _("Player 1: Right")); + act->setKeyEvent(KeyState(KEYCODE_d, 'd')); + act->addDefaultInputMapping("d"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("P2UP", _("Player 2: Up")); + act->setKeyEvent(KEYCODE_UP); + act->addDefaultInputMapping("UP"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("P2LT", _("Player 2: Left")); + act->setKeyEvent(KEYCODE_LEFT); + act->addDefaultInputMapping("LEFT"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("P2DN", _("Player 2: Down")); + act->setKeyEvent(KEYCODE_DOWN); + act->addDefaultInputMapping("DOWN"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("P2RT", _("Player 2: Right")); + act->setKeyEvent(KEYCODE_RIGHT); + act->addDefaultInputMapping("RIGHT"); // original keyboard + gameKeyMap->addAction(act); + + act = new Action("DBGFPS", _("Debug FPS")); + act->setKeyEvent(KEYCODE_F2); + act->addDefaultInputMapping("F2"); // original keyboard + gameKeyMap->addAction(act); } else if (gameId == "zbang") { act = new Action("ACTNXT", _("Next action")); act->setMouseWheelUpEvent(); @@ -1515,7 +1599,7 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common act = new Action("MCLK", _("Middle Click")); act->setMiddleClickEvent(); act->addDefaultInputMapping("MOUSE_MIDDLE"); // original mouse - engineKeyMap->addAction(act); + gameKeyMap->addAction(act); act = new Action("SCRLUP", _("Scroll up")); act->setMouseWheelUpEvent(); @@ -1542,8 +1626,51 @@ inline Common::KeymapArray getWintermuteKeymaps(const char *target, const Common act->addDefaultInputMapping("TAB"); // original keyboard gameKeyMap->addAction(act); } - result.push_back(gameKeyMap); + + + if (gameId == "carolreed4" || + gameId == "carolreed5" || + gameId == "carolreed6" || + gameId == "carolreed7" || + gameId == "carolreed8" || + gameId == "carolreed9" || + gameId == "carolreed10" || + gameId == "carolreed11" || + gameId == "carolreed12" || + gameId == "corrosion" || + gameId == "rebeccacarlson1" + ) { + act = new Action(kStandardActionMoveUp, _("Walk forward")); + act->setCustomEngineActionEvent(kClickAtEntityNearestToCenter); + act->addDefaultInputMapping("UP"); // extra keyboard + act->addDefaultInputMapping("KP5"); // extra keyboard + act->addDefaultInputMapping("JOY_UP"); // extra joy + extraKeyMap->addAction(act); + + act = new Action(kStandardActionMoveDown, _("Walk backward")); + act->setCustomEngineActionEvent(kClickAtBottom); + act->addDefaultInputMapping("DOWN"); // extra keyboard + act->addDefaultInputMapping("KP2"); // extra keyboard + act->addDefaultInputMapping("JOY_DOWN"); // extra joy + extraKeyMap->addAction(act); + + act = new Action(kStandardActionMoveLeft, _("Turn left")); + act->setCustomEngineActionEvent(kClickAtLeft); + act->addDefaultInputMapping("LEFT"); // extra keyboard + act->addDefaultInputMapping("KP4"); // extra keyboard + act->addDefaultInputMapping("JOY_LEFT"); // extra joy + extraKeyMap->addAction(act); + + act = new Action(kStandardActionMoveRight, _("Turn right")); + act->setCustomEngineActionEvent(kClickAtRight); + act->addDefaultInputMapping("RIGHT"); // extra keyboard + act->addDefaultInputMapping("KP6"); // extra keyboard + act->addDefaultInputMapping("JOY_RIGHT"); // extra joy + extraKeyMap->addAction(act); + } + result.push_back(extraKeyMap); + return result; } diff --git a/engines/wintermute/math/math_util.h b/engines/wintermute/math/math_util.h index 4421a7b9a46..bc455aa4b4e 100644 --- a/engines/wintermute/math/math_util.h +++ b/engines/wintermute/math/math_util.h @@ -29,7 +29,9 @@ #ifndef WINTERMUTE_MATHUTIL_H #define WINTERMUTE_MATHUTIL_H +#ifdef ENABLE_WME3D #include "math/vector3d.h" +#endif namespace Wintermute { diff --git a/graphics/colormasks.h b/graphics/colormasks.h index 27e6b167eae..d845b4f0886 100644 --- a/graphics/colormasks.h +++ b/graphics/colormasks.h @@ -116,18 +116,10 @@ struct ColorMasks<555> { kGreenBits = 5, kBlueBits = 5, -#ifdef __N64__ - /* Nintendo 64 uses a BGR555 color format for 16bit display */ - kAlphaShift = 0, - kRedShift = kBlueBits+kGreenBits+1, - kGreenShift = kBlueBits + 1, - kBlueShift = 1, -#else /* RGB555 */ kAlphaShift = 0, kRedShift = kGreenBits+kBlueBits, kGreenShift = kBlueBits, kBlueShift = 0, -#endif kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift, kRedMask = ((1 << kRedBits) - 1) << kRedShift, @@ -206,17 +198,10 @@ struct ColorMasks<4444> { kGreenBits = 4, kBlueBits = 4, -#ifdef __PSP__ //PSP uses ABGR - kAlphaShift = kRedBits+kGreenBits+kBlueBits, - kRedShift = 0, - kGreenShift = kRedBits, - kBlueShift = kRedBits+kGreenBits, -#else //ARGB kAlphaShift = kRedBits+kGreenBits+kBlueBits, kRedShift = kGreenBits+kBlueBits, kGreenShift = kBlueBits, kBlueShift = 0, -#endif kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift, kRedMask = ((1 << kRedBits) - 1) << kRedShift, @@ -302,35 +287,6 @@ struct ColorMasks<8888> { typedef uint32 PixelType; }; -#ifdef __WII__ -/* Gamecube/Wii specific ColorMask ARGB3444 */ -template<> -struct ColorMasks<3444> { - enum { - kBytesPerPixel = 2, - - kAlphaBits = 3, - kRedBits = 4, - kGreenBits = 4, - kBlueBits = 4, - - kBlueShift = 0, - kGreenShift = kBlueBits, - kRedShift = kGreenBits+kBlueBits, - kAlphaShift = kGreenBits+kBlueBits+kRedBits, - - kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift, - kRedMask = ((1 << kRedBits) - 1) << kRedShift, - kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift, - kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift, - - kRedBlueMask = kRedMask | kBlueMask - }; - - typedef uint16 PixelType; -}; -#endif - template uint32 RGBToColor(uint8 r, uint8 g, uint8 b) { return T::kAlphaMask | diff --git a/graphics/conversion.cpp b/graphics/conversion.cpp index 27180b80ad8..8df8a53b9f9 100644 --- a/graphics/conversion.cpp +++ b/graphics/conversion.cpp @@ -167,4 +167,290 @@ bool crossBlit(byte *dst, const byte *src, return true; } +namespace { + +template +void scaleNN(byte *dst, const byte *src, + const uint dstPitch, const uint srcPitch, + const uint dstW, const uint dstH, + const uint srcW, const uint srcH, + int *scaleCacheX) { + + const uint dstDelta = (dstPitch - dstW * sizeof(Size)); + + for (uint y = 0; y < dstH; y++) { + const Size *srcP = (const Size *)(src + ((y * srcH) / dstH) * srcPitch); + for (uint x = 0; x < dstW; x++) { + int val = srcP[scaleCacheX[x]]; + *(Size *)dst = val; + dst += sizeof(Size); + } + dst += dstDelta; + } +} + +} // End of anonymous namespace + +bool scaleBlit(byte *dst, const byte *src, + const uint dstPitch, const uint srcPitch, + const uint dstW, const uint dstH, + const uint srcW, const uint srcH, + const Graphics::PixelFormat &fmt) { + + int *scaleCacheX = new int[dstW]; + for (uint x = 0; x < dstW; x++) { + scaleCacheX[x] = (x * srcW) / dstW; + } + + switch (fmt.bytesPerPixel) { + case 1: + scaleNN(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX); + break; + case 2: + scaleNN(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX); + break; + case 4: + scaleNN(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX); + break; + default: + delete[] scaleCacheX; + return false; + } + + delete[] scaleCacheX; + + return true; +} + +/* + +The functions below are adapted from SDL_rotozoom.c, +taken from SDL_gfx-2.0.18. + +Its copyright notice: + +============================================================================= +SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces + +Copyright (C) 2001-2012 Andreas Schiffler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. + +Andreas Schiffler -- aschiffler at ferzkopp dot net +============================================================================= + + +The functions have been adapted for different structures, coordinate +systems and pixel formats. + +*/ + +namespace { + +inline byte scaleBlitBilinearInterpolate(byte c01, byte c00, byte c11, byte c10, int ex, int ey) { + int t1 = ((((c01 - c00) * ex) >> 16) + c00) & 0xff; + int t2 = ((((c11 - c10) * ex) >> 16) + c10) & 0xff; + return (((t2 - t1) * ey) >> 16) + t1; +} + +template +Size scaleBlitBilinearInterpolate(Size c01, Size c00, Size c11, Size c10, int ex, int ey, + const Graphics::PixelFormat &fmt) { + byte c01_a, c01_r, c01_g, c01_b; + fmt.colorToARGB(c01, c01_a, c01_r, c01_g, c01_b); + + byte c00_a, c00_r, c00_g, c00_b; + fmt.colorToARGB(c00, c00_a, c00_r, c00_g, c00_b); + + byte c11_a, c11_r, c11_g, c11_b; + fmt.colorToARGB(c11, c11_a, c11_r, c11_g, c11_b); + + byte c10_a, c10_r, c10_g, c10_b; + fmt.colorToARGB(c10, c10_a, c10_r, c10_g, c10_b); + + byte dp_a = scaleBlitBilinearInterpolate(c01_a, c00_a, c11_a, c10_a, ex, ey); + byte dp_r = scaleBlitBilinearInterpolate(c01_r, c00_r, c11_r, c10_r, ex, ey); + byte dp_g = scaleBlitBilinearInterpolate(c01_g, c00_g, c11_g, c10_g, ex, ey); + byte dp_b = scaleBlitBilinearInterpolate(c01_b, c00_b, c11_b, c10_b, ex, ey); + return fmt.ARGBToColor(dp_a, dp_r, dp_g, dp_b); +} + +template // TODO: See mirroring comment in RenderTicket ctor +void scaleBlitBilinearLogic(byte *dst, const byte *src, + const uint dstPitch, const uint srcPitch, + const uint dstW, const uint dstH, + const uint srcW, const uint srcH, + const Graphics::PixelFormat &fmt, + int *sax, int *say) { + + int spixelw = (srcW - 1); + int spixelh = (srcH - 1); + + const byte *sp = src; + + if (flipx) { + sp += spixelw; + } + if (flipy) { + sp += srcPitch * spixelh; + } + + int *csay = say; + for (uint y = 0; y < dstH; y++) { + Size *dp = (Size *)(dst + (dstPitch * y)); + const byte *csp = sp; + int *csax = sax; + for (uint x = 0; x < dstW; x++) { + /* + * Setup color source pointers + */ + int ex = (*csax & 0xffff); + int ey = (*csay & 0xffff); + int cx = (*csax >> 16); + int cy = (*csay >> 16); + + const byte *c00, *c01, *c10, *c11; + c00 = c01 = c10 = sp; + if (cy < spixelh) { + if (flipy) { + c10 -= srcPitch; + } else { + c10 += srcPitch; + } + } + c11 = c10; + if (cx < spixelw) { + if (flipx) { + c01 -= sizeof(Size); + c11 -= sizeof(Size); + } else { + c01 += sizeof(Size); + c11 += sizeof(Size); + } + } + + /* + * Draw and interpolate colors + */ + *dp = scaleBlitBilinearInterpolate(*(const Size *)c01, *(const Size *)c00, *(const Size *)c11, *(const Size *)c10, ex, ey, fmt); + /* + * Advance source pointer x + */ + int *salastx = csax; + csax++; + int sstepx = (*csax >> 16) - (*salastx >> 16); + if (flipx) { + sp -= sstepx * sizeof(Size); + } else { + sp += sstepx * sizeof(Size); + } + + /* + * Advance destination pointer x + */ + dp++; + } + /* + * Advance source pointer y + */ + int *salasty = csay; + csay++; + int sstepy = (*csay >> 16) - (*salasty >> 16); + sstepy *= srcPitch; + if (flipy) { + sp = csp - sstepy; + } else { + sp = csp + sstepy; + } + } +} + +} // End of anonymous namespace + +bool scaleBlitBilinear(byte *dst, const byte *src, + const uint dstPitch, const uint srcPitch, + const uint dstW, const uint dstH, + const uint srcW, const uint srcH, + const Graphics::PixelFormat &fmt) { + if (fmt.bytesPerPixel != 2 && fmt.bytesPerPixel != 4) + return false; + + int *sax = new int[dstW + 1]; + int *say = new int[dstH + 1]; + assert(sax && say); + + /* + * Precalculate row increments + */ + int spixelw = (srcW - 1); + int spixelh = (srcH - 1); + int sx = (int)(65536.0f * (float) spixelw / (float) (dstW - 1)); + int sy = (int)(65536.0f * (float) spixelh / (float) (dstH - 1)); + + /* Maximum scaled source size */ + int ssx = (srcW << 16) - 1; + int ssy = (srcH << 16) - 1; + + /* Precalculate horizontal row increments */ + int csx = 0; + int *csax = sax; + for (uint x = 0; x <= dstW; x++) { + *csax = csx; + csax++; + csx += sx; + + /* Guard from overflows */ + if (csx > ssx) { + csx = ssx; + } + } + + /* Precalculate vertical row increments */ + int csy = 0; + int *csay = say; + for (uint y = 0; y <= dstH; y++) { + *csay = csy; + csay++; + csy += sy; + + /* Guard from overflows */ + if (csy > ssy) { + csy = ssy; + } + } + + if (fmt.bytesPerPixel == 4) { + scaleBlitBilinearLogic(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say); + } else if (fmt.bytesPerPixel == 2) { + scaleBlitBilinearLogic(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say); + } else { + delete[] sax; + delete[] say; + + return false; + } + + delete[] sax; + delete[] say; + + return true; +} + } // End of namespace Graphics diff --git a/graphics/conversion.h b/graphics/conversion.h index 8ca529acc09..1e5486864a1 100644 --- a/graphics/conversion.h +++ b/graphics/conversion.h @@ -72,6 +72,18 @@ bool crossBlit(byte *dst, const byte *src, const uint w, const uint h, const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt); +bool scaleBlit(byte *dst, const byte *src, + const uint dstPitch, const uint srcPitch, + const uint dstW, const uint dstH, + const uint srcW, const uint srcH, + const Graphics::PixelFormat &fmt); + +bool scaleBlitBilinear(byte *dst, const byte *src, + const uint dstPitch, const uint srcPitch, + const uint dstW, const uint dstH, + const uint srcW, const uint srcH, + const Graphics::PixelFormat &fmt); + } // End of namespace Graphics #endif // GRAPHICS_CONVERSION_H diff --git a/graphics/maccursor.h b/graphics/maccursor.h index a4da7cb46fe..64a2e959229 100644 --- a/graphics/maccursor.h +++ b/graphics/maccursor.h @@ -54,18 +54,18 @@ public: /** Return the cursor's hotspot's y coordinate. */ uint16 getHotspotY() const { return _hotspotY; } /** Return the cursor's transparent key. */ - byte getKeyColor() const { return 0xFF; } + virtual byte getKeyColor() const { return 0xFF; } const byte *getSurface() const { return _surface; } - const byte *getPalette() const { return _palette; } + virtual const byte *getPalette() const { return _palette; } byte getPaletteStartIndex() const { return 0; } uint16 getPaletteCount() const { return 256; } /** Read the cursor's data out of a stream. */ bool readFromStream(Common::SeekableReadStream &stream, bool forceMonochrome = false, byte monochromeInvertedPixelColor = 0xff); -private: +protected: bool readFromCURS(Common::SeekableReadStream &stream, byte monochromeInvertedPixelColor); bool readFromCRSR(Common::SeekableReadStream &stream, bool forceMonochrome, byte monochromeInvertedPixelColor); diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp index d5d7f614c4a..bf166c2cedc 100644 --- a/graphics/managed_surface.cpp +++ b/graphics/managed_surface.cpp @@ -90,6 +90,12 @@ ManagedSurface &ManagedSurface::operator=(const ManagedSurface &surf) { _innerSurface.h = surf.h; _innerSurface.pitch = surf.pitch; this->format = surf.format; + + // Copy miscellaneous properties + _transparentColorSet = surf._transparentColorSet; + _transparentColor = surf._transparentColor; + _paletteSet = surf._paletteSet; + Common::copy(&surf._palette[0], &surf._palette[256], _palette); } return *this; @@ -123,6 +129,12 @@ void ManagedSurface::create(ManagedSurface &surf, const Common::Rect &bounds) { _innerSurface.h = bounds.height(); _owner = &surf; _disposeAfterUse = DisposeAfterUse::NO; + + // Copy miscellaneous properties + _transparentColorSet = surf._transparentColorSet; + _transparentColor = surf._transparentColor; + _paletteSet = surf._paletteSet; + Common::copy(&surf._palette[0], &surf._palette[256], _palette); } void ManagedSurface::free() { @@ -321,7 +333,7 @@ void ManagedSurface::transBlitFrom(const Surface &src, const Common::Rect &srcRe const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor, uint srcAlpha, const Surface *mask, bool maskOnly) { transBlitFromInner(src, srcRect, destRect, transColor, flipped, overrideColor, srcAlpha, - nullptr, mask, maskOnly); + nullptr, nullptr, mask, maskOnly); } void ManagedSurface::transBlitFrom(const ManagedSurface &src, uint transColor, bool flipped, @@ -355,23 +367,124 @@ void ManagedSurface::transBlitFrom(const ManagedSurface &src, const Common::Rect const Surface *mask, bool maskOnly) { if (transColor == (uint)-1 && src._transparentColorSet) transColor = src._transparentColor; - const uint32 *palette = src._paletteSet ? src._palette : nullptr; + const uint32 *srcPalette = src._paletteSet ? src._palette : nullptr; + const uint32 *dstPalette = _paletteSet ? _palette : nullptr; transBlitFromInner(src._innerSurface, srcRect, destRect, transColor, flipped, overrideColor, - srcAlpha, palette, mask, maskOnly); + srcAlpha, srcPalette, dstPalette, mask, maskOnly); +} + +static uint findBestColor(const uint32 *palette, byte cr, byte cg, byte cb) { + uint bestColor = 0; + double min = 0xFFFFFFFF; + + for (uint i = 0; i < 256; ++i) { + uint col = palette[i]; + + int rmean = ((col & 0xff) + cr) / 2; + int r = (col & 0xff) - cr; + int g = ((col >> 8) & 0xff) - cg; + int b = ((col >> 16) & 0xff) - cb; + + double dist = sqrt((((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8)); + if (min > dist) { + bestColor = i; + min = dist; + } + } + + return bestColor; +} + +static byte *createPaletteLookup(const uint32 *srcPalette, const uint32 *dstPalette) { + byte *lookup = new byte[256]; + + for (int i = 0; i < 256; i++) { + uint col = srcPalette[i]; + if (col == dstPalette[i]) { + lookup[i] = i; + } else { + lookup[i] = findBestColor(dstPalette, col & 0xff, (col >> 8) & 0xff, (col >> 16) & 0xff); + } + } + + return lookup; +} + +template +void transBlitPixel(TSRC srcVal, TDEST &destVal, const Graphics::PixelFormat &srcFormat, const Graphics::PixelFormat &destFormat, + uint overrideColor, uint srcAlpha, const uint32 *srcPalette, const byte *lookup) { + if (srcFormat == destFormat && srcAlpha == 0xff) { + // Matching formats, so we can do a straight copy + destVal = overrideColor ? overrideColor : srcVal; + return; + } + + // Otherwise we have to manually decode and re-encode each pixel + byte aSrc, rSrc, gSrc, bSrc; + if (srcFormat.bytesPerPixel == 1) { + assert(srcPalette != nullptr); // Catch the cases when palette is missing + + // Get the palette color + const uint32 col = srcPalette[srcVal]; + rSrc = col & 0xff; + gSrc = (col >> 8) & 0xff; + bSrc = (col >> 16) & 0xff; + aSrc = (col >> 24) & 0xff; + } else { + srcFormat.colorToARGB(srcVal, aSrc, rSrc, gSrc, bSrc); + } + + byte rDest, gDest, bDest; + destFormat.colorToRGB(destVal, rDest, gDest, bDest); + + if (srcAlpha != 0xff) { + aSrc = aSrc * srcAlpha / 255; + } + + if (aSrc == 0) { + // Completely transparent, so skip + return; + } else if (aSrc == 0xff) { + // Completely opaque, so copy RGB values over + rDest = rSrc; + gDest = gSrc; + bDest = bSrc; + } else { + // Partially transparent, so calculate new pixel colors + double alpha = (double)aSrc / 255.0; + rDest = static_cast((rSrc * alpha) + (rDest * (1.0 - alpha))); + gDest = static_cast((gSrc * alpha) + (gDest * (1.0 - alpha))); + bDest = static_cast((bSrc * alpha) + (bDest * (1.0 - alpha))); + } + + destVal = destFormat.ARGBToColor(0xff, rDest, gDest, bDest); +} + +template<> +void transBlitPixel(byte srcVal, byte &destVal, const Graphics::PixelFormat &srcFormat, const Graphics::PixelFormat &destFormat, + uint overrideColor, uint srcAlpha, const uint32 *srcPalette, const byte *lookup) { + if (srcAlpha == 0) { + // Completely transparent, so skip + return; + } + + destVal = overrideColor ? overrideColor : srcVal; + + if (lookup) + destVal = lookup[destVal]; } template void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, const Common::Rect &destRect, - TSRC transColor, bool flipped, uint overrideColor, uint srcAlpha, const uint32 *palette, - const Surface *mask, bool maskOnly) { + TSRC transColor, bool flipped, uint overrideColor, uint srcAlpha, const uint32 *srcPalette, + const uint32 *dstPalette, const Surface *mask, bool maskOnly) { int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width(); int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height(); - const Graphics::PixelFormat &srcFormat = src.format; - const Graphics::PixelFormat &destFormat = dest.format; - byte aSrc, rSrc, gSrc, bSrc; - byte rDest, gDest, bDest; - double alpha; + + byte *lookup = nullptr; + if (srcPalette && dstPalette) + lookup = createPaletteLookup(srcPalette, dstPalette); // Loop through drawing output lines for (int destY = destRect.top, scaleYCtr = 0; destY < destRect.bottom; ++destY, scaleYCtr += scaleY) { @@ -398,63 +511,25 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c TSRC mskVal = mskLine[flipped ? src.w - scaleXCtr / SCALE_THRESHOLD - 1 : scaleXCtr / SCALE_THRESHOLD]; if (!mskVal) continue; - } - if (srcFormat == destFormat && srcAlpha == 0xff) { - // Matching formats, so we can do a straight copy - destLine[xCtr] = overrideColor ? overrideColor : srcVal; + transBlitPixel(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, mskVal, srcPalette, lookup); } else { - // Otherwise we have to manually decode and re-encode each pixel - if (srcFormat.bytesPerPixel == 1) { - assert(palette != nullptr); // Catch the cases when palette is missing - - // Get the palette color - const uint32 col = palette[srcVal]; - rSrc = col & 0xff; - gSrc = (col >> 8) & 0xff; - bSrc = (col >> 16) & 0xff; - aSrc = (col >> 24) & 0xff; - } else { - srcFormat.colorToARGB(srcVal, aSrc, rSrc, gSrc, bSrc); - } - destFormat.colorToRGB(destLine[xCtr], rDest, gDest, bDest); - - if (srcAlpha != 0xff) { - aSrc = aSrc * srcAlpha / 255; - } - - if (aSrc == 0) { - // Completely transparent, so skip - continue; - } - else if (aSrc == 0xff) { - // Completely opaque, so copy RGB values over - rDest = rSrc; - gDest = gSrc; - bDest = bSrc; - } - else { - // Partially transparent, so calculate new pixel colors - alpha = (double)aSrc / 255.0; - rDest = static_cast((rSrc * alpha) + (rDest * (1.0 - alpha))); - gDest = static_cast((gSrc * alpha) + (gDest * (1.0 - alpha))); - bDest = static_cast((bSrc * alpha) + (bDest * (1.0 - alpha))); - } - - destLine[xCtr] = destFormat.ARGBToColor(0xff, rDest, gDest, bDest); + transBlitPixel(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, srcAlpha, srcPalette, lookup); } } } + + delete[] lookup; } #define HANDLE_BLIT(SRC_BYTES, DEST_BYTES, SRC_TYPE, DEST_TYPE) \ if (src.format.bytesPerPixel == SRC_BYTES && format.bytesPerPixel == DEST_BYTES) \ - transBlit(src, srcRect, _innerSurface, destRect, transColor, flipped, overrideColor, srcAlpha, palette, mask, maskOnly); \ + transBlit(src, srcRect, _innerSurface, destRect, transColor, flipped, overrideColor, srcAlpha, srcPalette, dstPalette, mask, maskOnly); \ else void ManagedSurface::transBlitFromInner(const Surface &src, const Common::Rect &srcRect, const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor, - uint srcAlpha, const uint32 *palette, const Surface *mask, bool maskOnly) { + uint srcAlpha, const uint32 *srcPalette, const uint32 *dstPalette, const Surface *mask, bool maskOnly) { if (src.w == 0 || src.h == 0 || destRect.width() == 0 || destRect.height() == 0) return; @@ -505,12 +580,18 @@ void ManagedSurface::setPalette(const byte *colors, uint start, uint num) { } _paletteSet = true; + + if (_owner) + _owner->setPalette(colors, start, num); } void ManagedSurface::setPalette(const uint32 *colors, uint start, uint num) { assert(start < 256 && (start + num) <= 256); Common::copy(colors, colors + num, &_palette[start]); _paletteSet = true; + + if (_owner) + _owner->setPalette(colors, start, num); } } // End of namespace Graphics diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h index 290b04aba4b..c79122f31cc 100644 --- a/graphics/managed_surface.h +++ b/graphics/managed_surface.h @@ -92,7 +92,7 @@ protected: */ void transBlitFromInner(const Surface &src, const Common::Rect &srcRect, const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor, - uint srcAlpha, const uint32 *palette, const Surface *mask, bool maskOnly); + uint srcAlpha, const uint32 *srcPalette, const uint32 *dstPalette, const Surface *mask, bool maskOnly); public: /** * Clips the given source bounds so the passed destBounds will be entirely on-screen @@ -299,7 +299,7 @@ public: * Copies another surface into this one ignoring pixels of a designated transparent color * @param src Source surface * @param destPos Destination position to draw the surface - * @param mask Mask definition (0-skip, other-copy) + * @param mask Mask definition */ void transBlitFrom(const Surface &src, const Common::Point &destPos, const ManagedSurface &mask); @@ -308,7 +308,7 @@ public: * Copies another surface into this one ignoring pixels of a designated transparent color * @param src Source surface * @param destPos Destination position to draw the surface - * @param mask Mask definition (0-skip, other-copy) + * @param mask Mask definition */ void transBlitFrom(const Surface &src, const Common::Point &destPos, const Surface &mask); @@ -323,8 +323,6 @@ public: * @param overrideColor Optional color to use instead of non-transparent pixels from * the source surface * @param srcAlpha Optional additional transparency applied to src - * @param mask Optional parameter with mask definition (0-skip, other-copy) - * @param maskOnly Optional parameter for using mask over transColor */ void transBlitFrom(const Surface &src, const Common::Rect &srcRect, const Common::Point &destPos, uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff); @@ -340,7 +338,7 @@ public: * @param overrideColor Optional color to use instead of non-transparent pixels from * the source surface * @param srcAlpha Optional additional transparency applied to src - * @param mask Optional parameter with mask definition (0-skip, other-copy) + * @param mask Optional parameter with mask definition * @param maskOnly Optional parameter for using mask over transColor */ void transBlitFrom(const Surface &src, const Common::Rect &srcRect, const Common::Rect &destRect, @@ -376,7 +374,7 @@ public: * Copies another surface into this one ignoring pixels of a designated transparent color * @param src Source surface * @param destPos Destination position to draw the surface - * @param mask Mask definition (0-skip, other-copy) + * @param mask Mask definition */ void transBlitFrom(const ManagedSurface &src, const Common::Point &destPos, const ManagedSurface &mask); @@ -406,6 +404,8 @@ public: * @param overrideColor Optional color to use instead of non-transparent pixels from * the source surface * @param srcAlpha Optional additional transparency applied to src + * @param mask Optional parameter with mask definition + * @param maskOnly Optional parameter for using mask over transColor */ void transBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect, const Common::Rect &destRect, uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff, diff --git a/graphics/nine_patch.cpp b/graphics/nine_patch.cpp index 155fc39ea92..34c37a559aa 100644 --- a/graphics/nine_patch.cpp +++ b/graphics/nine_patch.cpp @@ -47,6 +47,7 @@ #include "common/array.h" #include "graphics/transparent_surface.h" #include "graphics/nine_patch.h" +//#include "graphics/macgui/macwindowmanager.h" // ResidualVM specific #include "graphics/managed_surface.h" @@ -207,7 +208,7 @@ bad_bitmap: } } -void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette, int numColors) { +void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette, int numColors, MacWindowManager *wm) { /* don't draw bitmaps that are smaller than the fixed area */ if (dw < _h._fix || dh < _v._fix) return; @@ -231,7 +232,7 @@ void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, in /* Handle CLUT8 */ if (target.format.bytesPerPixel == 1) { - if (!palette) + if (!palette && !wm) error("NinePatchBitmap::blit(): Trying to blit into a surface with 8bpp, you need a palette."); Surface *srf = new Surface(); @@ -244,11 +245,24 @@ void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, in // recalculated when the palette changes. _cached_colors.clear(); - for (uint i = 0; i < srf->w; ++i) { - for (uint j = 0; j < srf->h; ++j) { - uint32 color = *(uint32*)srf->getBasePtr(i, j); - if (color > 0) { - *((byte *)target.getBasePtr(i, j)) = closestGrayscale(color, palette, numColors); + if (palette) { + for (uint i = 0; i < srf->w; ++i) { + for (uint j = 0; j < srf->h; ++j) { + uint32 color = *(uint32*)srf->getBasePtr(i, j); + if (color > 0) { + *((byte *)target.getBasePtr(i, j)) = closestGrayscale(color, palette, numColors); + } + } + } + } else { + for (uint i = 0; i < srf->w; ++i) { + for (uint j = 0; j < srf->h; ++j) { + uint32 color = *(uint32*)srf->getBasePtr(i, j); + byte r, g, b; + _bmp->format.colorToRGB(color, r, g, b); + if (color > 0) { +// *((byte *)target.getBasePtr(i, j)) = wm->findBestColor(r, g, b); // ResidualVM specific + } } } } diff --git a/graphics/nine_patch.h b/graphics/nine_patch.h index d341919baa8..c79c66b7112 100644 --- a/graphics/nine_patch.h +++ b/graphics/nine_patch.h @@ -54,6 +54,7 @@ namespace Graphics { struct TransparentSurface; struct Surface; +class MacWindowManager; struct NinePatchMark { int offset; @@ -88,7 +89,7 @@ public: NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bitmap); ~NinePatchBitmap(); - void blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette = NULL, int numColors = 0); + void blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette = NULL, int numColors = 0, MacWindowManager *wm = NULL); void blitClip(Graphics::Surface &target, Common::Rect clip, int dx, int dy, int dw, int dh); int getWidth() { return _width; } diff --git a/graphics/screen.cpp b/graphics/screen.cpp index f55ed2057b9..59ab767543d 100644 --- a/graphics/screen.cpp +++ b/graphics/screen.cpp @@ -122,6 +122,7 @@ void Screen::setPalette(const byte palette[PALETTE_SIZE]) { void Screen::setPalette(const byte *palette, uint start, uint num) { assert(format.bytesPerPixel == 1); g_system->getPaletteManager()->setPalette(palette, start, num); + ManagedSurface::setPalette(palette, start, num); } void Screen::clearPalette() { diff --git a/graphics/surface.cpp b/graphics/surface.cpp index e2e3401cc23..d389f139efa 100644 --- a/graphics/surface.cpp +++ b/graphics/surface.cpp @@ -368,6 +368,21 @@ void Surface::flipVertical(const Common::Rect &r) { delete[] temp; } +Graphics::Surface *Surface::scale(uint16 newWidth, uint16 newHeight, bool filtering) const { + + Graphics::Surface *target = new Graphics::Surface(); + + target->create(newWidth, newHeight, format); + + if (filtering) { + scaleBlitBilinear((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, target->w, target->h, w, h, format); + } else { + scaleBlit((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, target->w, target->h, w, h, format); + } + + return target; +} + void Surface::convertToInPlace(const PixelFormat &dstFormat, const byte *palette) { // Do not convert to the same format and ignore empty surfaces. if (format == dstFormat || pixels == 0) { diff --git a/graphics/surface.h b/graphics/surface.h index 87281062736..b7ada5ec28a 100644 --- a/graphics/surface.h +++ b/graphics/surface.h @@ -334,6 +334,19 @@ public: * @param r Rect to flip */ void flipVertical(const Common::Rect &r); + + /** + * Scale the data to the given size. + * + * The calling code must call free on the returned surface and then delete + * it. + * + * @param newWidth the resulting width. + * @param newHeight the resulting height. + * @param filtering Whether or not to use bilinear filtering. + */ + Graphics::Surface *scale(uint16 newWidth, uint16 newHeight, bool filtering = false) const; + }; /** diff --git a/graphics/transparent_surface.cpp b/graphics/transparent_surface.cpp index eb8d3fe5ce9..21dd893b473 100644 --- a/graphics/transparent_surface.cpp +++ b/graphics/transparent_surface.cpp @@ -33,6 +33,7 @@ #include "common/rect.h" #include "common/math.h" #include "common/textconsole.h" +#include "graphics/conversion.h" #include "graphics/primitives.h" #include "graphics/transparent_surface.h" #include "graphics/transform_tools.h" @@ -750,7 +751,7 @@ void TransparentSurface::setAlphaMode(AlphaType mode) { /* -The below two functions are adapted from SDL_rotozoom.c, +The function below is adapted from SDL_rotozoom.c, taken from SDL_gfx-2.0.18. Its copyright notice: @@ -908,186 +909,16 @@ TransparentSurface *TransparentSurface::rotoscaleT(const TransformStruct &transf return target; } -template -TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight) const { +TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight, bool filtering) const { TransparentSurface *target = new TransparentSurface(); - int srcW = w; - int srcH = h; - int dstW = newWidth; - int dstH = newHeight; - - target->create((uint16)dstW, (uint16)dstH, format); - - if (filteringMode == FILTER_BILINEAR) { - assert(format.bytesPerPixel == 4); - - bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor - - - int *sax = new int[dstW + 1]; - int *say = new int[dstH + 1]; - assert(sax && say); - - /* - * Precalculate row increments - */ - int spixelw = (srcW - 1); - int spixelh = (srcH - 1); - int sx = (int)(65536.0f * (float) spixelw / (float) (dstW - 1)); - int sy = (int)(65536.0f * (float) spixelh / (float) (dstH - 1)); - - /* Maximum scaled source size */ - int ssx = (srcW << 16) - 1; - int ssy = (srcH << 16) - 1; - - /* Precalculate horizontal row increments */ - int csx = 0; - int *csax = sax; - for (int x = 0; x <= dstW; x++) { - *csax = csx; - csax++; - csx += sx; - - /* Guard from overflows */ - if (csx > ssx) { - csx = ssx; - } - } - - /* Precalculate vertical row increments */ - int csy = 0; - int *csay = say; - for (int y = 0; y <= dstH; y++) { - *csay = csy; - csay++; - csy += sy; - - /* Guard from overflows */ - if (csy > ssy) { - csy = ssy; - } - } - - const tColorRGBA *sp = (const tColorRGBA *) getBasePtr(0, 0); - tColorRGBA *dp = (tColorRGBA *) target->getBasePtr(0, 0); - int spixelgap = srcW; - - if (flipx) { - sp += spixelw; - } - if (flipy) { - sp += spixelgap * spixelh; - } - - csay = say; - for (int y = 0; y < dstH; y++) { - const tColorRGBA *csp = sp; - csax = sax; - for (int x = 0; x < dstW; x++) { - /* - * Setup color source pointers - */ - int ex = (*csax & 0xffff); - int ey = (*csay & 0xffff); - int cx = (*csax >> 16); - int cy = (*csay >> 16); - - const tColorRGBA *c00, *c01, *c10, *c11; - c00 = sp; - c01 = sp; - c10 = sp; - if (cy < spixelh) { - if (flipy) { - c10 -= spixelgap; - } else { - c10 += spixelgap; - } - } - c11 = c10; - if (cx < spixelw) { - if (flipx) { - c01--; - c11--; - } else { - c01++; - c11++; - } - } - - /* - * Draw and interpolate colors - */ - int t1, t2; - t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; - t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; - dp->r = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; - t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; - dp->g = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; - t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; - dp->b = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; - t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; - dp->a = (((t2 - t1) * ey) >> 16) + t1; - - /* - * Advance source pointer x - */ - int *salastx = csax; - csax++; - int sstepx = (*csax >> 16) - (*salastx >> 16); - if (flipx) { - sp -= sstepx; - } else { - sp += sstepx; - } - - /* - * Advance destination pointer x - */ - dp++; - } - /* - * Advance source pointer y - */ - int *salasty = csay; - csay++; - int sstepy = (*csay >> 16) - (*salasty >> 16); - sstepy *= spixelgap; - if (flipy) { - sp = csp - sstepy; - } else { - sp = csp + sstepy; - } - } - - delete[] sax; - delete[] say; + target->create(newWidth, newHeight, format); + if (filtering) { + scaleBlitBilinear((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, target->w, target->h, w, h, format); } else { - int *scaleCacheX = new int[dstW]; - for (int x = 0; x < dstW; x++) { - scaleCacheX[x] = (x * srcW) / dstW; - } - - switch (format.bytesPerPixel) { - case 1: - scaleNN(scaleCacheX, target); - break; - case 2: - scaleNN(scaleCacheX, target); - break; - case 4: - scaleNN(scaleCacheX, target); - break; - default: - error("Can only scale 8bpp, 16bpp, and 32bpp"); - } - - delete[] scaleCacheX; + scaleBlit((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, target->w, target->h, w, h, format); } return target; @@ -1171,32 +1002,11 @@ TransparentSurface *TransparentSurface::convertTo(const PixelFormat &dstFormat, return surface; } -template -void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const { - for (int y = 0; y < target->h; y++) { - Size *destP = (Size *)target->getBasePtr(0, y); - const Size *srcP = (const Size *)getBasePtr(0, (y * h) / target->h); - for (int x = 0; x < target->w; x++) { - *destP++ = srcP[scaleCacheX[x]]; - } - } -} - template TransparentSurface *TransparentSurface::rotoscaleT(const TransformStruct &transform) const; template TransparentSurface *TransparentSurface::rotoscaleT(const TransformStruct &transform) const; -template TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight) const; -template TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight) const; - -template void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const; -template void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const; -template void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const; TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const { return rotoscaleT(transform); } -TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight) const { - return scaleT(newWidth, newHeight); -} - } // End of namespace Graphics diff --git a/graphics/transparent_surface.h b/graphics/transparent_surface.h index 8bfddef8c1a..ae0de7d2e22 100644 --- a/graphics/transparent_surface.h +++ b/graphics/transparent_surface.h @@ -145,12 +145,10 @@ struct TransparentSurface : public Graphics::Surface { * * @param newWidth the resulting width. * @param newHeight the resulting height. + * @param filtering Whether or not to use bilinear filtering. * @see TransformStruct */ - template - TransparentSurface *scaleT(uint16 newWidth, uint16 newHeight) const; - - TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const; + TransparentSurface *scale(uint16 newWidth, uint16 newHeight, bool filtering = false) const; /** * @brief Rotoscale function; this returns a transformed version of this surface after rotation and @@ -177,9 +175,6 @@ struct TransparentSurface : public Graphics::Surface { void setAlphaMode(AlphaType); private: AlphaType _alphaMode; - - template - void scaleNN(int *scaleCacheX, TransparentSurface *target) const; }; /** diff --git a/graphics/wincursor.cpp b/graphics/wincursor.cpp index 7abd1a33add..8c3cf97ec66 100644 --- a/graphics/wincursor.cpp +++ b/graphics/wincursor.cpp @@ -127,9 +127,9 @@ bool WinCursor::readFromStream(Common::SeekableReadStream &stream) { if (stream.readUint16LE() != 1) return false; - // Only 1bpp and 8bpp supported + // Only 1bpp, 4bpp and 8bpp supported uint16 bitsPerPixel = stream.readUint16LE(); - if (bitsPerPixel != 1 && bitsPerPixel != 8) + if (bitsPerPixel != 1 && bitsPerPixel != 4 && bitsPerPixel != 8) return false; // Compression @@ -180,6 +180,13 @@ bool WinCursor::readFromStream(Common::SeekableReadStream &stream) { *rowDest = 0; } } + } else if (bitsPerPixel == 4) { + // 4bpp + for (uint16 j = 0; j < (_width / 2); j++) { + byte p = src[j]; + *rowDest++ = p >> 4; + *rowDest++ = p & 0x0f; + } } else { // 8bpp memcpy(rowDest, src, _width); diff --git a/gui/about.cpp b/gui/about.cpp index d8e6a5206b4..c362a56a191 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -476,7 +476,6 @@ void EE::run() { case Common::EVENT_RETURN_TO_LAUNCHER: _shouldQuit = true; break; - case Common::EVENT_LBUTTONDOWN: break; case Common::EVENT_KEYDOWN: @@ -595,13 +594,12 @@ void EE::processKeyDown(Common::Event &e) { } void EE::getPos() { - int tx, velx, bnd; - for (int i = 0; i < 2; i++) { if (_keymove[i][kDirUp] && _frameindex[i] == -1) _frameindex[i] = 0; - tx = _x[i] + (velx = _keymove[i][kDirLeft] + _keymove[i][kDirRight]); - bnd = 3 + i * 155; + int velx = _keymove[i][kDirLeft] + _keymove[i][kDirRight]; + int tx = _x[i] + velx; + int bnd = 3 + i * 155; if (velx > 0) { if (tx < bnd + 119) _x[i] = tx; @@ -705,9 +703,7 @@ void EE::calcscore() { } int EE::destination(int pl, int destx, int tol) { - int xp; - - xp = _x[pl]; + int xp = _x[pl]; if (abs(xp - destx) < tol) { _keymove[pl][kDirLeft] = 0; _keymove[pl][kDirRight] = 0; @@ -726,16 +722,13 @@ int EE::destination(int pl, int destx, int tol) { int reset = false; bool EE::moveball() { - int rbvelx, rbvely; - bool hitfloor; - if (!reset) { _bx = 4096; _by = 8640; _bvelx = 125; _bvely = -259; reset = true; } - rbvelx = _bvelx; - rbvely = _bvely; + int rbvelx = _bvelx; + int rbvely = _bvely; if (rbvelx > 319) rbvelx = 319; if (rbvelx < -319) rbvelx = -319; if (rbvely > 319) rbvely = 319; @@ -771,6 +764,7 @@ bool EE::moveball() { rbvelx -= rbvelx >> 4; rbvely -= rbvely >> 4; } + bool hitfloor; if (_by > 11392) { _by = 11392; rbvely = -rbvely; @@ -793,14 +787,12 @@ bool EE::moveball() { } void EE::docollisions() { - int dx, dy, dist, rndoff; - for (int i = 0; i < 2; i++) { - dx = _tbx - _x[i] - i * 7; - dy = (_tby - _y[i]) >> 1; - dist = (dx >> 2) * dx + dy * dy; + int dx = _tbx - _x[i] - i * 7; + int dy = (_tby - _y[i]) >> 1; + int dist = (dx >> 2) * dx + dy * dy; if (dist < 110) { - rndoff = 8 - (_rnd & 15); + int rndoff = 8 - (_rnd & 15); if (_frameindex[i] > -1) _bvely = -abs(_bvely) + (jump[_frameindex[i]] << (3 << _servevel)); else @@ -849,7 +841,7 @@ void EE::docollisions() { } else if ((_tbx > 147 && 161 - _tbx >= polecol[91 - _tby]) || (_tbx < 148 && _tbx - 133 >= polecol[91 - _tby])) { if (_bvely > 0) { - dx = _tbx - 145; + int dx = _tbx - 145; if (dx < -5) _bvelx = -abs(_bvelx); if (dx > 5) _bvelx = abs(_bvelx); _bvely = -abs(_bvely); @@ -862,11 +854,10 @@ void EE::docollisions() { void EE::computer0() { - int ystep, destx, dx, rndoff, dest = 0; - _keymove[0][kDirUp] = 0; if (_tby < _bytop) _bytop = _tby; - rndoff = 5 - _rnd % 10; + int rndoff = 5 - _rnd % 10; + int dest = 0; if (_serve && ((_server & 1) == 0)) { switch (_compserve) { case 0: @@ -911,6 +902,7 @@ void EE::computer0() { } _keymove[0][kDirUp] = dest; } else if (_bvely > 0 && _tbx < 140) { + int ystep, destx; if (_bvely >> 6 == 0) ystep = 0; else @@ -921,7 +913,7 @@ void EE::computer0() { else destx = _tbx + (_bvelx >> 6) * ystep - 4; - dx = _x[0] - _tbx; + int dx = _x[0] - _tbx; if (abs(_bvelx) < 128 && _bytop < 75) { if ((_tby < 158) ^ (_bvelx < 0)) @@ -949,12 +941,11 @@ void EE::computer0() { } void EE::computer1() { - int ystep, destx, dx, rndoff, dest = 0; - _keymove[1][kDirUp] = 0; if (_tby < _bytop) _bytop = _tby; - rndoff = 5 - _rnd % 10; + int rndoff = 5 - _rnd % 10; if (_serve && ((_server & 1) == 1)) { + int dest = 0; switch (_compserve) { case 0: dest = destination(1, 232, 2); @@ -998,6 +989,7 @@ void EE::computer1() { } _keymove[1][kDirUp] = dest; } else if (_bvely > 0 && _tbx > 125) { + int ystep, destx; if (_bvely >> 6 == 0) ystep = 0; else @@ -1008,7 +1000,7 @@ void EE::computer1() { else destx = _tbx + (_bvelx >> 6) * ystep - 4; - dx = _x[1] - _tbx; + int dx = _x[1] - _tbx; if (abs(_bvelx) < 128 && _bytop < 75) { if ((_tby < 158) ^ (_bvelx < 0)) @@ -1041,11 +1033,9 @@ void EE::init() { _rnd = 0; _starter = _winner = _hits = 0; _bvelx = _bvely = 0; - _tbx = 200; - _tby = 20; + _tbx = 200; _tby = 20; _bytop = 200; - _x[0] = 64; - _x[1] = 226; + _x[0] = 64; _x[1] = 226; _air = false; @@ -1332,7 +1322,7 @@ static const uint32 head[38] = { }; static const uint32 legs[42] = { - 0xa0000000, 0x00000000, 0x80000000, 0x00000002, 0x80000000, 0x00000002,0xa0000000, + 0xa0000000, 0x00000000, 0x80000000, 0x00000002, 0x80000000, 0x00000002, 0xa0000000, 0x00000000, 0x50000000, 0x00000000, 0xf0000000, 0x00000003, 0xfc000000, 0x000003ff, 0xa0000000, 0x00000002, 0x0a000000, 0x0000000a, 0x02400000, 0x00000028, 0x00700000, diff --git a/gui/options.cpp b/gui/options.cpp index cc32911753c..4b6cd132ce7 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -1378,8 +1378,8 @@ void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &pref for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { Common::String deviceGuiOption = MidiDriver::musicType2GUIO(d->getMusicType()); - if ((_domain == Common::ConfigManager::kApplicationDomain && d->getMusicType() != MT_TOWNS // global dialog - skip useless FM-Towns, C64, Amiga, AppleIIGS options there - && d->getMusicType() != MT_C64 && d->getMusicType() != MT_AMIGA && d->getMusicType() != MT_APPLEIIGS && d->getMusicType() != MT_PC98) + if ((_domain == Common::ConfigManager::kApplicationDomain && d->getMusicType() != MT_TOWNS // global dialog - skip useless FM-Towns, C64, Amiga, AppleIIGS and SegaCD options there + && d->getMusicType() != MT_C64 && d->getMusicType() != MT_AMIGA && d->getMusicType() != MT_APPLEIIGS && d->getMusicType() != MT_PC98 && d->getMusicType() != MT_SEGACD) || (_domain != Common::ConfigManager::kApplicationDomain && !hasMidiDefined) // No flags are specified || (_guioptions.contains(deviceGuiOption)) // flag is present // HACK/FIXME: For now we have to show GM devices, even when the game only has GUIO_MIDIMT32 set, @@ -2474,6 +2474,7 @@ void GlobalOptionsDialog::apply() { #endif if (isRebuildNeeded) { + g_gui.setLanguageRTL(); if (_launcher != nullptr) _launcher->rebuild(); rebuild(); diff --git a/gui/themes/default.inc b/gui/themes/default.inc index f4907481c55..193593f6f17 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -302,7 +302,7 @@ const char *defaultXML1 = "" "height='5' " "xpos='left' " "ypos='10' " -"padding='2,0,7,0' " +"padding='7,0,0,0' " "orientation='bottom' " "/>" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" @@ -1241,7 +1241,7 @@ const char *defaultXML1 = "" "height='6' " "xpos='left' " "ypos='center' " -"padding='2,0,4,0' " +"padding='4,0,0,0' " "orientation='bottom' " "/>" "" diff --git a/gui/themes/modern.zip b/gui/themes/modern.zip index 424bdf5c3e8..617aeaf93c8 100644 Binary files a/gui/themes/modern.zip and b/gui/themes/modern.zip differ diff --git a/gui/themes/modern/modern_gfx.stx b/gui/themes/modern/modern_gfx.stx index 49c3af20d6b..35059f56f8e 100644 --- a/gui/themes/modern/modern_gfx.stx +++ b/gui/themes/modern/modern_gfx.stx @@ -543,7 +543,7 @@ height = '5' xpos = 'left' ypos = '10' - padding = '2, 0, 6, 0' + padding = '6, 0, 0, 0' orientation = 'bottom' /> @@ -554,7 +554,7 @@ height = '5' xpos = 'left' ypos = '4' - padding = '2, 0, 6, 0' + padding = '6, 0, 0, 0' orientation = 'top' /> @@ -620,7 +620,7 @@ height = '4' xpos = 'left' ypos = '9' - padding = '2, 0, 3, 0' + padding = '3, 0, 0, 0' orientation = 'bottom' /> @@ -631,7 +631,7 @@ height = '4' xpos = 'left' ypos = '4' - padding = '2, 0, 3, 0' + padding = '3, 0, 0, 0' orientation = 'top' /> @@ -698,7 +698,7 @@ height = '5' xpos = 'left' ypos = '10' - padding = '2, 0, 6, 0' + padding = '6, 0, 0, 0' orientation = 'bottom' /> @@ -709,7 +709,7 @@ height = '5' xpos = 'left' ypos = '4' - padding = '2, 0, 6, 0' + padding = '6, 0, 0, 0' orientation = 'top' /> @@ -775,7 +775,7 @@ height = '4' xpos = 'left' ypos = '9' - padding = '2, 0, 3, 0' + padding = '3, 0, 0, 0' orientation = 'bottom' /> @@ -786,7 +786,7 @@ height = '4' xpos = 'left' ypos = '4' - padding = '2, 0, 3, 0' + padding = '3, 0, 0, 0' orientation = 'top' /> @@ -853,7 +853,7 @@ height = '5' xpos = 'left' ypos = '10' - padding = '2, 0, 6, 0' + padding = '6, 0, 0, 0' orientation = 'bottom' /> @@ -864,7 +864,7 @@ height = '5' xpos = 'left' ypos = '4' - padding = '2, 0, 6, 0' + padding = '6, 0, 0, 0' orientation = 'top' /> @@ -930,7 +930,7 @@ height = '4' xpos = 'left' ypos = '9' - padding = '2, 0, 3, 0' + padding = '3, 0, 0, 0' orientation = 'bottom' /> @@ -941,7 +941,7 @@ height = '4' xpos = 'left' ypos = '4' - padding = '2, 0, 3, 0' + padding = '3, 0, 0, 0' orientation = 'top' /> @@ -1141,7 +1141,7 @@ height = '6' xpos = 'left' ypos = 'center' - padding = '2,0,2,0' + padding = '2,0,0,0' orientation = 'bottom' /> @@ -1256,7 +1256,7 @@ height = '6' xpos = 'left' ypos = 'center' - padding = '2,0,2,0' + padding = '2,0,0,0' orientation = 'bottom' /> @@ -1373,7 +1373,7 @@ height = '6' xpos = 'left' ypos = 'center' - padding = '2,0,2,0' + padding = '2,0,0,0' orientation = 'bottom' /> @@ -1488,7 +1488,7 @@ height = '6' xpos = 'left' ypos = 'center' - padding = '2,0,2,0' + padding = '2,0,0,0' orientation = 'bottom' /> @@ -1605,7 +1605,7 @@ height = '6' xpos = 'left' ypos = 'center' - padding = '2,0,2,0' + padding = '2,0,0,0' orientation = 'bottom' /> @@ -1726,7 +1726,7 @@ height = '6' xpos = 'left' ypos = 'center' - padding = '2,0,2,0' + padding = '2,0,0,0' orientation = 'bottom' /> @@ -1786,7 +1786,7 @@ height = '6' xpos = 'left' ypos = 'center' - padding = '0,0,0,0' + padding = '0,0,2,0' orientation = 'bottom' /> diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp index 2849350fc92..1934056c34c 100644 --- a/gui/widgets/editable.cpp +++ b/gui/widgets/editable.cpp @@ -163,8 +163,9 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) { case Common::KEYCODE_DOWN: case Common::KEYCODE_END: // Move caret to end - dirty = setCaretPos(_editString.size()); + setCaretPos(_editString.size()); forcecaret = true; + dirty = true; break; case Common::KEYCODE_LEFT: @@ -188,8 +189,9 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) { case Common::KEYCODE_UP: case Common::KEYCODE_HOME: // Move caret to start - dirty = setCaretPos(0); + setCaretPos(0); forcecaret = true; + dirty = true; break; case Common::KEYCODE_v: diff --git a/image/codecs/codec.cpp b/image/codecs/codec.cpp index fdd7e98de48..8716a01d4ed 100644 --- a/image/codecs/codec.cpp +++ b/image/codecs/codec.cpp @@ -273,6 +273,9 @@ Codec *createQuickTimeCodec(uint32 tag, int width, int height, int bitsPerPixel) case MKTAG('Q','k','B','k'): // CDToons: Used by most of the Broderbund games. return new CDToonsDecoder(width, height); + case MKTAG('r','a','w',' '): + // Used my L-Zone-mac (Director game) + return new BitmapRawDecoder(width, height, bitsPerPixel); default: warning("Unsupported QuickTime codec \'%s\'", tag2str(tag)); } diff --git a/test/module.mk b/test/module.mk index e18957b9cb6..9681bebb0dd 100644 --- a/test/module.mk +++ b/test/module.mk @@ -24,6 +24,10 @@ TEST_CFLAGS := $(CFLAGS) -I$(srcdir)/test/cxxtest TEST_LDFLAGS := $(LDFLAGS) $(LIBS) TEST_CXXFLAGS := $(filter-out -Wglobal-constructors,$(CXXFLAGS)) +ifdef WIN32 +TEST_LDFLAGS := $(filter-out -mwindows,$(TEST_LDFLAGS)) +endif + ifdef N64 TEST_LDFLAGS := $(filter-out -mno-crt0,$(TEST_LDFLAGS)) endif