OpenGL display driver

This commit is contained in:
elasota
2020-09-26 16:45:52 -04:00
parent da3cdb3a17
commit 45aa5b4cba
26 changed files with 2922 additions and 33 deletions

1
.gitignore vendored
View File

@@ -29,6 +29,7 @@ InstallerPackages/*
*.wixpdb
*.wixobj
*.CopyComplete
*.lnk
ReleasePackageInstaller/obj/*
ReleasePackageInstaller/bin/*
ReleasePackageInstaller/AerofoilPackageDefs.wxi

View File

@@ -20,7 +20,7 @@ namespace GpFiberStarter_Win32
GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc;
IGpFiber *creatingFiber = tss->m_creatingFiber;
void *context = tss->m_context;
creatingFiber->YieldTo();
SwitchToFiber(static_cast<GpFiber_Win32*>(creatingFiber)->GetFiber());
threadFunc(context);

View File

@@ -1,32 +1,32 @@
#include "GpFiber_Win32.h"
#include <new>
GpFiber_Win32::GpFiber_Win32(LPVOID fiber)
: m_fiber(fiber)
{
}
void GpFiber_Win32::YieldTo()
{
SwitchToFiber(m_fiber);
}
void GpFiber_Win32::Destroy()
#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::Destroy()
{
this->~GpFiber_Win32();
free(this);
}
GpFiber_Win32::~GpFiber_Win32()
{
DeleteFiber(m_fiber);
{
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);
return new (storage) GpFiber_Win32(fiber);
}

View File

@@ -5,14 +5,21 @@
class GpFiber_Win32 final : public IGpFiber
{
public:
void YieldTo() override;
void YieldTo(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;
}

View File

@@ -40,6 +40,10 @@
<Import Project="AerofoilSDL.props" />
<Import Project="..\Common.props" />
<Import Project="..\GpShell.props" />
<Import Project="..\GpMainApp.props" />
<Import Project="..\PortabilityLayer.props" />
<Import Project="..\GpCommon.props" />
<Import Project="..\Debug.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" />
@@ -47,6 +51,9 @@
<Import Project="..\Common.props" />
<Import Project="..\GpShell.props" />
<Import Project="..\Release.props" />
<Import Project="..\GpMainApp.props" />
<Import Project="..\PortabilityLayer.props" />
<Import Project="..\GpCommon.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
@@ -62,6 +69,7 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -71,9 +79,47 @@
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\Aerofoil\GpColorCursor_Win32.cpp" />
<ClCompile Include="..\Aerofoil\GpFileStream_Win32.cpp" />
<ClCompile Include="..\Aerofoil\GpFileSystem_Win32.cpp" />
<ClCompile Include="..\Aerofoil\GpLogDriver_Win32.cpp" />
<ClCompile Include="..\Aerofoil\GpMutex_Win32.cpp" />
<ClCompile Include="..\Aerofoil\GpSystemServices_Win32.cpp" />
<ClCompile Include="..\Aerofoil\GpThreadEvent_Win32.cpp" />
<ClCompile Include="GpDisplayDriver_SDL_GL2.cpp" />
<ClCompile Include="GpFiberStarter_SDL.cpp" />
<ClCompile Include="GpFiber_SDL.cpp" />
<ClCompile Include="GpMain_SDL_Win32.cpp" />
<ClCompile Include="ShaderCode\DrawQuadPaletteP.cpp" />
<ClCompile Include="ShaderCode\DrawQuadV.cpp" />
<ClCompile Include="ShaderCode\ScaleQuadP.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GpApp\GpApp.vcxproj">
<Project>{6233c3f2-5781-488e-b190-4fa8836f5a77}</Project>
</ProjectReference>
<ProjectReference Include="..\GpAudioDriver_XAudio2\GpAudioDriver_XAudio2.vcxproj">
<Project>{e3bdc783-8646-433e-adf0-8b6390d36669}</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>
<ProjectReference Include="..\GpShell\GpShell.vcxproj">
<Project>{10cf9b5f-61d0-4b5b-89f4-810b58fc053d}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="GpFiber_SDL.h" />
<ClInclude Include="ShaderCode\DrawQuadPixelConstants.h" />
<ClInclude Include="ShaderCode\Functions.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -13,10 +13,63 @@
<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>
<Filter Include="Source Files\ShaderCode">
<UniqueIdentifier>{85279826-1cd2-4894-a780-3f74af9c1260}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="GpMain_SDL_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Aerofoil\GpLogDriver_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Aerofoil\GpFileSystem_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Aerofoil\GpSystemServices_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Aerofoil\GpColorCursor_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Aerofoil\GpMutex_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Aerofoil\GpThreadEvent_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Aerofoil\GpFileStream_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ShaderCode\DrawQuadV.cpp">
<Filter>Source Files\ShaderCode</Filter>
</ClCompile>
<ClCompile Include="ShaderCode\DrawQuadPaletteP.cpp">
<Filter>Source Files\ShaderCode</Filter>
</ClCompile>
<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>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ShaderCode\Functions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ShaderCode\DrawQuadPixelConstants.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpFiber_SDL.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
#include "GpFiberStarter.h"
#include "GpFiber_SDL.h"
#include "GpSystemServices_Win32.h"
#include "HostThreadEvent.h"
#include "SDL_thread.h"
#include <assert.h>
namespace GpFiberStarter_SDL
{
struct FiberStartState
{
GpFiberStarter::ThreadFunc_t m_threadFunc;
PortabilityLayer::HostThreadEvent *m_creatingReturnEvent;
void *m_context;
};
static int SDLCALL FiberStartRoutine(void *lpThreadParameter)
{
const FiberStartState *tss = static_cast<const FiberStartState*>(lpThreadParameter);
GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc;
PortabilityLayer::HostThreadEvent *creatingReturnEvent = tss->m_creatingReturnEvent;
void *context = tss->m_context;
creatingReturnEvent->Signal();
threadFunc(context);
return 0;
}
}
IGpFiber *GpFiberStarter::StartFiber(ThreadFunc_t threadFunc, void *context, IGpFiber *creatingFiber)
{
PortabilityLayer::HostThreadEvent *returnEvent = GpSystemServices_Win32::GetInstance()->CreateThreadEvent(true, false);
GpFiberStarter_SDL::FiberStartState startState;
startState.m_context = context;
startState.m_creatingReturnEvent = returnEvent;
startState.m_threadFunc = threadFunc;
SDL_Thread *thread = SDL_CreateThread(GpFiberStarter_SDL::FiberStartRoutine, "Fiber", &startState);
if (!thread)
return nullptr;
returnEvent->Wait();
return new GpFiber_SDL(thread, returnEvent);
}

View File

@@ -0,0 +1,27 @@
#include "GpFiber_SDL.h"
#include "HostSystemServices.h"
#include "HostThreadEvent.h"
#include "GpSystemServices_Win32.h"
GpFiber_SDL::GpFiber_SDL(SDL_Thread *thread, PortabilityLayer::HostThreadEvent *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::Destroy()
{
delete this;
}

27
AerofoilSDL/GpFiber_SDL.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
#include "IGpFiber.h"
#include "SDL_thread.h"
namespace PortabilityLayer
{
class HostSystemServices;
class HostThreadEvent;
}
class GpFiber_SDL final : public IGpFiber
{
public:
explicit GpFiber_SDL(SDL_Thread *thread, PortabilityLayer::HostThreadEvent *threadEvent);
~GpFiber_SDL();
void YieldTo(IGpFiber *fromFiber) override;
void Destroy() override;
private:
static int SDLCALL InternalThreadFunction(void *data);
bool m_isDestroying;
PortabilityLayer::HostThreadEvent *m_event;
SDL_Thread *m_thread;
};

View File

@@ -1,6 +1,474 @@
#include "SDL_main.h"
#include "SDL.h"
SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[])
{
return 0;
#include "GpMain.h"
#include "GpAudioDriverFactory.h"
#include "GpCursor_Win32.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"
#include "GpInputDriverFactory.h"
#include "GpAppInterface.h"
#include "GpSystemServices_Win32.h"
#include "GpVOSEvent.h"
#include "IGpVOSEventQueue.h"
#include "HostFileSystem.h"
#include "HostThreadEvent.h"
#include "GpWindows.h"
#include "resource.h"
#include <shellapi.h>
#include <stdio.h>
#include <windowsx.h>
GpWindowsGlobals g_gpWindowsGlobals;
extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAudio2(const GpAudioDriverProperties &properties);
extern "C" __declspec(dllimport) IGpInputDriver *GpDriver_CreateInputDriver_XInput(const GpInputDriverProperties &properties);
extern "C" __declspec(dllimport) IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties);
IGpDisplayDriver *GpDriver_CreateDisplayDriver_SDL_GL2(const GpDisplayDriverProperties &properties);
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())
{
evt->m_eventType = GpVOSEventTypes::kMouseInput;
GpMouseInputEvent &mEvent = evt->m_event.m_mouseInputEvent;
mEvent.m_button = button;
mEvent.m_x = x;
mEvent.m_y = y;
mEvent.m_eventType = eventType;
if (pixelScaleX != 1.0f)
mEvent.m_x = static_cast<int32_t>(static_cast<float>(x) / pixelScaleX);
if (pixelScaleY != 1.0f)
mEvent.m_y = static_cast<int32_t>(static_cast<float>(y) / pixelScaleX);
}
}
static bool IdentifyVKey(const WPARAM &wparam, const LPARAM &lparam, GpKeyIDSubset_t &outSubset, GpKeyboardInputEvent::KeyUnion &outKey)
{
switch (wparam)
{
case VK_ESCAPE:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kEscape;
break;
case VK_PRINT:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kPrintScreen;
break;
case VK_SCROLL:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kScrollLock;
break;
case VK_PAUSE:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kPause;
break;
case VK_INSERT:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kInsert;
break;
case VK_HOME:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kHome;
break;
case VK_PRIOR:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kPageUp;
break;
case VK_NEXT:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kPageDown;
break;
case VK_DELETE:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kDelete;
break;
case VK_TAB:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kTab;
break;
case VK_END:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kEnd;
break;
case VK_BACK:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kBackspace;
break;
case VK_CAPITAL:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kCapsLock;
break;
case VK_RETURN:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kEnter;
break;
case VK_SHIFT:
{
UINT vkey = MapVirtualKeyW((lparam >> 16) & 0xff, MAPVK_VSC_TO_VK_EX);
if (vkey == VK_LSHIFT || vkey == VK_SHIFT)
{
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kLeftShift;
}
else if (vkey == VK_RSHIFT)
{
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kRightShift;
}
else
return false;
}
break;
case VK_RSHIFT:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kRightShift;
break;
case VK_CONTROL:
outSubset = GpKeyIDSubsets::kSpecial;
if (lparam & 0x01000000)
outKey.m_specialKey = GpKeySpecials::kRightCtrl;
else
outKey.m_specialKey = GpKeySpecials::kLeftCtrl;
break;
case VK_MENU:
outSubset = GpKeyIDSubsets::kSpecial;
if (lparam & 0x01000000)
outKey.m_specialKey = GpKeySpecials::kRightAlt;
else
outKey.m_specialKey = GpKeySpecials::kLeftAlt;
break;
case VK_NUMLOCK:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kNumLock;
break;
case VK_NUMPAD0:
case VK_NUMPAD1:
case VK_NUMPAD2:
case VK_NUMPAD3:
case VK_NUMPAD4:
case VK_NUMPAD5:
case VK_NUMPAD6:
case VK_NUMPAD7:
case VK_NUMPAD8:
case VK_NUMPAD9:
outSubset = GpKeyIDSubsets::kNumPadNumber;
outKey.m_numPadNumber = static_cast<uint8_t>(wparam - VK_NUMPAD0);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
outSubset = GpKeyIDSubsets::kASCII;
outKey.m_asciiChar = static_cast<char>(wparam);
break;
case VK_F1:
case VK_F2:
case VK_F3:
case VK_F4:
case VK_F5:
case VK_F6:
case VK_F7:
case VK_F8:
case VK_F9:
case VK_F10:
case VK_F11:
case VK_F12:
case VK_F13:
case VK_F14:
case VK_F15:
case VK_F16:
case VK_F17:
case VK_F18:
case VK_F19:
case VK_F20:
case VK_F21:
case VK_F22:
case VK_F23:
case VK_F24:
outSubset = GpKeyIDSubsets::kFKey;
outKey.m_fKey = static_cast<uint8_t>(wparam - VK_F1 + 1);
break;
case VK_OEM_COMMA:
outSubset = GpKeyIDSubsets::kASCII;
outKey.m_asciiChar = ',';
break;
case VK_OEM_MINUS:
outSubset = GpKeyIDSubsets::kASCII;
outKey.m_asciiChar = '-';
break;
case VK_OEM_PERIOD:
outSubset = GpKeyIDSubsets::kASCII;
outKey.m_asciiChar = '.';
break;
case VK_OEM_PLUS:
outSubset = GpKeyIDSubsets::kASCII;
outKey.m_asciiChar = '+';
break;
case VK_UP:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kUpArrow;
break;
case VK_DOWN:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kDownArrow;
break;
case VK_LEFT:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kLeftArrow;
break;
case VK_RIGHT:
outSubset = GpKeyIDSubsets::kSpecial;
outKey.m_specialKey = GpKeySpecials::kRightArrow;
break;
default:
{
if (wparam >= VK_OEM_1 && wparam <= VK_OEM_102)
{
UINT charCode = MapVirtualKeyW(static_cast<UINT>(wparam), MAPVK_VK_TO_CHAR);
if (charCode == 0)
return false;
if (charCode < 128)
{
outSubset = GpKeyIDSubsets::kASCII;
outKey.m_asciiChar = static_cast<char>(charCode);
break;
}
else
{
outSubset = GpKeyIDSubsets::kUnicode;
outKey.m_unicodeChar = charCode;;
break;
}
}
}
return false;
}
return true;
}
static void PostKeyboardEvent(IGpVOSEventQueue *eventQueue, GpKeyboardInputEventType_t eventType, GpKeyIDSubset_t subset, const GpKeyboardInputEvent::KeyUnion &key, uint32_t repeatCount)
{
if (GpVOSEvent *evt = eventQueue->QueueEvent())
{
evt->m_eventType = GpVOSEventTypes::kKeyboardInput;
GpKeyboardInputEvent &mEvent = evt->m_event.m_keyboardInputEvent;
mEvent.m_key = key;
mEvent.m_eventType = eventType;
mEvent.m_keyIDSubset = subset;
mEvent.m_repeatCount = repeatCount;
}
}
static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY)
{
WPARAM wParam = msg->wParam;
LPARAM lParam = msg->lParam;
switch (msg->message)
{
case WM_LBUTTONDOWN:
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_LBUTTONUP:
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_MBUTTONDOWN:
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_MBUTTONUP:
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_RBUTTONDOWN:
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_RBUTTONUP:
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_XBUTTONDOWN:
if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2)
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_XBUTTONUP:
if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2)
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_MOUSEMOVE:
PostMouseEvent(eventQueue, GpMouseEventTypes::kMove, GpMouseButtons::kNone, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
break;
case WM_MOUSELEAVE:
PostMouseEvent(eventQueue, GpMouseEventTypes::kLeave, GpMouseButtons::kNone, 0, 0, pixelScaleX, pixelScaleY);
break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{
GpKeyIDSubset_t subset;
GpKeyboardInputEvent::KeyUnion key;
bool isRepeat = ((lParam & 0x40000000) != 0);
const GpKeyboardInputEventType_t keyEventType = isRepeat ? GpKeyboardInputEventTypes::kAuto : GpKeyboardInputEventTypes::kDown;
if (IdentifyVKey(wParam, lParam, subset, key))
PostKeyboardEvent(eventQueue, keyEventType, subset, key, static_cast<uint32_t>(lParam & 0xffff));
(void)TranslateMessage(msg);
}
break;
case WM_KEYUP:
case WM_SYSKEYUP:
{
GpKeyIDSubset_t subset;
GpKeyboardInputEvent::KeyUnion key;
if (IdentifyVKey(wParam, lParam, subset, key))
PostKeyboardEvent(eventQueue, GpKeyboardInputEventTypes::kUp, subset, key, (lParam & 0xffff));
}
break;
case WM_CHAR:
case WM_UNICHAR:
{
bool isRepeat = ((lParam & 0x4000000) != 0);
const GpKeyboardInputEventType_t keyEventType = isRepeat ? GpKeyboardInputEventTypes::kAutoChar : GpKeyboardInputEventTypes::kDownChar;
GpKeyboardInputEvent::KeyUnion key;
GpKeyIDSubset_t subset = GpKeyIDSubsets::kASCII;
if (wParam <= 128)
key.m_asciiChar = static_cast<char>(wParam);
else
{
subset = GpKeyIDSubsets::kUnicode;
key.m_unicodeChar = static_cast<uint32_t>(wParam);
}
PostKeyboardEvent(eventQueue, keyEventType, subset, key, (lParam & 0xffff));
}
break;
case WM_QUIT:
{
if (GpVOSEvent *evt = eventQueue->QueueEvent())
evt->m_eventType = GpVOSEventTypes::kQuit;
}
break;
default:
break;
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
return -1;
LPWSTR cmdLine = GetCommandLineW();
int nArgs;
LPWSTR *cmdLineArgs = CommandLineToArgvW(cmdLine, &nArgs);
for (int i = 1; i < nArgs; i++)
{
if (!wcscmp(cmdLineArgs[i], L"-diagnostics"))
GpLogDriver_Win32::Init();
}
IGpLogDriver *logger = GpLogDriver_Win32::GetInstance();
GpAppInterface_Get()->PL_HostFileSystem_SetInstance(GpFileSystem_Win32::GetInstance());
GpAppInterface_Get()->PL_HostSystemServices_SetInstance(GpSystemServices_Win32::GetInstance());
GpAppInterface_Get()->PL_HostLogDriver_SetInstance(GpLogDriver_Win32::GetInstance());
g_gpWindowsGlobals.m_hInstance = hInstance;
g_gpWindowsGlobals.m_hPrevInstance = hPrevInstance;
g_gpWindowsGlobals.m_cmdLine = cmdLine;
g_gpWindowsGlobals.m_cmdLineArgc = nArgs;
g_gpWindowsGlobals.m_cmdLineArgv = cmdLineArgs;
g_gpWindowsGlobals.m_nCmdShow = nCmdShow;
g_gpWindowsGlobals.m_baseDir = GpFileSystem_Win32::GetInstance()->GetBasePath();
g_gpWindowsGlobals.m_hwnd = nullptr;
//g_gpWindowsGlobals.m_hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_ICON1));
//g_gpWindowsGlobals.m_hIconSm = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_ICON2));
g_gpWindowsGlobals.m_loadCursorFunc = GpCursor_Win32::Load;
g_gpWindowsGlobals.m_translateWindowsMessageFunc = TranslateWindowsMessage;
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_SDL_GL2;
g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_XAudio2;
g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_FreeType2;
EGpInputDriverType inputDrivers[] =
{
EGpInputDriverType_XInput
};
g_gpGlobalConfig.m_inputDriverTypes = inputDrivers;
g_gpGlobalConfig.m_numInputDrivers = sizeof(inputDrivers) / sizeof(inputDrivers[0]);
g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals;
g_gpGlobalConfig.m_logger = logger;
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_SDL_GL2, GpDriver_CreateDisplayDriver_SDL_GL2);
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, "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);
LocalFree(cmdLineArgs);
return returnCode;
}

View File

@@ -0,0 +1,28 @@
#include "Functions.h"
#include "DrawQuadPixelConstants.h"
#define GP_GL_SHADER_CODE_DRAWQUADPALETTEP_GLSL "varying vec4 texCoord;\n"\
"uniform sampler2D surfaceTexture;\n"\
"uniform sampler2D paletteTexture;\n"\
"\n"\
"vec3 SamplePixel(vec2 tc)\n"\
"{\n"\
" float surfaceColor = texture2D(surfaceTexture, tc).r;\n"\
" return texture2D(paletteTexture, vec2(surfaceColor * (255.0 / 256.0) + (0.5 / 256.0), 0.5)).rgb;\n"\
"}\n"\
"\n"\
"void main()\n"\
"{\n"\
" vec4 resultColor = vec4(SamplePixel(texCoord.xy), 1.0);\n"\
" resultColor *= constants_Modulation;\n"\
" resultColor = ApplyFlicker(constants_FlickerAxis, texCoord.xy, constants_FlickerStartThreshold, constants_FlickerEndThreshold, resultColor * constants_Modulation);\n"\
" resultColor = ApplyDesaturation(constants_Desaturation, resultColor);\n"\
"\n"\
" gl_FragColor = vec4(ApplyColorSpaceTransform(resultColor.rgb), resultColor.a);\n"\
"}\n"
namespace GpBinarizedShaders
{
const char *g_drawQuadPaletteP_GL2 = GP_GL_SHADER_CODE_DRAWQUADPIXELCONSTANTS_H GP_GL_SHADER_CODE_FUNCTIONS_H GP_GL_SHADER_CODE_DRAWQUADPALETTEP_GLSL;
const char *g_drawQuadPaletteICCP_GL2 = "#define USE_ICC_PROFILE\n" GP_GL_SHADER_CODE_DRAWQUADPIXELCONSTANTS_H GP_GL_SHADER_CODE_FUNCTIONS_H GP_GL_SHADER_CODE_DRAWQUADPALETTEP_GLSL;
}

View File

@@ -0,0 +1,5 @@
#define GP_GL_SHADER_CODE_DRAWQUADPIXELCONSTANTS_H "uniform vec4 constants_Modulation;\n"\
"uniform vec2 constants_FlickerAxis;\n"\
"uniform float constants_FlickerStartThreshold;\n"\
"uniform float constants_FlickerEndThreshold;\n"\
"uniform float constants_Desaturation;\n"

View File

@@ -0,0 +1,17 @@
#define GP_GL_SHADER_CODE_DRAWQUADV_GLSL "uniform vec4 ndcOriginAndDimensions;\n"\
"uniform vec4 surfaceDimensions_TextureRegion;\n"\
"attribute vec2 posUV;\n"\
"varying vec4 texCoord;\n"\
"\n"\
"void main()\n"\
"{\n"\
" vec2 ndcPos = ndcOriginAndDimensions.xy + posUV.xy * ndcOriginAndDimensions.zw;\n"\
"\n"\
" gl_Position = vec4(ndcPos.x, ndcPos.y, 0.0, 1.0);\n"\
" texCoord = vec4(posUV.xyxy * surfaceDimensions_TextureRegion.zwxy);\n"\
"}\n"
namespace GpBinarizedShaders
{
const char *g_drawQuadV_GL2 = GP_GL_SHADER_CODE_DRAWQUADV_GLSL;
}

View File

@@ -0,0 +1,100 @@
#define GP_GL_SHADER_CODE_FUNCTIONS_H "vec3 pow3(vec3 v, float ex)\n"\
"{\n"\
" return vec3(pow(v.x, ex), pow(v.y, ex), pow(v.z, ex));\n"\
"}\n"\
"\n"\
"float SRGBToLinear(float v)\n"\
"{\n"\
" if (v <= 0.04045)\n"\
" return v * (1.0 / 12.92);\n"\
" else\n"\
" return pow(((v + 0.055) * (1.0 / 1.055)), 2.4);\n"\
"}\n"\
"\n"\
"vec2 SRGBToLinear(vec2 v)\n"\
"{\n"\
" return vec2(SRGBToLinear(v.x), SRGBToLinear(v.y));\n"\
"}\n"\
"\n"\
"vec3 SRGBToLinear(vec3 v)\n"\
"{\n"\
" return vec3(SRGBToLinear(v.x), SRGBToLinear(v.y), SRGBToLinear(v.z));\n"\
"}\n"\
"\n"\
"float LinearToSRGB(float v)\n"\
"{\n"\
" if (v <= 0.0031308)\n"\
" return 12.92 * v;\n"\
" else\n"\
" return 1.055 * pow(v, 1.0 / 2.4) - 0.055;\n"\
"}\n"\
"\n"\
"vec2 LinearToSRGB(vec2 v)\n"\
"{\n"\
" return vec2(LinearToSRGB(v.x), LinearToSRGB(v.y));\n"\
"}\n"\
"\n"\
"vec3 LinearToSRGB(vec3 v)\n"\
"{\n"\
" return vec3(LinearToSRGB(v.x), LinearToSRGB(v.y), LinearToSRGB(v.z));\n"\
"}\n"\
"\n"\
"vec4 ApplyFlicker(vec2 flickerAxis, vec2 coordinate, float startThreshold, float endThreshold, vec4 color)\n"\
"{\n"\
" float flickerTotal = dot(flickerAxis, coordinate);\n"\
" if (flickerTotal < startThreshold)\n"\
" return vec4(0, 0, 0, 0);\n"\
" else if (flickerTotal >= endThreshold)\n"\
" return color;\n"\
"\n"\
" return vec4(1, 1, 1, 1);\n"\
"}\n"\
"\n"\
"vec4 ApplyDesaturation(float desaturation, vec4 color)\n"\
"{\n"\
" // This is intentionally done in gamma space\n"\
" if (desaturation == 0.0)\n"\
" return color;\n"\
"\n"\
" float grayLevel = dot(color.rgb, vec3(3.0, 6.0, 1.0) / 10.0);\n"\
"\n"\
" color.rgb = color.rgb * (1.0 - desaturation) + vec3(grayLevel, grayLevel, grayLevel) * desaturation;\n"\
" return color;\n"\
"}\n"\
"\n"\
"float saturate(float v)\n"\
"{\n"\
" return min(1.0, max(0.0, v));\n"\
"}\n"\
"\n"\
"vec2 saturate(vec2 v)\n"\
"{\n"\
" return vec2(saturate(v.x), saturate(v.y));\n"\
"}\n"\
"\n"\
"vec3 saturate(vec3 v)\n"\
"{\n"\
" return vec3(saturate(v.x), saturate(v.y), saturate(v.z));\n"\
"}\n"\
"\n"\
"vec3 AppleRGBToSRGBLinear(vec3 color)\n"\
"{\n"\
" color = pow3(saturate(color), 1.8);\n"\
"\n"\
" vec3 result;\n"\
" result = color.r * vec3(1.06870538834699, 0.024110476735, 0.00173499822713);\n"\
" result += color.g * vec3(-0.07859532843279, 0.96007030899244, 0.02974755969275);\n"\
" result += color.b * vec3(0.00988984558395, 0.01581936633364, 0.96851741859153);\n"\
"\n"\
" return result;\n"\
"}\n"\
"\n"\
"vec3 ApplyColorSpaceTransform(vec3 color)\n"\
"{\n"\
"#ifdef USE_ICC_PROFILE\n"\
" return saturate(AppleRGBToSRGBLinear(color));\n"\
"#else\n"\
" return SRGBToLinear(color);\n"\
"#endif\n"\
"}\n"\
"\n"

View File

@@ -0,0 +1,50 @@
#include "Functions.h"
#define GP_GL_SHADER_CODE_SCALEQUADP_GLSL "uniform sampler2D surfaceTexture;\n"\
"varying vec4 texCoord;\n"\
"\n"\
"uniform vec4 dxdy_dimensions;\n"\
"\n"\
"vec3 SamplePixel(vec2 coord)\n"\
"{\n"\
" return texture2D(surfaceTexture, (coord + vec2(0.5, 0.5)) / dxdy_dimensions.zw).rgb;\n"\
"}\n"\
"\n"\
"void main()\n"\
"{\n"\
" float dx = dxdy_dimensions.x;\n"\
" float dy = dxdy_dimensions.y;\n"\
" vec2 dimensions = dxdy_dimensions.zw;\n"\
" vec2 texCoordInteger = dxdy_dimensions.zw;\n"\
"\n"\
" vec2 pixelTopLeftCoord = max(vec2(0.0, 0.0), texCoord.zw - vec2(dx, dy) * 0.5);\n"\
" vec2 pixelBottomRightCoord = pixelTopLeftCoord + min(vec2(1.0, 1.0), vec2(dx, dy));\n"\
"\n"\
" vec2 topLeftCoordInteger = floor(pixelTopLeftCoord);\n"\
" vec2 bottomRightCoordInteger = floor(pixelBottomRightCoord);\n"\
"\n"\
" vec2 interpolators = saturate((pixelBottomRightCoord - bottomRightCoordInteger) / vec2(dx, dy));\n"\
"\n"\
" vec3 topLeftColor = SamplePixel(topLeftCoordInteger);\n"\
" vec3 topRightColor = SamplePixel(vec2(bottomRightCoordInteger.x, topLeftCoordInteger.y));\n"\
" vec3 bottomLeftColor = SamplePixel(vec2(topLeftCoordInteger.x, bottomRightCoordInteger.y));\n"\
" vec3 bottomRightColor = SamplePixel(bottomRightCoordInteger);\n"\
"\n"\
" vec3 topColor = (1.0 - interpolators.x) * topLeftColor + interpolators.x * topRightColor;\n"\
" vec3 bottomColor = (1.0 - interpolators.x) * bottomLeftColor + interpolators.x * bottomRightColor;\n"\
" vec3 interpolatedColor = (1.0 - interpolators.y) * topColor + interpolators.y * bottomColor;\n"\
"\n"\
" gl_FragColor = vec4(LinearToSRGB(interpolatedColor), 1.0);\n"\
"}\n"
namespace GpBinarizedShaders
{
const char *g_scaleQuadP_GL2 = GP_GL_SHADER_CODE_FUNCTIONS_H GP_GL_SHADER_CODE_SCALEQUADP_GLSL;
extern const char *g_drawQuadRGBP_GL2;
extern const char *g_drawQuad15BitP_GL2;
extern const char *g_drawQuadRGBICCP_GL2;
extern const char *g_drawQuad15BitICCP_GL2;
}

View File

@@ -2,7 +2,8 @@
enum EGpDisplayDriverType
{
EGpDisplayDriverType_D3D11,
EGpDisplayDriverType_D3D11,
EGpDisplayDriverType_SDL_GL2,
EGpDisplayDriverType_Count,
};

View File

@@ -3,6 +3,8 @@
#include "GpPixelFormat.h"
#include "EGpStandardCursor.h"
#include <stdint.h>
struct IGpDisplayDriverSurface;
struct IGpCursor;
struct IGpPrefsHandler;
@@ -30,7 +32,7 @@ public:
virtual void GetDisplayResolution(unsigned int *width, unsigned int *height) = 0;
virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) = 0;
virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat) = 0;
virtual void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects) = 0;
virtual IGpCursor *LoadCursor(bool isColor, int cursorID) = 0;

View File

@@ -4,6 +4,6 @@
struct IGpFiber
{
virtual void YieldTo() = 0;
virtual void YieldTo(IGpFiber *toFiber) = 0;
virtual void Destroy() = 0;
};

View File

@@ -1245,7 +1245,7 @@ void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned in
*height = m_windowHeightVirtual;
}
IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat)
IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat)
{
return GpDisplayDriverSurfaceD3D11::Create(m_device, m_deviceContext, width, height, pixelFormat);
}

View File

@@ -41,7 +41,7 @@ public:
void GetDisplayResolution(unsigned int *width, unsigned int *height) override;
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) override;
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat) override;
void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects) override;
IGpCursor *LoadCursor(bool isColor, int cursorID) override;

View File

@@ -2,7 +2,9 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup>
<IncludePath>$(SolutionDir)Aerofoil;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>GP_APP_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@@ -57,7 +57,7 @@ GpDisplayDriverTickStatus_t GpAppEnvironment::Tick(IGpFiber *vosFiber)
return GpDisplayDriverTickStatuses::kOK;
case ApplicationState_Running:
SynchronizeState();
m_applicationFiber->YieldTo();
m_vosFiber->YieldTo(m_applicationFiber);
break;
case ApplicationState_SystemCall:
{
@@ -135,7 +135,7 @@ void GpAppEnvironment::AppThreadFunc()
GpAppInterface_Get()->ApplicationMain();
m_applicationState = ApplicationState_Terminated;
m_vosFiber->YieldTo();
m_applicationFiber->YieldTo(m_vosFiber);
}
void GpAppEnvironment::InitializeApplicationState()
@@ -165,7 +165,7 @@ void GpAppEnvironment::StaticSuspendHookFunc(void *context, PortabilityLayer::Ho
appEnv->m_suspendReturnValue = returnValue;
appEnv->m_applicationState = ApplicationState_SystemCall;
appEnv->m_vosFiber->YieldTo();
appEnv->m_applicationFiber->YieldTo(appEnv->m_vosFiber);
}
void GpAppEnvironment::DispatchSystemCall(PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)

View File

@@ -28,7 +28,7 @@ void DrawSurface::PushToDDSurface(IGpDisplayDriver *displayDriver)
}
if (m_ddSurface == nullptr)
m_ddSurface = displayDriver->CreateSurface(pixMap->m_rect.right - pixMap->m_rect.left, pixMap->m_rect.bottom - pixMap->m_rect.top, pixMap->m_pixelFormat);
m_ddSurface = displayDriver->CreateSurface(pixMap->m_rect.right - pixMap->m_rect.left, pixMap->m_rect.bottom - pixMap->m_rect.top, pixMap->m_pitch, pixMap->m_pixelFormat);
if (m_port.IsDirty(PortabilityLayer::QDPortDirtyFlag_Contents) && m_ddSurface != nullptr)
{

View File

@@ -6,6 +6,7 @@
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>GP_DEBUG_CONFIG=0;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />