diff --git a/.gitignore b/.gitignore index 7a6f99e..4803db3 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ *.idb *.aps *.res +*.a .vs/* Packaged/* DebugData/* @@ -30,9 +31,21 @@ InstallerPackages/* *.wixobj *.CopyComplete *.lnk +*.cmake ReleasePackageInstaller/obj/* ReleasePackageInstaller/bin/* ReleasePackageInstaller/AerofoilPackageDefs.wxi ReleasePackageInstaller/AerofoilPackageVersion.wxi packages/* !SDL2-2.0.12/lib/x64/* +CMakeCache.txt +CMakeFiles/* +Makefile +SDL2-2.0.12/CMakeFiles/* +SDL2-2.0.12/build +SDL2-2.0.12/config.status +SDL2-2.0.12/libtool +SDL2-2.0.12/Makefile.rules +SDL2-2.0.12/sdl2.pc +SDL2-2.0.12/sdl2-config +install_manifest.txt diff --git a/AerofoilAndroid/app/jni/main/GpMain_SDL_Android.cpp b/AerofoilAndroid/app/jni/main/GpMain_SDL_Android.cpp index 4008cf4..6d6db0e 100644 --- a/AerofoilAndroid/app/jni/main/GpMain_SDL_Android.cpp +++ b/AerofoilAndroid/app/jni/main/GpMain_SDL_Android.cpp @@ -4,7 +4,7 @@ #include "GpAudioDriverFactory.h" #include "GpDisplayDriverFactory.h" #include "GpGlobalConfig.h" -#include "GpFiber_SDL.h" +#include "GpFiber_Thread.h" #include "GpFileSystem_Android.h" #include "GpFontHandlerFactory.h" #include "GpInputDriverFactory.h" diff --git a/AerofoilPortable/Android.mk b/AerofoilPortable/Android.mk index 905a937..2c4ef33 100644 --- a/AerofoilPortable/Android.mk +++ b/AerofoilPortable/Android.mk @@ -15,6 +15,8 @@ LOCAL_CFLAGS := -DGP_DEBUG_CONFIG=0 # Add your application source files here... LOCAL_SRC_FILES := \ GpThreadEvent_Cpp11.cpp \ - GpSystemServices_POSIX.cpp + GpSystemServices_POSIX.cpp \ + GpFiber_Thread.cpp \ + GpFiberStarter_Thread.cpp \ include $(BUILD_STATIC_LIBRARY) diff --git a/AerofoilSDL/GpFiberStarter_SDL.cpp b/AerofoilPortable/GpFiberStarter_Thread.cpp similarity index 80% rename from AerofoilSDL/GpFiberStarter_SDL.cpp rename to AerofoilPortable/GpFiberStarter_Thread.cpp index 492d657..9e4fe79 100644 --- a/AerofoilSDL/GpFiberStarter_SDL.cpp +++ b/AerofoilPortable/GpFiberStarter_Thread.cpp @@ -1,14 +1,12 @@ #include "GpFiberStarter.h" -#include "GpFiber_SDL.h" +#include "GpFiber_Thread.h" #include "IGpSystemServices.h" #include "IGpThreadEvent.h" -#include "SDL_thread.h" - #include -namespace GpFiberStarter_SDL +namespace GpFiberStarter_Thread { struct FiberStartState { @@ -18,7 +16,7 @@ namespace GpFiberStarter_SDL void *m_context; }; - static int SDLCALL FiberStartRoutine(void *lpThreadParameter) + static int FiberStartRoutine(void *lpThreadParameter) { const FiberStartState *tss = static_cast(lpThreadParameter); @@ -49,13 +47,13 @@ IGpFiber *GpFiberStarter::StartFiber(IGpSystemServices *systemServices, ThreadFu return nullptr; } - GpFiberStarter_SDL::FiberStartState startState; + GpFiberStarter_Thread::FiberStartState startState; startState.m_context = context; startState.m_creatingReturnEvent = returnEvent; startState.m_creatingWakeEvent = wakeEvent; startState.m_threadFunc = threadFunc; - SDL_Thread *thread = SDL_CreateThread(GpFiberStarter_SDL::FiberStartRoutine, "Fiber", &startState); + void *thread = systemServices->CreateThread(GpFiberStarter_Thread::FiberStartRoutine, &startState); if (!thread) { returnEvent->Destroy(); @@ -66,5 +64,5 @@ IGpFiber *GpFiberStarter::StartFiber(IGpSystemServices *systemServices, ThreadFu returnEvent->Wait(); returnEvent->Destroy(); - return new GpFiber_SDL(thread, wakeEvent); + return new GpFiber_Thread(thread, wakeEvent); } diff --git a/AerofoilPortable/GpFiber_Thread.cpp b/AerofoilPortable/GpFiber_Thread.cpp new file mode 100644 index 0000000..46bb92a --- /dev/null +++ b/AerofoilPortable/GpFiber_Thread.cpp @@ -0,0 +1,29 @@ +#include "GpFiber_Thread.h" +#include "IGpThreadEvent.h" + +GpFiber_Thread::GpFiber_Thread(void *thread, IGpThreadEvent *threadEvent) + : m_event(threadEvent) + , m_thread(thread) +{ +} + +GpFiber_Thread::~GpFiber_Thread() +{ + m_event->Destroy(); +} + +void GpFiber_Thread::YieldTo(IGpFiber *toFiber) +{ + static_cast(toFiber)->m_event->Signal(); + m_event->Wait(); +} + +void GpFiber_Thread::YieldToTerminal(IGpFiber *toFiber) +{ + static_cast(toFiber)->m_event->Signal(); +} + +void GpFiber_Thread::Destroy() +{ + delete this; +} diff --git a/AerofoilSDL/GpFiber_SDL.h b/AerofoilPortable/GpFiber_Thread.h similarity index 52% rename from AerofoilSDL/GpFiber_SDL.h rename to AerofoilPortable/GpFiber_Thread.h index bcc1abe..09cc60d 100644 --- a/AerofoilSDL/GpFiber_SDL.h +++ b/AerofoilPortable/GpFiber_Thread.h @@ -1,24 +1,23 @@ #pragma once #include "IGpFiber.h" -#include "SDL_thread.h" struct IGpThreadEvent; -class GpFiber_SDL final : public IGpFiber +class GpFiber_Thread final : public IGpFiber { public: - explicit GpFiber_SDL(SDL_Thread *thread, IGpThreadEvent *threadEvent); - ~GpFiber_SDL(); + explicit GpFiber_Thread(void *thread, IGpThreadEvent *threadEvent); + ~GpFiber_Thread(); void YieldTo(IGpFiber *fromFiber) override; void YieldToTerminal(IGpFiber *fromFiber) override; void Destroy() override; private: - static int SDLCALL InternalThreadFunction(void *data); + static int InternalThreadFunction(void *data); bool m_isDestroying; IGpThreadEvent *m_event; - SDL_Thread *m_thread; + void *m_thread; }; diff --git a/AerofoilSDL/Android.mk b/AerofoilSDL/Android.mk index 471fc92..6f6d341 100644 --- a/AerofoilSDL/Android.mk +++ b/AerofoilSDL/Android.mk @@ -11,6 +11,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/../GpShell \ $(LOCAL_PATH)/../Common \ $(LOCAL_PATH)/../PortabilityLayer \ + $(LOCAL_PATH)/../AerofoilPortable \ $(LOCAL_PATH)/$(SDL_PATH)/include LOCAL_CFLAGS := -DGP_DEBUG_CONFIG=0 @@ -19,8 +20,6 @@ LOCAL_CFLAGS := -DGP_DEBUG_CONFIG=0 LOCAL_SRC_FILES := \ GpAudioDriver_SDL2.cpp \ GpDisplayDriver_SDL_GL2.cpp \ - GpFiber_SDL.cpp \ - GpFiberStarter_SDL.cpp \ ShaderCode/CopyQuadP.cpp \ ShaderCode/DrawQuadPaletteP.cpp \ ShaderCode/DrawQuad32P.cpp \ diff --git a/AerofoilSDL/GpAudioDriver_SDL2.cpp b/AerofoilSDL/GpAudioDriver_SDL2.cpp index c70d4fc..9955a8b 100644 --- a/AerofoilSDL/GpAudioDriver_SDL2.cpp +++ b/AerofoilSDL/GpAudioDriver_SDL2.cpp @@ -1,3 +1,4 @@ +#include "CoreDefs.h" #include "IGpAudioDriver.h" #include "IGpAudioChannel.h" #include "IGpAudioChannelCallbacks.h" @@ -5,8 +6,7 @@ #include "IGpPrefsHandler.h" #include "IGpSystemServices.h" #include "GpAudioDriverProperties.h" -#include "CoreDefs.h" - +#include "GpSDL.h" #include "SDL_audio.h" #include "GpRingBuffer.h" diff --git a/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp b/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp index 3d88e38..b5bd605 100644 --- a/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp +++ b/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp @@ -2,11 +2,12 @@ #include "GpApplicationName.h" #include "GpComPtr.h" -#include "GpFiber_SDL.h" +#include "GpFiber_Thread.h" #include "GpDisplayDriverProperties.h" #include "GpVOSEvent.h" #include "GpRingBuffer.h" #include "GpInputDriver_SDL_Gamepad.h" +#include "GpSDL.h" #include "IGpCursor.h" #include "IGpDisplayDriverSurface.h" #include "IGpLogDriver.h" @@ -1847,7 +1848,7 @@ void GpDisplayDriver_SDL_GL2::Run() IGpLogDriver *logger = m_properties.m_logger; m_vosEvent = m_properties.m_systemServices->CreateThreadEvent(true, false); - m_vosFiber = new GpFiber_SDL(nullptr, m_vosEvent); + m_vosFiber = new GpFiber_Thread(nullptr, m_vosEvent); uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; if (m_properties.m_systemServices->IsFullscreenOnStartup()) diff --git a/AerofoilSDL/GpFiber_SDL.cpp b/AerofoilSDL/GpFiber_SDL.cpp deleted file mode 100644 index 4760e24..0000000 --- a/AerofoilSDL/GpFiber_SDL.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "GpFiber_SDL.h" -#include "IGpThreadEvent.h" - -GpFiber_SDL::GpFiber_SDL(SDL_Thread *thread, IGpThreadEvent *threadEvent) - : m_event(threadEvent) - , m_thread(thread) -{ -} - -GpFiber_SDL::~GpFiber_SDL() -{ - m_event->Destroy(); -} - -void GpFiber_SDL::YieldTo(IGpFiber *toFiber) -{ - static_cast(toFiber)->m_event->Signal(); - m_event->Wait(); -} - -void GpFiber_SDL::YieldToTerminal(IGpFiber *toFiber) -{ - static_cast(toFiber)->m_event->Signal(); -} - -void GpFiber_SDL::Destroy() -{ - delete this; -} diff --git a/AerofoilSDL/GpMain_SDL_Win32.cpp b/AerofoilSDL/GpMain_SDL_Win32.cpp index 186ee39..b4886e4 100644 --- a/AerofoilSDL/GpMain_SDL_Win32.cpp +++ b/AerofoilSDL/GpMain_SDL_Win32.cpp @@ -5,7 +5,6 @@ #include "GpDisplayDriverFactory.h" #include "GpGlobalConfig.h" #include "GpFiber_Win32.h" -#include "GpFiber_SDL.h" #include "GpFileSystem_Win32.h" #include "GpLogDriver_Win32.h" #include "GpFontHandlerFactory.h" diff --git a/AerofoilSDL/GpSDL.h b/AerofoilSDL/GpSDL.h new file mode 100644 index 0000000..e661666 --- /dev/null +++ b/AerofoilSDL/GpSDL.h @@ -0,0 +1,5 @@ +#ifdef __CYGWIN__ +#define GP_SDL_DIRECTORY_PREFIX "SDL2/" +#else +#define GP_SDL_DIRECTORY_PREFIX +#endif diff --git a/AerofoilX/GpFileSystem_X.cpp b/AerofoilX/GpFileSystem_X.cpp new file mode 100644 index 0000000..400f7d4 --- /dev/null +++ b/AerofoilX/GpFileSystem_X.cpp @@ -0,0 +1,518 @@ +#define _LARGEFILE64_SOURCE +#include "GpFileSystem_X.h" +#include "GpIOStream.h" +#include "IGpDirectoryCursor.h" +#include "IGpSystemServices.h" +#include "IGpMutex.h" +#include "IGpThreadRelay.h" +#include "VirtualDirectory.h" + +#include "PLDrivers.h" + +#include "SDL2/SDL.h" +#include "SDL2/SDL_rwops.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "UTF8.h" + +#ifdef __CYGWIN__ +typedef off_t off64_t; +#define fstat64 fstat +#define fseek64 fseek +#define ftruncate64 ftruncate +#define stat64 stat +#endif + +class GpFileStream_X_File final : public GpIOStream +{ +public: + GpFileStream_X_File(FILE *f, bool readOnly, bool writeOnly); + ~GpFileStream_X_File(); + + size_t Read(void *bytesOut, size_t size) override; + size_t Write(const void *bytes, size_t size) override; + bool IsSeekable() const override; + bool IsReadOnly() const override; + bool IsWriteOnly() const override; + bool SeekStart(GpUFilePos_t loc) override; + bool SeekCurrent(GpFilePos_t loc) override; + bool SeekEnd(GpUFilePos_t loc) override; + GpUFilePos_t Size() const override; + GpUFilePos_t Tell() const override; + void Close() override; + void Flush() override; + +private: + FILE *m_f; + bool m_seekable; + bool m_isReadOnly; + bool m_isWriteOnly; +}; + + +GpFileStream_X_File::GpFileStream_X_File(FILE *f, bool readOnly, bool writeOnly) + : m_f(f) + , m_isReadOnly(readOnly) + , m_isWriteOnly(writeOnly) +{ + m_seekable = (fseek(m_f, 0, SEEK_CUR) == 0); +} + +GpFileStream_X_File::~GpFileStream_X_File() +{ + fclose(m_f); +} + +size_t GpFileStream_X_File::Read(void *bytesOut, size_t size) +{ + if (m_isWriteOnly) + return 0; + return fread(bytesOut, 1, size, m_f); +} + +size_t GpFileStream_X_File::Write(const void *bytes, size_t size) +{ + if (m_isReadOnly) + return 0; + return fwrite(bytes, 1, size, m_f); +} + +bool GpFileStream_X_File::IsSeekable() const +{ + return m_seekable; +} + +bool GpFileStream_X_File::IsReadOnly() const +{ + return m_isReadOnly; +} + +bool GpFileStream_X_File::IsWriteOnly() const +{ + return m_isWriteOnly; +} + +bool GpFileStream_X_File::SeekStart(GpUFilePos_t loc) +{ + if (!m_seekable) + return false; + + fflush(m_f); + return fseek64(m_f, static_cast(loc), SEEK_SET) >= 0; +} + +bool GpFileStream_X_File::SeekCurrent(GpFilePos_t loc) +{ + if (!m_seekable) + return false; + + fflush(m_f); + return fseek64(m_f, static_cast(loc), SEEK_CUR) >= 0; +} + +bool GpFileStream_X_File::SeekEnd(GpUFilePos_t loc) +{ + if (!m_seekable) + return false; + + fflush(m_f); + return fseek64(m_f, -static_cast(loc), SEEK_END) >= 0; +} + +GpUFilePos_t GpFileStream_X_File::Size() const +{ + fflush(m_f); + + struct stat64 s; + if (fstat64(fileno(m_f), &s) < 0) + return 0; + + return static_cast(s.st_size); +} + +GpUFilePos_t GpFileStream_X_File::Tell() const +{ + return static_cast(ftell(m_f)); +} + +void GpFileStream_X_File::Close() +{ + this->~GpFileStream_X_File(); + free(this); +} + +void GpFileStream_X_File::Flush() +{ + fflush(m_f); +} + +bool GpFileSystem_X::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution) +{ + const char *prefsAppend = nullptr; + + switch (virtualDirectory) + { + case PortabilityLayer::VirtualDirectories::kApplicationData: + resolution = std::string("Packaged"); + break; + case PortabilityLayer::VirtualDirectories::kGameData: + resolution = std::string("Packaged/Houses"); + break; + case PortabilityLayer::VirtualDirectories::kFonts: + resolution = std::string("Resources"); + break; + case PortabilityLayer::VirtualDirectories::kHighScores: + prefsAppend = "HighScores"; + break; + case PortabilityLayer::VirtualDirectories::kUserData: + prefsAppend = "Houses"; + break; + case PortabilityLayer::VirtualDirectories::kUserSaves: + prefsAppend = "SavedGames"; + break; + case PortabilityLayer::VirtualDirectories::kPrefs: + prefsAppend = "Prefs"; + break; + case PortabilityLayer::VirtualDirectories::kFontCache: + prefsAppend = "FontCache"; + break; + default: + return false; + }; + + if (prefsAppend) + resolution = m_prefsPath + prefsAppend; + else + resolution = m_basePath + resolution; + + for (size_t i = 0; i < numPaths; i++) + { + resolution += "/"; + resolution += paths[i]; + } + + return true; +} + +GpFileSystem_X::GpFileSystem_X() + : m_relay(nullptr) + , m_delayCallback(nullptr) +{ +} + +GpFileSystem_X::~GpFileSystem_X() +{ +} + +void GpFileSystem_X::Init() +{ + char *prefsDir = SDL_GetPrefPath("aerofoil", "aerofoil"); + m_prefsPath = prefsDir; + + char *baseDir = SDL_GetBasePath(); + m_basePath = baseDir; + SDL_free(baseDir); + + char baseDirSeparator = m_basePath[m_basePath.size() - 1]; + if (m_basePath.size() >= 4 && m_basePath.substr(m_basePath.size() - 4, 3) == "bin") + m_basePath = m_basePath.substr(0, m_basePath.size() - 4) + "lib" + baseDirSeparator + "aerofoil" + baseDirSeparator; + + const char *extensions[] = { "HighScores", "Houses", "SavedGames", "Prefs", "FontCache" }; + for (size_t i = 0; i < sizeof(extensions) / sizeof(extensions[0]); i++) + { + std::string prefsPath = std::string(prefsDir) + extensions[i]; + int created = mkdir(prefsPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + } + SDL_free(prefsDir); +} + +bool GpFileSystem_X::FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) +{ + std::string resolvedPath; + if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath)) + return false; + + struct stat s; + return stat(resolvedPath.c_str(), &s) == 0; +} + +bool GpFileSystem_X::FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &exists) +{ + std::string resolvedPath; + if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath)) + { + if (exists) + exists = false; + return false; + } + + int permissions = access(resolvedPath.c_str(), W_OK | F_OK); + exists = ((permissions & F_OK) != 0); + return ((permissions & W_OK) != 0); +} + +GpIOStream *GpFileSystem_X::OpenFileNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* subPaths, size_t numSubPaths, bool writeAccess, GpFileCreationDisposition_t createDisposition) +{ + const char *mode = nullptr; + bool canWrite = false; + bool needResetPosition = false; + + switch (createDisposition) + { + case GpFileCreationDispositions::kCreateOrOverwrite: + mode = "wb"; + break; + case GpFileCreationDispositions::kCreateNew: + mode = "x+b"; + break; + case GpFileCreationDispositions::kCreateOrOpen: + mode = "a+b"; + needResetPosition = true; + break; + case GpFileCreationDispositions::kOpenExisting: + mode = writeAccess ? "r+b" : "rb"; + break; + case GpFileCreationDispositions::kOverwriteExisting: + mode = "r+b"; + break; + default: + return nullptr; + }; + + if (virtualDirectory == PortabilityLayer::VirtualDirectories::kSourceExport) + return nullptr; + + std::string resolvedPath; + if (!ResolvePath(virtualDirectory, subPaths, numSubPaths, resolvedPath)) + return nullptr; + + void *objStorage = malloc(sizeof(GpFileStream_X_File)); + if (!objStorage) + return nullptr; + + FILE *f = fopen(resolvedPath.c_str(), mode); + if (!f) + { + free(objStorage); + return nullptr; + } + + if (needResetPosition) + fseek(f, 0, SEEK_SET); + + if (createDisposition == GpFileCreationDispositions::kOverwriteExisting) + { + if (ftruncate64(fileno(f), 0) < 0) + { + free(objStorage); + fclose(f); + return nullptr; + } + } + + return new (objStorage) GpFileStream_X_File(f, !writeAccess, false); +} + +bool GpFileSystem_X::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) +{ + std::string resolvedPath; + if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath)) + { + existed = false; + return false; + } + + if (unlink(resolvedPath.c_str()) < 0) + { + existed = (errno != ENOENT); + return false; + } + existed = true; + return true; +} + +IGpDirectoryCursor *GpFileSystem_X::ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *const *paths, size_t numPaths) +{ + ScanDirectoryNestedContext ctx; + ctx.m_this = this; + ctx.m_returnValue = nullptr; + ctx.m_virtualDirectory = virtualDirectory; + ctx.m_paths = paths; + ctx.m_numPaths = numPaths; + m_relay->Invoke(ScanDirectoryNestedThunk, &ctx); + + return ctx.m_returnValue; +} + +void GpFileSystem_X::ScanDirectoryNestedThunk(void *context) +{ + ScanDirectoryNestedContext *ctx = static_cast(context); + ctx->m_returnValue = ctx->m_this->ScanDirectoryNestedInternal(ctx->m_virtualDirectory, ctx->m_paths, ctx->m_numPaths); +} + +IGpDirectoryCursor *GpFileSystem_X::ScanDirectoryNestedInternal(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *const *paths, size_t numPaths) +{ + return ScanDirectory(virtualDirectory, paths, numPaths); +} + +bool GpFileSystem_X::ValidateFilePath(const char *path, size_t length) const +{ + for (size_t i = 0; i < length; i++) + { + const char c = path[i]; + if (c >= '0' && c <= '9') + continue; + + if (c == '_' || c == '.' || c == '\'' || c == '!') + continue; + + if (c == ' ' && i != 0 && i != length - 1) + continue; + + if (c >= 'a' && c <= 'z') + continue; + + if (c >= 'A' && c <= 'Z') + continue; + + return false; + } + + return true; +} + +bool GpFileSystem_X::ValidateFilePathUnicodeChar(uint32_t c) const +{ + if (c >= '0' && c <= '9') + return true; + + if (c == '_' || c == '\'') + return true; + + if (c == ' ') + return true; + + if (c >= 'a' && c <= 'z') + return true; + + if (c >= 'A' && c <= 'Z') + return true; + + return false; +} + +void GpFileSystem_X::SetMainThreadRelay(IGpThreadRelay *relay) +{ + m_relay = relay; +} + +void GpFileSystem_X::SetDelayCallback(DelayCallback_t delayCallback) +{ + m_delayCallback = delayCallback; +} + +GpFileSystem_X *GpFileSystem_X::GetInstance() +{ + return &ms_instance; +} + +class GpDirectoryCursor_StringList final : public IGpDirectoryCursor +{ +public: + explicit GpDirectoryCursor_StringList(std::vector &paths); + ~GpDirectoryCursor_StringList(); + + bool GetNext(const char *&outFileName) override; + void Destroy() override; + +private: + std::vector m_paths; + size_t m_index; +}; + +GpDirectoryCursor_StringList::GpDirectoryCursor_StringList(std::vector &paths) + : m_index(0) +{ + std::swap(paths, m_paths); +} + +GpDirectoryCursor_StringList::~GpDirectoryCursor_StringList() +{ +} + +bool GpDirectoryCursor_StringList::GetNext(const char *&outFileName) +{ + if (m_index == m_paths.size()) + return false; + outFileName = m_paths[m_index].c_str(); + m_index++; + return true; +} + +void GpDirectoryCursor_StringList::Destroy() +{ + delete this; +} + +class GpDirectoryCursor_POSIX final : public IGpDirectoryCursor +{ +public: + explicit GpDirectoryCursor_POSIX(DIR *dir); + ~GpDirectoryCursor_POSIX(); + + bool GetNext(const char *&outFileName) override; + void Destroy() override; + +private: + DIR *m_dir; +}; + +GpDirectoryCursor_POSIX::GpDirectoryCursor_POSIX(DIR *dir) + : m_dir(dir) +{ +} + +GpDirectoryCursor_POSIX::~GpDirectoryCursor_POSIX() +{ + closedir(m_dir); +} + +bool GpDirectoryCursor_POSIX::GetNext(const char *&outFileName) +{ + struct dirent *dir = readdir(m_dir); + if (!dir) + return false; + + outFileName = dir->d_name; + return true; +} + +void GpDirectoryCursor_POSIX::Destroy() +{ + delete this; +} + + +IGpDirectoryCursor *GpFileSystem_X::ScanDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths) +{ + std::string resolvedPath; + std::vector subPaths; + if (!ResolvePath(virtualDirectory, paths, numPaths, resolvedPath)) + return nullptr; + + DIR *d = opendir(resolvedPath.c_str()); + if (!d) + return nullptr; + + return new GpDirectoryCursor_POSIX(d); +} + + +GpFileSystem_X GpFileSystem_X::ms_instance; diff --git a/AerofoilX/GpFileSystem_X.h b/AerofoilX/GpFileSystem_X.h new file mode 100644 index 0000000..fead533 --- /dev/null +++ b/AerofoilX/GpFileSystem_X.h @@ -0,0 +1,59 @@ +#pragma once + +#include "IGpFileSystem.h" + +#include "GpCoreDefs.h" + +#include +#include + +struct IGpMutex; + +class GpFileSystem_X final : public IGpFileSystem +{ +public: + GpFileSystem_X(); + ~GpFileSystem_X(); + + void Init(); + + bool FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) override; + bool FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &exists) override; + GpIOStream *OpenFileNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* subPaths, size_t numSubPaths, bool writeAccess, GpFileCreationDisposition_t createDisposition) override; + bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) override; + IGpDirectoryCursor *ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths) override; + + bool ValidateFilePath(const char *path, size_t pathLen) const override; + bool ValidateFilePathUnicodeChar(uint32_t ch) const override; + + void SetMainThreadRelay(IGpThreadRelay *relay) override; + void SetDelayCallback(DelayCallback_t delayCallback) override; + + static GpFileSystem_X *GetInstance(); + +private: + struct ScanDirectoryNestedContext + { + GpFileSystem_X *m_this; + + IGpDirectoryCursor *m_returnValue; + PortabilityLayer::VirtualDirectory_t m_virtualDirectory; + char const *const *m_paths; + size_t m_numPaths; + }; + + static void ScanDirectoryNestedThunk(void *context); + IGpDirectoryCursor *ScanDirectoryNestedInternal(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths); + + IGpDirectoryCursor *ScanDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths); + + bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution); + + IGpThreadRelay *m_relay; + DelayCallback_t m_delayCallback; + + std::string m_prefsPath; + std::string m_basePath; + + static GpFileSystem_X ms_instance; +}; diff --git a/AerofoilX/GpLogDriver_X.cpp b/AerofoilX/GpLogDriver_X.cpp new file mode 100644 index 0000000..5f0b8c6 --- /dev/null +++ b/AerofoilX/GpLogDriver_X.cpp @@ -0,0 +1,127 @@ +#include "GpLogDriver_X.h" +#include "GpFileSystem_X.h" + +#include "GpApplicationName.h" +#include "GpIOStream.h" + +#include +#include + +GpLogDriver_X::GpLogDriver_X() + : m_stream(nullptr) + , m_isInitialized(false) +{ +} + +void GpLogDriver_X::Init() +{ + ms_instance.InitInternal(); +} + +void GpLogDriver_X::VPrintf(Category category, const char *fmt, va_list args) +{ + size_t fmtSize = 0; + bool hasFormatting = false; + for (const char *fmtCheck = fmt; *fmtCheck; fmtCheck++) + { + if (*fmtCheck == '%') + hasFormatting = true; + + fmtSize++; + } + + time_t t = time(nullptr); + struct tm sysTime = *localtime(&t); + + char timestampBuffer[64]; + sprintf(timestampBuffer, "[%02d:%02d:%02d] ", sysTime.tm_hour, sysTime.tm_min, sysTime.tm_sec); + + if (m_stream) + m_stream->Write(timestampBuffer, strlen(timestampBuffer)); + + const char *debugTag = ""; + + switch (category) + { + case Category_Warning: + debugTag = "[WARNING] "; + break; + case Category_Error: + debugTag = "[ERROR] "; + break; + }; + + if (debugTag[0]) + { + if (m_stream) + m_stream->Write(debugTag, strlen(debugTag)); + } + + if (!hasFormatting) + { + if (m_stream) + m_stream->Write(fmt, fmtSize); + } + else + { + int formattedSize = vsnprintf(nullptr, 0, fmt, args); + if (formattedSize <= 0) + return; + + char *charBuff = static_cast(malloc(formattedSize + 1)); + if (!charBuff) + return; + + vsnprintf(charBuff, formattedSize + 1, fmt, args); + + if (m_stream) + m_stream->Write(charBuff, formattedSize); + + free(charBuff); + } + + if (m_stream) + { + m_stream->Write("\n", 1); + m_stream->Flush(); + } +} + +void GpLogDriver_X::Shutdown() +{ + if (m_stream) + m_stream->Close(); +} + +GpLogDriver_X *GpLogDriver_X::GetInstance() +{ + if (ms_instance.m_isInitialized) + return &ms_instance; + else + return nullptr; +} + +void GpLogDriver_X::InitInternal() +{ + time_t t = time(nullptr); + struct tm utcTime = *gmtime(&t); + + char logFileName[256]; + + sprintf(logFileName, GP_APPLICATION_NAME "-%04d-%02d-%02d_%02d-%02d_%02d.txt", utcTime.tm_year, utcTime.tm_mon, utcTime.tm_mday, utcTime.tm_hour, utcTime.tm_min, utcTime.tm_sec); + + m_stream = GpFileSystem_X::GetInstance()->OpenFile(PortabilityLayer::VirtualDirectories::kLogs, logFileName, true, GpFileCreationDispositions::kCreateOrOverwrite); + if (m_stream) + { + this->Printf(IGpLogDriver::Category_Information, GP_APPLICATION_NAME " build " __TIMESTAMP__); +#if !GP_DEBUG_CONFIG + this->Printf(IGpLogDriver::Category_Information, "Configuration: Release"); +#else + this->Printf(IGpLogDriver::Category_Information, "Configuration: Debug"); +#endif + + m_isInitialized = true; + } +} + +GpLogDriver_X GpLogDriver_X::ms_instance; diff --git a/AerofoilX/GpLogDriver_X.h b/AerofoilX/GpLogDriver_X.h new file mode 100644 index 0000000..5ca4c2b --- /dev/null +++ b/AerofoilX/GpLogDriver_X.h @@ -0,0 +1,28 @@ +#pragma once + +#include "IGpLogDriver.h" + +#include + +class GpIOStream; + +class GpLogDriver_X : public IGpLogDriver +{ +public: + GpLogDriver_X(); + + static void Init(); + + void VPrintf(Category category, const char *fmt, va_list args) override; + void Shutdown() override; + + static GpLogDriver_X *GetInstance(); + +private: + void InitInternal(); + + GpIOStream *m_stream; + bool m_isInitialized; + + static GpLogDriver_X ms_instance; +}; diff --git a/AerofoilX/GpMain_SDL_X.cpp b/AerofoilX/GpMain_SDL_X.cpp new file mode 100644 index 0000000..758359c --- /dev/null +++ b/AerofoilX/GpMain_SDL_X.cpp @@ -0,0 +1,81 @@ +#include "SDL.h" +#include "SDL_main.h" + +#include "GpMain.h" +#include "GpAudioDriverFactory.h" +#include "GpDisplayDriverFactory.h" +#include "GpGlobalConfig.h" +#include "GpFiber_Thread.h" +#include "GpFileSystem_X.h" +#include "GpLogDriver_X.h" +#include "GpFontHandlerFactory.h" +#include "GpInputDriverFactory.h" +#include "GpAppInterface.h" +#include "GpSystemServices_X.h" +#include "GpVOSEvent.h" +#include "GpX.h" + +#include "IGpFileSystem.h" +#include "IGpThreadEvent.h" +#include "IGpVOSEventQueue.h" + +#include + +GpXGlobals g_gpXGlobals; + +extern "C" IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties); + +IGpDisplayDriver *GpDriver_CreateDisplayDriver_SDL_GL2(const GpDisplayDriverProperties &properties); +IGpAudioDriver *GpDriver_CreateAudioDriver_SDL(const GpAudioDriverProperties &properties); +IGpInputDriver *GpDriver_CreateInputDriver_SDL2_Gamepad(const GpInputDriverProperties &properties); + + +SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]) +{ + GpLogDriver_X::Init(); + + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0) + return -1; + + GpFileSystem_X::GetInstance()->Init(); + + IGpLogDriver *logger = GpLogDriver_X::GetInstance(); + GpDriverCollection *drivers = GpAppInterface_Get()->PL_GetDriverCollection(); + + drivers->SetDriver(GpFileSystem_X::GetInstance()); + drivers->SetDriver(GpSystemServices_X::GetInstance()); + drivers->SetDriver(GpLogDriver_X::GetInstance()); + + g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_SDL_GL2; + + g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_SDL2; + + g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_FreeType2; + + EGpInputDriverType inputDrivers[] = + { + EGpInputDriverType_SDL2_Gamepad + }; + + g_gpGlobalConfig.m_inputDriverTypes = inputDrivers; + g_gpGlobalConfig.m_numInputDrivers = sizeof(inputDrivers) / sizeof(inputDrivers[0]); + + g_gpGlobalConfig.m_osGlobals = &g_gpXGlobals; + g_gpGlobalConfig.m_logger = logger; + g_gpGlobalConfig.m_systemServices = GpSystemServices_X::GetInstance(); + + GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_SDL_GL2, GpDriver_CreateDisplayDriver_SDL_GL2); + GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_SDL2, GpDriver_CreateAudioDriver_SDL); + GpInputDriverFactory::RegisterInputDriverFactory(EGpInputDriverType_SDL2_Gamepad, GpDriver_CreateInputDriver_SDL2_Gamepad); + GpFontHandlerFactory::RegisterFontHandlerFactory(EGpFontHandlerType_FreeType2, GpDriver_CreateFontHandler_FreeType2); + + if (logger) + logger->Printf(IGpLogDriver::Category_Information, "SDL environment configured, starting up"); + + int returnCode = GpMain::Run(); + + if (logger) + logger->Printf(IGpLogDriver::Category_Information, "SDL environment exited with code %i, cleaning up", returnCode); + + return returnCode; +} diff --git a/AerofoilX/GpSystemServices_X.cpp b/AerofoilX/GpSystemServices_X.cpp new file mode 100644 index 0000000..ed1401a --- /dev/null +++ b/AerofoilX/GpSystemServices_X.cpp @@ -0,0 +1,137 @@ +#include "GpSystemServices_X.h" + +#include "IGpClipboardContents.h" +#include "IGpThreadEvent.h" +#include "SDL2/SDL.h" + +#include +#include +#include + +struct GpSystemServices_X_ThreadStartParams +{ + GpSystemServices_X::ThreadFunc_t m_threadFunc; + void *m_threadContext; + IGpThreadEvent *m_threadStartEvent; +}; + +static void *StaticStartThread(void *lpThreadParameter) +{ + const GpSystemServices_X_ThreadStartParams *threadParams = static_cast(lpThreadParameter); + + GpSystemServices_X::ThreadFunc_t threadFunc = threadParams->m_threadFunc; + void *threadContext = threadParams->m_threadContext; + IGpThreadEvent *threadStartEvent = threadParams->m_threadStartEvent; + + threadStartEvent->Signal(); + + return reinterpret_cast(static_cast(threadFunc(threadContext))); +} + +GpSystemServices_X::GpSystemServices_X() + : m_textInputEnabled(false) + , m_clipboardContents(nullptr) +{ +} + +GpSystemServices_X::~GpSystemServices_X() +{ + if (m_clipboardContents) + m_clipboardContents->Destroy(); +} + +void *GpSystemServices_X::CreateThread(ThreadFunc_t threadFunc, void *context) +{ + IGpThreadEvent *evt = CreateThreadEvent(true, false); + if (!evt) + return nullptr; + + GpSystemServices_X_ThreadStartParams startParams; + startParams.m_threadContext = context; + startParams.m_threadFunc = threadFunc; + startParams.m_threadStartEvent = evt; + + pthread_t thread = nullptr; + if (pthread_create(&thread, nullptr, StaticStartThread, &startParams) != 0) + { + evt->Destroy(); + return nullptr; + } + + evt->Wait(); + evt->Destroy(); + + return thread; +} + +void GpSystemServices_X::Beep() const +{ +} + +bool GpSystemServices_X::IsTouchscreen() const +{ + return false; +} + +bool GpSystemServices_X::IsUsingMouseAsTouch() const +{ + return false; +} + +bool GpSystemServices_X::IsTextInputObstructive() const +{ + return false; +} + +bool GpSystemServices_X::IsFullscreenPreferred() const +{ + return true; +} + +bool GpSystemServices_X::IsFullscreenOnStartup() const +{ + return false; +} + +unsigned int GpSystemServices_X::GetCPUCount() const +{ + return SDL_GetCPUCount(); +} + +void GpSystemServices_X::SetTextInputEnabled(bool isEnabled) +{ + m_textInputEnabled = isEnabled; +} + +bool GpSystemServices_X::IsTextInputEnabled() const +{ + return m_textInputEnabled; +} + +bool GpSystemServices_X::AreFontResourcesSeekable() const +{ + return true; +} + +IGpClipboardContents *GpSystemServices_X::GetClipboardContents() const +{ + return m_clipboardContents; +} + +void GpSystemServices_X::SetClipboardContents(IGpClipboardContents *contents) +{ + if (contents != m_clipboardContents) + { + if (m_clipboardContents) + m_clipboardContents->Destroy(); + + m_clipboardContents = contents; + } +} + +GpSystemServices_X *GpSystemServices_X::GetInstance() +{ + return &ms_instance; +} + +GpSystemServices_X GpSystemServices_X::ms_instance; diff --git a/AerofoilX/GpSystemServices_X.h b/AerofoilX/GpSystemServices_X.h new file mode 100644 index 0000000..f9e9998 --- /dev/null +++ b/AerofoilX/GpSystemServices_X.h @@ -0,0 +1,35 @@ +#pragma once + +#include "GpSystemServices_POSIX.h" +#include "GpCoreDefs.h" + +struct IGpClipboardContents; + +class GpSystemServices_X final : public GpSystemServices_POSIX +{ +public: + GpSystemServices_X(); + ~GpSystemServices_X(); + + void *CreateThread(ThreadFunc_t threadFunc, void *context) override; + void Beep() const override; + bool IsTouchscreen() const override; + bool IsUsingMouseAsTouch() const override; + bool IsTextInputObstructive() const override; + bool IsFullscreenPreferred() const override; + bool IsFullscreenOnStartup() const override; + unsigned int GetCPUCount() const override; + void SetTextInputEnabled(bool isEnabled) override; + bool IsTextInputEnabled() const override; + bool AreFontResourcesSeekable() const override; + IGpClipboardContents *GetClipboardContents() const override; + void SetClipboardContents(IGpClipboardContents *contents) override; + + static GpSystemServices_X *GetInstance(); + +private: + static GpSystemServices_X ms_instance; + + IGpClipboardContents *m_clipboardContents; + bool m_textInputEnabled; +}; diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f6dfe01 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,314 @@ +cmake_minimum_required(VERSION 3.10) + +project (Aerofoil) + +message(${CMAKE_BINARY_DIR}) + +find_package(SDL2 REQUIRED) + +add_definitions(-DGP_DEBUG_CONFIG=0) + +add_library(stb STATIC + stb/stb_image_write.c + ) + + +add_library(FreeType STATIC + FreeType/freetype/src/base/ftbase.c + FreeType/freetype/src/base/ftbitmap.c + FreeType/freetype/src/base/ftdebug.c + FreeType/freetype/src/base/ftinit.c + FreeType/freetype/src/base/ftsystem.c + FreeType/freetype/src/winfonts/winfnt.c + FreeType/freetype/src/autofit/autofit.c + FreeType/freetype/src/bdf/bdf.c + FreeType/freetype/src/cff/cff.c + FreeType/freetype/src/gzip/ftgzip.c + FreeType/freetype/src/lzw/ftlzw.c + FreeType/freetype/src/pcf/pcf.c + FreeType/freetype/src/pfr/pfr.c + FreeType/freetype/src/psaux/psaux.c + FreeType/freetype/src/pshinter/pshinter.c + FreeType/freetype/src/psnames/psnames.c + FreeType/freetype/src/raster/raster.c + FreeType/freetype/src/sfnt/sfnt.c + FreeType/freetype/src/smooth/smooth.c + FreeType/freetype/src/truetype/truetype.c + FreeType/freetype/src/type1/type1.c + FreeType/freetype/src/cid/type1cid.c + FreeType/freetype/src/type42/type42.c + ) + +target_compile_options(FreeType PRIVATE -ansi) +target_compile_definitions(FreeType PRIVATE -DFT2_BUILD_LIBRARY) + +target_include_directories(FreeType PRIVATE + $ + ) + +add_library(GpFontHandler_FreeType2 STATIC + GpFontHandler_FreeType2/GpFontHandler_FreeType2.cpp + ) + +target_include_directories(GpFontHandler_FreeType2 PRIVATE + $ + $ + $ + ) + +target_link_libraries(GpFontHandler_FreeType2 FreeType) + + +add_library(zlib STATIC + zlib/adler32.c + zlib/crc32.c + zlib/deflate.c + zlib/inffast.c + zlib/inflate.c + zlib/inftrees.c + zlib/trees.c + zlib/zutil.c + ) + +add_library(MacRomanConversion STATIC + MacRomanConversion/MacRomanConversion.cpp + ) + +add_library(PortabilityLayer STATIC + PortabilityLayer/AntiAliasTable.cpp + PortabilityLayer/AppEventHandler.cpp + PortabilityLayer/BinHex4.cpp + PortabilityLayer/BitmapImage.cpp + PortabilityLayer/ByteSwap.cpp + PortabilityLayer/CFileStream.cpp + PortabilityLayer/DeflateCodec.cpp + PortabilityLayer/DialogManager.cpp + PortabilityLayer/DisplayDeviceManager.cpp + PortabilityLayer/EllipsePlotter.cpp + PortabilityLayer/FileBrowserUI.cpp + PortabilityLayer/FileManager.cpp + PortabilityLayer/FileSectionStream.cpp + PortabilityLayer/FontFamily.cpp + PortabilityLayer/FontManager.cpp + PortabilityLayer/FontRenderer.cpp + PortabilityLayer/GPArchive.cpp + PortabilityLayer/HostSuspendHook.cpp + PortabilityLayer/IconLoader.cpp + PortabilityLayer/InflateStream.cpp + PortabilityLayer/InputManager.cpp + PortabilityLayer/LinePlotter.cpp + PortabilityLayer/MacBinary2.cpp + PortabilityLayer/MacFileInfo.cpp + PortabilityLayer/MacFileMem.cpp + PortabilityLayer/MemoryManager.cpp + PortabilityLayer/MemReaderStream.cpp + PortabilityLayer/MenuManager.cpp + PortabilityLayer/MMBlock.cpp + PortabilityLayer/MMHandleBlock.cpp + PortabilityLayer/PLApplication.cpp + PortabilityLayer/PLButtonWidget.cpp + PortabilityLayer/PLControlDefinitions.cpp + PortabilityLayer/PLCore.cpp + PortabilityLayer/PLCTabReducer.cpp + PortabilityLayer/PLDialogs.cpp + PortabilityLayer/PLDrivers.cpp + PortabilityLayer/PLEditboxWidget.cpp + PortabilityLayer/PLEventQueue.cpp + PortabilityLayer/PLHacks.cpp + PortabilityLayer/PLHandle.cpp + PortabilityLayer/PLIconWidget.cpp + PortabilityLayer/PLImageWidget.cpp + PortabilityLayer/PLInvisibleWidget.cpp + PortabilityLayer/PLKeyEncoding.cpp + PortabilityLayer/PLLabelWidget.cpp + PortabilityLayer/PLMenus.cpp + PortabilityLayer/PLMovies.cpp + PortabilityLayer/PLNumberFormatting.cpp + PortabilityLayer/PLPopupMenuWidget.cpp + PortabilityLayer/PLQDOffscreen.cpp + PortabilityLayer/PLQDraw.cpp + PortabilityLayer/PLResourceManager.cpp + PortabilityLayer/PLResources.cpp + PortabilityLayer/PLScrollBarWidget.cpp + PortabilityLayer/PLSound.cpp + PortabilityLayer/PLStandardColors.cpp + PortabilityLayer/PLStringCompare.cpp + PortabilityLayer/PLSysCalls.cpp + PortabilityLayer/PLTimeTaggedVOSEvent.cpp + PortabilityLayer/PLWidgets.cpp + PortabilityLayer/QDGraf.cpp + PortabilityLayer/QDManager.cpp + PortabilityLayer/QDPictDecoder.cpp + PortabilityLayer/QDPictEmitContext.cpp + PortabilityLayer/QDPictHeader.cpp + PortabilityLayer/QDPixMap.cpp + PortabilityLayer/QDPort.cpp + PortabilityLayer/QDStandardPalette.cpp + PortabilityLayer/RandomNumberGenerator.cpp + PortabilityLayer/ResolveCachingColor.cpp + PortabilityLayer/ResourceCompiledRef.cpp + PortabilityLayer/ResourceFile.cpp + PortabilityLayer/ScanlineMask.cpp + PortabilityLayer/ScanlineMaskBuilder.cpp + PortabilityLayer/ScanlineMaskConverter.cpp + PortabilityLayer/ScanlineMaskIterator.cpp + PortabilityLayer/SimpleGraphic.cpp + PortabilityLayer/TextPlacer.cpp + PortabilityLayer/UTF8.cpp + PortabilityLayer/UTF16.cpp + PortabilityLayer/WindowDef.cpp + PortabilityLayer/WindowManager.cpp + PortabilityLayer/WorkerThread.cpp + PortabilityLayer/XModemCRC.cpp + PortabilityLayer/ZipFileProxy.cpp + ) + +target_include_directories(PortabilityLayer PRIVATE + $ + $ + $ + $ + $ + $ + $ + ) + +target_compile_options(PortabilityLayer PRIVATE -Wno-multichar) + +target_link_libraries(PortabilityLayer zlib MacRomanConversion stb) + + +add_library(GpShell STATIC + GpShell/GpAppEnvironment.cpp + GpShell/GpAudioDriverFactory.cpp + GpShell/GpDisplayDriverFactory.cpp + GpShell/GpFontHandlerFactory.cpp + GpShell/GpGlobalConfig.cpp + GpShell/GpInputDriverFactory.cpp + GpShell/GpMain.cpp + GpShell/GpVOSEventQueue.cpp + ) + +target_include_directories(GpShell PRIVATE + $ + $ + $ + ) + +add_library(GpApp STATIC + GpApp/About.cpp + GpApp/AnimCursor.cpp + GpApp/AppleEvents.cpp + GpApp/Banner.cpp + GpApp/ColorUtils.cpp + GpApp/Coordinates.cpp + GpApp/DialogUtils.cpp + GpApp/DynamicMaps.cpp + GpApp/Dynamics.cpp + GpApp/Dynamics2.cpp + GpApp/Dynamics3.cpp + GpApp/Environ.cpp + GpApp/Events.cpp + GpApp/FileError.cpp + GpApp/GameOver.cpp + GpApp/GpAppInterface.cpp + GpApp/Grease.cpp + GpApp/HighScores.cpp + GpApp/House.cpp + GpApp/HouseInfo.cpp + GpApp/HouseIO.cpp + GpApp/HouseLegal.cpp + GpApp/Input.cpp + GpApp/Interactions.cpp + GpApp/InterfaceInit.cpp + GpApp/Link.cpp + GpApp/Main.cpp + GpApp/MainMenuUI.cpp + GpApp/MainWindow.cpp + GpApp/Map.cpp + GpApp/Marquee.cpp + GpApp/Menu.cpp + GpApp/Modes.cpp + GpApp/Music.cpp + GpApp/ObjectAdd.cpp + GpApp/ObjectDraw.cpp + GpApp/ObjectDraw2.cpp + GpApp/ObjectDrawAll.cpp + GpApp/ObjectEdit.cpp + GpApp/ObjectInfo.cpp + GpApp/ObjectRects.cpp + GpApp/Objects.cpp + GpApp/Play.cpp + GpApp/Player.cpp + GpApp/Prefs.cpp + GpApp/RectUtils.cpp + GpApp/Render.cpp + GpApp/Room.cpp + GpApp/RoomGraphics.cpp + GpApp/RoomInfo.cpp + GpApp/RubberBands.cpp + GpApp/SavedGames.cpp + GpApp/Scoreboard.cpp + GpApp/Scrap.cpp + GpApp/SelectHouse.cpp + GpApp/Settings.cpp + GpApp/Sound.cpp + GpApp/SoundSync_Cpp11.cpp + GpApp/SourceExport.cpp + GpApp/StringUtils.cpp + GpApp/StructuresInit.cpp + GpApp/StructuresInit2.cpp + GpApp/Tools.cpp + GpApp/Transit.cpp + GpApp/Transitions.cpp + GpApp/Triggers.cpp + GpApp/Trip.cpp + GpApp/Utilities.cpp + GpApp/WindowUtils.cpp + ) + +target_compile_options(GpApp PRIVATE -Wno-multichar) + +target_include_directories(GpApp PRIVATE + $ + $ + $ + ) + +target_link_libraries(GpApp PortabilityLayer) + +if(CMAKE_HOST_UNIX) + add_executable(AerofoilX + AerofoilPortable/GpSystemServices_POSIX.cpp + AerofoilPortable/GpThreadEvent_Cpp11.cpp + AerofoilPortable/GpFiber_Thread.cpp + AerofoilPortable/GpFiberStarter_Thread.cpp + AerofoilSDL/GpAudioDriver_SDL2.cpp + AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp + AerofoilSDL/GpInputDriver_SDL_Gamepad.cpp + AerofoilSDL/ShaderCode/CopyQuadP.cpp + AerofoilSDL/ShaderCode/DrawQuad32P.cpp + AerofoilSDL/ShaderCode/DrawQuadPaletteP.cpp + AerofoilSDL/ShaderCode/DrawQuadV.cpp + AerofoilSDL/ShaderCode/ScaleQuadP.cpp + AerofoilX/GpMain_SDL_X.cpp + AerofoilX/GpLogDriver_X.cpp + AerofoilX/GpSystemServices_X.cpp + AerofoilX/GpFileSystem_X.cpp + ) + + target_include_directories(AerofoilX PRIVATE + $ + $ + $ + $ + $ + $ + ${SDL2_INCLUDE_DIRS} + ) + + target_link_libraries(AerofoilX ${SDL2_LIBRARIES} GpApp GpShell GpFontHandler_FreeType2) +endif() + + +install (TARGETS AerofoilX) diff --git a/Common/CoreDefs.h b/Common/CoreDefs.h index 5483174..e22753c 100644 --- a/Common/CoreDefs.h +++ b/Common/CoreDefs.h @@ -1,6 +1,7 @@ #pragma once #include +#include #if __cplusplus >= 199711L #define GP_IS_CPP11 1 diff --git a/GpApp/Environ.cpp b/GpApp/Environ.cpp index a24dd1b..2cbe1e8 100644 --- a/GpApp/Environ.cpp +++ b/GpApp/Environ.cpp @@ -19,6 +19,7 @@ #include "PLPasStr.h" #include +#include #define kSwitchDepthAlert 130 #define kSetMemoryAlert 180 diff --git a/GpCommon/GpIOStream.h b/GpCommon/GpIOStream.h index 590252c..302a3a5 100644 --- a/GpCommon/GpIOStream.h +++ b/GpCommon/GpIOStream.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "GpFilePos.h" class GpIOStream diff --git a/GpCommon/GpX.h b/GpCommon/GpX.h new file mode 100644 index 0000000..3da7359 --- /dev/null +++ b/GpCommon/GpX.h @@ -0,0 +1,12 @@ +#pragma once + +struct IGpFiber; +struct IGpBWCursor_Win32; +struct IGpCursor_Win32; +struct IGpVOSEventQueue; + +struct GpXGlobals +{ +}; + +extern GpXGlobals g_gpXGlobals; diff --git a/GpCommon/IGpAudioChannel.h b/GpCommon/IGpAudioChannel.h index cbbb080..15a8699 100644 --- a/GpCommon/IGpAudioChannel.h +++ b/GpCommon/IGpAudioChannel.h @@ -1,5 +1,7 @@ #pragma once +#include + struct IGpAudioChannelCallbacks; struct IGpAudioChannel diff --git a/GpCommon/IGpClipboardContents.h b/GpCommon/IGpClipboardContents.h index 8bfd1ba..6291c44 100644 --- a/GpCommon/IGpClipboardContents.h +++ b/GpCommon/IGpClipboardContents.h @@ -1,6 +1,7 @@ #include "GpClipboardContentsType.h" #include +#include struct IGpClipboardContents { diff --git a/GpCommon/IGpDisplayDriver.h b/GpCommon/IGpDisplayDriver.h index df155e6..b8c6c4b 100644 --- a/GpCommon/IGpDisplayDriver.h +++ b/GpCommon/IGpDisplayDriver.h @@ -4,6 +4,7 @@ #include "EGpStandardCursor.h" #include +#include struct IGpDisplayDriverSurface; struct IGpCursor; diff --git a/GpCommon/IGpFileSystem.h b/GpCommon/IGpFileSystem.h index 18435be..a87d26d 100644 --- a/GpCommon/IGpFileSystem.h +++ b/GpCommon/IGpFileSystem.h @@ -4,6 +4,7 @@ #include "VirtualDirectory.h" #include +#include class GpIOStream; struct IGpThreadRelay; diff --git a/GpShell/GpGlobalConfig.h b/GpShell/GpGlobalConfig.h index 153747e..d37849d 100644 --- a/GpShell/GpGlobalConfig.h +++ b/GpShell/GpGlobalConfig.h @@ -6,6 +6,7 @@ #include "EGpInputDriverType.h" #include +#include struct IGpLogDriver; struct IGpSystemServices; diff --git a/GpShell/GpVOSEventQueue.h b/GpShell/GpVOSEventQueue.h index b76f80f..8d76d02 100644 --- a/GpShell/GpVOSEventQueue.h +++ b/GpShell/GpVOSEventQueue.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "IGpVOSEventQueue.h" #include "GpVOSEvent.h" diff --git a/PortabilityLayer/AntiAliasTable.cpp b/PortabilityLayer/AntiAliasTable.cpp index bd0ac68..c062703 100644 --- a/PortabilityLayer/AntiAliasTable.cpp +++ b/PortabilityLayer/AntiAliasTable.cpp @@ -8,61 +8,10 @@ #include #include +#include -// TODO: This is not gamma correct... namespace PortabilityLayer { -#if 0 - void AntiAliasTable::GenerateForPalette(const RGBAColor &baseColorRef, const RGBAColor *colors, size_t numColors) - { - const RGBAColor baseColor = baseColorRef; - - if (numColors > 256) - numColors = 256; - - unsigned int baseCh[3] = { baseColor.r, baseColor.g, baseColor.b }; - - for (size_t i = 0; i < numColors; i++) - { - const RGBAColor existingColor = colors[i]; - - unsigned int existingCh[3] = { existingColor.r, existingColor.g, existingColor.b }; - - // 0 alpha is always the same color - m_aaTranslate[i][0] = static_cast(i); - - for (unsigned int b = 1; b < 16; b++) - { - unsigned int newCh[3]; - - for (unsigned int ch = 0; ch < 3; ch++) - newCh[ch] = (15 - b) * existingCh[ch] + b * baseCh[ch]; - - uint32_t bestError = 0xffffffffU; - size_t bestColor = 0; - for (size_t cmp = 0; cmp < numColors; cmp++) - { - int16_t existingChScaled[3] = { colors[cmp].r * 15, colors[cmp].g * 15, colors[cmp].b * 15 }; - - uint32_t error = 0; - for (unsigned int ch = 0; ch < 3; ch++) - { - int16_t delta = static_cast(newCh[ch]) - existingChScaled[ch]; - error += static_cast(delta * delta); - } - - if (error < bestError) - { - bestError = error; - bestColor = cmp; - } - } - - m_aaTranslate[i][b] = static_cast(bestColor); - } - } - } -#else bool AntiAliasTable::LoadFromCache(const char *cacheFileName) { GpIOStream *stream = PLDrivers::GetFileSystem()->OpenFile(PortabilityLayer::VirtualDirectories::kFontCache, cacheFileName, false, GpFileCreationDispositions::kOpenExisting); @@ -203,5 +152,4 @@ namespace PortabilityLayer if (cacheable) SaveToCache(cacheFileName); } -#endif } diff --git a/PortabilityLayer/AntiAliasTable.h b/PortabilityLayer/AntiAliasTable.h index 097c575..148f1f5 100644 --- a/PortabilityLayer/AntiAliasTable.h +++ b/PortabilityLayer/AntiAliasTable.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace PortabilityLayer { diff --git a/PortabilityLayer/DeflateCodec.h b/PortabilityLayer/DeflateCodec.h index 98ff4ce..5d2a5c4 100644 --- a/PortabilityLayer/DeflateCodec.h +++ b/PortabilityLayer/DeflateCodec.h @@ -1,6 +1,7 @@ #pragma once #include +#include class GpIOStream; diff --git a/PortabilityLayer/FileBrowserUI.h b/PortabilityLayer/FileBrowserUI.h index ff3de18..df7c2bc 100644 --- a/PortabilityLayer/FileBrowserUI.h +++ b/PortabilityLayer/FileBrowserUI.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "VirtualDirectory.h" diff --git a/PortabilityLayer/FileManager.cpp b/PortabilityLayer/FileManager.cpp index 1120e3e..e1ccccd 100644 --- a/PortabilityLayer/FileManager.cpp +++ b/PortabilityLayer/FileManager.cpp @@ -16,6 +16,7 @@ #include "PLSysCalls.h" #include +#include namespace PortabilityLayer { diff --git a/PortabilityLayer/HostSuspendCallArgument.h b/PortabilityLayer/HostSuspendCallArgument.h index 9c3432c..847cfd5 100644 --- a/PortabilityLayer/HostSuspendCallArgument.h +++ b/PortabilityLayer/HostSuspendCallArgument.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "HostSuspendCallID.h" diff --git a/PortabilityLayer/MemoryManager.h b/PortabilityLayer/MemoryManager.h index 2ed0a66..5d56fe4 100644 --- a/PortabilityLayer/MemoryManager.h +++ b/PortabilityLayer/MemoryManager.h @@ -3,6 +3,7 @@ #define __PL_MEMORY_MANAGER_H__ #include +#include namespace PortabilityLayer { diff --git a/PortabilityLayer/MenuManager.h b/PortabilityLayer/MenuManager.h index 061e8c9..e373b8a 100644 --- a/PortabilityLayer/MenuManager.h +++ b/PortabilityLayer/MenuManager.h @@ -1,6 +1,8 @@ #pragma once #include +#include + #include "PLErrorCodes.h" template diff --git a/PortabilityLayer/PLArrayView.h b/PortabilityLayer/PLArrayView.h index 95edb52..51e0085 100644 --- a/PortabilityLayer/PLArrayView.h +++ b/PortabilityLayer/PLArrayView.h @@ -1,6 +1,7 @@ #pragma once #include +#include template class ArrayViewIterator; diff --git a/PortabilityLayer/PLCore.cpp b/PortabilityLayer/PLCore.cpp index 8ebf1e5..5d118c0 100644 --- a/PortabilityLayer/PLCore.cpp +++ b/PortabilityLayer/PLCore.cpp @@ -50,6 +50,7 @@ #include #include +#include class PLMainThreadRelay final : public IGpThreadRelay { diff --git a/PortabilityLayer/QDPictEmitContext.h b/PortabilityLayer/QDPictEmitContext.h index 53deecd..f55f5fb 100644 --- a/PortabilityLayer/QDPictEmitContext.h +++ b/PortabilityLayer/QDPictEmitContext.h @@ -1,6 +1,7 @@ #pragma once #include +#include struct Rect; class GpIOStream; diff --git a/PortabilityLayer/ScanlineMaskBuilder.h b/PortabilityLayer/ScanlineMaskBuilder.h index 744c07a..f761ee3 100644 --- a/PortabilityLayer/ScanlineMaskBuilder.h +++ b/PortabilityLayer/ScanlineMaskBuilder.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace PortabilityLayer { diff --git a/PortabilityLayer/ScanlineMaskConverter.h b/PortabilityLayer/ScanlineMaskConverter.h index 82ef623..ac9fbe7 100644 --- a/PortabilityLayer/ScanlineMaskConverter.h +++ b/PortabilityLayer/ScanlineMaskConverter.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace PortabilityLayer { diff --git a/PortabilityLayer/ScanlineMaskIterator.h b/PortabilityLayer/ScanlineMaskIterator.h index 16e4373..60016dd 100644 --- a/PortabilityLayer/ScanlineMaskIterator.h +++ b/PortabilityLayer/ScanlineMaskIterator.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "ScanlineMaskDataStorage.h" diff --git a/PortabilityLayer/TextPlacer.h b/PortabilityLayer/TextPlacer.h index 49f3a77..da25dbc 100644 --- a/PortabilityLayer/TextPlacer.h +++ b/PortabilityLayer/TextPlacer.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "Vec2i.h" class PLPasStr; diff --git a/PortabilityLayer/UTF16.h b/PortabilityLayer/UTF16.h index bc81078..4de6ab9 100644 --- a/PortabilityLayer/UTF16.h +++ b/PortabilityLayer/UTF16.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace PortabilityLayer { diff --git a/PortabilityLayer/UTF8.h b/PortabilityLayer/UTF8.h index 4a68004..2c9412a 100644 --- a/PortabilityLayer/UTF8.h +++ b/PortabilityLayer/UTF8.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace PortabilityLayer { diff --git a/PortabilityLayer/UnsafePascalStr.h b/PortabilityLayer/UnsafePascalStr.h index 6f32553..57f1e60 100644 --- a/PortabilityLayer/UnsafePascalStr.h +++ b/PortabilityLayer/UnsafePascalStr.h @@ -5,6 +5,8 @@ #include "DataTypes.h" #include "SmallestInt.h" + +#include class PLPasStr; diff --git a/PortabilityLayer/XModemCRC.h b/PortabilityLayer/XModemCRC.h index e34708c..7c5ac90 100644 --- a/PortabilityLayer/XModemCRC.h +++ b/PortabilityLayer/XModemCRC.h @@ -1,7 +1,7 @@ #pragma once -#ifndef __PL_XMODEMCRC_H__ -#define __PL_XMODEMCRC_H__ +#include +#include #include "DataTypes.h" @@ -9,5 +9,3 @@ namespace PortabilityLayer { uint16_t XModemCRC(const void *bytes, size_t size, uint16_t initialValue); } - -#endif