mirror of
https://github.com/elasota/Aerofoil.git
synced 2026-03-16 11:15:38 +00:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b90d0c303c | ||
|
|
7842e721e5 | ||
|
|
93195207dc | ||
|
|
59741dd966 | ||
|
|
1ac69c2c75 | ||
|
|
69f59f769d | ||
|
|
bb2af5abb3 | ||
|
|
3692a966bf | ||
|
|
7916c72fc4 | ||
|
|
7951f579e0 | ||
|
|
b64c904558 | ||
|
|
a6f6ffcdcc | ||
|
|
6fb45f480b | ||
|
|
9ba0e9f13d | ||
|
|
0df94405f8 | ||
|
|
ae69696cbd | ||
|
|
50f420d2b1 | ||
|
|
c87f238563 | ||
|
|
48fe83bb33 | ||
|
|
b2b27ef335 | ||
|
|
89831f0ff6 | ||
|
|
99fd71196d | ||
|
|
7060676b73 | ||
|
|
184f867f79 | ||
|
|
cbd759c754 | ||
|
|
2ada8029d0 | ||
|
|
8e0d8e261e | ||
|
|
20b9eef64d | ||
|
|
c147e1100e | ||
|
|
0a2e730d26 | ||
|
|
922cd0fd06 | ||
|
|
b8bf6be44f | ||
|
|
2897c4ffab | ||
|
|
35c174984b | ||
|
|
da16edea8d |
13
.gitignore
vendored
13
.gitignore
vendored
@@ -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
|
||||
|
||||
12
Aerofoil.sln
12
Aerofoil.sln
@@ -63,6 +63,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AerofoilSDL", "AerofoilSDL\
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MergeGPF", "MergeGPF\MergeGPF.vcxproj", "{36DAF5FA-6ADB-4F20-9810-1610DE0AE653}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GenerateFonts", "GenerateFonts\GenerateFonts.vcxproj", "{3B7FD18D-7A50-4DF5-AC25-543E539BFACE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin2h", "bin2h\bin2h.vcxproj", "{D045F28D-F245-44DD-B576-CC91BF3BE6E9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -175,6 +179,14 @@ Global
|
||||
{36DAF5FA-6ADB-4F20-9810-1610DE0AE653}.Debug|x64.Build.0 = Debug|x64
|
||||
{36DAF5FA-6ADB-4F20-9810-1610DE0AE653}.Release|x64.ActiveCfg = Release|x64
|
||||
{36DAF5FA-6ADB-4F20-9810-1610DE0AE653}.Release|x64.Build.0 = Release|x64
|
||||
{3B7FD18D-7A50-4DF5-AC25-543E539BFACE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3B7FD18D-7A50-4DF5-AC25-543E539BFACE}.Debug|x64.Build.0 = Debug|x64
|
||||
{3B7FD18D-7A50-4DF5-AC25-543E539BFACE}.Release|x64.ActiveCfg = Release|x64
|
||||
{3B7FD18D-7A50-4DF5-AC25-543E539BFACE}.Release|x64.Build.0 = Release|x64
|
||||
{D045F28D-F245-44DD-B576-CC91BF3BE6E9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D045F28D-F245-44DD-B576-CC91BF3BE6E9}.Debug|x64.Build.0 = Debug|x64
|
||||
{D045F28D-F245-44DD-B576-CC91BF3BE6E9}.Release|x64.ActiveCfg = Release|x64
|
||||
{D045F28D-F245-44DD-B576-CC91BF3BE6E9}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -84,14 +84,12 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GpBWCursor_Win32.cpp" />
|
||||
<ClCompile Include="GpColorCursor_Win32.cpp" />
|
||||
<ClCompile Include="GpFiber_Win32.cpp" />
|
||||
<ClCompile Include="GpFileStream_Win32.cpp" />
|
||||
<ClCompile Include="GpFileSystem_Win32.cpp" />
|
||||
<ClCompile Include="GpLogDriver_Win32.cpp" />
|
||||
<ClCompile Include="GpMain_Win32.cpp" />
|
||||
<ClCompile Include="GpMutex_Win32.cpp" />
|
||||
<ClCompile Include="GpSystemServices_Win32.cpp" />
|
||||
<ClCompile Include="GpFiberStarter_Win32.cpp" />
|
||||
<ClCompile Include="GpThreadEvent_Win32.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -108,7 +106,6 @@
|
||||
<ClInclude Include="..\GpCommon\IGpLogDriver.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpPrefsHandler.h" />
|
||||
<ClInclude Include="GpBWCursor_Win32.h" />
|
||||
<ClInclude Include="GpFiber_Win32.h" />
|
||||
<ClInclude Include="GpFileStream_Win32.h" />
|
||||
<ClInclude Include="GpFileSystem_Win32.h" />
|
||||
<ClInclude Include="GpLogDriver_Win32.h" />
|
||||
@@ -127,9 +124,6 @@
|
||||
<ProjectReference Include="..\GpDisplayDriver_D3D11\GpDisplayDriver_D3D11.vcxproj">
|
||||
<Project>{ffc961ac-55b4-4a38-a83e-06ae98f59acc}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GpFontHandler_FreeType2\GpFontHandler_FreeType2.vcxproj">
|
||||
<Project>{4b564030-8985-4975-91e1-e1b2c16ae2a1}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GpInputDriver_XInput\GpInputDriver_XInput.vcxproj">
|
||||
<Project>{17b96f07-ef92-47cd-95a5-8e6ee38ab564}</Project>
|
||||
</ProjectReference>
|
||||
|
||||
@@ -4,12 +4,6 @@
|
||||
<ClCompile Include="GpColorCursor_Win32.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GpFiber_Win32.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GpFiberStarter_Win32.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GpFileStream_Win32.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -48,9 +42,6 @@
|
||||
<ClInclude Include="..\GpCommon\GpDisplayDriverTickStatus.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GpFiber_Win32.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\GpFileCreationDisposition.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#include "GpFiberStarter.h"
|
||||
#include "GpFiber_Win32.h"
|
||||
#include "GpWindows.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace GpFiberStarter_Win32
|
||||
{
|
||||
struct FiberStartState
|
||||
{
|
||||
GpFiberStarter::ThreadFunc_t m_threadFunc;
|
||||
IGpFiber *m_creatingFiber;
|
||||
void *m_context;
|
||||
};
|
||||
|
||||
static VOID WINAPI FiberStartRoutine(LPVOID lpThreadParameter)
|
||||
{
|
||||
const FiberStartState *tss = static_cast<const FiberStartState*>(lpThreadParameter);
|
||||
|
||||
GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc;
|
||||
IGpFiber *creatingFiber = tss->m_creatingFiber;
|
||||
void *context = tss->m_context;
|
||||
SwitchToFiber(static_cast<GpFiber_Win32*>(creatingFiber)->GetFiber());
|
||||
|
||||
threadFunc(context);
|
||||
|
||||
assert(!"Fiber function exited");
|
||||
}
|
||||
}
|
||||
|
||||
IGpFiber *GpFiberStarter::StartFiber(IGpSystemServices *systemServices, ThreadFunc_t threadFunc, void *context, IGpFiber *creatingFiber)
|
||||
{
|
||||
ULONG_PTR lowLimit;
|
||||
ULONG_PTR highLimit;
|
||||
|
||||
#if 0
|
||||
GetCurrentThreadStackLimits(&lowLimit, &highLimit);
|
||||
|
||||
ULONG_PTR stackSize = highLimit - lowLimit;
|
||||
#else
|
||||
ULONG_PTR stackSize = 1024 * 1024;
|
||||
#endif
|
||||
|
||||
GpFiberStarter_Win32::FiberStartState startState;
|
||||
startState.m_context = context;
|
||||
startState.m_creatingFiber = creatingFiber;
|
||||
startState.m_threadFunc = threadFunc;
|
||||
|
||||
void *fiber = CreateFiber(static_cast<SIZE_T>(stackSize), GpFiberStarter_Win32::FiberStartRoutine, &startState);
|
||||
if (!fiber)
|
||||
return nullptr;
|
||||
|
||||
SwitchToFiber(fiber);
|
||||
|
||||
return GpFiber_Win32::Create(fiber);
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#include "GpFiber_Win32.h"
|
||||
#include <new>
|
||||
|
||||
GpFiber_Win32::GpFiber_Win32(LPVOID fiber)
|
||||
: m_fiber(fiber)
|
||||
{
|
||||
}
|
||||
|
||||
void GpFiber_Win32::YieldTo(IGpFiber *toFiber)
|
||||
{
|
||||
SwitchToFiber(static_cast<GpFiber_Win32*>(toFiber)->m_fiber);
|
||||
}
|
||||
|
||||
void GpFiber_Win32::YieldToTerminal(IGpFiber *toFiber)
|
||||
{
|
||||
YieldTo(toFiber);
|
||||
}
|
||||
|
||||
void GpFiber_Win32::Destroy()
|
||||
{
|
||||
this->~GpFiber_Win32();
|
||||
free(this);
|
||||
}
|
||||
|
||||
GpFiber_Win32::~GpFiber_Win32()
|
||||
{
|
||||
DeleteFiber(m_fiber);
|
||||
}
|
||||
|
||||
IGpFiber *GpFiber_Win32::Create(LPVOID fiber)
|
||||
{
|
||||
void *storage = malloc(sizeof(GpFiber_Win32));
|
||||
if (!storage)
|
||||
return nullptr;
|
||||
|
||||
return new (storage) GpFiber_Win32(fiber);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
#include "GpWindows.h"
|
||||
#include "IGpFiber.h"
|
||||
|
||||
class GpFiber_Win32 final : public IGpFiber
|
||||
{
|
||||
public:
|
||||
void YieldTo(IGpFiber *toFiber) override;
|
||||
void YieldToTerminal(IGpFiber *toFiber) override;
|
||||
void Destroy() override;
|
||||
|
||||
static IGpFiber *Create(LPVOID fiber);
|
||||
|
||||
LPVOID GetFiber() const;
|
||||
|
||||
private:
|
||||
explicit GpFiber_Win32(LPVOID fiber);
|
||||
~GpFiber_Win32();
|
||||
|
||||
LPVOID m_fiber;
|
||||
};
|
||||
|
||||
inline LPVOID GpFiber_Win32::GetFiber() const
|
||||
{
|
||||
return m_fiber;
|
||||
}
|
||||
@@ -158,7 +158,7 @@ GpFileSystem_Win32::GpFileSystem_Win32()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wcscat_s(m_executablePath, L"Resources"))
|
||||
if (wcscat_s(m_executablePath, L"Packaged"))
|
||||
{
|
||||
currentPathLength = 0;
|
||||
break;
|
||||
@@ -177,7 +177,6 @@ GpFileSystem_Win32::GpFileSystem_Win32()
|
||||
{
|
||||
m_packagedDir = std::wstring(m_executablePath) + L"Packaged\\";
|
||||
m_housesDir = std::wstring(m_executablePath) + L"Packaged\\Houses\\";
|
||||
m_resourcesDir = std::wstring(m_executablePath) + L"Resources\\";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,11 +318,6 @@ bool GpFileSystem_Win32::ValidateFilePathUnicodeChar(uint32_t c) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void GpFileSystem_Win32::SetMainThreadRelay(IGpThreadRelay *relay)
|
||||
{
|
||||
(void)relay;
|
||||
}
|
||||
|
||||
void GpFileSystem_Win32::SetDelayCallback(GpFileSystem_Win32::DelayCallback_t delayCallback)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ public:
|
||||
bool ValidateFilePath(const char *path, size_t sz) const override;
|
||||
bool ValidateFilePathUnicodeChar(uint32_t ch) const override;
|
||||
|
||||
void SetMainThreadRelay(IGpThreadRelay *relay) override;
|
||||
void SetDelayCallback(DelayCallback_t delayCallback) override;
|
||||
|
||||
const wchar_t *GetBasePath() const;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "GpColorCursor_Win32.h"
|
||||
#include "GpDisplayDriverFactory.h"
|
||||
#include "GpGlobalConfig.h"
|
||||
#include "GpFiber_Win32.h"
|
||||
#include "GpFileSystem_Win32.h"
|
||||
#include "GpLogDriver_Win32.h"
|
||||
#include "GpFontHandlerFactory.h"
|
||||
@@ -28,7 +27,6 @@ GpWindowsGlobals g_gpWindowsGlobals;
|
||||
extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAudio2(const GpAudioDriverProperties &properties);
|
||||
extern "C" __declspec(dllimport) IGpDisplayDriver *GpDriver_CreateDisplayDriver_D3D11(const GpDisplayDriverProperties &properties);
|
||||
extern "C" __declspec(dllimport) IGpInputDriver *GpDriver_CreateInputDriver_XInput(const GpInputDriverProperties &properties);
|
||||
extern "C" __declspec(dllimport) IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties);
|
||||
|
||||
static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y, float pixelScaleX, float pixelScaleY)
|
||||
{
|
||||
@@ -430,7 +428,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
g_gpWindowsGlobals.m_hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_ICON1));
|
||||
g_gpWindowsGlobals.m_hIconSm = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_ICON2));
|
||||
|
||||
g_gpWindowsGlobals.m_createFiberFunc = GpFiber_Win32::Create;
|
||||
g_gpWindowsGlobals.m_createBWCursorFunc = GpBWCursor_Win32::Create;
|
||||
g_gpWindowsGlobals.m_createColorCursorFunc = GpColorCursor_Win32::Create;
|
||||
g_gpWindowsGlobals.m_translateWindowsMessageFunc = TranslateWindowsMessage;
|
||||
@@ -439,7 +436,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
|
||||
g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_XAudio2;
|
||||
|
||||
g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_FreeType2;
|
||||
g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_None;
|
||||
|
||||
EGpInputDriverType inputDrivers[] =
|
||||
{
|
||||
@@ -456,7 +453,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDriver_CreateDisplayDriver_D3D11);
|
||||
GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_XAudio2, GpDriver_CreateAudioDriver_XAudio2);
|
||||
GpInputDriverFactory::RegisterInputDriverFactory(EGpInputDriverType_XInput, GpDriver_CreateInputDriver_XInput);
|
||||
GpFontHandlerFactory::RegisterFontHandlerFactory(EGpFontHandlerType_FreeType2, GpDriver_CreateFontHandler_FreeType2);
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Windows environment configured, starting up");
|
||||
|
||||
@@ -15,8 +15,8 @@ android {
|
||||
}
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 29
|
||||
versionCode 11
|
||||
versionName "1.0.15"
|
||||
versionCode 14
|
||||
versionName "1.1.0"
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
arguments "APP_PLATFORM=android-16"
|
||||
|
||||
1
AerofoilAndroid/app/jni/.gitignore
vendored
1
AerofoilAndroid/app/jni/.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
AerofoilSDL
|
||||
AerofoilPortable
|
||||
Common
|
||||
FreeType
|
||||
GpApp
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../../AerofoilPortable
|
||||
@@ -24,7 +24,7 @@ LOCAL_SRC_FILES := \
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := SDL2
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := GpShell GpFontHandler_FreeType2 AerofoilPortable AerofoilSDL GpApp
|
||||
LOCAL_STATIC_LIBRARIES := GpShell AerofoilPortable AerofoilSDL GpApp
|
||||
|
||||
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
|
||||
|
||||
|
||||
@@ -450,7 +450,6 @@ bool GpFileSystem_Android::ResolvePath(PortabilityLayer::VirtualDirectory_t virt
|
||||
|
||||
GpFileSystem_Android::GpFileSystem_Android()
|
||||
: m_activity(nullptr)
|
||||
, m_relay(nullptr)
|
||||
, m_delayCallback(nullptr)
|
||||
, m_sourceExportMutex(nullptr)
|
||||
, m_sourceExportFD(0)
|
||||
@@ -680,25 +679,6 @@ bool GpFileSystem_Android::DeleteFile(PortabilityLayer::VirtualDirectory_t virtu
|
||||
}
|
||||
|
||||
IGpDirectoryCursor *GpFileSystem_Android::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_Android::ScanDirectoryNestedThunk(void *context)
|
||||
{
|
||||
ScanDirectoryNestedContext *ctx = static_cast<ScanDirectoryNestedContext*>(context);
|
||||
ctx->m_returnValue = ctx->m_this->ScanDirectoryNestedInternal(ctx->m_virtualDirectory, ctx->m_paths, ctx->m_numPaths);
|
||||
}
|
||||
|
||||
IGpDirectoryCursor *GpFileSystem_Android::ScanDirectoryNestedInternal(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *const *paths, size_t numPaths)
|
||||
{
|
||||
if (virtualDirectory == PortabilityLayer::VirtualDirectories::kGameData || virtualDirectory == PortabilityLayer::VirtualDirectories::kApplicationData)
|
||||
return ScanAssetDirectory(virtualDirectory, paths, numPaths);
|
||||
@@ -752,11 +732,6 @@ bool GpFileSystem_Android::ValidateFilePathUnicodeChar(uint32_t c) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void GpFileSystem_Android::SetMainThreadRelay(IGpThreadRelay *relay)
|
||||
{
|
||||
m_relay = relay;
|
||||
}
|
||||
|
||||
void GpFileSystem_Android::SetDelayCallback(DelayCallback_t delayCallback)
|
||||
{
|
||||
m_delayCallback = delayCallback;
|
||||
|
||||
@@ -27,7 +27,6 @@ public:
|
||||
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;
|
||||
|
||||
void PostSourceExportRequest(bool cancelled, int fd, jobject pfd);
|
||||
@@ -36,26 +35,12 @@ public:
|
||||
static GpFileSystem_Android *GetInstance();
|
||||
|
||||
private:
|
||||
struct ScanDirectoryNestedContext
|
||||
{
|
||||
GpFileSystem_Android *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 *ScanAssetDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths);
|
||||
IGpDirectoryCursor *ScanStorageDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths);
|
||||
|
||||
bool OpenSourceExportFD(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, int &fd, jobject &pfd);
|
||||
bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution, bool &isAsset);
|
||||
|
||||
IGpThreadRelay *m_relay;
|
||||
DelayCallback_t m_delayCallback;
|
||||
|
||||
jobject m_activity;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "GpAudioDriverFactory.h"
|
||||
#include "GpDisplayDriverFactory.h"
|
||||
#include "GpGlobalConfig.h"
|
||||
#include "GpFiber_SDL.h"
|
||||
#include "GpFileSystem_Android.h"
|
||||
#include "GpFontHandlerFactory.h"
|
||||
#include "GpInputDriverFactory.h"
|
||||
@@ -24,8 +23,6 @@
|
||||
|
||||
GpAndroidGlobals g_gpAndroidGlobals;
|
||||
|
||||
extern "C" IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties);
|
||||
|
||||
IGpDisplayDriver *GpDriver_CreateDisplayDriver_SDL_GL2(const GpDisplayDriverProperties &properties);
|
||||
IGpAudioDriver *GpDriver_CreateAudioDriver_SDL(const GpAudioDriverProperties &properties);
|
||||
|
||||
@@ -91,7 +88,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_SDL2;
|
||||
|
||||
g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_FreeType2;
|
||||
g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_None;
|
||||
|
||||
g_gpGlobalConfig.m_inputDriverTypes = nullptr;
|
||||
g_gpGlobalConfig.m_numInputDrivers = 0;
|
||||
@@ -102,7 +99,6 @@ int main(int argc, char* argv[])
|
||||
|
||||
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_SDL_GL2, GpDriver_CreateDisplayDriver_SDL_GL2);
|
||||
GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_SDL2, GpDriver_CreateAudioDriver_SDL);
|
||||
GpFontHandlerFactory::RegisterFontHandlerFactory(EGpFontHandlerType_FreeType2, GpDriver_CreateFontHandler_FreeType2);
|
||||
|
||||
int returnCode = GpMain::Run();
|
||||
|
||||
|
||||
@@ -11,12 +11,9 @@ mklink /D app\jni\SDL2 ..\..\..\SDL2-2.0.12
|
||||
mklink /D app\jni\GpApp ..\..\..\GpApp
|
||||
mklink /D app\jni\GpShell ..\..\..\GpShell
|
||||
mklink /D app\jni\GpCommon ..\..\..\GpCommon
|
||||
mklink /D app\jni\GpFontHandler_FreeType2 ..\..\..\GpFontHandler_FreeType2
|
||||
mklink /D app\jni\PortabilityLayer ..\..\..\PortabilityLayer
|
||||
mklink /D app\jni\FreeType ..\..\..\FreeType
|
||||
mklink /D app\jni\rapidjson ..\..\..\rapidjson
|
||||
mklink /D app\jni\MacRomanConversion ..\..\..\MacRomanConversion
|
||||
mklink /D app\jni\stb ..\..\..\stb
|
||||
mklink /D app\src\main\assets\Resources ..\..\..\..\..\Resources
|
||||
|
||||
pause
|
||||
|
||||
@@ -8,11 +8,7 @@ rmdir app\jni\SDL2
|
||||
rmdir app\jni\GpShell
|
||||
rmdir app\jni\GpCommon
|
||||
rmdir app\jni\GpApp
|
||||
rmdir app\jni\GpFontHandler_FreeType2
|
||||
rmdir app\jni\PortabilityLayer
|
||||
rmdir app\jni\FreeType
|
||||
rmdir app\jni\zlib
|
||||
rmdir app\jni\rapidjson
|
||||
rmdir app\jni\MacRomanConversion
|
||||
rmdir app\jni\stb
|
||||
rmdir app\src\main\assets\Resources
|
||||
|
||||
8
AerofoilPortable.props
Normal file
8
AerofoilPortable.props
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
@@ -17,4 +17,5 @@ LOCAL_SRC_FILES := \
|
||||
GpThreadEvent_Cpp11.cpp \
|
||||
GpSystemServices_POSIX.cpp
|
||||
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<IncludePath>$(SolutionDir)SDL2-2.0.12\include;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(SolutionDir)SDL2-2.0.12\include;$(SolutionDir)AerofoilPortable;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)SDL2-2.0.12\lib\x64;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
|
||||
@@ -93,8 +93,6 @@
|
||||
<ClCompile Include="..\Aerofoil\GpThreadEvent_Win32.cpp" />
|
||||
<ClCompile Include="GpAudioDriver_SDL2.cpp" />
|
||||
<ClCompile Include="GpDisplayDriver_SDL_GL2.cpp" />
|
||||
<ClCompile Include="GpFiberStarter_SDL.cpp" />
|
||||
<ClCompile Include="GpFiber_SDL.cpp" />
|
||||
<ClCompile Include="GpInputDriver_SDL_Gamepad.cpp" />
|
||||
<ClCompile Include="GpMain_SDL_Win32.cpp" />
|
||||
<ClCompile Include="ShaderCode\CopyQuadP.cpp" />
|
||||
|
||||
@@ -48,12 +48,6 @@
|
||||
<ClCompile Include="ShaderCode\ScaleQuadP.cpp">
|
||||
<Filter>Source Files\ShaderCode</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GpFiber_SDL.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GpFiberStarter_SDL.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GpDisplayDriver_SDL_GL2.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
8
AerofoilSDL/AerofoilSDL_Combined.cpp
Normal file
8
AerofoilSDL/AerofoilSDL_Combined.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "GpAudioDriver_SDL2.cpp"
|
||||
#include "GpDisplayDriver_SDL_GL2.cpp"
|
||||
#include "GpInputDriver_SDL_Gamepad.cpp"
|
||||
#include "ShaderCode/CopyQuadP.cpp"
|
||||
#include "ShaderCode/DrawQuadPaletteP.cpp"
|
||||
#include "ShaderCode/DrawQuad32P.cpp"
|
||||
#include "ShaderCode/DrawQuadV.cpp"
|
||||
#include "ShaderCode/ScaleQuadP.cpp"
|
||||
@@ -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 \
|
||||
|
||||
@@ -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"
|
||||
@@ -437,7 +437,7 @@ bool GpAudioDriver_SDL2::Init()
|
||||
requestedSpec.channels = 1;
|
||||
requestedSpec.format = AUDIO_S16;
|
||||
requestedSpec.freq = m_properties.m_sampleRate;
|
||||
requestedSpec.samples = 512;
|
||||
requestedSpec.samples = 1024;
|
||||
requestedSpec.userdata = this;
|
||||
|
||||
if (SDL_OpenAudio(&requestedSpec, nullptr))
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include "IGpDisplayDriver.h"
|
||||
|
||||
#include "CoreDefs.h"
|
||||
#include "GpApplicationName.h"
|
||||
#include "GpComPtr.h"
|
||||
#include "GpFiber_SDL.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"
|
||||
@@ -28,6 +29,9 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#pragma push_macro("LoadCursor")
|
||||
#ifdef LoadCursor
|
||||
@@ -214,6 +218,7 @@ struct GpGLFunctions
|
||||
|
||||
static void CheckGLError(const GpGLFunctions &gl, IGpLogDriver *logger)
|
||||
{
|
||||
#if GP_DEBUG_CONFIG
|
||||
GLenum errorCode = gl.GetError();
|
||||
if (errorCode != 0)
|
||||
{
|
||||
@@ -222,6 +227,7 @@ static void CheckGLError(const GpGLFunctions &gl, IGpLogDriver *logger)
|
||||
}
|
||||
|
||||
assert(errorCode == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
class GpGLObject
|
||||
@@ -729,17 +735,18 @@ public:
|
||||
explicit GpDisplayDriver_SDL_GL2(const GpDisplayDriverProperties &properties);
|
||||
~GpDisplayDriver_SDL_GL2();
|
||||
|
||||
bool Init();
|
||||
bool Init() GP_ASYNCIFY_PARANOID_OVERRIDE;
|
||||
void ServeTicks(int tickCount) GP_ASYNCIFY_PARANOID_OVERRIDE;
|
||||
void ForceSync() override;
|
||||
void Shutdown() GP_ASYNCIFY_PARANOID_OVERRIDE;
|
||||
|
||||
void TranslateSDLMessage(const SDL_Event *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY, bool obstructiveTextInput);
|
||||
|
||||
void Run() override;
|
||||
void Shutdown() override;
|
||||
void GetInitialDisplayResolution(unsigned int *width, unsigned int *height) override;
|
||||
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext) override;
|
||||
void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects) override;
|
||||
IGpCursor *CreateBWCursor(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY) override;
|
||||
IGpCursor *CreateColorCursor(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY) override;
|
||||
IGpCursor *CreateBWCursor(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY) GP_ASYNCIFY_PARANOID_OVERRIDE;
|
||||
IGpCursor *CreateColorCursor(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY) GP_ASYNCIFY_PARANOID_OVERRIDE;
|
||||
void SetCursor(IGpCursor *cursor) override;
|
||||
void SetStandardCursor(EGpStandardCursor_t standardCursor) override;
|
||||
void UpdatePalette(const void *paletteData) override;
|
||||
@@ -797,7 +804,7 @@ private:
|
||||
|
||||
void ScaleVirtualScreen();
|
||||
|
||||
GpDisplayDriverTickStatus_t PresentFrameAndSync();
|
||||
bool SyncRender();
|
||||
|
||||
GpGLFunctions m_gl;
|
||||
GpDisplayDriverProperties m_properties;
|
||||
@@ -906,9 +913,6 @@ private:
|
||||
EGpStandardCursor_t m_pendingStandardCursor;
|
||||
bool m_mouseIsInClientArea;
|
||||
|
||||
IGpFiber *m_vosFiber;
|
||||
IGpThreadEvent *m_vosEvent;
|
||||
|
||||
float m_bgColor[4];
|
||||
bool m_bgIsDark;
|
||||
|
||||
@@ -1193,8 +1197,6 @@ GpDisplayDriver_SDL_GL2::GpDisplayDriver_SDL_GL2(const GpDisplayDriverProperties
|
||||
, m_pixelScaleX(1.0f)
|
||||
, m_pixelScaleY(1.0f)
|
||||
, m_useUpscaleFilter(false)
|
||||
, m_vosFiber(nullptr)
|
||||
, m_vosEvent(nullptr)
|
||||
, m_pendingCursor(nullptr)
|
||||
, m_activeCursor(nullptr)
|
||||
, m_currentStandardCursor(EGpStandardCursors::kArrow)
|
||||
@@ -1339,9 +1341,247 @@ GpDisplayDriver_SDL_GL2::~GpDisplayDriver_SDL_GL2()
|
||||
|
||||
bool GpDisplayDriver_SDL_GL2::Init()
|
||||
{
|
||||
#if GP_GL_IS_OPENGL_4_CONTEXT
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
#else
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
#endif
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
|
||||
IGpLogDriver *logger = m_properties.m_logger;
|
||||
|
||||
uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
|
||||
if (m_properties.m_systemServices->IsFullscreenOnStartup())
|
||||
{
|
||||
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
m_isFullScreen = true;
|
||||
}
|
||||
else
|
||||
windowFlags |= SDL_WINDOW_RESIZABLE;
|
||||
|
||||
m_window = SDL_CreateWindow(GP_APPLICATION_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_windowWidthPhysical, m_windowHeightPhysical, windowFlags);
|
||||
|
||||
if (m_isFullScreen)
|
||||
{
|
||||
m_windowModeRevertWidth = m_windowWidthPhysical;
|
||||
m_windowModeRevertHeight = m_windowHeightPhysical;
|
||||
|
||||
int windowWidth = 0;
|
||||
int windowHeight = 0;
|
||||
SDL_GetWindowSize(m_window, &windowWidth, &windowHeight);
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Initialized fullscreen SDL window %i x %i", windowWidth, windowHeight);
|
||||
|
||||
m_windowWidthPhysical = windowWidth;
|
||||
m_windowHeightPhysical = windowHeight;
|
||||
|
||||
uint32_t desiredWidth = windowWidth;
|
||||
uint32_t desiredHeight = windowHeight;
|
||||
uint32_t virtualWidth = m_windowWidthVirtual;
|
||||
uint32_t virtualHeight = m_windowHeightVirtual;
|
||||
float pixelScaleX = m_pixelScaleX;
|
||||
float pixelScaleY = m_pixelScaleY;
|
||||
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
|
||||
{
|
||||
m_windowWidthVirtual = virtualWidth;
|
||||
m_windowHeightVirtual = virtualHeight;
|
||||
m_pixelScaleX = pixelScaleX;
|
||||
m_pixelScaleY = pixelScaleY;
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "AdjustedRequestedResolution succeeded. Virtual dimensions %i x %i Pixel scale %f x %f", static_cast<int>(virtualWidth), static_cast<int>(virtualHeight), static_cast<float>(pixelScaleX), static_cast<float>(pixelScaleY));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "AdjustedRequestedResolution failed!");
|
||||
}
|
||||
}
|
||||
|
||||
const bool obstructiveTextInput = m_properties.m_systemServices->IsTextInputObstructive();
|
||||
|
||||
if (!obstructiveTextInput)
|
||||
SDL_StartTextInput();
|
||||
|
||||
StartOpenGLForWindow(logger);
|
||||
|
||||
if (!m_gl.LookUpFunctions())
|
||||
return false;
|
||||
|
||||
m_initialWidthVirtual = m_windowWidthVirtual;
|
||||
m_initialHeightVirtual = m_windowHeightVirtual;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GpDisplayDriver_SDL_GL2::ServeTicks(int ticks)
|
||||
{
|
||||
IGpLogDriver *logger = m_properties.m_logger;
|
||||
const bool obstructiveTextInput = m_properties.m_systemServices->IsTextInputObstructive();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SDL_Event msg;
|
||||
if (SDL_PollEvent(&msg) != 0)
|
||||
{
|
||||
switch (msg.type)
|
||||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
if (!m_mouseIsInClientArea)
|
||||
m_mouseIsInClientArea = true;
|
||||
}
|
||||
break;
|
||||
//case SDL_MOUSELEAVE: // Does SDL support this??
|
||||
// m_mouseIsInClientArea = false;
|
||||
// break;
|
||||
case SDL_RENDER_DEVICE_RESET:
|
||||
case SDL_RENDER_TARGETS_RESET:
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Triggering GL context reset due to device loss (Type: %i)", static_cast<int>(msg.type));
|
||||
|
||||
m_contextLost = true;
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
case SDL_CONTROLLERDEVICEREMAPPED:
|
||||
if (IGpInputDriverSDLGamepad *gamepadDriver = IGpInputDriverSDLGamepad::GetInstance())
|
||||
gamepadDriver->ProcessSDLEvent(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
TranslateSDLMessage(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY, obstructiveTextInput);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_isFullScreen != m_isFullScreenDesired)
|
||||
{
|
||||
if (m_isFullScreenDesired)
|
||||
BecomeFullScreen();
|
||||
else
|
||||
BecomeWindowed();
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Triggering GL context reset due to fullscreen state change");
|
||||
|
||||
m_contextLost = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
int clientWidth = 0;
|
||||
int clientHeight = 0;
|
||||
SDL_GetWindowSize(m_window, &clientWidth, &clientHeight);
|
||||
|
||||
unsigned int desiredWidth = clientWidth;
|
||||
unsigned int desiredHeight = clientHeight;
|
||||
if (desiredWidth != m_windowWidthPhysical || desiredHeight != m_windowHeightPhysical || m_isResolutionResetDesired)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Detected window size change");
|
||||
|
||||
uint32_t prevWidthPhysical = m_windowWidthPhysical;
|
||||
uint32_t prevHeightPhysical = m_windowHeightPhysical;
|
||||
uint32_t prevWidthVirtual = m_windowWidthVirtual;
|
||||
uint32_t prevHeightVirtual = m_windowHeightVirtual;
|
||||
uint32_t virtualWidth = m_windowWidthVirtual;
|
||||
uint32_t virtualHeight = m_windowHeightVirtual;
|
||||
float pixelScaleX = 1.0f;
|
||||
float pixelScaleY = 1.0f;
|
||||
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
|
||||
{
|
||||
bool resizedOK = ResizeOpenGLWindow(m_windowWidthPhysical, m_windowHeightPhysical, desiredWidth, desiredHeight, logger);
|
||||
|
||||
if (!resizedOK)
|
||||
break; // Critical video driver error, exit
|
||||
|
||||
m_windowWidthVirtual = virtualWidth;
|
||||
m_windowHeightVirtual = virtualHeight;
|
||||
m_pixelScaleX = pixelScaleX;
|
||||
m_pixelScaleY = pixelScaleY;
|
||||
m_isResolutionResetDesired = false;
|
||||
|
||||
if (GpVOSEvent *resizeEvent = m_properties.m_eventQueue->QueueEvent())
|
||||
{
|
||||
resizeEvent->m_eventType = GpVOSEventTypes::kVideoResolutionChanged;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_prevWidth = prevWidthVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_prevHeight = prevHeightVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newWidth = m_windowWidthVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newHeight = m_windowHeightVirtual;
|
||||
}
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Triggering GL context reset due to window size change");
|
||||
|
||||
m_contextLost = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_contextLost)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Resetting OpenGL context. Physical: %i x %i Virtual %i x %i", static_cast<int>(m_windowWidthPhysical), static_cast<int>(m_windowHeightPhysical), static_cast<int>(m_windowWidthVirtual), static_cast<int>(m_windowHeightVirtual));
|
||||
|
||||
// Drop everything and reset
|
||||
m_res.~InstancedResources();
|
||||
new (&m_res) InstancedResources();
|
||||
|
||||
if (m_firstSurface)
|
||||
m_firstSurface->DestroyAll();
|
||||
|
||||
if (!InitResources(m_windowWidthPhysical, m_windowHeightPhysical, m_windowWidthVirtual, m_windowHeightVirtual))
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Terminating display driver due to InitResources failing");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_firstSurface)
|
||||
m_firstSurface->RecreateAll();
|
||||
|
||||
m_contextLost = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool wantTextInput = m_properties.m_systemServices->IsTextInputEnabled();
|
||||
if (wantTextInput != m_textInputEnabled)
|
||||
{
|
||||
m_textInputEnabled = wantTextInput;
|
||||
if (m_textInputEnabled)
|
||||
SDL_StartTextInput();
|
||||
else
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
|
||||
// Handle dismissal of on-screen keyboard
|
||||
const bool isTextInputActuallyActive = SDL_IsTextInputActive();
|
||||
m_textInputEnabled = isTextInputActuallyActive;
|
||||
m_properties.m_systemServices->SetTextInputEnabled(isTextInputActuallyActive);
|
||||
|
||||
if (SyncRender())
|
||||
{
|
||||
ticks--;
|
||||
if (ticks <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GpDisplayDriver_SDL_GL2::ForceSync()
|
||||
{
|
||||
m_frameTimeAccumulated = std::chrono::nanoseconds::zero();
|
||||
}
|
||||
|
||||
static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y, float pixelScaleX, float pixelScaleY)
|
||||
{
|
||||
if (GpVOSEvent *evt = eventQueue->QueueEvent())
|
||||
@@ -1379,7 +1619,7 @@ static void PostTouchEvent(IGpVOSEventQueue *eventQueue, GpTouchEventType_t even
|
||||
|
||||
static bool IdentifyVKey(const SDL_KeyboardEvent *keyEvt, GpKeyIDSubset_t &outSubset, GpKeyboardInputEvent::KeyUnion &outKey)
|
||||
{
|
||||
SDL_KeyCode keyCode = static_cast<SDL_KeyCode>(keyEvt->keysym.sym);
|
||||
SDL_Keycode keyCode = static_cast<SDL_Keycode>(keyEvt->keysym.sym);
|
||||
|
||||
switch (keyCode)
|
||||
{
|
||||
@@ -1835,248 +2075,6 @@ void GpDisplayDriver_SDL_GL2::TranslateSDLMessage(const SDL_Event *msg, IGpVOSEv
|
||||
}
|
||||
}
|
||||
|
||||
void GpDisplayDriver_SDL_GL2::Run()
|
||||
{
|
||||
#if GP_GL_IS_OPENGL_4_CONTEXT
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
#else
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
#endif
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
|
||||
IGpLogDriver *logger = m_properties.m_logger;
|
||||
|
||||
m_vosEvent = m_properties.m_systemServices->CreateThreadEvent(true, false);
|
||||
m_vosFiber = new GpFiber_SDL(nullptr, m_vosEvent);
|
||||
|
||||
uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
|
||||
if (m_properties.m_systemServices->IsFullscreenOnStartup())
|
||||
{
|
||||
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
m_isFullScreen = true;
|
||||
}
|
||||
else
|
||||
windowFlags |= SDL_WINDOW_RESIZABLE;
|
||||
|
||||
m_window = SDL_CreateWindow(GP_APPLICATION_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_windowWidthPhysical, m_windowHeightPhysical, windowFlags);
|
||||
|
||||
if (m_isFullScreen)
|
||||
{
|
||||
m_windowModeRevertWidth = m_windowWidthPhysical;
|
||||
m_windowModeRevertHeight = m_windowHeightPhysical;
|
||||
|
||||
int windowWidth = 0;
|
||||
int windowHeight = 0;
|
||||
SDL_GetWindowSize(m_window, &windowWidth, &windowHeight);
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Initialized fullscreen SDL window %i x %i", windowWidth, windowHeight);
|
||||
|
||||
m_windowWidthPhysical = windowWidth;
|
||||
m_windowHeightPhysical = windowHeight;
|
||||
|
||||
uint32_t desiredWidth = windowWidth;
|
||||
uint32_t desiredHeight = windowHeight;
|
||||
uint32_t virtualWidth = m_windowWidthVirtual;
|
||||
uint32_t virtualHeight = m_windowHeightVirtual;
|
||||
float pixelScaleX = m_pixelScaleX;
|
||||
float pixelScaleY = m_pixelScaleY;
|
||||
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
|
||||
{
|
||||
m_windowWidthVirtual = virtualWidth;
|
||||
m_windowHeightVirtual = virtualHeight;
|
||||
m_pixelScaleX = pixelScaleX;
|
||||
m_pixelScaleY = pixelScaleY;
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "AdjustedRequestedResolution succeeded. Virtual dimensions %i x %i Pixel scale %f x %f", static_cast<int>(virtualWidth), static_cast<int>(virtualHeight), static_cast<float>(pixelScaleX), static_cast<float>(pixelScaleY));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "AdjustedRequestedResolution failed!");
|
||||
}
|
||||
}
|
||||
|
||||
const bool obstructiveTextInput = m_properties.m_systemServices->IsTextInputObstructive();
|
||||
|
||||
if (!obstructiveTextInput)
|
||||
SDL_StartTextInput();
|
||||
|
||||
StartOpenGLForWindow(logger);
|
||||
|
||||
if (!m_gl.LookUpFunctions())
|
||||
return;
|
||||
|
||||
m_initialWidthVirtual = m_windowWidthVirtual;
|
||||
m_initialHeightVirtual = m_windowHeightVirtual;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SDL_Event msg;
|
||||
if (SDL_PollEvent(&msg) != 0)
|
||||
{
|
||||
switch (msg.type)
|
||||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
if (!m_mouseIsInClientArea)
|
||||
m_mouseIsInClientArea = true;
|
||||
}
|
||||
break;
|
||||
//case SDL_MOUSELEAVE: // Does SDL support this??
|
||||
// m_mouseIsInClientArea = false;
|
||||
// break;
|
||||
case SDL_RENDER_DEVICE_RESET:
|
||||
case SDL_RENDER_TARGETS_RESET:
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Triggering GL context reset due to device loss (Type: %i)", static_cast<int>(msg.type));
|
||||
|
||||
m_contextLost = true;
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
case SDL_CONTROLLERDEVICEREMAPPED:
|
||||
if (IGpInputDriverSDLGamepad *gamepadDriver = IGpInputDriverSDLGamepad::GetInstance())
|
||||
gamepadDriver->ProcessSDLEvent(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
TranslateSDLMessage(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY, obstructiveTextInput);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_isFullScreen != m_isFullScreenDesired)
|
||||
{
|
||||
if (m_isFullScreenDesired)
|
||||
BecomeFullScreen();
|
||||
else
|
||||
BecomeWindowed();
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Triggering GL context reset due to fullscreen state change");
|
||||
|
||||
m_contextLost = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
int clientWidth = 0;
|
||||
int clientHeight = 0;
|
||||
SDL_GetWindowSize(m_window, &clientWidth, &clientHeight);
|
||||
|
||||
unsigned int desiredWidth = clientWidth;
|
||||
unsigned int desiredHeight = clientHeight;
|
||||
if (desiredWidth != m_windowWidthPhysical || desiredHeight != m_windowHeightPhysical || m_isResolutionResetDesired)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Detected window size change");
|
||||
|
||||
uint32_t prevWidthPhysical = m_windowWidthPhysical;
|
||||
uint32_t prevHeightPhysical = m_windowHeightPhysical;
|
||||
uint32_t prevWidthVirtual = m_windowWidthVirtual;
|
||||
uint32_t prevHeightVirtual = m_windowHeightVirtual;
|
||||
uint32_t virtualWidth = m_windowWidthVirtual;
|
||||
uint32_t virtualHeight = m_windowHeightVirtual;
|
||||
float pixelScaleX = 1.0f;
|
||||
float pixelScaleY = 1.0f;
|
||||
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
|
||||
{
|
||||
bool resizedOK = ResizeOpenGLWindow(m_windowWidthPhysical, m_windowHeightPhysical, desiredWidth, desiredHeight, logger);
|
||||
|
||||
if (!resizedOK)
|
||||
break; // Critical video driver error, exit
|
||||
|
||||
m_windowWidthVirtual = virtualWidth;
|
||||
m_windowHeightVirtual = virtualHeight;
|
||||
m_pixelScaleX = pixelScaleX;
|
||||
m_pixelScaleY = pixelScaleY;
|
||||
m_isResolutionResetDesired = false;
|
||||
|
||||
if (GpVOSEvent *resizeEvent = m_properties.m_eventQueue->QueueEvent())
|
||||
{
|
||||
resizeEvent->m_eventType = GpVOSEventTypes::kVideoResolutionChanged;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_prevWidth = prevWidthVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_prevHeight = prevHeightVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newWidth = m_windowWidthVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newHeight = m_windowHeightVirtual;
|
||||
}
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Triggering GL context reset due to window size change");
|
||||
|
||||
m_contextLost = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_contextLost)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Resetting OpenGL context. Physical: %i x %i Virtual %i x %i", static_cast<int>(m_windowWidthPhysical), static_cast<int>(m_windowHeightPhysical), static_cast<int>(m_windowWidthVirtual), static_cast<int>(m_windowHeightVirtual));
|
||||
|
||||
// Drop everything and reset
|
||||
m_res.~InstancedResources();
|
||||
new (&m_res) InstancedResources();
|
||||
|
||||
if (m_firstSurface)
|
||||
m_firstSurface->DestroyAll();
|
||||
|
||||
if (!InitResources(m_windowWidthPhysical, m_windowHeightPhysical, m_windowWidthVirtual, m_windowHeightVirtual))
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Terminating display driver due to InitResources failing");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_firstSurface)
|
||||
m_firstSurface->RecreateAll();
|
||||
|
||||
m_contextLost = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool wantTextInput = m_properties.m_systemServices->IsTextInputEnabled();
|
||||
if (wantTextInput != m_textInputEnabled)
|
||||
{
|
||||
m_textInputEnabled = wantTextInput;
|
||||
if (m_textInputEnabled)
|
||||
SDL_StartTextInput();
|
||||
else
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
|
||||
// Handle dismissal of on-screen keyboard
|
||||
const bool isTextInputActuallyActive = SDL_IsTextInputActive();
|
||||
m_textInputEnabled = isTextInputActuallyActive;
|
||||
m_properties.m_systemServices->SetTextInputEnabled(isTextInputActuallyActive);
|
||||
|
||||
GpDisplayDriverTickStatus_t tickStatus = PresentFrameAndSync();
|
||||
if (tickStatus == GpDisplayDriverTickStatuses::kFatalFault || tickStatus == GpDisplayDriverTickStatuses::kApplicationTerminated)
|
||||
{
|
||||
if (logger)
|
||||
{
|
||||
if (tickStatus == GpDisplayDriverTickStatuses::kFatalFault)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Terminating display driver due to fatal fault");
|
||||
if (tickStatus == GpDisplayDriverTickStatuses::kApplicationTerminated)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Terminating display driver due to application termination");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit
|
||||
}
|
||||
|
||||
void GpDisplayDriver_SDL_GL2::Shutdown()
|
||||
{
|
||||
this->~GpDisplayDriver_SDL_GL2();
|
||||
@@ -3058,8 +3056,15 @@ bool GpDisplayDriver_SDL_GL2::BlitQuadProgram::Link(GpDisplayDriver_SDL_GL2 *dri
|
||||
return true;
|
||||
}
|
||||
|
||||
GpDisplayDriverTickStatus_t GpDisplayDriver_SDL_GL2::PresentFrameAndSync()
|
||||
bool GpDisplayDriver_SDL_GL2::SyncRender()
|
||||
{
|
||||
if (m_frameTimeAccumulated >= m_frameTimeSliceSize)
|
||||
{
|
||||
m_frameTimeAccumulated -= m_frameTimeSliceSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SynchronizeCursors();
|
||||
|
||||
float bgColor[4];
|
||||
@@ -3091,6 +3096,10 @@ GpDisplayDriverTickStatus_t GpDisplayDriver_SDL_GL2::PresentFrameAndSync()
|
||||
|
||||
SDL_GL_SwapWindow(m_window);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_sleep(1);
|
||||
#endif
|
||||
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock>::duration syncTime = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||
const intmax_t periodNum = std::chrono::high_resolution_clock::period::num;
|
||||
const intmax_t periodDen = std::chrono::high_resolution_clock::period::den;
|
||||
@@ -3181,22 +3190,9 @@ GpDisplayDriverTickStatus_t GpDisplayDriver_SDL_GL2::PresentFrameAndSync()
|
||||
}
|
||||
|
||||
m_frameTimeAccumulated += frameTimeStep;
|
||||
while (m_frameTimeAccumulated >= m_frameTimeSliceSize)
|
||||
{
|
||||
GpDisplayDriverTickStatus_t tickStatus = m_properties.m_tickFunc(m_properties.m_tickFuncContext, m_vosFiber);
|
||||
m_frameTimeAccumulated -= m_frameTimeSliceSize;
|
||||
|
||||
if (tickStatus == GpDisplayDriverTickStatuses::kSynchronizing)
|
||||
{
|
||||
m_frameTimeAccumulated = std::chrono::high_resolution_clock::duration::zero();
|
||||
break;
|
||||
}
|
||||
else if (tickStatus != GpDisplayDriverTickStatuses::kOK)
|
||||
return tickStatus;
|
||||
}
|
||||
}
|
||||
|
||||
return GpDisplayDriverTickStatuses::kOK;
|
||||
return false;
|
||||
}
|
||||
|
||||
IGpDisplayDriver *GpDriver_CreateDisplayDriver_SDL_GL2(const GpDisplayDriverProperties &properties)
|
||||
@@ -3205,18 +3201,9 @@ IGpDisplayDriver *GpDriver_CreateDisplayDriver_SDL_GL2(const GpDisplayDriverProp
|
||||
if (!driver)
|
||||
return nullptr;
|
||||
|
||||
new (driver) GpDisplayDriver_SDL_GL2(properties);
|
||||
|
||||
if (!driver->Init())
|
||||
{
|
||||
driver->Shutdown();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return driver;
|
||||
return new (driver) GpDisplayDriver_SDL_GL2(properties);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
T *GpGLObjectImpl<T>::Create(GpDisplayDriver_SDL_GL2 *driver)
|
||||
{
|
||||
@@ -3237,4 +3224,33 @@ T *GpGLObjectImpl<T>::Create(GpDisplayDriver_SDL_GL2 *driver)
|
||||
return obj;
|
||||
}
|
||||
|
||||
#if GP_ASYNCIFY_PARANOID
|
||||
bool IGpDisplayDriver::Init()
|
||||
{
|
||||
return static_cast<GpDisplayDriver_SDL_GL2*>(this)->Init();
|
||||
}
|
||||
|
||||
void IGpDisplayDriver::ServeTicks(int tickCount)
|
||||
{
|
||||
static_cast<GpDisplayDriver_SDL_GL2*>(this)->ServeTicks(tickCount);
|
||||
}
|
||||
|
||||
void IGpDisplayDriver::Shutdown()
|
||||
{
|
||||
static_cast<GpDisplayDriver_SDL_GL2*>(this)->Shutdown();
|
||||
}
|
||||
|
||||
IGpCursor *IGpDisplayDriver::CreateBWCursor(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY)
|
||||
{
|
||||
return static_cast<GpDisplayDriver_SDL_GL2*>(this)->CreateBWCursor(width, height, pixelData, maskData, hotSpotX, hotSpotY);
|
||||
}
|
||||
|
||||
IGpCursor *IGpDisplayDriver::CreateColorCursor(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY)
|
||||
{
|
||||
return static_cast<GpDisplayDriver_SDL_GL2*>(this)->CreateColorCursor(width, height, pixelDataRGBA, hotSpotX, hotSpotY);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#pragma pop_macro("LoadCursor")
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#include "GpFiberStarter.h"
|
||||
#include "GpFiber_SDL.h"
|
||||
|
||||
#include "IGpSystemServices.h"
|
||||
#include "IGpThreadEvent.h"
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace GpFiberStarter_SDL
|
||||
{
|
||||
struct FiberStartState
|
||||
{
|
||||
GpFiberStarter::ThreadFunc_t m_threadFunc;
|
||||
IGpThreadEvent *m_creatingReturnEvent;
|
||||
IGpThreadEvent *m_creatingWakeEvent;
|
||||
void *m_context;
|
||||
};
|
||||
|
||||
static int SDLCALL FiberStartRoutine(void *lpThreadParameter)
|
||||
{
|
||||
const FiberStartState *tss = static_cast<const FiberStartState*>(lpThreadParameter);
|
||||
|
||||
GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc;
|
||||
IGpThreadEvent *creatingReturnEvent = tss->m_creatingReturnEvent;
|
||||
IGpThreadEvent *wakeEvent = tss->m_creatingWakeEvent;
|
||||
void *context = tss->m_context;
|
||||
creatingReturnEvent->Signal();
|
||||
|
||||
wakeEvent->Wait();
|
||||
|
||||
threadFunc(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
IGpFiber *GpFiberStarter::StartFiber(IGpSystemServices *systemServices, ThreadFunc_t threadFunc, void *context, IGpFiber *creatingFiber)
|
||||
{
|
||||
IGpThreadEvent *returnEvent = systemServices->CreateThreadEvent(true, false);
|
||||
if (!returnEvent)
|
||||
return nullptr;
|
||||
|
||||
IGpThreadEvent *wakeEvent = systemServices->CreateThreadEvent(true, false);
|
||||
if (!wakeEvent)
|
||||
{
|
||||
returnEvent->Destroy();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GpFiberStarter_SDL::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);
|
||||
if (!thread)
|
||||
{
|
||||
returnEvent->Destroy();
|
||||
wakeEvent->Destroy();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
returnEvent->Wait();
|
||||
returnEvent->Destroy();
|
||||
|
||||
return new GpFiber_SDL(thread, wakeEvent);
|
||||
}
|
||||
@@ -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<GpFiber_SDL*>(toFiber)->m_event->Signal();
|
||||
m_event->Wait();
|
||||
}
|
||||
|
||||
void GpFiber_SDL::YieldToTerminal(IGpFiber *toFiber)
|
||||
{
|
||||
static_cast<GpFiber_SDL*>(toFiber)->m_event->Signal();
|
||||
}
|
||||
|
||||
void GpFiber_SDL::Destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpFiber.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
struct IGpThreadEvent;
|
||||
|
||||
class GpFiber_SDL final : public IGpFiber
|
||||
{
|
||||
public:
|
||||
explicit GpFiber_SDL(SDL_Thread *thread, IGpThreadEvent *threadEvent);
|
||||
~GpFiber_SDL();
|
||||
|
||||
void YieldTo(IGpFiber *fromFiber) override;
|
||||
void YieldToTerminal(IGpFiber *fromFiber) override;
|
||||
void Destroy() override;
|
||||
|
||||
private:
|
||||
static int SDLCALL InternalThreadFunction(void *data);
|
||||
|
||||
bool m_isDestroying;
|
||||
IGpThreadEvent *m_event;
|
||||
SDL_Thread *m_thread;
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "GpInputDriver_SDL_Gamepad.h"
|
||||
#include "GpVOSEvent.h"
|
||||
#include "GpWindows.h"
|
||||
#include "IGpVOSEventQueue.h"
|
||||
|
||||
#include "SDL_events.h"
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "GpAudioDriverFactory.h"
|
||||
#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"
|
||||
|
||||
5
AerofoilSDL/GpSDL.h
Normal file
5
AerofoilSDL/GpSDL.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#ifdef __CYGWIN__
|
||||
#define GP_SDL_DIRECTORY_PREFIX "SDL2/"
|
||||
#else
|
||||
#define GP_SDL_DIRECTORY_PREFIX
|
||||
#endif
|
||||
3
AerofoilWeb/.gitignore
vendored
Normal file
3
AerofoilWeb/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
obj
|
||||
res
|
||||
bin
|
||||
4
AerofoilWeb/AerofoilWeb_Combined.cpp
Normal file
4
AerofoilWeb/AerofoilWeb_Combined.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#include "GpFileSystem_Web.cpp"
|
||||
#include "GpLogDriver_Web.cpp"
|
||||
#include "GpMain_SDL_Web.cpp"
|
||||
#include "GpSystemServices_Web.cpp"
|
||||
15
AerofoilWeb/AerofoilWeb_Resources.cpp
Normal file
15
AerofoilWeb/AerofoilWeb_Resources.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "GpFileSystem_Web_Resources.h"
|
||||
|
||||
namespace GpFileSystem_Web_Resources
|
||||
{
|
||||
namespace ApplicationData
|
||||
{
|
||||
#include "res/ApplicationData.h"
|
||||
}
|
||||
namespace GameData
|
||||
{
|
||||
#include "res/GameData.h"
|
||||
}
|
||||
}
|
||||
7
AerofoilWeb/BuildAerofoilSDL.bat
Normal file
7
AerofoilWeb/BuildAerofoilSDL.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
set INPUT_DIR=../AerofoilSDL
|
||||
set OUTPUT_DIR=obj
|
||||
set FLAGS=-s USE_SDL=2 -flto -I../GpCommon/ -I../PortabilityLayer/ -I../Common/ -s ASYNCIFY -O3 -DGP_DEBUG_CONFIG=0
|
||||
|
||||
emcc -c %INPUT_DIR%/AerofoilSDL_Combined.cpp -o %OUTPUT_DIR%/AerofoilSDL_Combined.o %FLAGS%
|
||||
|
||||
pause
|
||||
7
AerofoilWeb/BuildAerofoilWeb.bat
Normal file
7
AerofoilWeb/BuildAerofoilWeb.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
set INPUT_DIR=.
|
||||
set OUTPUT_DIR=obj
|
||||
set FLAGS=-s USE_SDL=2 -flto -I../GpCommon/ -I../PortabilityLayer/ -I../Common/ -I../GpShell/ -s ASYNCIFY -O3 -DGP_DEBUG_CONFIG=0
|
||||
|
||||
emcc -c %INPUT_DIR%/AerofoilWeb_Combined.cpp -o %OUTPUT_DIR%/AerofoilWeb_Combined.o %FLAGS%
|
||||
|
||||
pause
|
||||
7
AerofoilWeb/BuildGpApp.bat
Normal file
7
AerofoilWeb/BuildGpApp.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
set INPUT_DIR=../GpApp
|
||||
set OUTPUT_DIR=obj
|
||||
set FLAGS=-s USE_SDL=2 -flto -I../GpCommon/ -I../PortabilityLayer/ -I../Common/ -s ASYNCIFY -O3 -DGP_DEBUG_CONFIG=0
|
||||
|
||||
emcc -c %INPUT_DIR%/GpApp_Combined.cpp -o %OUTPUT_DIR%/GpApp_Combined.o %FLAGS%
|
||||
|
||||
pause
|
||||
7
AerofoilWeb/BuildGpShell.bat
Normal file
7
AerofoilWeb/BuildGpShell.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
set INPUT_DIR=../GpShell
|
||||
set OUTPUT_DIR=obj
|
||||
set FLAGS=-s USE_SDL=2 -flto -I../GpCommon/ -I../PortabilityLayer/ -I../Common/ -s ASYNCIFY -O3 -DGP_DEBUG_CONFIG=0
|
||||
|
||||
emcc -c %INPUT_DIR%/GpShell_Combined.cpp -o %OUTPUT_DIR%/GpShell_Combined.o %FLAGS%
|
||||
|
||||
pause
|
||||
7
AerofoilWeb/BuildMacRomanConversion.bat
Normal file
7
AerofoilWeb/BuildMacRomanConversion.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
set INPUT_DIR=../MacRomanConversion
|
||||
set OUTPUT_DIR=obj
|
||||
set FLAGS=-flto -I../MacRomanConversion/ -s ASYNCIFY -O3
|
||||
|
||||
emcc -c %INPUT_DIR%/MacRomanConversion.cpp -o %OUTPUT_DIR%/MacRomanConversion.o %FLAGS%
|
||||
|
||||
pause
|
||||
7
AerofoilWeb/BuildPortabilityLayer.bat
Normal file
7
AerofoilWeb/BuildPortabilityLayer.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
set INPUT_DIR=../PortabilityLayer
|
||||
set OUTPUT_DIR=obj
|
||||
set FLAGS=-s USE_ZLIB=1 -flto -I../GpCommon/ -I../Common/ -I../PortabilityLayer/ -I../rapidjson/include/ -I../MacRomanConversion/ -I../stb/ -s ASYNCIFY -O3 -DGP_DEBUG_CONFIG=0 -Wno-tautological-constant-out-of-range-compare
|
||||
|
||||
emcc -c %INPUT_DIR%/PortabilityLayer_Combined.cpp -o %OUTPUT_DIR%/PortabilityLayer_Combined.o %FLAGS%
|
||||
|
||||
pause
|
||||
10
AerofoilWeb/BuildResources.bat
Normal file
10
AerofoilWeb/BuildResources.bat
Normal file
@@ -0,0 +1,10 @@
|
||||
..\x64\Release\bin2h.exe ..\Packaged res\ApplicationData.h
|
||||
..\x64\Release\bin2h.exe ..\Packaged\Houses res\GameData.h
|
||||
|
||||
set INPUT_DIR=.
|
||||
set OUTPUT_DIR=obj
|
||||
set FLAGS=-flto -O3 -DGP_DEBUG_CONFIG=0
|
||||
|
||||
emcc -c %INPUT_DIR%/AerofoilWeb_Resources.cpp -o %OUTPUT_DIR%/AerofoilWeb_Resources.o %FLAGS%
|
||||
|
||||
pause
|
||||
626
AerofoilWeb/GpFileSystem_Web.cpp
Normal file
626
AerofoilWeb/GpFileSystem_Web.cpp
Normal file
@@ -0,0 +1,626 @@
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include "GpFileSystem_Web.h"
|
||||
#include "GpIOStream.h"
|
||||
#include "IGpDirectoryCursor.h"
|
||||
#include "IGpSystemServices.h"
|
||||
#include "IGpMutex.h"
|
||||
#include "VirtualDirectory.h"
|
||||
|
||||
#include "PLDrivers.h"
|
||||
|
||||
#include "SDL2/SDL.h"
|
||||
#include "SDL2/SDL_rwops.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "UTF8.h"
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__EMSCRIPTEN__)
|
||||
typedef off_t off64_t;
|
||||
#define fstat64 fstat
|
||||
#define fseek64 fseek
|
||||
#define ftruncate64 ftruncate
|
||||
#define stat64 stat
|
||||
#endif
|
||||
|
||||
|
||||
class GpFileStream_Web_StaticMemFile final : public GpIOStream
|
||||
{
|
||||
public:
|
||||
GpFileStream_Web_StaticMemFile(const unsigned char *bytes, size_t size);
|
||||
~GpFileStream_Web_StaticMemFile();
|
||||
|
||||
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:
|
||||
const unsigned char *m_bytes;
|
||||
size_t m_offset;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
GpFileStream_Web_StaticMemFile::GpFileStream_Web_StaticMemFile(const unsigned char *bytes, size_t size)
|
||||
: m_bytes(bytes)
|
||||
, m_size(size)
|
||||
, m_offset(0)
|
||||
{
|
||||
}
|
||||
|
||||
GpFileStream_Web_StaticMemFile::~GpFileStream_Web_StaticMemFile()
|
||||
{
|
||||
}
|
||||
|
||||
size_t GpFileStream_Web_StaticMemFile::Read(void *bytesOut, size_t size)
|
||||
{
|
||||
size_t available = m_size - m_offset;
|
||||
size = std::min(size, available);
|
||||
|
||||
memcpy(bytesOut, m_bytes + m_offset, size);
|
||||
m_offset += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t GpFileStream_Web_StaticMemFile::Write(const void *bytes, size_t size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_StaticMemFile::IsSeekable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_StaticMemFile::IsReadOnly() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_StaticMemFile::IsWriteOnly() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_StaticMemFile::SeekStart(GpUFilePos_t loc)
|
||||
{
|
||||
if (loc > m_size)
|
||||
return false;
|
||||
|
||||
m_offset = static_cast<size_t>(loc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_StaticMemFile::SeekCurrent(GpFilePos_t loc)
|
||||
{
|
||||
GpFilePos_t minOffset = -static_cast<GpFilePos_t>(m_offset);
|
||||
GpFilePos_t maxOffset = static_cast<GpFilePos_t>(m_size - m_offset);
|
||||
|
||||
if (loc < minOffset || loc > maxOffset)
|
||||
return false;
|
||||
|
||||
m_offset = static_cast<size_t>(static_cast<GpFilePos_t>(m_offset) + loc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_StaticMemFile::SeekEnd(GpUFilePos_t loc)
|
||||
{
|
||||
if (loc > m_size)
|
||||
return false;
|
||||
|
||||
m_offset = m_size - loc;
|
||||
return true;
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_Web_StaticMemFile::Size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_Web_StaticMemFile::Tell() const
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
void GpFileStream_Web_StaticMemFile::Close()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void GpFileStream_Web_StaticMemFile::Flush()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
class GpFileStream_Web_File final : public GpIOStream
|
||||
{
|
||||
public:
|
||||
GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly);
|
||||
~GpFileStream_Web_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_Web_File::GpFileStream_Web_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_Web_File::~GpFileStream_Web_File()
|
||||
{
|
||||
fclose(m_f);
|
||||
}
|
||||
|
||||
size_t GpFileStream_Web_File::Read(void *bytesOut, size_t size)
|
||||
{
|
||||
if (m_isWriteOnly)
|
||||
return 0;
|
||||
return fread(bytesOut, 1, size, m_f);
|
||||
}
|
||||
|
||||
size_t GpFileStream_Web_File::Write(const void *bytes, size_t size)
|
||||
{
|
||||
if (m_isReadOnly)
|
||||
return 0;
|
||||
return fwrite(bytes, 1, size, m_f);
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_File::IsSeekable() const
|
||||
{
|
||||
return m_seekable;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_File::IsReadOnly() const
|
||||
{
|
||||
return m_isReadOnly;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_File::IsWriteOnly() const
|
||||
{
|
||||
return m_isWriteOnly;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_File::SeekStart(GpUFilePos_t loc)
|
||||
{
|
||||
if (!m_seekable)
|
||||
return false;
|
||||
|
||||
fflush(m_f);
|
||||
return fseek64(m_f, static_cast<off64_t>(loc), SEEK_SET) >= 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_File::SeekCurrent(GpFilePos_t loc)
|
||||
{
|
||||
if (!m_seekable)
|
||||
return false;
|
||||
|
||||
fflush(m_f);
|
||||
return fseek64(m_f, static_cast<off64_t>(loc), SEEK_CUR) >= 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_Web_File::SeekEnd(GpUFilePos_t loc)
|
||||
{
|
||||
if (!m_seekable)
|
||||
return false;
|
||||
|
||||
fflush(m_f);
|
||||
return fseek64(m_f, -static_cast<off64_t>(loc), SEEK_END) >= 0;
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_Web_File::Size() const
|
||||
{
|
||||
fflush(m_f);
|
||||
|
||||
struct stat64 s;
|
||||
if (fstat64(fileno(m_f), &s) < 0)
|
||||
return 0;
|
||||
|
||||
return static_cast<GpUFilePos_t>(s.st_size);
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_Web_File::Tell() const
|
||||
{
|
||||
return static_cast<GpUFilePos_t>(ftell(m_f));
|
||||
}
|
||||
|
||||
void GpFileStream_Web_File::Close()
|
||||
{
|
||||
this->~GpFileStream_Web_File();
|
||||
free(this);
|
||||
}
|
||||
|
||||
void GpFileStream_Web_File::Flush()
|
||||
{
|
||||
fflush(m_f);
|
||||
}
|
||||
|
||||
bool GpFileSystem_Web::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_Web::GpFileSystem_Web()
|
||||
: m_delayCallback(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
GpFileSystem_Web::~GpFileSystem_Web()
|
||||
{
|
||||
}
|
||||
|
||||
void GpFileSystem_Web::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_Web::FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path)
|
||||
{
|
||||
if (const GpFileSystem_Web_Resources::FileCatalog *catalog = GetCatalogForVirtualDirectory(virtualDirectory))
|
||||
{
|
||||
for (size_t i = 0; i < catalog->m_numEntries; i++)
|
||||
{
|
||||
const GpFileSystem_Web_Resources::FileCatalogEntry &entry = catalog->m_entries[i];
|
||||
if (!strcmp(path, entry.m_fileName))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string resolvedPath;
|
||||
if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath))
|
||||
return false;
|
||||
|
||||
struct stat s;
|
||||
return stat(resolvedPath.c_str(), &s) == 0;
|
||||
}
|
||||
|
||||
bool GpFileSystem_Web::FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &exists)
|
||||
{
|
||||
if (const GpFileSystem_Web_Resources::FileCatalog *catalog = GetCatalogForVirtualDirectory(virtualDirectory))
|
||||
{
|
||||
for (size_t i = 0; i < catalog->m_numEntries; i++)
|
||||
{
|
||||
const GpFileSystem_Web_Resources::FileCatalogEntry &entry = catalog->m_entries[i];
|
||||
if (!strcmp(path, entry.m_fileName))
|
||||
{
|
||||
exists = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
exists = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
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_Web::OpenFileNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* subPaths, size_t numSubPaths, bool writeAccess, GpFileCreationDisposition_t createDisposition)
|
||||
{
|
||||
if (numSubPaths == 1)
|
||||
{
|
||||
if (const GpFileSystem_Web_Resources::FileCatalog *catalog = GetCatalogForVirtualDirectory(virtualDirectory))
|
||||
{
|
||||
for (size_t i = 0; i < catalog->m_numEntries; i++)
|
||||
{
|
||||
const GpFileSystem_Web_Resources::FileCatalogEntry &entry = catalog->m_entries[i];
|
||||
if (!strcmp(subPaths[0], entry.m_fileName))
|
||||
return new GpFileStream_Web_StaticMemFile(entry.m_data, entry.m_size);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
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_Web_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_Web_File(f, !writeAccess, false);
|
||||
}
|
||||
|
||||
bool GpFileSystem_Web::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed)
|
||||
{
|
||||
if (const GpFileSystem_Web_Resources::FileCatalog *catalog = GetCatalogForVirtualDirectory(virtualDirectory))
|
||||
return false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool GpFileSystem_Web::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_Web::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_Web::SetDelayCallback(DelayCallback_t delayCallback)
|
||||
{
|
||||
m_delayCallback = delayCallback;
|
||||
}
|
||||
|
||||
GpFileSystem_Web *GpFileSystem_Web::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
class GpDirectoryCursor_StringList final : public IGpDirectoryCursor
|
||||
{
|
||||
public:
|
||||
explicit GpDirectoryCursor_StringList(std::vector<std::string> &paths);
|
||||
~GpDirectoryCursor_StringList();
|
||||
|
||||
bool GetNext(const char *&outFileName) override;
|
||||
void Destroy() override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_paths;
|
||||
size_t m_index;
|
||||
};
|
||||
|
||||
GpDirectoryCursor_StringList::GpDirectoryCursor_StringList(std::vector<std::string> &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;
|
||||
}
|
||||
|
||||
|
||||
IGpDirectoryCursor *GpFileSystem_Web::ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths)
|
||||
{
|
||||
if (const GpFileSystem_Web_Resources::FileCatalog *catalog = GetCatalogForVirtualDirectory(virtualDirectory))
|
||||
return ScanCatalog(*catalog);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GpFileSystem_Web_Resources::FileCatalog *GpFileSystem_Web::GetCatalogForVirtualDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory)
|
||||
{
|
||||
if (virtualDirectory == PortabilityLayer::VirtualDirectories::kApplicationData)
|
||||
return &GpFileSystem_Web_Resources::ApplicationData::GetCatalog();
|
||||
|
||||
if (virtualDirectory == PortabilityLayer::VirtualDirectories::kGameData)
|
||||
return &GpFileSystem_Web_Resources::GameData::GetCatalog();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IGpDirectoryCursor *GpFileSystem_Web::ScanCatalog(const GpFileSystem_Web_Resources::FileCatalog &catalog)
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
for (size_t i = 0; i < catalog.m_numEntries; i++)
|
||||
paths.push_back(std::string(catalog.m_entries[i].m_fileName));
|
||||
|
||||
return new GpDirectoryCursor_StringList(paths);
|
||||
}
|
||||
|
||||
|
||||
GpFileSystem_Web GpFileSystem_Web::ms_instance;
|
||||
62
AerofoilWeb/GpFileSystem_Web.h
Normal file
62
AerofoilWeb/GpFileSystem_Web.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpFileSystem.h"
|
||||
#include "GpFileSystem_Web_Resources.h"
|
||||
|
||||
#include "GpCoreDefs.h"
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
struct IGpMutex;
|
||||
|
||||
class GpFileSystem_Web final : public IGpFileSystem
|
||||
{
|
||||
public:
|
||||
GpFileSystem_Web();
|
||||
~GpFileSystem_Web();
|
||||
|
||||
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 SetDelayCallback(DelayCallback_t delayCallback) override;
|
||||
|
||||
static GpFileSystem_Web *GetInstance();
|
||||
|
||||
private:
|
||||
struct ScanDirectoryNestedContext
|
||||
{
|
||||
GpFileSystem_Web *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);
|
||||
|
||||
static const GpFileSystem_Web_Resources::FileCatalog *GetCatalogForVirtualDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory);
|
||||
|
||||
static IGpDirectoryCursor *ScanCatalog(const GpFileSystem_Web_Resources::FileCatalog &catalog);
|
||||
|
||||
bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution);
|
||||
|
||||
DelayCallback_t m_delayCallback;
|
||||
|
||||
std::string m_prefsPath;
|
||||
std::string m_basePath;
|
||||
|
||||
static GpFileSystem_Web ms_instance;
|
||||
};
|
||||
28
AerofoilWeb/GpFileSystem_Web_Resources.h
Normal file
28
AerofoilWeb/GpFileSystem_Web_Resources.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
namespace GpFileSystem_Web_Resources
|
||||
{
|
||||
struct FileCatalogEntry
|
||||
{
|
||||
const char *m_fileName;
|
||||
const unsigned char *m_data;
|
||||
const unsigned int m_size;
|
||||
};
|
||||
|
||||
struct FileCatalog
|
||||
{
|
||||
const FileCatalogEntry *m_entries;
|
||||
const unsigned int m_numEntries;
|
||||
const unsigned int m_size;
|
||||
const unsigned int m_size0;
|
||||
};
|
||||
|
||||
namespace ApplicationData
|
||||
{
|
||||
const FileCatalog &GetCatalog();
|
||||
}
|
||||
namespace GameData
|
||||
{
|
||||
const FileCatalog &GetCatalog();
|
||||
}
|
||||
}
|
||||
89
AerofoilWeb/GpLogDriver_Web.cpp
Normal file
89
AerofoilWeb/GpLogDriver_Web.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#include "GpLogDriver_Web.h"
|
||||
#include "GpFileSystem_Web.h"
|
||||
|
||||
#include "GpApplicationName.h"
|
||||
#include "GpIOStream.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <cstring>
|
||||
|
||||
GpLogDriver_Web::GpLogDriver_Web()
|
||||
{
|
||||
}
|
||||
|
||||
void GpLogDriver_Web::Init()
|
||||
{
|
||||
ms_instance.InitInternal();
|
||||
}
|
||||
|
||||
void GpLogDriver_Web::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);
|
||||
|
||||
const char *debugTag = "";
|
||||
|
||||
switch (category)
|
||||
{
|
||||
case Category_Warning:
|
||||
debugTag = "[WARNING] ";
|
||||
break;
|
||||
case Category_Error:
|
||||
debugTag = "[ERROR] ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
int formattedSize = vsnprintf(nullptr, 0, fmt, args);
|
||||
if (formattedSize <= 0)
|
||||
return;
|
||||
|
||||
char *charBuff = static_cast<char*>(malloc(formattedSize + 1));
|
||||
if (!charBuff)
|
||||
return;
|
||||
|
||||
vsnprintf(charBuff, formattedSize + 1, fmt, args);
|
||||
|
||||
fprintf(stderr, "%s%s%s\n", timestampBuffer, debugTag, charBuff);
|
||||
fflush(stderr);
|
||||
|
||||
free(charBuff);
|
||||
}
|
||||
|
||||
void GpLogDriver_Web::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
GpLogDriver_Web *GpLogDriver_Web::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
void GpLogDriver_Web::InitInternal()
|
||||
{
|
||||
time_t t = time(nullptr);
|
||||
struct tm utcTime = *gmtime(&t);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
GpLogDriver_Web GpLogDriver_Web::ms_instance;
|
||||
25
AerofoilWeb/GpLogDriver_Web.h
Normal file
25
AerofoilWeb/GpLogDriver_Web.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpLogDriver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
class GpIOStream;
|
||||
|
||||
class GpLogDriver_Web : public IGpLogDriver
|
||||
{
|
||||
public:
|
||||
GpLogDriver_Web();
|
||||
|
||||
static void Init();
|
||||
|
||||
void VPrintf(Category category, const char *fmt, va_list args) override;
|
||||
void Shutdown() override;
|
||||
|
||||
static GpLogDriver_Web *GetInstance();
|
||||
|
||||
private:
|
||||
void InitInternal();
|
||||
|
||||
static GpLogDriver_Web ms_instance;
|
||||
};
|
||||
91
AerofoilWeb/GpMain_SDL_Web.cpp
Normal file
91
AerofoilWeb/GpMain_SDL_Web.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <SDL.h>
|
||||
#include "SDL_main.h"
|
||||
|
||||
#include "GpMain.h"
|
||||
#include "GpAudioDriverFactory.h"
|
||||
#include "GpDisplayDriverFactory.h"
|
||||
#include "GpGlobalConfig.h"
|
||||
#include "GpFileSystem_Web.h"
|
||||
#include "GpLogDriver_Web.h"
|
||||
#include "GpFontHandlerFactory.h"
|
||||
#include "GpInputDriverFactory.h"
|
||||
#include "GpAppInterface.h"
|
||||
#include "GpSystemServices_Web.h"
|
||||
#include "GpVOSEvent.h"
|
||||
#include "GpX.h"
|
||||
|
||||
#include "IGpFileSystem.h"
|
||||
#include "IGpThreadEvent.h"
|
||||
#include "IGpVOSEventQueue.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
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);
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
GpLogDriver_Web::Init();
|
||||
IGpLogDriver *logger = GpLogDriver_Web::GetInstance();
|
||||
|
||||
#if GP_ASYNCIFY_PARANOID
|
||||
SDL_SetHint(SDL_HINT_EMSCRIPTEN_ASYNCIFY, "0");
|
||||
#endif
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0)
|
||||
return -1;
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Starting filesystem...");
|
||||
|
||||
GpFileSystem_Web::GetInstance()->Init();
|
||||
|
||||
GpDriverCollection *drivers = GpAppInterface_Get()->PL_GetDriverCollection();
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Setting up drivers...");
|
||||
|
||||
drivers->SetDriver<GpDriverIDs::kFileSystem>(GpFileSystem_Web::GetInstance());
|
||||
drivers->SetDriver<GpDriverIDs::kSystemServices>(GpSystemServices_Web::GetInstance());
|
||||
drivers->SetDriver<GpDriverIDs::kLog>(GpLogDriver_Web::GetInstance());
|
||||
|
||||
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_SDL_GL2;
|
||||
|
||||
g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_SDL2;
|
||||
|
||||
g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_None;
|
||||
|
||||
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_Web::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);
|
||||
|
||||
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);
|
||||
|
||||
SDL_Quit();
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
209
AerofoilWeb/GpSystemServices_Web.cpp
Normal file
209
AerofoilWeb/GpSystemServices_Web.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
#include "GpSystemServices_Web.h"
|
||||
|
||||
#include "IGpClipboardContents.h"
|
||||
#include "IGpThreadEvent.h"
|
||||
#include "SDL2/SDL.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
class GpMutex_Web_Null final : public IGpMutex
|
||||
{
|
||||
public:
|
||||
void Destroy() override;
|
||||
|
||||
void Lock() override;
|
||||
void Unlock() override;
|
||||
|
||||
static IGpMutex *GetInstance();
|
||||
|
||||
private:
|
||||
static GpMutex_Web_Null ms_instance;
|
||||
};
|
||||
|
||||
void GpMutex_Web_Null::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
void GpMutex_Web_Null::Lock()
|
||||
{
|
||||
}
|
||||
|
||||
void GpMutex_Web_Null::Unlock()
|
||||
{
|
||||
}
|
||||
|
||||
IGpMutex *GpMutex_Web_Null::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
GpMutex_Web_Null GpMutex_Web_Null::ms_instance;
|
||||
|
||||
|
||||
class GpThreadEvent_Web_Null final : public IGpThreadEvent
|
||||
{
|
||||
public:
|
||||
void Wait() override;
|
||||
bool WaitTimed(uint32_t msec) override;
|
||||
void Signal() override;
|
||||
void Destroy() override;
|
||||
|
||||
static IGpThreadEvent *GetInstance();
|
||||
|
||||
private:
|
||||
static GpThreadEvent_Web_Null ms_instance;
|
||||
};
|
||||
|
||||
GpThreadEvent_Web_Null GpThreadEvent_Web_Null::ms_instance;
|
||||
|
||||
|
||||
void GpThreadEvent_Web_Null::Wait()
|
||||
{
|
||||
}
|
||||
|
||||
bool GpThreadEvent_Web_Null::WaitTimed(uint32_t msec)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void GpThreadEvent_Web_Null::Signal()
|
||||
{
|
||||
}
|
||||
|
||||
void GpThreadEvent_Web_Null::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
IGpThreadEvent *GpThreadEvent_Web_Null::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
|
||||
GpSystemServices_Web::GpSystemServices_Web()
|
||||
: m_textInputEnabled(false)
|
||||
, m_clipboardContents(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
int64_t GpSystemServices_Web::GetTime() const
|
||||
{
|
||||
time_t t = time(nullptr);
|
||||
return static_cast<int64_t>(t) - 2082844800;
|
||||
}
|
||||
|
||||
void GpSystemServices_Web::GetLocalDateTime(unsigned int &year, unsigned int &month, unsigned int &day, unsigned int &hour, unsigned int &minute, unsigned int &second) const
|
||||
{
|
||||
time_t t = time(nullptr);
|
||||
tm *tmObject = localtime(&t);
|
||||
year = static_cast<unsigned int>(tmObject->tm_year);
|
||||
month = static_cast<unsigned int>(tmObject->tm_mon + 1);
|
||||
hour = static_cast<unsigned int>(tmObject->tm_hour);
|
||||
minute = static_cast<unsigned int>(tmObject->tm_min);
|
||||
second = static_cast<unsigned int>(tmObject->tm_sec);
|
||||
}
|
||||
|
||||
IGpMutex *GpSystemServices_Web::CreateMutex()
|
||||
{
|
||||
return GpMutex_Web_Null::GetInstance();
|
||||
}
|
||||
|
||||
IGpMutex *GpSystemServices_Web::CreateRecursiveMutex()
|
||||
{
|
||||
return GpMutex_Web_Null::GetInstance();
|
||||
}
|
||||
|
||||
IGpThreadEvent *GpSystemServices_Web::CreateThreadEvent(bool autoReset, bool startSignaled)
|
||||
{
|
||||
return GpThreadEvent_Web_Null::GetInstance();
|
||||
}
|
||||
|
||||
uint64_t GpSystemServices_Web::GetFreeMemoryCosmetic() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GpSystemServices_Web::~GpSystemServices_Web()
|
||||
{
|
||||
if (m_clipboardContents)
|
||||
m_clipboardContents->Destroy();
|
||||
}
|
||||
|
||||
void *GpSystemServices_Web::CreateThread(ThreadFunc_t threadFunc, void *context)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GpSystemServices_Web::Beep() const
|
||||
{
|
||||
}
|
||||
|
||||
bool GpSystemServices_Web::IsTouchscreen() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GpSystemServices_Web::IsUsingMouseAsTouch() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GpSystemServices_Web::IsTextInputObstructive() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GpSystemServices_Web::IsFullscreenPreferred() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GpSystemServices_Web::IsFullscreenOnStartup() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int GpSystemServices_Web::GetCPUCount() const
|
||||
{
|
||||
return SDL_GetCPUCount();
|
||||
}
|
||||
|
||||
void GpSystemServices_Web::SetTextInputEnabled(bool isEnabled)
|
||||
{
|
||||
m_textInputEnabled = isEnabled;
|
||||
}
|
||||
|
||||
bool GpSystemServices_Web::IsTextInputEnabled() const
|
||||
{
|
||||
return m_textInputEnabled;
|
||||
}
|
||||
|
||||
bool GpSystemServices_Web::AreFontResourcesSeekable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
IGpClipboardContents *GpSystemServices_Web::GetClipboardContents() const
|
||||
{
|
||||
return m_clipboardContents;
|
||||
}
|
||||
|
||||
void GpSystemServices_Web::SetClipboardContents(IGpClipboardContents *contents)
|
||||
{
|
||||
if (contents != m_clipboardContents)
|
||||
{
|
||||
if (m_clipboardContents)
|
||||
m_clipboardContents->Destroy();
|
||||
|
||||
m_clipboardContents = contents;
|
||||
}
|
||||
}
|
||||
|
||||
GpSystemServices_Web *GpSystemServices_Web::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
GpSystemServices_Web GpSystemServices_Web::ms_instance;
|
||||
41
AerofoilWeb/GpSystemServices_Web.h
Normal file
41
AerofoilWeb/GpSystemServices_Web.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpSystemServices.h"
|
||||
#include "GpCoreDefs.h"
|
||||
|
||||
struct IGpClipboardContents;
|
||||
|
||||
class GpSystemServices_Web final : public IGpSystemServices
|
||||
{
|
||||
public:
|
||||
GpSystemServices_Web();
|
||||
~GpSystemServices_Web();
|
||||
|
||||
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;
|
||||
int64_t GetTime() const override;
|
||||
void GetLocalDateTime(unsigned int &year, unsigned int &month, unsigned int &day, unsigned int &hour, unsigned int &minute, unsigned int &second) const override;
|
||||
IGpMutex *CreateMutex() override;
|
||||
IGpMutex *CreateRecursiveMutex() override;
|
||||
IGpThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) override;
|
||||
uint64_t GetFreeMemoryCosmetic() const override;
|
||||
|
||||
static GpSystemServices_Web *GetInstance();
|
||||
|
||||
private:
|
||||
static GpSystemServices_Web ms_instance;
|
||||
|
||||
IGpClipboardContents *m_clipboardContents;
|
||||
bool m_textInputEnabled;
|
||||
};
|
||||
5
AerofoilWeb/Link.bat
Normal file
5
AerofoilWeb/Link.bat
Normal file
@@ -0,0 +1,5 @@
|
||||
set INPUT_DIR=.
|
||||
set OUTPUT_DIR=bin
|
||||
set FLAGS=-flto -O3 -s USE_SDL=2 -s USE_ZLIB=1 -s ASYNCIFY -s ASYNCIFY_IGNORE_INDIRECT -s INITIAL_MEMORY=33554432 -s ASYNCIFY_ADVISE
|
||||
|
||||
emcc obj/AerofoilWeb_Combined.o obj/AerofoilWeb_Resources.o obj/GpShell_Combined.o obj/AerofoilSDL_Combined.o obj/GpApp_Combined.o obj/PortabilityLayer_Combined.o obj/MacRomanConversion.o -o %OUTPUT_DIR%/aerofoil.html %FLAGS%
|
||||
3
AerofoilWeb/MakeBuildDirs.bat
Normal file
3
AerofoilWeb/MakeBuildDirs.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
mkdir obj
|
||||
mkdir bin
|
||||
mkdir res
|
||||
9
AerofoilWeb/Rebuild.bat
Normal file
9
AerofoilWeb/Rebuild.bat
Normal file
@@ -0,0 +1,9 @@
|
||||
call MakeBuildDirs.bat
|
||||
call BuildAerofoilSDL.bat
|
||||
call BuildAerofoilWeb.bat
|
||||
call BuildGpApp.bat
|
||||
call BuildGpShell.bat
|
||||
call BuildMacRomanConversion.bat
|
||||
call BuildPortabilityLayer.bat
|
||||
call BuildResources.bat
|
||||
call Link.bat
|
||||
1
AerofoilWeb/Run.bat
Normal file
1
AerofoilWeb/Run.bat
Normal file
@@ -0,0 +1 @@
|
||||
emrun bin/aerofoil.html
|
||||
12
AerofoilWin.props
Normal file
12
AerofoilWin.props
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)Aerofoil;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
488
AerofoilX/GpFileSystem_X.cpp
Normal file
488
AerofoilX/GpFileSystem_X.cpp
Normal file
@@ -0,0 +1,488 @@
|
||||
#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 <string>
|
||||
#include <vector>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#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<off64_t>(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<off64_t>(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<off64_t>(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<GpUFilePos_t>(s.st_size);
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_X_File::Tell() const
|
||||
{
|
||||
return static_cast<GpUFilePos_t>(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_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;
|
||||
}
|
||||
|
||||
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::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<std::string> &paths);
|
||||
~GpDirectoryCursor_StringList();
|
||||
|
||||
bool GetNext(const char *&outFileName) override;
|
||||
void Destroy() override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_paths;
|
||||
size_t m_index;
|
||||
};
|
||||
|
||||
GpDirectoryCursor_StringList::GpDirectoryCursor_StringList(std::vector<std::string> &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::ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths)
|
||||
{
|
||||
std::string resolvedPath;
|
||||
std::vector<std::string> 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;
|
||||
42
AerofoilX/GpFileSystem_X.h
Normal file
42
AerofoilX/GpFileSystem_X.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpFileSystem.h"
|
||||
|
||||
#include "GpCoreDefs.h"
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
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 SetDelayCallback(DelayCallback_t delayCallback) override;
|
||||
|
||||
static GpFileSystem_X *GetInstance();
|
||||
|
||||
private:
|
||||
bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution);
|
||||
|
||||
DelayCallback_t m_delayCallback;
|
||||
|
||||
std::string m_prefsPath;
|
||||
std::string m_basePath;
|
||||
|
||||
static GpFileSystem_X ms_instance;
|
||||
};
|
||||
127
AerofoilX/GpLogDriver_X.cpp
Normal file
127
AerofoilX/GpLogDriver_X.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#include "GpLogDriver_X.h"
|
||||
#include "GpFileSystem_X.h"
|
||||
|
||||
#include "GpApplicationName.h"
|
||||
#include "GpIOStream.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <cstring>
|
||||
|
||||
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<char*>(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;
|
||||
28
AerofoilX/GpLogDriver_X.h
Normal file
28
AerofoilX/GpLogDriver_X.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpLogDriver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
};
|
||||
77
AerofoilX/GpMain_SDL_X.cpp
Normal file
77
AerofoilX/GpMain_SDL_X.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "SDL.h"
|
||||
#include "SDL_main.h"
|
||||
|
||||
#include "GpMain.h"
|
||||
#include "GpAudioDriverFactory.h"
|
||||
#include "GpDisplayDriverFactory.h"
|
||||
#include "GpGlobalConfig.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 <string>
|
||||
|
||||
GpXGlobals g_gpXGlobals;
|
||||
|
||||
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<GpDriverIDs::kFileSystem>(GpFileSystem_X::GetInstance());
|
||||
drivers->SetDriver<GpDriverIDs::kSystemServices>(GpSystemServices_X::GetInstance());
|
||||
drivers->SetDriver<GpDriverIDs::kLog>(GpLogDriver_X::GetInstance());
|
||||
|
||||
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_SDL_GL2;
|
||||
|
||||
g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_SDL2;
|
||||
|
||||
g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_None;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
137
AerofoilX/GpSystemServices_X.cpp
Normal file
137
AerofoilX/GpSystemServices_X.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#include "GpSystemServices_X.h"
|
||||
|
||||
#include "IGpClipboardContents.h"
|
||||
#include "IGpThreadEvent.h"
|
||||
#include "SDL2/SDL.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
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<const GpSystemServices_X_ThreadStartParams*>(lpThreadParameter);
|
||||
|
||||
GpSystemServices_X::ThreadFunc_t threadFunc = threadParams->m_threadFunc;
|
||||
void *threadContext = threadParams->m_threadContext;
|
||||
IGpThreadEvent *threadStartEvent = threadParams->m_threadStartEvent;
|
||||
|
||||
threadStartEvent->Signal();
|
||||
|
||||
return reinterpret_cast<void*>(static_cast<intptr_t>(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;
|
||||
35
AerofoilX/GpSystemServices_X.h
Normal file
35
AerofoilX/GpSystemServices_X.h
Normal file
@@ -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;
|
||||
};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
@@ -14,8 +14,6 @@
|
||||
"DITL/2008.json" : "ApplicationResourcePatches/DITL/2008.json",
|
||||
"PICT/1300.bmp" : "ApplicationResourcePatches/PICT/1300.bmp",
|
||||
"PICT/1301.bmp" : "ApplicationResourcePatches/PICT/1301.bmp",
|
||||
"PICT/1302.bmp" : "ApplicationResourcePatches/PICT/1302.bmp",
|
||||
"PICT/1303.bmp" : "ApplicationResourcePatches/PICT/1303.bmp",
|
||||
"PICT/1971.bmp" : "ApplicationResourcePatches/PICT/1971.bmp",
|
||||
"PICT/1972.bmp" : "ApplicationResourcePatches/PICT/1972.bmp",
|
||||
"PICT/1973.bmp" : "ApplicationResourcePatches/PICT/1973.bmp",
|
||||
|
||||
265
CMakeLists.txt
Normal file
265
CMakeLists.txt
Normal file
@@ -0,0 +1,265 @@
|
||||
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(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
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Common>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpCommon>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/PortabilityLayer>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/zlib>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/MacRomanConversion>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/stb>
|
||||
)
|
||||
|
||||
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
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Common>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpCommon>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/PortabilityLayer>
|
||||
)
|
||||
|
||||
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
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Common>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpCommon>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/PortabilityLayer>
|
||||
)
|
||||
|
||||
target_link_libraries(GpApp PortabilityLayer)
|
||||
|
||||
if(CMAKE_HOST_UNIX)
|
||||
add_executable(AerofoilX
|
||||
AerofoilPortable/GpSystemServices_POSIX.cpp
|
||||
AerofoilPortable/GpThreadEvent_Cpp11.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
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Common>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpCommon>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpShell>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/AerofoilSDL>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/AerofoilPortable>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/PortabilityLayer>
|
||||
${SDL2_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(AerofoilX ${SDL2_LIBRARIES} GpApp GpShell)
|
||||
endif()
|
||||
|
||||
|
||||
install (TARGETS AerofoilX)
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if __cplusplus >= 199711L
|
||||
#define GP_IS_CPP11 1
|
||||
@@ -52,3 +53,19 @@ static const size_t GP_SYSTEM_MEMORY_ALIGNMENT = 16;
|
||||
#if !defined(GP_DEBUG_CONFIG)
|
||||
#error "GP_DEBUG_CONFIG was not set"
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define GP_ASYNCIFY_PARANOID 1
|
||||
#else
|
||||
#define GP_ASYNCIFY_PARANOID 0
|
||||
#endif
|
||||
|
||||
#if GP_ASYNCIFY_PARANOID
|
||||
#define GP_ASYNCIFY_PARANOID_VIRTUAL
|
||||
#define GP_ASYNCIFY_PARANOID_PURE
|
||||
#define GP_ASYNCIFY_PARANOID_OVERRIDE
|
||||
#else
|
||||
#define GP_ASYNCIFY_PARANOID_VIRTUAL virtual
|
||||
#define GP_ASYNCIFY_PARANOID_PURE = 0
|
||||
#define GP_ASYNCIFY_PARANOID_OVERRIDE override
|
||||
#endif
|
||||
|
||||
@@ -4,12 +4,23 @@ mkdir Packaged
|
||||
mkdir Packaged\Houses
|
||||
|
||||
x64\Release\MiniRez.exe "GliderProData\Glider PRO.r" Packaged\ApplicationResources.gpr
|
||||
|
||||
x64\Release\gpr2gpa.exe "Packaged\ApplicationResources.gpr" "DefaultTimestamp.timestamp" "Packaged\ApplicationResources.gpa" "ApplicationResourcePatches\manifest.json"
|
||||
x64\Release\FTagData.exe "DefaultTimestamp.timestamp" "Packaged\ApplicationResources.gpf" data ozm5 0 0 locked
|
||||
|
||||
x64\Release\MergeGPF.exe "Packaged\ApplicationResources.gpf"
|
||||
|
||||
x64\Release\GenerateFonts.exe
|
||||
|
||||
x64\Release\MiniRez.exe "Empty.r" Packaged\Fonts.gpr
|
||||
x64\Release\gpr2gpa.exe "Packaged\Fonts.gpr" "DefaultTimestamp.timestamp" "Packaged\Fonts.gpa" "Packaged\FontCacheManifest.json"
|
||||
x64\Release\FTagData.exe "DefaultTimestamp.timestamp" "Packaged\Fonts.gpf" data ozm5 0 0 locked
|
||||
x64\Release\MergeGPF.exe "Packaged\Fonts.gpf"
|
||||
|
||||
del /Q Packaged\CachedFont*.bin
|
||||
del Packaged\FontCacheCatalog.bin
|
||||
del Packaged\FontCacheManifest.json
|
||||
del Packaged\Fonts.gpr
|
||||
del Packaged\Fonts.gpa
|
||||
|
||||
x64\Release\ConvertColorCursors.exe
|
||||
|
||||
attrib -R Packaged\ApplicationResources.gpf
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#include "CFileStream.h"
|
||||
#include "CombinedTimestamp.h"
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
#include "WindowsUnicodeToolShim.h"
|
||||
|
||||
int toolMain(int argc, const char **argv)
|
||||
{
|
||||
if (argc < 7)
|
||||
{
|
||||
@@ -28,12 +30,11 @@ int main(int argc, const char **argv)
|
||||
return -3;
|
||||
}
|
||||
|
||||
FILE *tsF = nullptr;
|
||||
errno_t ferr = fopen_s(&tsF, timestampPath.c_str(), "rb");
|
||||
FILE *tsF = fopen_utf8(timestampPath.c_str(), "rb");
|
||||
int64_t timestamp = 0;
|
||||
PortabilityLayer::CombinedTimestamp ts;
|
||||
|
||||
if (!ferr)
|
||||
if (tsF)
|
||||
{
|
||||
if (fread(&ts, 1, sizeof(ts), tsF) != sizeof(ts))
|
||||
{
|
||||
@@ -77,9 +78,8 @@ int main(int argc, const char **argv)
|
||||
PortabilityLayer::MacFilePropertiesSerialized mps;
|
||||
mps.Serialize(mfp);
|
||||
|
||||
FILE *file = nullptr;
|
||||
errno_t err = fopen_s(&file, outPath.c_str(), "wb");
|
||||
if (!err)
|
||||
FILE *file = fopen_utf8(outPath.c_str(), "wb");
|
||||
if (file)
|
||||
{
|
||||
PortabilityLayer::CFileStream stream(file);
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\Debug.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
@@ -48,6 +49,7 @@
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\Release.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
@@ -77,6 +79,9 @@
|
||||
<ProjectReference Include="..\PortabilityLayer\PortabilityLayer.vcxproj">
|
||||
<Project>{6ec62b0f-9353-40a4-a510-3788f1368b33}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WindowsUnicodeToolShim\WindowsUnicodeToolShim.vcxproj">
|
||||
<Project>{15009625-1120-405e-8bba-69a16cd6713d}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="FTagData.cpp" />
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := FreeType
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH)/freetype/include
|
||||
|
||||
# Add your application source files here...
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LOCAL_PATH)/freetype/src/base/ftbase.c \
|
||||
$(LOCAL_PATH)/freetype/src/base/ftbitmap.c \
|
||||
$(LOCAL_PATH)/freetype/src/base/ftdebug.c \
|
||||
$(LOCAL_PATH)/freetype/src/base/ftinit.c \
|
||||
$(LOCAL_PATH)/freetype/src/base/ftsystem.c \
|
||||
$(LOCAL_PATH)/freetype/src/winfonts/winfnt.c \
|
||||
$(LOCAL_PATH)/freetype/src/autofit/autofit.c \
|
||||
$(LOCAL_PATH)/freetype/src/bdf/bdf.c \
|
||||
$(LOCAL_PATH)/freetype/src/cff/cff.c \
|
||||
$(LOCAL_PATH)/freetype/src/gzip/ftgzip.c \
|
||||
$(LOCAL_PATH)/freetype/src/lzw/ftlzw.c \
|
||||
$(LOCAL_PATH)/freetype/src/pcf/pcf.c \
|
||||
$(LOCAL_PATH)/freetype/src/pfr/pfr.c \
|
||||
$(LOCAL_PATH)/freetype/src/psaux/psaux.c \
|
||||
$(LOCAL_PATH)/freetype/src/pshinter/pshinter.c \
|
||||
$(LOCAL_PATH)/freetype/src/psnames/psnames.c \
|
||||
$(LOCAL_PATH)/freetype/src/raster/raster.c \
|
||||
$(LOCAL_PATH)/freetype/src/sfnt/sfnt.c \
|
||||
$(LOCAL_PATH)/freetype/src/smooth/smooth.c \
|
||||
$(LOCAL_PATH)/freetype/src/truetype/truetype.c \
|
||||
$(LOCAL_PATH)/freetype/src/type1/type1.c \
|
||||
$(LOCAL_PATH)/freetype/src/cid/type1cid.c \
|
||||
$(LOCAL_PATH)/freetype/src/type42/type42.c
|
||||
|
||||
LOCAL_CFLAGS := -DFT2_BUILD_LIBRARY
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
313
GenerateFonts/GenerateFonts.cpp
Normal file
313
GenerateFonts/GenerateFonts.cpp
Normal file
@@ -0,0 +1,313 @@
|
||||
#include "FontFamily.h"
|
||||
#include "FontManager.h"
|
||||
#include "FontRenderer.h"
|
||||
#include "IGpFont.h"
|
||||
#include "IGpFontHandler.h"
|
||||
#include "GpAppInterface.h"
|
||||
#include "GpDriverIndex.h"
|
||||
#include "GpFontHandlerProperties.h"
|
||||
#include "GpFileSystem_Win32.h"
|
||||
#include "GpSystemServices_Win32.h"
|
||||
#include "CFileStream.h"
|
||||
|
||||
#include "PLDrivers.h"
|
||||
#include "RenderedFont.h"
|
||||
#include "RenderedFontCatalog.h"
|
||||
|
||||
#include "WindowsUnicodeToolShim.h"
|
||||
|
||||
extern "C" __declspec(dllimport) IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties);
|
||||
|
||||
class MemBufferStream final : public GpIOStream
|
||||
{
|
||||
public:
|
||||
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;
|
||||
|
||||
const uint8_t *GetBytes() const;
|
||||
|
||||
private:
|
||||
size_t m_writeOffset;
|
||||
std::vector<uint8_t> m_buffer;
|
||||
};
|
||||
|
||||
size_t MemBufferStream::Read(void *bytesOut, size_t size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t MemBufferStream::Write(const void *bytes, size_t size)
|
||||
{
|
||||
const uint8_t *bytesUInt8 = static_cast<const uint8_t*>(bytes);
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
if (m_writeOffset == m_buffer.size())
|
||||
m_buffer.push_back(bytesUInt8[i]);
|
||||
else
|
||||
m_buffer[m_writeOffset] = bytesUInt8[i];
|
||||
|
||||
m_writeOffset++;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
bool MemBufferStream::IsSeekable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemBufferStream::IsReadOnly() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MemBufferStream::IsWriteOnly() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemBufferStream::SeekStart(GpUFilePos_t loc)
|
||||
{
|
||||
m_writeOffset = static_cast<size_t>(loc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemBufferStream::SeekCurrent(GpFilePos_t loc)
|
||||
{
|
||||
m_writeOffset = static_cast<size_t>(static_cast<GpFilePos_t>(m_writeOffset) + loc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemBufferStream::SeekEnd(GpUFilePos_t loc)
|
||||
{
|
||||
m_writeOffset = this->Size() - loc;
|
||||
return true;
|
||||
}
|
||||
|
||||
GpUFilePos_t MemBufferStream::Size() const
|
||||
{
|
||||
return m_buffer.size();
|
||||
}
|
||||
|
||||
GpUFilePos_t MemBufferStream::Tell() const
|
||||
{
|
||||
return m_writeOffset;
|
||||
}
|
||||
|
||||
void MemBufferStream::Close()
|
||||
{
|
||||
}
|
||||
|
||||
void MemBufferStream::Flush()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const uint8_t *MemBufferStream::GetBytes() const
|
||||
{
|
||||
return &m_buffer[0];
|
||||
}
|
||||
|
||||
struct KnownFontSpec
|
||||
{
|
||||
public:
|
||||
KnownFontSpec();
|
||||
KnownFontSpec(const char *path, int size, bool aa, PortabilityLayer::FontHacks hacks);
|
||||
|
||||
bool operator==(const KnownFontSpec &other) const;
|
||||
bool operator!=(const KnownFontSpec &other) const;
|
||||
|
||||
private:
|
||||
std::string m_path;
|
||||
int m_size;
|
||||
bool m_aa;
|
||||
PortabilityLayer::FontHacks m_hacks;
|
||||
};
|
||||
|
||||
|
||||
KnownFontSpec::KnownFontSpec()
|
||||
: m_size(0)
|
||||
, m_aa(false)
|
||||
, m_hacks(PortabilityLayer::FontHacks_None)
|
||||
{
|
||||
}
|
||||
|
||||
KnownFontSpec::KnownFontSpec(const char *path, int size, bool aa, PortabilityLayer::FontHacks hacks)
|
||||
: m_path(path)
|
||||
, m_size(size)
|
||||
, m_aa(aa)
|
||||
, m_hacks(hacks)
|
||||
{
|
||||
}
|
||||
|
||||
bool KnownFontSpec::operator==(const KnownFontSpec &other) const
|
||||
{
|
||||
return !((*this) != other);
|
||||
}
|
||||
|
||||
bool KnownFontSpec::operator!=(const KnownFontSpec &other) const
|
||||
{
|
||||
return m_path != other.m_path ||
|
||||
m_size != other.m_size ||
|
||||
m_aa != other.m_aa ||
|
||||
m_hacks != other.m_hacks;
|
||||
}
|
||||
|
||||
int toolMain(int argc, const char **argv)
|
||||
{
|
||||
GpFontHandlerProperties fhProperties;
|
||||
fhProperties.m_type = EGpFontHandlerType_FreeType2;
|
||||
|
||||
IGpFontHandler *ft2Handler = GpDriver_CreateFontHandler_FreeType2(fhProperties);
|
||||
|
||||
PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance();
|
||||
PortabilityLayer::FontRenderer *fontRenderer = PortabilityLayer::FontRenderer::GetInstance();
|
||||
fontManager->Init();
|
||||
|
||||
std::vector<std::string> paths;
|
||||
std::vector<PortabilityLayer::RenderedFontCatalogRFontEntry> catalog;
|
||||
std::vector<KnownFontSpec> fontSpecs;
|
||||
|
||||
FILE *manifestF = fopen_utf8("Packaged/FontCacheManifest.json", "wb");
|
||||
|
||||
fprintf(manifestF, "{\n");
|
||||
fprintf(manifestF, "\t\"add\" :\n");
|
||||
fprintf(manifestF, "\t{\n");
|
||||
fprintf(manifestF, "\t\t\"RFCT/1000.bin\" : \"Packaged/FontCacheCatalog.bin\"");
|
||||
|
||||
int numFontsEmitted = 0;
|
||||
for (int presetIndex = 0; presetIndex < PortabilityLayer::FontPresets::kCount; presetIndex++)
|
||||
{
|
||||
int size = 0;
|
||||
int flags = 0;
|
||||
bool aa = false;
|
||||
PortabilityLayer::FontFamilyID_t fontFamilyID;
|
||||
|
||||
fontManager->GetFontPreset(static_cast<PortabilityLayer::FontPreset_t>(presetIndex), &fontFamilyID, &size, &flags, &aa);
|
||||
PortabilityLayer::FontFamily *fontFamily = fontManager->GetFont(fontFamilyID);
|
||||
|
||||
int variation = fontFamily->GetVariationForFlags(flags);
|
||||
|
||||
PortabilityLayer::FontHacks hacks;
|
||||
const char *path = nullptr;
|
||||
fontFamily->GetFontSpec(variation, hacks, path);
|
||||
|
||||
KnownFontSpec spec(path, size, aa, hacks);
|
||||
|
||||
if (std::find(fontSpecs.begin(), fontSpecs.end(), spec) != fontSpecs.end())
|
||||
continue;
|
||||
|
||||
fontSpecs.push_back(spec);
|
||||
|
||||
std::string resPath = std::string("Resources/") + path;
|
||||
FILE *fontFile = fopen_utf8(resPath.c_str(), "rb");
|
||||
|
||||
if (fontFile)
|
||||
{
|
||||
PortabilityLayer::CFileStream stream(fontFile);
|
||||
|
||||
IGpFont *font = ft2Handler->LoadFont(&stream);
|
||||
if (!ft2Handler->KeepStreamOpen())
|
||||
stream.Close();
|
||||
|
||||
PortabilityLayer::RenderedFont *rfont = fontRenderer->RenderFont(font, size, aa, hacks);
|
||||
|
||||
|
||||
{
|
||||
char fontPath[1024];
|
||||
sprintf(fontPath, "Packaged/CachedFont%i.bin", numFontsEmitted);
|
||||
|
||||
FILE *cachedFontF = fopen_utf8(fontPath, "wb");
|
||||
PortabilityLayer::CFileStream cacheStream(cachedFontF);
|
||||
|
||||
fontRenderer->SaveCache(rfont, &cacheStream);
|
||||
cacheStream.Close();
|
||||
|
||||
fprintf(manifestF, ",\n\t\t\"RFNT/%i.bin\" : \"%s\"", 1000 + numFontsEmitted, fontPath);
|
||||
}
|
||||
|
||||
rfont->Destroy();
|
||||
|
||||
font->Destroy();
|
||||
|
||||
PortabilityLayer::RenderedFontCatalogRFontEntry catEntry;
|
||||
catEntry.m_fontSize = static_cast<uint8_t>(size);
|
||||
catEntry.m_hacks = static_cast<uint8_t>(hacks);
|
||||
catEntry.m_isAA = aa ? 1 : 0;
|
||||
catEntry.m_pathIndex = 0;
|
||||
|
||||
bool foundPath = false;
|
||||
for (size_t i = 0; i < paths.size(); i++)
|
||||
{
|
||||
if (paths[i] == path)
|
||||
{
|
||||
catEntry.m_pathIndex = static_cast<uint8_t>(i);
|
||||
foundPath = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundPath)
|
||||
{
|
||||
catEntry.m_pathIndex = static_cast<uint8_t>(paths.size());
|
||||
paths.push_back(std::string(path));
|
||||
}
|
||||
|
||||
catalog.push_back(catEntry);
|
||||
|
||||
numFontsEmitted++;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(manifestF, "\n\t},\n");
|
||||
fprintf(manifestF, "\t\"delete\" :\n");
|
||||
fprintf(manifestF, "\t[\n");
|
||||
fprintf(manifestF, "\t]\n");
|
||||
fprintf(manifestF, "}\n");
|
||||
|
||||
PortabilityLayer::RenderedFontCatalogHeader catHeader;
|
||||
|
||||
FILE *catF = fopen_utf8("Packaged/FontCacheCatalog.bin", "wb");
|
||||
|
||||
catHeader.m_version = PortabilityLayer::RenderedFontCatalogHeader::kVersion;
|
||||
catHeader.m_pathsOffset = static_cast<uint32_t>(sizeof(PortabilityLayer::RenderedFontCatalogHeader) + paths.size() * sizeof(PortabilityLayer::RenderedFontCatalogPathEntry) + numFontsEmitted * sizeof(PortabilityLayer::RenderedFontCatalogRFontEntry));
|
||||
catHeader.m_numPaths = static_cast<uint16_t>(paths.size());
|
||||
catHeader.m_numRFonts = static_cast<uint16_t>(numFontsEmitted);
|
||||
|
||||
fwrite(&catHeader, sizeof(catHeader), 1, catF);
|
||||
|
||||
PortabilityLayer::RenderedFontCatalogPathEntry pathEntry;
|
||||
pathEntry.m_pathOffset = 0;
|
||||
pathEntry.m_pathSize = 0;
|
||||
for (size_t i = 0; i < paths.size(); i++)
|
||||
{
|
||||
pathEntry.m_pathOffset = static_cast<uint16_t>(pathEntry.m_pathOffset) + pathEntry.m_pathSize;
|
||||
pathEntry.m_pathSize = static_cast<uint16_t>(paths[i].size());
|
||||
|
||||
fwrite(&pathEntry, sizeof(pathEntry), 1, catF);
|
||||
}
|
||||
|
||||
fwrite(&catalog[0], sizeof(PortabilityLayer::RenderedFontCatalogRFontEntry), catalog.size(), catF);
|
||||
|
||||
for (size_t i = 0; i < paths.size(); i++)
|
||||
{
|
||||
const std::string &str = paths[i];
|
||||
fwrite(&str[0], str.size(), 1, catF);
|
||||
}
|
||||
|
||||
fclose(catF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
101
GenerateFonts/GenerateFonts.vcxproj
Normal file
101
GenerateFonts/GenerateFonts.vcxproj
Normal file
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{3B7FD18D-7A50-4DF5-AC25-543E539BFACE}</ProjectGuid>
|
||||
<RootNamespace>GenerateFonts</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\AerofoilWin.props" />
|
||||
<Import Project="..\Debug.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\AerofoilWin.props" />
|
||||
<Import Project="..\Release.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GpFontHandler_FreeType2\GpFontHandler_FreeType2.vcxproj">
|
||||
<Project>{4b564030-8985-4975-91e1-e1b2c16ae2a1}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PortabilityLayer\PortabilityLayer.vcxproj">
|
||||
<Project>{6ec62b0f-9353-40a4-a510-3788f1368b33}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WindowsUnicodeToolShim\WindowsUnicodeToolShim.vcxproj">
|
||||
<Project>{15009625-1120-405e-8bba-69a16cd6713d}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GenerateFonts.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
22
GenerateFonts/GenerateFonts.vcxproj.filters
Normal file
22
GenerateFonts/GenerateFonts.vcxproj.filters
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GenerateFonts.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -136,7 +136,7 @@ void DoAbout (void)
|
||||
|
||||
do // Loop until user wants to exit
|
||||
{
|
||||
hit = aboutDialog->ExecuteModal(nullptr, AboutFilter);
|
||||
hit = aboutDialog->ExecuteModal(nullptr, PL_FILTER_FUNC(AboutFilter));
|
||||
}
|
||||
while (hit != kOkayButton);
|
||||
|
||||
@@ -218,7 +218,7 @@ void DoLicenseReader(int resID)
|
||||
|
||||
do
|
||||
{
|
||||
hit = dialog->ExecuteModal(nullptr, LicenseReaderFilter);
|
||||
hit = dialog->ExecuteModal(nullptr, PL_FILTER_FUNC(LicenseReaderFilter));
|
||||
} while (hit != kOkayButton);
|
||||
|
||||
dialog->Destroy();
|
||||
@@ -265,7 +265,7 @@ void DoAboutOpenSource(void)
|
||||
|
||||
do
|
||||
{
|
||||
hit = dialog->ExecuteModal(nullptr, AboutFrameworkFilter);
|
||||
hit = dialog->ExecuteModal(nullptr, PL_FILTER_FUNC(AboutFrameworkFilter));
|
||||
|
||||
switch (hit)
|
||||
{
|
||||
@@ -314,8 +314,8 @@ void DoAboutFramework (void)
|
||||
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(windowRect, PortabilityLayer::WindowStyleFlags::kAlert, true, 0, 0, PSTR(""));
|
||||
|
||||
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
|
||||
PortabilityLayer::RenderedFont *font = GetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *fontLight = GetApplicationFont(8, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *font = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
|
||||
PortabilityLayer::RenderedFont *fontLight = GetFont(PortabilityLayer::FontPresets::kApplication8);
|
||||
|
||||
int16_t verticalPoint = 16 + font->GetMetrics().m_ascent;
|
||||
int16_t horizontalOffset = 16;
|
||||
@@ -359,7 +359,7 @@ void DoAboutFramework (void)
|
||||
|
||||
do
|
||||
{
|
||||
hit = dialog->ExecuteModal(nullptr, AboutFrameworkFilter);
|
||||
hit = dialog->ExecuteModal(nullptr, PL_FILTER_FUNC(AboutFrameworkFilter));
|
||||
|
||||
if (hit == kAboutOpenSourceButton)
|
||||
DoAboutOpenSource();
|
||||
@@ -578,7 +578,7 @@ static int16_t AboutFrameworkFilter(void *context, Dialog *dialog, const TimeTag
|
||||
|
||||
void DrawLicenseReader(Window *window)
|
||||
{
|
||||
PortabilityLayer::RenderedFont *rfont = GetMonospaceFont(10, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *rfont = GetFont(PortabilityLayer::FontPresets::kMono10);
|
||||
if (!rfont)
|
||||
return;
|
||||
|
||||
@@ -766,3 +766,6 @@ static int16_t LicenseReaderFilter(void *context, Dialog *dialog, const TimeTagg
|
||||
return hit;
|
||||
}
|
||||
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(AboutFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(LicenseReaderFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(AboutFrameworkFilter)
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
#include "MemoryManager.h"
|
||||
#include "ResourceManager.h"
|
||||
|
||||
#include "PLBigEndian.h"
|
||||
#include "PLDrivers.h"
|
||||
#include "PLResources.h"
|
||||
#include "PLBigEndian.h"
|
||||
#include "PLSysCalls.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -375,6 +376,8 @@ void DecrementCursor (void)
|
||||
|
||||
void SpinCursor (short incrementIndex)
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
|
||||
UInt32 dummyLong;
|
||||
short i;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Utilities.h"
|
||||
#include "WindowDef.h"
|
||||
#include "WindowManager.h"
|
||||
#include "PLSysCalls.h"
|
||||
|
||||
|
||||
#define kBannerPageTopPICT 1993
|
||||
@@ -118,7 +119,7 @@ void DrawBannerMessage (Point topLeft)
|
||||
|
||||
PasStringCopy((*thisHouse)->banner, bannerStr);
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont = GetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
|
||||
|
||||
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
|
||||
|
||||
@@ -179,11 +180,13 @@ void BringUpBanner (void)
|
||||
(BitMap *)*GetGWorldPixMap(workSrcMap),
|
||||
&wholePage, &wholePage, srcCopy);
|
||||
|
||||
|
||||
if (demoGoing)
|
||||
WaitForInputEvent(4);
|
||||
else
|
||||
WaitForInputEvent(15);
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
if (demoGoing)
|
||||
WaitForInputEvent(4);
|
||||
else
|
||||
WaitForInputEvent(15);
|
||||
}
|
||||
|
||||
// if (quickerTransitions)
|
||||
// DissBitsChunky(&justRoomsRect);
|
||||
@@ -221,7 +224,7 @@ void DisplayStarsRemaining(void)
|
||||
|
||||
DrawSurface *surface = starsWindow->GetDrawSurface();
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont = GetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
|
||||
|
||||
NumToString((long)numStarsRemaining, theStr);
|
||||
|
||||
@@ -237,8 +240,11 @@ void DisplayStarsRemaining(void)
|
||||
if (doZooms)
|
||||
wm->FlickerWindowIn(starsWindow, 32);
|
||||
|
||||
DelayTicks(60);
|
||||
WaitForInputEvent(30);
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
DelayTicks(60);
|
||||
WaitForInputEvent(30);
|
||||
}
|
||||
|
||||
if (doZooms)
|
||||
wm->FlickerWindowOut(starsWindow, 32);
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
|
||||
#include "Externs.h"
|
||||
#include "PLPalettes.h"
|
||||
#include "PLPasStr.h"
|
||||
#include "QDStandardPalette.h"
|
||||
#include "ResolveCachingColor.h"
|
||||
|
||||
@@ -75,7 +75,7 @@ void UpdateCoordWindow (void)
|
||||
PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White();
|
||||
PortabilityLayer::ResolveCachingColor blueColor = StdColors::Blue();
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont = GetApplicationFont(9, 0, true);
|
||||
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9);
|
||||
|
||||
DrawSurface *surface = coordWindow->GetDrawSurface();
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "PLNumberFormatting.h"
|
||||
#include "PLPasStr.h"
|
||||
#include "PLStandardColors.h"
|
||||
#include "PLSysCalls.h"
|
||||
#include "PLWidgets.h"
|
||||
#include "QDStandardPalette.h"
|
||||
#include "DialogUtils.h"
|
||||
@@ -341,6 +342,8 @@ void ZoomOutAlertRect (short alertID)
|
||||
|
||||
void FlashDialogButton (Dialog *theDialog, short itemNumber)
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
|
||||
ControlHandle itemHandle;
|
||||
UInt32 dummyLong;
|
||||
|
||||
@@ -568,7 +571,7 @@ void DrawDialogUserText (Dialog *dial, short item, StringPtr text, Boolean inver
|
||||
|
||||
DrawSurface *surface = dial->GetWindow()->GetDrawSurface();
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont = GetApplicationFont(9, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9);
|
||||
|
||||
PasStringCopy(text, stringCopy);
|
||||
|
||||
@@ -619,7 +622,7 @@ void DrawDialogUserText2 (Dialog *dial, short item, StringPtr text)
|
||||
Str255 stringCopy;
|
||||
|
||||
DrawSurface *surface = dial->GetWindow()->GetDrawSurface();
|
||||
PortabilityLayer::RenderedFont *appFont = GetApplicationFont(9, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9);
|
||||
|
||||
PasStringCopy(text, stringCopy);
|
||||
const Rect iRect = dial->GetItems()[item - 1].GetWidget()->GetRect();
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "PLPasStr.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#define kSwitchDepthAlert 130
|
||||
#define kSetMemoryAlert 180
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Environ.h
|
||||
//----------------------------------------------------------------------------
|
||||
//============================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PLQDraw.h"
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "Rect2i.h"
|
||||
#include "WindowManager.h"
|
||||
|
||||
#include "PLSysCalls.h"
|
||||
|
||||
void HandleMouseEvent (const GpMouseInputEvent &, uint32_t);
|
||||
void HandleKeyEvent (const KeyDownStates &keyStates, const GpKeyboardInputEvent &);
|
||||
@@ -419,7 +420,10 @@ void HandleEvent (void)
|
||||
SelectTool(kSelectTool);
|
||||
}
|
||||
|
||||
itHappened = WaitForEvent(&theEvent, sleep);
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
itHappened = WaitForEvent(&theEvent, sleep);
|
||||
}
|
||||
|
||||
if (itHappened)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "RenderedFont.h"
|
||||
#include "ResolveCachingColor.h"
|
||||
#include "Utilities.h"
|
||||
#include "PLSysCalls.h"
|
||||
|
||||
|
||||
#define kNumCountDownFrames 16
|
||||
@@ -107,7 +108,7 @@ void SetUpFinalScreen (void)
|
||||
{
|
||||
GetLineOfText(tempStr, count, subStr);
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont = GetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
|
||||
offset = ((thisMac.constrainedScreen.right - thisMac.constrainedScreen.left) -
|
||||
appFont->MeasurePStr(subStr)) / 2;
|
||||
|
||||
@@ -489,6 +490,7 @@ void DoDiedGameOver (void)
|
||||
}
|
||||
}
|
||||
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
Delay(1, nullptr);
|
||||
}
|
||||
while (TickCount() < nextLoop);
|
||||
|
||||
@@ -14,13 +14,12 @@ void gpAppInit();
|
||||
class GpAppInterfaceImpl final : public GpAppInterface
|
||||
{
|
||||
public:
|
||||
void ApplicationInit() override;
|
||||
int ApplicationMain() override;
|
||||
void ApplicationInit() GP_ASYNCIFY_PARANOID_OVERRIDE;
|
||||
int ApplicationMain() GP_ASYNCIFY_PARANOID_OVERRIDE;
|
||||
|
||||
void PL_IncrementTickCounter(uint32_t count) override;
|
||||
void PL_Render(IGpDisplayDriver *displayDriver) override;
|
||||
GpDriverCollection *PL_GetDriverCollection() override;
|
||||
void PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) override;
|
||||
bool PL_AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY) override;
|
||||
};
|
||||
|
||||
@@ -31,7 +30,11 @@ void GpAppInterfaceImpl::ApplicationInit()
|
||||
|
||||
int GpAppInterfaceImpl::ApplicationMain()
|
||||
{
|
||||
#if GP_ASYNCIFY_PARANOID
|
||||
return gpAppMain();
|
||||
#else
|
||||
return PLSysCalls::MainExitWrapper(gpAppMain);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GpAppInterfaceImpl::PL_IncrementTickCounter(uint32_t count)
|
||||
@@ -50,11 +53,6 @@ GpDriverCollection *GpAppInterfaceImpl::PL_GetDriverCollection()
|
||||
return PLDrivers::GetDriverCollection();
|
||||
}
|
||||
|
||||
void GpAppInterfaceImpl::PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context)
|
||||
{
|
||||
PortabilityLayer::InstallHostSuspendHook(hook, context);
|
||||
}
|
||||
|
||||
bool GpAppInterfaceImpl::PL_AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY)
|
||||
{
|
||||
PortabilityLayer::DisplayDeviceManager::IResolutionChangeHandler *handler = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetResolutionChangeHandler();
|
||||
@@ -75,3 +73,15 @@ GP_APP_DLL_EXPORT_API GpAppInterface *GpAppInterface_Get()
|
||||
{
|
||||
return &gs_application;
|
||||
}
|
||||
|
||||
#if GP_ASYNCIFY_PARANOID
|
||||
void GpAppInterface::ApplicationInit()
|
||||
{
|
||||
static_cast<GpAppInterfaceImpl*>(this)->ApplicationInit();
|
||||
}
|
||||
|
||||
int GpAppInterface::ApplicationMain()
|
||||
{
|
||||
return static_cast<GpAppInterfaceImpl*>(this)->ApplicationMain();
|
||||
}
|
||||
#endif
|
||||
|
||||
69
GpApp/GpApp_Combined.cpp
Normal file
69
GpApp/GpApp_Combined.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "About.cpp"
|
||||
#include "AnimCursor.cpp"
|
||||
#include "AppleEvents.cpp"
|
||||
#include "Banner.cpp"
|
||||
#include "ColorUtils.cpp"
|
||||
#include "Coordinates.cpp"
|
||||
#include "DialogUtils.cpp"
|
||||
#include "DynamicMaps.cpp"
|
||||
#include "Dynamics.cpp"
|
||||
#include "Dynamics2.cpp"
|
||||
#include "Dynamics3.cpp"
|
||||
#include "Environ.cpp"
|
||||
#include "Events.cpp"
|
||||
#include "FileError.cpp"
|
||||
#include "GameOver.cpp"
|
||||
#include "GpAppInterface.cpp"
|
||||
#include "Grease.cpp"
|
||||
#include "HighScores.cpp"
|
||||
#include "House.cpp"
|
||||
#include "HouseInfo.cpp"
|
||||
#include "HouseIO.cpp"
|
||||
#include "HouseLegal.cpp"
|
||||
#include "Input.cpp"
|
||||
#include "Interactions.cpp"
|
||||
#include "InterfaceInit.cpp"
|
||||
#include "Link.cpp"
|
||||
#include "Main.cpp"
|
||||
#include "MainMenuUI.cpp"
|
||||
#include "MainWindow.cpp"
|
||||
#include "Map.cpp"
|
||||
#include "Marquee.cpp"
|
||||
#include "Menu.cpp"
|
||||
#include "Modes.cpp"
|
||||
#include "Music.cpp"
|
||||
#include "ObjectAdd.cpp"
|
||||
#include "ObjectDraw.cpp"
|
||||
#include "ObjectDraw2.cpp"
|
||||
#include "ObjectDrawAll.cpp"
|
||||
#include "ObjectEdit.cpp"
|
||||
#include "ObjectInfo.cpp"
|
||||
#include "ObjectRects.cpp"
|
||||
#include "Objects.cpp"
|
||||
#include "Play.cpp"
|
||||
#include "Player.cpp"
|
||||
#include "Prefs.cpp"
|
||||
#include "RectUtils.cpp"
|
||||
#include "Render.cpp"
|
||||
#include "Room.cpp"
|
||||
#include "RoomGraphics.cpp"
|
||||
#include "RoomInfo.cpp"
|
||||
#include "RubberBands.cpp"
|
||||
#include "SavedGames.cpp"
|
||||
#include "Scoreboard.cpp"
|
||||
#include "Scrap.cpp"
|
||||
#include "SelectHouse.cpp"
|
||||
#include "Settings.cpp"
|
||||
#include "Sound.cpp"
|
||||
#include "SoundSync_Cpp11.cpp"
|
||||
#include "SourceExport.cpp"
|
||||
#include "StringUtils.cpp"
|
||||
#include "StructuresInit.cpp"
|
||||
#include "StructuresInit2.cpp"
|
||||
#include "Tools.cpp"
|
||||
#include "Transit.cpp"
|
||||
#include "Transitions.cpp"
|
||||
#include "Triggers.cpp"
|
||||
#include "Trip.cpp"
|
||||
#include "Utilities.cpp"
|
||||
#include "WindowUtils.cpp"
|
||||
@@ -96,8 +96,12 @@ void DoHighScores (void)
|
||||
// DissBits(&workSrcRect);
|
||||
|
||||
InitCursor();
|
||||
DelayTicks(60);
|
||||
WaitForInputEvent(30);
|
||||
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
DelayTicks(60);
|
||||
WaitForInputEvent(30);
|
||||
}
|
||||
|
||||
RedrawSplashScreen();
|
||||
}
|
||||
@@ -145,7 +149,7 @@ void DrawHighScores (DrawSurface *surface)
|
||||
DisposeGWorld(tempMap);
|
||||
DisposeGWorld(tempMask);
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont14 = GetApplicationFont(14, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *appFont14 = GetFont(PortabilityLayer::FontPresets::kApplication14Bold);
|
||||
|
||||
PasStringCopy(PSTR("\xa5 "), tempStr);
|
||||
PasStringConcat(tempStr, thisHouseName);
|
||||
@@ -157,7 +161,7 @@ void DrawHighScores (DrawSurface *surface)
|
||||
const Point scoreTextPoint = Point::Create(scoreLeft + ((kScoreWide - appFont14->MeasurePStr(tempStr)) / 2), dropIt - 65);
|
||||
surface->DrawString(scoreTextPoint, tempStr, cyanColor, appFont14);
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont12 = GetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *appFont12 = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
|
||||
|
||||
thisHousePtr = *thisHouse;
|
||||
// message for score #1
|
||||
@@ -264,7 +268,7 @@ void DrawHighScores (DrawSurface *surface)
|
||||
}
|
||||
}
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont9 = GetApplicationFont(9, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *appFont9 = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
|
||||
|
||||
const Point textPos = Point::Create(scoreLeft + 80, dropIt - 1 + (10 * kScoreSpacing));
|
||||
GetLocalizedString(8, tempStr);
|
||||
@@ -553,7 +557,7 @@ void GetHighScoreName (short place)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = theDial->ExecuteModal(nullptr, NameFilter);
|
||||
item = theDial->ExecuteModal(nullptr, PL_FILTER_FUNC(NameFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -666,7 +670,7 @@ void GetHighScoreBanner (void)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = theDial->ExecuteModal(nullptr, BannerFilter);
|
||||
item = theDial->ExecuteModal(nullptr, PL_FILTER_FUNC(BannerFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -789,3 +793,5 @@ Boolean ReadScoresFromDisk (void)
|
||||
return (true);
|
||||
}
|
||||
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(NameFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(BannerFilter)
|
||||
|
||||
@@ -52,24 +52,24 @@ extern Boolean houseOpen, noRoomAtAll;
|
||||
extern Boolean twoPlayerGame, wardBitSet, phoneBitSet;
|
||||
|
||||
|
||||
static void FBUI_DrawLabels(DrawSurface *surface, const Point &basePoint)
|
||||
static void FBUI_House_DrawLabels(DrawSurface *surface, const Point &basePoint)
|
||||
{
|
||||
}
|
||||
|
||||
static void FBUI_DrawFileDetails(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails)
|
||||
static void FBUI_House_DrawFileDetails(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails)
|
||||
{
|
||||
}
|
||||
|
||||
static void *FBUI_LoadFileDetails(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
|
||||
static void *FBUI_House_LoadFileDetails(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void FBUI_FreeFileDetails(void *fileDetails)
|
||||
static void FBUI_House_FreeFileDetails(void *fileDetails)
|
||||
{
|
||||
}
|
||||
|
||||
static bool FBUI_FilterFile(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
|
||||
static bool FBUI_House_FilterFile(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
|
||||
{
|
||||
PortabilityLayer::CompositeFile *cfile = PortabilityLayer::FileManager::GetInstance()->OpenCompositeFile(dirID, filename);
|
||||
|
||||
@@ -80,11 +80,11 @@ static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI()
|
||||
{
|
||||
PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api;
|
||||
|
||||
api.m_drawLabelsCallback = FBUI_DrawLabels;
|
||||
api.m_drawFileDetailsCallback = FBUI_DrawFileDetails;
|
||||
api.m_loadFileDetailsCallback = FBUI_LoadFileDetails;
|
||||
api.m_freeFileDetailsCallback = FBUI_FreeFileDetails;
|
||||
api.m_filterFileCallback = FBUI_FilterFile;
|
||||
api.m_drawLabelsCallback = FBUI_House_DrawLabels;
|
||||
api.m_drawFileDetailsCallback = FBUI_House_DrawFileDetails;
|
||||
api.m_loadFileDetailsCallback = FBUI_House_LoadFileDetails;
|
||||
api.m_freeFileDetailsCallback = FBUI_House_FreeFileDetails;
|
||||
api.m_filterFileCallback = FBUI_House_FilterFile;
|
||||
|
||||
return api;
|
||||
}
|
||||
@@ -707,7 +707,7 @@ int16_t GoToFilter(void *context, Dialog *dial, const TimeTaggedVOSEvent *evt)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = theDialog->ExecuteModal(nullptr, GoToFilter);
|
||||
item = theDialog->ExecuteModal(nullptr, PL_FILTER_FUNC(GoToFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -863,3 +863,4 @@ void ShiftWholeHouse (short howFar)
|
||||
CloseMessageWindow();
|
||||
}
|
||||
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(GoToFilter)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "FileManager.h"
|
||||
#include "GpIOStream.h"
|
||||
#include "House.h"
|
||||
#include "IGpLogDriver.h"
|
||||
#include "IGpSystemServices.h"
|
||||
#include "ObjectEdit.h"
|
||||
#include "ResourceManager.h"
|
||||
@@ -858,6 +859,11 @@ Boolean QuerySaveChanges (void)
|
||||
|
||||
void YellowAlert (short whichAlert, short identifier)
|
||||
{
|
||||
IGpLogDriver *logger = PLDrivers::GetLogDriver();
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Warning, "Yellow alert %i identifier %i", static_cast<int>(whichAlert), static_cast<int>(identifier));
|
||||
|
||||
#define kYellowAlert 1006
|
||||
Str255 errStr, errNumStr;
|
||||
short whoCares;
|
||||
|
||||
@@ -249,7 +249,7 @@ void DoHouseInfo (void)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = houseInfoDialog->ExecuteModal(nullptr, HouseFilter);
|
||||
item = houseInfoDialog->ExecuteModal(nullptr, PL_FILTER_FUNC(HouseFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -334,3 +334,4 @@ void HowToZeroScores (void)
|
||||
|
||||
#endif
|
||||
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(HouseFilter)
|
||||
|
||||
@@ -158,7 +158,7 @@ void DrawTouchScreenMenu (DrawSurface *surface, const THandle<BitmapImage> &back
|
||||
|
||||
const int numItems = sizeof(itemTexts) / sizeof(itemTexts[0]);
|
||||
|
||||
PortabilityLayer::RenderedFont *rfont = GetHandwritingFont(48, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *rfont = GetFont(PortabilityLayer::FontPresets::kHandwriting48);
|
||||
if (!rfont)
|
||||
return;
|
||||
|
||||
|
||||
648
GpApp/Main.cpp
648
GpApp/Main.cpp
@@ -15,6 +15,7 @@
|
||||
#include "FontManager.h"
|
||||
#include "GpApplicationName.h"
|
||||
#include "GpRenderedFontMetrics.h"
|
||||
#include "IGpLogDriver.h"
|
||||
#include "IGpMutex.h"
|
||||
#include "IGpThreadEvent.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
@@ -43,14 +44,6 @@
|
||||
|
||||
#include <atomic>
|
||||
|
||||
int loadScreenWindowPhase;
|
||||
int loadScreenRingStep;
|
||||
WindowPtr loadScreenWindow;
|
||||
Rect loadScreenProgressBarRect;
|
||||
int loadScreenProgress;
|
||||
DrawSurface *loadScreenRingSurface;
|
||||
|
||||
|
||||
#define kPrefsVersion 0x0039
|
||||
|
||||
|
||||
@@ -364,545 +357,6 @@ void WriteOutPrefs (void)
|
||||
modulePrefs.Dispose();
|
||||
}
|
||||
|
||||
void StepLoadScreenRing()
|
||||
{
|
||||
if (loadScreenWindow)
|
||||
{
|
||||
const int loadScreenStepGranularity = 2;
|
||||
loadScreenRingStep++;
|
||||
if (loadScreenRingStep == 24 * loadScreenStepGranularity)
|
||||
loadScreenRingStep = 0;
|
||||
|
||||
Rect ringDestRect = Rect::Create(8, 8, 24, 24);
|
||||
Rect ringSrcRect = Rect::Create(0, 0, 16, 16) + Point::Create((loadScreenRingStep / loadScreenStepGranularity) * 16, 0);
|
||||
|
||||
if (loadScreenWindowPhase == 0)
|
||||
{
|
||||
ringDestRect = Rect::Create(0, 0, 64, 64);
|
||||
|
||||
const int progression = (loadScreenRingStep / loadScreenStepGranularity);
|
||||
ringSrcRect = Rect::Create(0, 0, 64, 64) + Point::Create((progression % 6) * 64, (progression / 6) * 64);
|
||||
}
|
||||
|
||||
CopyBits(*loadScreenRingSurface->m_port.GetPixMap(), *loadScreenWindow->GetDrawSurface()->m_port.GetPixMap(), &ringSrcRect, &ringDestRect, srcCopy);
|
||||
loadScreenWindow->GetDrawSurface()->m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CreateLoadScreenWindow(int phase)
|
||||
{
|
||||
FlushResolutionChange();
|
||||
|
||||
if (loadScreenRingSurface)
|
||||
{
|
||||
DisposeGWorld(loadScreenRingSurface);
|
||||
loadScreenRingSurface = nullptr;
|
||||
}
|
||||
|
||||
if (loadScreenWindow)
|
||||
{
|
||||
PortabilityLayer::WindowManager::GetInstance()->DestroyWindow(loadScreenWindow);
|
||||
loadScreenWindow = nullptr;
|
||||
}
|
||||
|
||||
if (phase == 0)
|
||||
{
|
||||
static const int kLoadScreenHeight = 64;
|
||||
static const int kLoadScreenWidth = 64;
|
||||
static const int kLoadRingResource = 1303;
|
||||
|
||||
ForceSyncFrame();
|
||||
PLSysCalls::Sleep(1);
|
||||
|
||||
THandle<BitmapImage> loadRingImageH = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('PICT', kLoadRingResource).StaticCast<BitmapImage>();
|
||||
BitmapImage *loadRingImage = *loadRingImageH;
|
||||
|
||||
DrawSurface *loadRingSurface = nullptr;
|
||||
Rect loadRingRect = loadRingImage->GetRect();
|
||||
loadRingRect.right *= 2;
|
||||
loadRingRect.bottom *= 2;
|
||||
CreateOffScreenGWorld(&loadRingSurface, &loadRingRect);
|
||||
loadRingSurface->DrawPicture(loadRingImageH, loadRingRect, false);
|
||||
|
||||
int32_t lsX = (thisMac.fullScreen.Width() - kLoadScreenWidth) / 2;
|
||||
int32_t lsY = (thisMac.fullScreen.Height() - kLoadScreenHeight) / 2;
|
||||
|
||||
|
||||
const Rect loadScreenRect = Rect::Create(lsY, lsX, lsY + kLoadScreenHeight, lsX + kLoadScreenWidth);
|
||||
const Rect loadScreenLocalRect = Rect::Create(0, 0, loadScreenRect.Height(), loadScreenRect.Width());
|
||||
|
||||
PortabilityLayer::WindowDef def = PortabilityLayer::WindowDef::Create(loadScreenRect, PortabilityLayer::WindowStyleFlags::kBorderless, true, 0, 0, PSTR(""));
|
||||
|
||||
loadScreenWindow = PortabilityLayer::WindowManager::GetInstance()->CreateWindow(def);
|
||||
PortabilityLayer::WindowManager::GetInstance()->PutWindowBehind(loadScreenWindow, PL_GetPutInFrontWindowPtr());
|
||||
|
||||
DrawSurface *surface = loadScreenWindow->GetDrawSurface();
|
||||
PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black());
|
||||
|
||||
surface->FillRect(loadScreenLocalRect, blackColor);
|
||||
|
||||
loadScreenProgressBarRect = Rect::Create(0, 0, 0, 0);
|
||||
loadScreenProgress = 0;
|
||||
|
||||
Rect ringDestRect = Rect::Create(0, 0, 64, 64);
|
||||
Rect ringSrcRect = Rect::Create(0, 0, 64, 64);
|
||||
CopyBits(*loadRingSurface->m_port.GetPixMap(), *surface->m_port.GetPixMap(), &ringSrcRect, &ringDestRect, srcCopy);
|
||||
|
||||
loadRingImageH.Dispose();
|
||||
|
||||
loadScreenRingSurface = loadRingSurface;
|
||||
}
|
||||
else if (phase == 1)
|
||||
{
|
||||
static const int kLoadScreenHeight = 32;
|
||||
static const int kLoadRingResource = 1302;
|
||||
|
||||
int kLoadScreenWidth = 296;
|
||||
PLPasStr loadingText = PSTR("Loading...");
|
||||
|
||||
if (!isPrefsLoaded)
|
||||
{
|
||||
loadingText = PSTR("Getting some things ready...");
|
||||
kLoadScreenWidth = 440;
|
||||
}
|
||||
|
||||
ForceSyncFrame();
|
||||
PLSysCalls::Sleep(1);
|
||||
|
||||
THandle<BitmapImage> loadRingImageH = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('PICT', kLoadRingResource).StaticCast<BitmapImage>();
|
||||
BitmapImage *loadRingImage = *loadRingImageH;
|
||||
|
||||
DrawSurface *loadRingSurface = nullptr;
|
||||
Rect loadRingRect = loadRingImage->GetRect();
|
||||
CreateOffScreenGWorld(&loadRingSurface, &loadRingRect);
|
||||
loadRingSurface->DrawPicture(loadRingImageH, loadRingRect, false);
|
||||
|
||||
int32_t lsX = (thisMac.fullScreen.Width() - kLoadScreenWidth) / 2;
|
||||
int32_t lsY = (thisMac.fullScreen.Height() - kLoadScreenHeight) / 2;
|
||||
|
||||
|
||||
const Rect loadScreenRect = Rect::Create(lsY, lsX, lsY + kLoadScreenHeight, lsX + kLoadScreenWidth);
|
||||
const Rect loadScreenLocalRect = Rect::Create(0, 0, loadScreenRect.Height(), loadScreenRect.Width());
|
||||
|
||||
PortabilityLayer::WindowDef def = PortabilityLayer::WindowDef::Create(loadScreenRect, PortabilityLayer::WindowStyleFlags::kAlert, true, 0, 0, PSTR(""));
|
||||
|
||||
loadScreenWindow = PortabilityLayer::WindowManager::GetInstance()->CreateWindow(def);
|
||||
PortabilityLayer::WindowManager::GetInstance()->PutWindowBehind(loadScreenWindow, PL_GetPutInFrontWindowPtr());
|
||||
|
||||
DrawSurface *surface = loadScreenWindow->GetDrawSurface();
|
||||
PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black());
|
||||
PortabilityLayer::ResolveCachingColor whiteColor(StdColors::White());
|
||||
|
||||
surface->FillRect(loadScreenLocalRect, whiteColor);
|
||||
|
||||
PortabilityLayer::WindowManager::GetInstance()->FlickerWindowIn(loadScreenWindow, 32);
|
||||
|
||||
PortabilityLayer::RenderedFont *font = GetApplicationFont(18, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
int32_t textY = (kLoadScreenHeight + font->GetMetrics().m_ascent) / 2;
|
||||
surface->DrawString(Point::Create(4 + 16 + 8, textY), loadingText, blackColor, font);
|
||||
|
||||
static const int32_t loadBarPadding = 16;
|
||||
static const int32_t loadBarHeight = 10;
|
||||
int32_t loadBarStartX = static_cast<int32_t>(font->MeasureString(loadingText.UChars(), loadingText.Length())) + 4 + 16 + 8 + loadBarPadding;
|
||||
int32_t loadBarEndX = loadScreenLocalRect.right - loadBarPadding;
|
||||
|
||||
loadScreenProgressBarRect = Rect::Create((loadScreenLocalRect.Height() - loadBarHeight) / 2, loadBarStartX, (loadScreenLocalRect.Height() + loadBarHeight) / 2, loadBarEndX);
|
||||
|
||||
PortabilityLayer::ResolveCachingColor partialFillColor(PortabilityLayer::RGBAColor::Create(255, 255, 204, 255));
|
||||
surface->FrameRect(loadScreenProgressBarRect, blackColor);
|
||||
surface->FillRect(loadScreenProgressBarRect.Inset(1, 1), partialFillColor);
|
||||
|
||||
Rect ringDestRect = Rect::Create(8, 8, 24, 24);
|
||||
Rect ringSrcRect = Rect::Create(0, 0, 16, 16);
|
||||
CopyBits(*loadRingSurface->m_port.GetPixMap(), *surface->m_port.GetPixMap(), &ringSrcRect, &ringDestRect, srcCopy);
|
||||
|
||||
loadRingImageH.Dispose();
|
||||
|
||||
loadScreenRingSurface = loadRingSurface;
|
||||
}
|
||||
}
|
||||
|
||||
void StepLoadScreen(int steps, bool insertDelay)
|
||||
{
|
||||
if (loadScreenWindow)
|
||||
{
|
||||
static const int kLoadScreenPhaseSwitchBreakpoint = 20;
|
||||
|
||||
int oldProgress = loadScreenProgress;
|
||||
|
||||
if (loadScreenProgress + steps >= kLoadScreenPhaseSwitchBreakpoint && loadScreenWindowPhase == 0)
|
||||
{
|
||||
loadScreenWindowPhase = 1;
|
||||
CreateLoadScreenWindow(loadScreenWindowPhase);
|
||||
|
||||
// Reset old progress since the progress bar was redrawn
|
||||
oldProgress = 0;
|
||||
}
|
||||
|
||||
const Rect loadScreenProgressBarFillRect = loadScreenProgressBarRect.Inset(1, 1);
|
||||
|
||||
int loadScreenMax = 43;
|
||||
loadScreenProgress = loadScreenProgress + steps;
|
||||
if (loadScreenProgress > loadScreenMax)
|
||||
loadScreenProgress = loadScreenMax;
|
||||
|
||||
PortabilityLayer::ResolveCachingColor fillColor(PortabilityLayer::RGBAColor::Create(51, 51, 51, 255));
|
||||
|
||||
int prevStep = oldProgress * loadScreenProgressBarFillRect.Width() / loadScreenMax;
|
||||
int thisStep = loadScreenProgress * loadScreenProgressBarFillRect.Width() / loadScreenMax;
|
||||
|
||||
loadScreenWindow->GetDrawSurface()->FillRect(Rect::Create(loadScreenProgressBarFillRect.top, loadScreenProgressBarFillRect.left + prevStep, loadScreenProgressBarFillRect.bottom, loadScreenProgressBarFillRect.left + thisStep), fillColor);
|
||||
ForceSyncFrame();
|
||||
|
||||
if (insertDelay)
|
||||
{
|
||||
StepLoadScreenRing();
|
||||
Delay(1, nullptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
SpinCursor(steps);
|
||||
}
|
||||
|
||||
void InitLoadingWindow()
|
||||
{
|
||||
// Only phones are slow enough for this to matter
|
||||
if (!thisMac.isTouchscreen)
|
||||
return;
|
||||
|
||||
if (isPrefsLoaded)
|
||||
loadScreenWindowPhase = 1;
|
||||
else
|
||||
loadScreenWindowPhase = 0;
|
||||
|
||||
CreateLoadScreenWindow(loadScreenWindowPhase);
|
||||
}
|
||||
|
||||
enum PreloadFontCategory
|
||||
{
|
||||
FontCategory_System,
|
||||
FontCategory_Application,
|
||||
FontCategory_Handwriting,
|
||||
FontCategory_Monospace,
|
||||
};
|
||||
|
||||
struct PreloadFontSpec
|
||||
{
|
||||
PreloadFontCategory m_category;
|
||||
int m_size;
|
||||
int m_flags;
|
||||
bool m_aa;
|
||||
};
|
||||
|
||||
struct PreloadFontWorkSlot
|
||||
{
|
||||
IGpThreadEvent *m_completedEvent;
|
||||
PortabilityLayer::WorkerThread *m_workerThread;
|
||||
std::atomic<int> m_singleJobCompleted;
|
||||
const PreloadFontSpec *m_spec;
|
||||
bool m_queued;
|
||||
|
||||
PreloadFontWorkSlot();
|
||||
~PreloadFontWorkSlot();
|
||||
};
|
||||
|
||||
PreloadFontWorkSlot::PreloadFontWorkSlot()
|
||||
: m_completedEvent(nullptr)
|
||||
, m_workerThread(nullptr)
|
||||
, m_spec(nullptr)
|
||||
, m_queued(false)
|
||||
{
|
||||
}
|
||||
|
||||
PreloadFontWorkSlot::~PreloadFontWorkSlot()
|
||||
{
|
||||
if (m_workerThread)
|
||||
m_workerThread->Destroy();
|
||||
}
|
||||
|
||||
void PreloadSingleFont (const PreloadFontSpec &spec)
|
||||
{
|
||||
switch (spec.m_category)
|
||||
{
|
||||
case FontCategory_Application:
|
||||
GetApplicationFont(spec.m_size, spec.m_flags, spec.m_aa);
|
||||
break;
|
||||
case FontCategory_System:
|
||||
GetSystemFont(spec.m_size, spec.m_flags, spec.m_aa);
|
||||
break;
|
||||
case FontCategory_Handwriting:
|
||||
GetHandwritingFont(spec.m_size, spec.m_flags, spec.m_aa);
|
||||
break;
|
||||
case FontCategory_Monospace:
|
||||
GetMonospaceFont(spec.m_size, spec.m_flags, spec.m_aa);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PreloadFontThreadFunc(void *context)
|
||||
{
|
||||
PreloadFontWorkSlot *wSlot = static_cast<PreloadFontWorkSlot*>(context);
|
||||
|
||||
PreloadSingleFont(*wSlot->m_spec);
|
||||
wSlot->m_singleJobCompleted.fetch_add(1, std::memory_order_release);
|
||||
wSlot->m_completedEvent->Signal();
|
||||
}
|
||||
|
||||
void PreloadFonts()
|
||||
{
|
||||
static PreloadFontSpec specs[] =
|
||||
{
|
||||
// First entry should be the one needed to show the load screen
|
||||
{ FontCategory_Application, 18, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
|
||||
{ FontCategory_System, 9, PortabilityLayer::FontFamilyFlag_Bold, true },
|
||||
{ FontCategory_System, 10, PortabilityLayer::FontFamilyFlag_Bold, true },
|
||||
{ FontCategory_System, 12, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
{ FontCategory_System, 12, PortabilityLayer::FontFamilyFlag_Bold, true },
|
||||
{ FontCategory_Application, 8, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
{ FontCategory_Application, 9, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
{ FontCategory_Application, 12, PortabilityLayer::FontFamilyFlag_Bold, true },
|
||||
{ FontCategory_Application, 14, PortabilityLayer::FontFamilyFlag_Bold, true },
|
||||
{ FontCategory_Application, 14, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
{ FontCategory_Application, 40, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
{ FontCategory_Handwriting, 24, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
{ FontCategory_Handwriting, 48, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
{ FontCategory_Monospace, 10, PortabilityLayer::FontFamilyFlag_None, true },
|
||||
};
|
||||
|
||||
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
|
||||
|
||||
const int numFontSpecs = sizeof(specs) / sizeof(specs[0]);
|
||||
|
||||
int queuedSpecs = 0;
|
||||
int completedSpecs = 0;
|
||||
|
||||
// We can't actually slot these because FT isn't thread-safe when accessing the same font,
|
||||
// but we can do this to unclog the render thread.
|
||||
PreloadFontWorkSlot slot;
|
||||
slot.m_workerThread = PortabilityLayer::WorkerThread::Create();
|
||||
slot.m_completedEvent = PLDrivers::GetSystemServices()->CreateThreadEvent(true, false);
|
||||
|
||||
while (completedSpecs < numFontSpecs)
|
||||
{
|
||||
if (slot.m_queued)
|
||||
{
|
||||
if (slot.m_singleJobCompleted.load(std::memory_order_acquire) != 0)
|
||||
{
|
||||
slot.m_completedEvent->Wait();
|
||||
slot.m_queued = false;
|
||||
completedSpecs++;
|
||||
|
||||
StepLoadScreen(1, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!slot.m_queued)
|
||||
{
|
||||
if (queuedSpecs < numFontSpecs)
|
||||
{
|
||||
slot.m_queued = true;
|
||||
slot.m_spec = specs + queuedSpecs;
|
||||
slot.m_singleJobCompleted.store(0, std::memory_order_release);
|
||||
slot.m_workerThread->AsyncExecuteTask(PreloadFontThreadFunc, &slot);
|
||||
|
||||
queuedSpecs++;
|
||||
}
|
||||
}
|
||||
|
||||
StepLoadScreenRing();
|
||||
Delay(1, nullptr);
|
||||
}
|
||||
|
||||
PortabilityLayer::FontManager::GetInstance()->PurgeCache();
|
||||
}
|
||||
|
||||
struct PreloadAATableSpec
|
||||
{
|
||||
PortabilityLayer::RGBAColor m_color;
|
||||
bool m_isTone;
|
||||
};
|
||||
|
||||
struct PreloadAATableWorkSlot
|
||||
{
|
||||
IGpThreadEvent *m_completedEvent;
|
||||
IGpMutex *m_mutex;
|
||||
PortabilityLayer::WorkerThread *m_workerThread;
|
||||
std::atomic<int> m_singleJobCompleted;
|
||||
const PreloadAATableSpec *m_spec;
|
||||
bool m_queued;
|
||||
|
||||
PreloadAATableWorkSlot();
|
||||
~PreloadAATableWorkSlot();
|
||||
};
|
||||
|
||||
PreloadAATableWorkSlot::PreloadAATableWorkSlot()
|
||||
: m_completedEvent(nullptr)
|
||||
, m_workerThread(nullptr)
|
||||
, m_spec(nullptr)
|
||||
, m_queued(false)
|
||||
{
|
||||
}
|
||||
|
||||
PreloadAATableWorkSlot::~PreloadAATableWorkSlot()
|
||||
{
|
||||
if (m_workerThread)
|
||||
m_workerThread->Destroy();
|
||||
}
|
||||
|
||||
|
||||
void PreloadAATableThreadFunc(void *context)
|
||||
{
|
||||
PreloadAATableWorkSlot *wSlot = static_cast<PreloadAATableWorkSlot*>(context);
|
||||
|
||||
PortabilityLayer::StandardPalette *sp = PortabilityLayer::StandardPalette::GetInstance();
|
||||
|
||||
if (wSlot->m_spec->m_isTone)
|
||||
sp->GetCachedToneAATable(wSlot->m_spec->m_color.r, wSlot->m_mutex);
|
||||
else
|
||||
sp->GetCachedPaletteAATable(wSlot->m_spec->m_color, wSlot->m_mutex);
|
||||
|
||||
wSlot->m_singleJobCompleted.fetch_add(1, std::memory_order_release);
|
||||
wSlot->m_completedEvent->Signal();
|
||||
}
|
||||
|
||||
void PreloadAATables()
|
||||
{
|
||||
PortabilityLayer::StandardPalette *sp = PortabilityLayer::StandardPalette::GetInstance();
|
||||
PortabilityLayer::RGBAColor preloadColors[] =
|
||||
{
|
||||
PortabilityLayer::RGBAColor::Create(255, 255, 255, 255),
|
||||
PortabilityLayer::RGBAColor::Create(255, 51, 51, 255),
|
||||
PortabilityLayer::RGBAColor::Create(255, 0, 0, 255),
|
||||
PortabilityLayer::RGBAColor::Create(255, 255, 0, 255),
|
||||
PortabilityLayer::RGBAColor::Create(0, 255, 255, 255),
|
||||
PortabilityLayer::RGBAColor::Create(0, 0, 255, 255),
|
||||
PortabilityLayer::RGBAColor::Create(204, 102, 51, 255),
|
||||
};
|
||||
|
||||
const size_t numPalettePreloads = sizeof(preloadColors) / sizeof(preloadColors[0]);
|
||||
const size_t maxTonePreloads = numPalettePreloads * 3;
|
||||
|
||||
PreloadAATableSpec specs[numPalettePreloads + maxTonePreloads];
|
||||
for (size_t i = 0; i < numPalettePreloads; i++)
|
||||
{
|
||||
specs[i].m_color = preloadColors[i];
|
||||
specs[i].m_isTone = false;
|
||||
}
|
||||
|
||||
size_t numTonePreloads = 0;
|
||||
for (size_t i = 0; i < numPalettePreloads; i++)
|
||||
{
|
||||
const uint8_t rgb[3] = { preloadColors[i].r, preloadColors[i].g, preloadColors[i].b };
|
||||
|
||||
for (int ch = 0; ch < 3; ch++)
|
||||
{
|
||||
uint8_t tone = rgb[ch];
|
||||
|
||||
bool toneAlreadyQueued = false;
|
||||
for (size_t j = 0; j < numTonePreloads; j++)
|
||||
{
|
||||
if (specs[numPalettePreloads + j].m_color.r == tone)
|
||||
{
|
||||
toneAlreadyQueued = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!toneAlreadyQueued)
|
||||
{
|
||||
PreloadAATableSpec &spec = specs[i + numTonePreloads];
|
||||
numTonePreloads++;
|
||||
|
||||
spec.m_color = PortabilityLayer::RGBAColor::Create(tone, tone, tone, 255);
|
||||
spec.m_isTone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
|
||||
|
||||
const int numAASpecs = numPalettePreloads + numTonePreloads;
|
||||
|
||||
unsigned int cpus = PLDrivers::GetSystemServices()->GetCPUCount();
|
||||
if (cpus < 2)
|
||||
{
|
||||
for (size_t i = 0; i < numAASpecs; i++)
|
||||
{
|
||||
PreloadAATableThreadFunc(specs + i);
|
||||
StepLoadScreen(1, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cpus -= 1;
|
||||
|
||||
int queuedSpecs = 0;
|
||||
int completedSpecs = 0;
|
||||
|
||||
PreloadAATableWorkSlot *slots = static_cast<PreloadAATableWorkSlot*>(mm->Alloc(sizeof(PreloadAATableWorkSlot) * cpus));
|
||||
|
||||
IGpMutex *mutex = PLDrivers::GetSystemServices()->CreateMutex();
|
||||
|
||||
for (unsigned int i = 0; i < cpus; i++)
|
||||
{
|
||||
PreloadAATableWorkSlot *slot = new (slots + i) PreloadAATableWorkSlot();
|
||||
slot->m_workerThread = PortabilityLayer::WorkerThread::Create();
|
||||
slot->m_completedEvent = PLDrivers::GetSystemServices()->CreateThreadEvent(true, false);
|
||||
slot->m_mutex = mutex;
|
||||
}
|
||||
|
||||
while (completedSpecs < numAASpecs)
|
||||
{
|
||||
int completedThisStep = 0;
|
||||
for (unsigned int i = 0; i < cpus; i++)
|
||||
{
|
||||
PreloadAATableWorkSlot &slot = slots[i];
|
||||
|
||||
if (slot.m_queued)
|
||||
{
|
||||
if (slot.m_singleJobCompleted.load(std::memory_order_acquire) != 0)
|
||||
{
|
||||
slot.m_completedEvent->Wait();
|
||||
slot.m_queued = false;
|
||||
completedSpecs++;
|
||||
|
||||
completedThisStep++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!slot.m_queued)
|
||||
{
|
||||
if (queuedSpecs < numAASpecs)
|
||||
{
|
||||
slot.m_queued = true;
|
||||
slot.m_spec = specs + queuedSpecs;
|
||||
slot.m_singleJobCompleted.store(0, std::memory_order_release);
|
||||
slot.m_workerThread->AsyncExecuteTask(PreloadAATableThreadFunc, &slot);
|
||||
|
||||
queuedSpecs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (completedThisStep > 0)
|
||||
StepLoadScreen(completedThisStep, false);
|
||||
|
||||
StepLoadScreenRing();
|
||||
Delay(1, nullptr);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < cpus; i++)
|
||||
slots[i].~PreloadAATableWorkSlot();
|
||||
|
||||
mm->Release(slots);
|
||||
mutex->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void ShowInitialLaunchDisclaimer()
|
||||
{
|
||||
const char *disclaimerLines[] =
|
||||
@@ -930,8 +384,8 @@ void ShowInitialLaunchDisclaimer()
|
||||
|
||||
const size_t numLines = sizeof(disclaimerLines) / sizeof(disclaimerLines[0]);
|
||||
|
||||
PortabilityLayer::RenderedFont *rfont = GetApplicationFont(14, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *buttonFont = GetApplicationFont(18, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *rfont = GetFont(PortabilityLayer::FontPresets::kApplication14);
|
||||
PortabilityLayer::RenderedFont *buttonFont = GetFont(PortabilityLayer::FontPresets::kApplication18);
|
||||
|
||||
const int kButtonSpacing = 16;
|
||||
const int kButtonHeight = 32;
|
||||
@@ -1066,15 +520,20 @@ void gpAppInit()
|
||||
//-------------------------------------------------------------- main
|
||||
// Here is main(). The first function called when Glider PRO comes up.
|
||||
|
||||
int gpAppMain()
|
||||
int AppStartup()
|
||||
{
|
||||
// long wasSeed;
|
||||
// long wasSeed;
|
||||
long theErr;
|
||||
PLError_t fileErr;
|
||||
Boolean whoCares, copyGood;
|
||||
|
||||
PL_Init();
|
||||
|
||||
IGpLogDriver *logger = PLDrivers::GetLogDriver();
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Init phase 1...");
|
||||
|
||||
ToolBoxInit();
|
||||
CheckOurEnvirons();
|
||||
|
||||
@@ -1087,23 +546,24 @@ int gpAppMain()
|
||||
RedAlert(kErrNeedSystem7);
|
||||
if (thisMac.numScreens == 0)
|
||||
RedAlert(kErrNeed16Or256Colors);
|
||||
// dataResFile = OpenResFile("\pMermaid");
|
||||
// dataResFile = OpenResFile("\pMermaid");
|
||||
SetUpAppleEvents();
|
||||
LoadCursors();
|
||||
ReadInPrefs();
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Init phase 2...");
|
||||
|
||||
SpinCursor(2); // Tick once to let the display driver flush any resolution changes from prefs
|
||||
FlushResolutionChange();
|
||||
|
||||
InitLoadingWindow(); StepLoadScreen(2, true);
|
||||
PreloadAATables();
|
||||
assert(isPrefsLoaded || loadScreenWindowPhase == 0);
|
||||
PreloadFonts(); StepLoadScreen(2, true);
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Init phase 3...");
|
||||
|
||||
#if defined COMPILEDEMO
|
||||
copyGood = true;
|
||||
#elif defined COMPILENOCP
|
||||
// didValidation = false;
|
||||
// didValidation = false;
|
||||
copyGood = true;
|
||||
#else
|
||||
didValidation = false;
|
||||
@@ -1114,28 +574,18 @@ int gpAppMain()
|
||||
WriteOutPrefs(); SpinCursor(3);
|
||||
#endif
|
||||
|
||||
// if ((thisMac.numScreens > 1) && (isUseSecondScreen))
|
||||
// ReflectSecondMonitorEnvirons(false, true, true);
|
||||
// if ((thisMac.numScreens > 1) && (isUseSecondScreen))
|
||||
// ReflectSecondMonitorEnvirons(false, true, true);
|
||||
HandleDepthSwitching();
|
||||
VariableInit(); StepLoadScreen(2, true);
|
||||
GetExtraCursors(); StepLoadScreen(2, true);
|
||||
VariableInit();
|
||||
GetExtraCursors();
|
||||
InitMarquee();
|
||||
CreatePointers(); StepLoadScreen(2, true);
|
||||
CreatePointers();
|
||||
InitSrcRects();
|
||||
CreateOffscreens(); StepLoadScreen(2, true);
|
||||
CreateOffscreens();
|
||||
|
||||
if (loadScreenWindow)
|
||||
{
|
||||
PortabilityLayer::WindowManager::GetInstance()->FlickerWindowOut(loadScreenWindow, 32);
|
||||
PortabilityLayer::WindowManager::GetInstance()->DestroyWindow(loadScreenWindow);
|
||||
PLSysCalls::Sleep(15);
|
||||
}
|
||||
|
||||
if (loadScreenRingSurface)
|
||||
{
|
||||
DisposeGWorld(loadScreenRingSurface);
|
||||
loadScreenRingSurface = nullptr;
|
||||
}
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Init phase 3...");
|
||||
|
||||
bool resolutionChanged = false;
|
||||
|
||||
@@ -1149,7 +599,7 @@ int gpAppMain()
|
||||
FlushResolutionChange();
|
||||
}
|
||||
|
||||
ShowInitialLaunchDisclaimer();
|
||||
//ShowInitialLaunchDisclaimer();
|
||||
}
|
||||
|
||||
if (thisMac.isResolutionDirty)
|
||||
@@ -1163,19 +613,32 @@ int gpAppMain()
|
||||
if (isDoColorFade)
|
||||
PortabilityLayer::WindowManager::GetInstance()->SetWindowDesaturation(mainWindow, 1.0);
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Init phase 4...");
|
||||
|
||||
InitSound(); SpinCursor(2);
|
||||
InitMusic(); SpinCursor(2);
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Init phase 5...");
|
||||
|
||||
BuildHouseList();
|
||||
OpenHouse(true);
|
||||
|
||||
PlayPrioritySound(kBirdSound, kBirdPriority);
|
||||
DelayTicks(6);
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
DelayTicks(6);
|
||||
}
|
||||
InitializeMenus(); InitCursor();
|
||||
|
||||
#if BUILD_ARCADE_VERSION
|
||||
// HideMenuBarOld();
|
||||
// HideMenuBarOld();
|
||||
#endif
|
||||
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "Initialization completed");
|
||||
|
||||
if (isDoColorFade)
|
||||
WashColorIn();
|
||||
|
||||
@@ -1184,14 +647,16 @@ int gpAppMain()
|
||||
if (thisMac.isTouchscreen)
|
||||
StartMainMenuUI();
|
||||
|
||||
while (!quitting) // this is the main loop
|
||||
HandleEvent();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
#if BUILD_ARCADE_VERSION
|
||||
ShowMenuBarOld();
|
||||
#endif
|
||||
*/
|
||||
int AppShutdown()
|
||||
{
|
||||
/*
|
||||
#if BUILD_ARCADE_VERSION
|
||||
ShowMenuBarOld();
|
||||
#endif
|
||||
*/
|
||||
KillMusic();
|
||||
KillSound();
|
||||
if (houseOpen)
|
||||
@@ -1206,8 +671,19 @@ int gpAppMain()
|
||||
}
|
||||
WriteOutPrefs();
|
||||
PL_DEAD(FlushEvents());
|
||||
// theErr = LoadScrap();
|
||||
// theErr = LoadScrap();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpAppMain()
|
||||
{
|
||||
int returnCode = AppStartup();
|
||||
if (returnCode != 0)
|
||||
return returnCode;
|
||||
|
||||
while (!quitting) // this is the main loop
|
||||
HandleEvent();
|
||||
|
||||
return AppShutdown();
|
||||
}
|
||||
|
||||
@@ -64,13 +64,13 @@ struct MainMenuUIState
|
||||
ControlID m_activeControl;
|
||||
|
||||
static const unsigned int kControlHeight = 40;
|
||||
static const unsigned int kControlFontSize = 24;
|
||||
static const unsigned int kControlLeftSpacing = 20;
|
||||
static const unsigned int kControlBottomSpacing = 20;
|
||||
static const unsigned int kControlIntermediateSpacing = 16;
|
||||
static const unsigned int kControlInteriorSpacing = 6;
|
||||
static const unsigned int kControlScrollInDecay = 32;
|
||||
static const unsigned int kControlScrollInDecayFalloffBits = 0;
|
||||
static const PortabilityLayer::FontPreset_t kControlFontPreset = PortabilityLayer::FontPresets::kHandwriting24;
|
||||
};
|
||||
|
||||
static MainMenuUIState mainMenu;
|
||||
@@ -135,7 +135,7 @@ static void DrawMainMenuControl(DrawSurface *surface, MainMenuUIState::ControlID
|
||||
{
|
||||
case MainMenuUIState::ControlStyle_Text:
|
||||
{
|
||||
PortabilityLayer::RenderedFont *rfont = GetHandwritingFont(MainMenuUIState::kControlFontSize, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *rfont = GetFont(MainMenuUIState::kControlFontPreset);
|
||||
if (!rfont)
|
||||
return;
|
||||
|
||||
@@ -219,7 +219,7 @@ void StartMainMenuUI()
|
||||
{
|
||||
DismissMainMenuUI();
|
||||
|
||||
PortabilityLayer::RenderedFont *rfont = GetHandwritingFont(MainMenuUIState::kControlFontSize, PortabilityLayer::FontFamilyFlag_None, true);
|
||||
PortabilityLayer::RenderedFont *rfont = GetFont(MainMenuUIState::kControlFontPreset);
|
||||
if (!rfont)
|
||||
return;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "PLDrivers.h"
|
||||
#include "PLNumberFormatting.h"
|
||||
#include "PLPasStr.h"
|
||||
#include "PLSysCalls.h"
|
||||
|
||||
#define kMainWindowID 128
|
||||
#define kEditWindowID 129
|
||||
@@ -52,6 +53,7 @@ extern short toolSelected;
|
||||
extern Boolean noRoomAtAll, isUseSecondScreen;
|
||||
extern Boolean quickerTransitions, houseIsReadOnly;
|
||||
extern Boolean menusUp;
|
||||
extern Boolean houseOpen;
|
||||
|
||||
//============================================================== Functions
|
||||
//-------------------------------------------------------------- DrawOnSplash
|
||||
@@ -61,13 +63,16 @@ extern Boolean menusUp;
|
||||
void DrawOnSplash(DrawSurface *surface)
|
||||
{
|
||||
Str255 houseLoadedStr;
|
||||
|
||||
if (!houseOpen)
|
||||
return;
|
||||
|
||||
PasStringCopy(PSTR("House: "), houseLoadedStr);
|
||||
PasStringConcat(houseLoadedStr, thisHouseName);
|
||||
if ((thisMac.hasQT) && (hasMovie))
|
||||
PasStringConcat(houseLoadedStr, PSTR(" (TV)"));
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont = GetApplicationFont(9, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
|
||||
|
||||
const Point textPoint = Point::Create(splashOriginH + 436, splashOriginV + 314);
|
||||
if (thisMac.isDepth == 4)
|
||||
@@ -260,14 +265,14 @@ void OpenMainWindow (void)
|
||||
// fadeGraysOut = false;
|
||||
// ForceCTSeed((CGrafPtr)mainWindow, wasSeed);
|
||||
// }
|
||||
|
||||
UpdateMainWindow();
|
||||
}
|
||||
|
||||
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
|
||||
GetPortBitMapForCopyBits(mainWindow->GetDrawSurface()),
|
||||
&mainWindowRect, &mainWindowRect, srcCopy);
|
||||
|
||||
UpdateMainWindow();
|
||||
|
||||
mainWindow->GetDrawSurface()->m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
|
||||
}
|
||||
|
||||
@@ -567,6 +572,8 @@ void HardDrawMainWindow (void)
|
||||
// palette. In this way, color appears to slowly wash in.
|
||||
void WashColorIn (void)
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
|
||||
#define kGray2ColorSteps 180
|
||||
long longDelta;
|
||||
short i, c;
|
||||
|
||||
@@ -1057,7 +1057,7 @@ void DrawCalendar (Rect *theRect)
|
||||
backSrcMap->DrawPicture(thePicture, bounds);
|
||||
thePicture.Dispose();
|
||||
|
||||
PortabilityLayer::RenderedFont *appFont = GetApplicationFont(9, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
|
||||
|
||||
GetTime(&timeRec);
|
||||
GetIndString(monthStr, kMonthStringID, timeRec.month);
|
||||
|
||||
@@ -785,7 +785,7 @@ void DoBlowerObjectInfo (short what)
|
||||
{
|
||||
bool redrawMain = false;
|
||||
|
||||
item = infoDial->ExecuteModal(nullptr, BlowerFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(BlowerFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -937,7 +937,7 @@ void DoFurnitureObjectInfo (void)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = infoDial->ExecuteModal(nullptr, FurnitureFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(FurnitureFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
leaving = true;
|
||||
@@ -997,7 +997,7 @@ void DoCustPictObjectInfo (void)
|
||||
{
|
||||
bool redrawMain = false;
|
||||
|
||||
item = infoDial->ExecuteModal(nullptr, CustPictFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(CustPictFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -1106,7 +1106,7 @@ void DoSwitchObjectInfo (void)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = infoDial->ExecuteModal(nullptr, SwitchFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(SwitchFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -1231,7 +1231,7 @@ void DoTriggerObjectInfo (void)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = infoDial->ExecuteModal(nullptr, TriggerFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(TriggerFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -1371,7 +1371,7 @@ void DoLightObjectInfo (void)
|
||||
while (!leaving)
|
||||
{
|
||||
bool redrawMain = false;
|
||||
item = infoDial->ExecuteModal(nullptr, LightFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(LightFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -1465,7 +1465,7 @@ void DoApplianceObjectInfo (short what)
|
||||
while (!leaving)
|
||||
{
|
||||
bool redrawMain = false;
|
||||
item = infoDial->ExecuteModal(nullptr, ApplianceFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(ApplianceFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -1585,7 +1585,7 @@ void DoMicrowaveObjectInfo (void)
|
||||
while (!leaving)
|
||||
{
|
||||
bool redrawMain = false;
|
||||
item = infoDial->ExecuteModal(nullptr, MicrowaveFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(MicrowaveFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -1695,7 +1695,7 @@ void DoGreaseObjectInfo (void)
|
||||
{
|
||||
bool redrawMain = false;
|
||||
|
||||
item = infoDial->ExecuteModal(nullptr, GreaseFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(GreaseFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -1783,7 +1783,7 @@ void DoInvisBonusObjectInfo (void)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = infoDial->ExecuteModal(nullptr, InvisBonusFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(InvisBonusFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -1907,7 +1907,7 @@ void DoTransObjectInfo (short what)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = infoDial->ExecuteModal(nullptr, TransFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(TransFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -2017,7 +2017,7 @@ void DoEnemyObjectInfo (short what)
|
||||
|
||||
while (!leaving)
|
||||
{
|
||||
item = infoDial->ExecuteModal(nullptr, EnemyFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(EnemyFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -2113,7 +2113,7 @@ void DoFlowerObjectInfo (void)
|
||||
{
|
||||
bool redrawMain = false;
|
||||
|
||||
item = infoDial->ExecuteModal(nullptr, FlowerFilter);
|
||||
item = infoDial->ExecuteModal(nullptr, PL_FILTER_FUNC(FlowerFilter));
|
||||
|
||||
if (item == kOkayButton)
|
||||
{
|
||||
@@ -2361,3 +2361,17 @@ void DoObjectInfo (void)
|
||||
|
||||
#endif
|
||||
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(BlowerFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(FurnitureFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(CustPictFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(SwitchFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(TriggerFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(LightFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(ApplianceFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(MicrowaveFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(GreaseFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(InvisBonusFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(TransFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(EnemyFilter)
|
||||
PL_IMPLEMENT_FILTER_FUNCTION(FlowerFilter)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "RectUtils.h"
|
||||
#include "Room.h"
|
||||
#include "RubberBands.h"
|
||||
|
||||
#include "PLSysCalls.h"
|
||||
|
||||
#define kMaxGarbageRects 48
|
||||
|
||||
@@ -739,6 +739,7 @@ void RenderFrame (void)
|
||||
|
||||
while (TickCount() < nextFrame)
|
||||
{
|
||||
PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
|
||||
Delay(1, nullptr);
|
||||
}
|
||||
nextFrame = TickCount() + kTicksPerFrame;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user