Compare commits

..

7 Commits

Author SHA1 Message Date
elasota
611f53ef91 Fix audio driver starting in debug mode, add -diagnostics mode 2020-05-29 21:56:33 -04:00
elasota
98afd82d64 Fix missing NDEBUG flags 2020-05-29 01:45:40 -04:00
elasota
efae9cacd8 Add PDB directory to release script 2020-05-29 00:00:11 -04:00
elasota
5184d1594f Fix comment typo 2020-05-28 23:10:30 -04:00
elasota
42e124a90c Fix crash if audio init fails (especially if there are no output devices) 2020-05-28 23:05:32 -04:00
elasota
11628ddd93 Fix link crash 2020-05-27 18:06:22 -04:00
elasota
7d5f844fd4 Fix bad usage formatting 2020-05-27 18:06:12 -04:00
39 changed files with 595 additions and 46 deletions

View File

@@ -156,6 +156,7 @@
<ClCompile Include="GpFontHandler_FreeType2.cpp" />
<ClCompile Include="GpGlobalConfig.cpp" />
<ClCompile Include="GpInputDriverFactory.cpp" />
<ClCompile Include="GpLogDriver_Win32.cpp" />
<ClCompile Include="GpMain.cpp" />
<ClCompile Include="GpMain_Win32.cpp" />
<ClCompile Include="GpMemoryBuffer.cpp" />
@@ -175,6 +176,7 @@
<ClInclude Include="..\GpCommon\IGpCursor.h" />
<ClInclude Include="..\GpCommon\IGpAudioChannelCallbacks.h" />
<ClInclude Include="..\GpCommon\IGpDisplayDriverSurface.h" />
<ClInclude Include="..\GpCommon\IGpLogDriver.h" />
<ClInclude Include="GpAppEnvironment.h" />
<ClInclude Include="GpAudioDriverFactory.h" />
<ClInclude Include="GpDisplayDriverFactory.h" />
@@ -185,6 +187,7 @@
<ClInclude Include="GpFontHandlerFactory.h" />
<ClInclude Include="GpGlobalConfig.h" />
<ClInclude Include="GpInputDriverFactory.h" />
<ClInclude Include="GpLogDriver_Win32.h" />
<ClInclude Include="GpMain.h" />
<ClInclude Include="GpMemoryBuffer.h" />
<ClInclude Include="GpMutex_Win32.h" />

View File

@@ -58,6 +58,9 @@
<ClCompile Include="GpThreadEvent_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpLogDriver_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\GpCommon\EGpInputDriverType.h">
@@ -141,6 +144,10 @@
<ClInclude Include="resource.h">
<Filter>Resource Files</Filter>
</ClInclude>
<ClInclude Include="..\GpCommon\IGpLogDriver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpLogDriver_Win32.h" />
</ItemGroup>
<ItemGroup>
<Image Include="ConvertedResources\Large128.ico">

View File

@@ -142,3 +142,8 @@ void GpFileStream_Win32::Close()
{
CloseHandle(m_handle);
}
void GpFileStream_Win32::Flush()
{
FlushFileBuffers(m_handle);
}

View File

@@ -20,7 +20,8 @@ public:
bool Truncate(PortabilityLayer::UFilePos_t loc) override;
PortabilityLayer::UFilePos_t Size() const override;
PortabilityLayer::UFilePos_t Tell() const override;
void Close() override;
void Close() override;
void Flush() override;
private:
HANDLE m_handle;

View File

@@ -122,16 +122,19 @@ GpFileSystem_Win32::GpFileSystem_Win32()
m_userHousesDir = m_prefsDir + L"\\Houses";
m_userSavesDir = m_prefsDir + L"\\SavedGames";
m_scoresDir = m_prefsDir + L"\\Scores";
m_logsDir = m_prefsDir + L"\\Logs";
CreateDirectoryW(m_prefsDir.c_str(), nullptr);
CreateDirectoryW(m_scoresDir.c_str(), nullptr);
CreateDirectoryW(m_userHousesDir.c_str(), nullptr);
CreateDirectoryW(m_userSavesDir.c_str(), nullptr);
CreateDirectoryW(m_logsDir.c_str(), nullptr);
m_prefsDir.append(L"\\");
m_scoresDir.append(L"\\");
m_userHousesDir.append(L"\\");
m_userSavesDir.append(L"\\");
m_logsDir.append(L"\\");
}
DWORD modulePathSize = GetModuleFileNameW(nullptr, m_executablePath, MAX_PATH);
@@ -514,6 +517,9 @@ bool GpFileSystem_Win32::ResolvePath(PortabilityLayer::VirtualDirectory_t virtua
case PortabilityLayer::VirtualDirectories::kHighScores:
baseDir = m_scoresDir.c_str();
break;
case PortabilityLayer::VirtualDirectories::kLogs:
baseDir = m_logsDir.c_str();
break;
default:
return false;
}

View File

@@ -34,6 +34,7 @@ private:
std::wstring m_scoresDir;
std::wstring m_packagedDir;
std::wstring m_housesDir;
std::wstring m_logsDir;
std::wstring m_userHousesDir;
std::wstring m_userSavesDir;
std::wstring m_resourcesDir;

View File

@@ -2,7 +2,9 @@
#include "EGpDisplayDriverType.h"
#include "EGpAudioDriverType.h"
#include "EGpInputDriverType.h"
#include "EGpInputDriverType.h"
struct IGpLogDriver;
struct GpGlobalConfig
{
@@ -11,6 +13,7 @@ struct GpGlobalConfig
const EGpInputDriverType *m_inputDriverTypes;
size_t m_numInputDrivers;
IGpLogDriver *m_logger;
void *m_osGlobals;
};

View File

@@ -0,0 +1,113 @@
#include "GpLogDriver_Win32.h"
#include "GpFileSystem_Win32.h"
#include "GpApplicationName.h"
#include "IOStream.h"
GpLogDriver_Win32::GpLogDriver_Win32()
: m_stream(nullptr)
, m_isInitialized(false)
{
}
void GpLogDriver_Win32::Init()
{
ms_instance.InitInternal();
}
void GpLogDriver_Win32::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++;
}
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
char timestampBuffer[64];
sprintf(timestampBuffer, "[%02d:%02d:%02d:%03d] ", sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds);
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])
m_stream->Write(debugTag, strlen(debugTag));
if (!hasFormatting)
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);
m_stream->Write(charBuff, formattedSize);
free(charBuff);
}
m_stream->Write("\n", 1);
m_stream->Flush();
}
void GpLogDriver_Win32::Shutdown()
{
if (m_stream)
m_stream->Close();
}
GpLogDriver_Win32 *GpLogDriver_Win32::GetInstance()
{
if (ms_instance.m_isInitialized)
return &ms_instance;
else
return nullptr;
}
void GpLogDriver_Win32::InitInternal()
{
SYSTEMTIME utcTime;
GetSystemTime(&utcTime);
char logFileName[256];
sprintf(logFileName, GP_APPLICATION_NAME "-%04d-%02d-%02d_%02d-%02d_%02d.txt", utcTime.wYear, utcTime.wMonth, utcTime.wDay, utcTime.wHour, utcTime.wMinute, utcTime.wSecond);
m_stream = GpFileSystem_Win32::GetInstance()->OpenFile(PortabilityLayer::VirtualDirectories::kLogs, logFileName, true, GpFileCreationDispositions::kCreateOrOverwrite);
if (m_stream)
{
this->Printf(IGpLogDriver::Category_Information, GP_APPLICATION_NAME " build " __TIMESTAMP__);
#ifdef NDEBUG
this->Printf(IGpLogDriver::Category_Information, "Configuration: Release");
#else
this->Printf(IGpLogDriver::Category_Information, "Configuration: Debug");
#endif
m_isInitialized = true;
}
}
GpLogDriver_Win32 GpLogDriver_Win32::ms_instance;

View File

@@ -0,0 +1,29 @@
#pragma once
#include "IGpLogDriver.h"
namespace PortabilityLayer
{
class IOStream;
}
class GpLogDriver_Win32 : public IGpLogDriver
{
public:
GpLogDriver_Win32();
static void Init();
void VPrintf(Category category, const char *fmt, va_list args) override;
void Shutdown() override;
static GpLogDriver_Win32 *GetInstance();
private:
void InitInternal();
PortabilityLayer::IOStream *m_stream;
bool m_isInitialized;
static GpLogDriver_Win32 ms_instance;
};

View File

@@ -63,6 +63,7 @@ int GpMain::Run()
ddProps.m_type = g_gpGlobalConfig.m_displayDriverType;
ddProps.m_osGlobals = g_gpGlobalConfig.m_osGlobals;
ddProps.m_eventQueue = eventQueue;
ddProps.m_logger = g_gpGlobalConfig.m_logger;
GpAudioDriverProperties adProps;
memset(&adProps, 0, sizeof(adProps));
@@ -72,10 +73,11 @@ int GpMain::Run()
adProps.m_type = g_gpGlobalConfig.m_audioDriverType;
adProps.m_sampleRate = (244800 * 2 + 11) / (11 * 2);
#ifdef NDEBUG
adProps.m_debug = true;
#else
adProps.m_debug = false;
#else
adProps.m_debug = true;
#endif
adProps.m_logger = g_gpGlobalConfig.m_logger;
IGpInputDriver **inputDrivers = static_cast<IGpInputDriver**>(malloc(sizeof(IGpInputDriver*) * g_gpGlobalConfig.m_numInputDrivers));

View File

@@ -5,6 +5,7 @@
#include "GpGlobalConfig.h"
#include "GpFiber_Win32.h"
#include "GpFileSystem_Win32.h"
#include "GpLogDriver_Win32.h"
#include "GpInputDriverFactory.h"
#include "GpAppInterface.h"
#include "GpSystemServices_Win32.h"
@@ -17,6 +18,7 @@
#include "resource.h"
#include <shellapi.h>
#include <stdio.h>
#include <windowsx.h>
@@ -394,12 +396,28 @@ static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
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 = lpCmdLine;
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;
@@ -422,10 +440,21 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
g_gpGlobalConfig.m_numInputDrivers = sizeof(inputDrivers) / sizeof(inputDrivers[0]);
g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals;
g_gpGlobalConfig.m_logger = logger;
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDriver_CreateDisplayDriver_D3D11);
GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_XAudio2, GpDriver_CreateAudioDriver_XAudio2);
GpInputDriverFactory::RegisterInputDriverFactory(EGpInputDriverType_XInput, GpDriver_CreateInputDriver_XInput);
return GpMain::Run();
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "Windows environment configured, starting up");
int returnCode = GpMain::Run();
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "Windows environment exited with code %i, cleaning up", returnCode);
LocalFree(cmdLineArgs);
return returnCode;
}

View File

@@ -69,6 +69,7 @@
<Import Project="GpApp.props" />
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
<Import Project="..\Release.props" />
</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" />

View File

@@ -5,6 +5,7 @@
#include "HostFileSystem.h"
#include "HostFontHandler.h"
#include "HostDisplayDriver.h"
#include "HostLogDriver.h"
#include "HostSystemServices.h"
#include "HostVOSEventQueue.h"
#include "MenuManager.h"
@@ -22,6 +23,7 @@ public:
void PL_HostDisplayDriver_SetInstance(IGpDisplayDriver *instance) override;
void PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) override;
void PL_HostAudioDriver_SetInstance(IGpAudioDriver *instance) override;
void PL_HostLogDriver_SetInstance(IGpLogDriver *instance) override;
void PL_HostFontHandler_SetInstance(PortabilityLayer::HostFontHandler *instance) override;
void PL_HostVOSEventQueue_SetInstance(PortabilityLayer::HostVOSEventQueue *instance) override;
void PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) override;
@@ -55,6 +57,11 @@ void GpAppInterfaceImpl::PL_HostDisplayDriver_SetInstance(IGpDisplayDriver *inst
PortabilityLayer::HostDisplayDriver::SetInstance(instance);
}
void GpAppInterfaceImpl::PL_HostLogDriver_SetInstance(IGpLogDriver *instance)
{
PortabilityLayer::HostLogDriver::SetInstance(instance);
}
void GpAppInterfaceImpl::PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance)
{
PortabilityLayer::HostSystemServices::SetInstance(instance);

View File

@@ -244,12 +244,13 @@ void OpenLinkWindow (void)
basicState.m_text.Set(4, "Link");
basicState.m_window = linkWindow;
linkControl = PortabilityLayer::ButtonWidget::Create(basicState, nullptr);
PortabilityLayer::ButtonWidget::AdditionalData addlData;
linkControl = PortabilityLayer::ButtonWidget::Create(basicState, &addlData);
basicState.m_rect = Rect::Create(5, 5, 25, 59);
basicState.m_text.Set(6, "Unlink");
basicState.m_window = linkWindow;
unlinkControl = PortabilityLayer::ButtonWidget::Create(basicState, nullptr);
unlinkControl = PortabilityLayer::ButtonWidget::Create(basicState, &addlData);
linkWindow->DrawControls();

View File

@@ -134,7 +134,7 @@ void ToggleMusicWhilePlaying (void)
void SetMusicalMode (short newMode)
{
if (dontLoadMusic)
if (dontLoadMusic || failedMusic)
return;
musicMutex->Lock();
@@ -302,6 +302,12 @@ void InitMusic (void)
return;
}
theErr = OpenMusicChannel();
if (theErr != PLErrors::kNone)
{
YellowAlert(kYellowNoMusic, theErr);
failedMusic = true;
return;
}
musicScore[0] = 0;
musicScore[1] = 1;

View File

@@ -1,19 +1,30 @@
#include "GpAudioChannelXAudio2.h"
#include "GpAudioDriverXAudio2.h"
#include "IGpAudioChannelCallbacks.h"
#include "IGpLogDriver.h"
#include <stdlib.h>
#include <new>
GpAudioChannelXAudio2 *GpAudioChannelXAudio2::Create(GpAudioDriverXAudio2 *driver)
{
IGpLogDriver *logger = driver->GetProperties().m_logger;
void *storage = malloc(sizeof(GpAudioChannelXAudio2));
if (!storage)
{
if (!logger)
logger->Printf(IGpLogDriver::Category_Error, "GpAudioChannelXAudio2::Create failed, malloc failed");
return nullptr;
}
GpAudioChannelXAudio2 *channel = new (storage) GpAudioChannelXAudio2(driver);
if (!channel->Init())
{
if (!logger)
logger->Printf(IGpLogDriver::Category_Error, "GpAudioChannelXAudio2::Init failed");
channel->Destroy();
return nullptr;
}
@@ -23,6 +34,8 @@ GpAudioChannelXAudio2 *GpAudioChannelXAudio2::Create(GpAudioDriverXAudio2 *drive
bool GpAudioChannelXAudio2::Init()
{
IGpLogDriver *logger = m_driver->GetProperties().m_logger;
const unsigned int sampleRate = m_driver->GetRealSampleRate();
IXAudio2 *const xa2 = m_driver->GetXA2();
@@ -49,7 +62,12 @@ bool GpAudioChannelXAudio2::Init()
HRESULT hr = xa2->CreateSourceVoice(&m_sourceVoice, &format, XAUDIO2_VOICE_NOPITCH | XAUDIO2_VOICE_NOSRC, 1.0f, &m_xAudioCallbacks, nullptr, nullptr);
if (hr != S_OK)
{
if (!logger)
logger->Printf(IGpLogDriver::Category_Error, "CreateSourceVoice failed with code %lx", hr);
return false;
}
return true;
}

View File

@@ -1,5 +1,6 @@
#include "GpAudioDriverXAudio2.h"
#include "IGpLogDriver.h"
#include "GpAudioChannelXAudio2.h"
#include <xaudio2.h>
@@ -31,34 +32,62 @@ unsigned int GpAudioDriverXAudio2::GetRealSampleRate() const
GpAudioDriverXAudio2 *GpAudioDriverXAudio2::Create(const GpAudioDriverProperties &properties)
{
IGpLogDriver *logger = properties.m_logger;
IXAudio2 *xa = nullptr;
IXAudio2MasteringVoice *mv = nullptr;
const unsigned int realSampleRate = (properties.m_sampleRate + 50) / XAUDIO2_QUANTUM_DENOMINATOR * XAUDIO2_QUANTUM_DENOMINATOR;
if (CoInitializeEx(nullptr, COINIT_MULTITHREADED) != S_OK)
if (logger)
{
logger->Printf(IGpLogDriver::Category_Information, "XAudio2 Driver starting");
logger->Printf(IGpLogDriver::Category_Information, "Real sample rate: %u", realSampleRate);
}
HRESULT result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "CoInitializeEx failed with code %lx", result);
CoUninitialize();
return nullptr;
}
UINT flags = 0;
if (properties.m_debug)
flags |= XAUDIO2_DEBUG_ENGINE;
if (FAILED(XAudio2Create(&xa, flags, XAUDIO2_DEFAULT_PROCESSOR)))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "Starting XAudio in debug mode");
flags |= XAUDIO2_DEBUG_ENGINE;
}
result = XAudio2Create(&xa, flags, XAUDIO2_DEFAULT_PROCESSOR);
if (FAILED(result))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "XAudio2Create failed with code %lx", result);
CoUninitialize();
return nullptr;
}
if (FAILED(xa->CreateMasteringVoice(&mv, 2, realSampleRate, 0, nullptr, nullptr, AudioCategory_GameEffects)))
result = xa->CreateMasteringVoice(&mv, 2, realSampleRate, 0, nullptr, nullptr, AudioCategory_GameEffects);
if (FAILED(result))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "CreateMasteringVoice failed with code %lx", result);
CoUninitialize();
xa->Release();
return nullptr;
}
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "XAudio2 started OK", result);
return new GpAudioDriverXAudio2(properties, realSampleRate, xa, mv);
}

View File

@@ -63,6 +63,7 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\GpCommon.props" />
<Import Project="..\Release.props" />
</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" />
@@ -71,6 +72,7 @@
<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="..\GpCommon.props" />
<Import Project="..\Release.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />

View File

@@ -3,6 +3,7 @@
#include "EGpAudioDriverType.h"
struct IGpAudioDriver;
struct IGpLogDriver;
struct GpAudioDriverProperties
{
@@ -10,4 +11,6 @@ struct GpAudioDriverProperties
unsigned int m_sampleRate;
bool m_debug;
IGpLogDriver *m_logger;
};

View File

@@ -8,6 +8,7 @@
struct IGpDisplayDriver;
struct IGpFiber;
struct IGpVOSEventQueue;
struct IGpLogDriver;
struct GpDisplayDriverProperties
{
@@ -39,4 +40,5 @@ struct GpDisplayDriverProperties
void *m_adjustRequestedResolutionFuncContext;
IGpVOSEventQueue *m_eventQueue;
IGpLogDriver *m_logger;
};

View File

@@ -19,7 +19,9 @@ struct GpWindowsGlobals
{
HINSTANCE m_hInstance;
HINSTANCE m_hPrevInstance;
LPCSTR m_cmdLine;
LPCWSTR m_cmdLine;
int m_cmdLineArgc;
LPWSTR *m_cmdLineArgv;
LPCWSTR m_baseDir;
HWND m_hwnd;
HICON m_hIcon;

28
GpCommon/IGpLogDriver.h Normal file
View File

@@ -0,0 +1,28 @@
#pragma once
#include <cstdarg>
#include <stdio.h>
struct IGpLogDriver
{
enum Category
{
Category_Information,
Category_Warning,
Category_Error,
};
virtual void VPrintf(Category category, const char *fmt, va_list args) = 0;
virtual void Shutdown() = 0;
void Printf(Category category, const char *fmt, ...);
};
inline void IGpLogDriver::Printf(Category category, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
this->VPrintf(category, fmt, args);
va_end(args);
}

View File

@@ -7,6 +7,8 @@
#include "IGpFiber.h"
#include "IGpVOSEventQueue.h"
#include "IGpLogDriver.h"
#include <d3d11.h>
#include <dxgi1_2.h>
#include <float.h>
@@ -125,7 +127,7 @@ bool ResizeSwapChain(IDXGISwapChain1 *swapChain, UINT width, UINT height)
return true;
}
void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpComPtr<ID3D11Device>& outDevice, GpComPtr<ID3D11DeviceContext>& outContext)
void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpComPtr<ID3D11Device>& outDevice, GpComPtr<ID3D11DeviceContext>& outContext, IGpLogDriver *logger)
{
DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullscreenDesc;
@@ -153,6 +155,14 @@ void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpCom
HRESULT result = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, featureLevels, sizeof(featureLevels) / sizeof(featureLevels[0]),
D3D11_SDK_VERSION, &device, &selectedFeatureLevel, &context);
if (logger)
{
if (result == S_OK)
logger->Printf(IGpLogDriver::Category_Information, "StartD3DForWindow: D3D11CreateDevice succeeded. Selected feature level is %i", static_cast<int>(selectedFeatureLevel));
else
logger->Printf(IGpLogDriver::Category_Error, "StartD3DForWindow: D3D11CreateDevice failed with code %lx", result);
}
InitSwapChainForWindow(hWnd, device, outSwapChain);
// GP TODO: Fix the error handling here, it's bad...
@@ -160,8 +170,11 @@ void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpCom
outContext = context;
}
bool ResizeD3DWindow(HWND hWnd, DWORD &windowWidth, DWORD &windowHeight, LONG desiredWidth, LONG desiredHeight, DWORD windowStyle, HMENU menus)
bool ResizeD3DWindow(HWND hWnd, DWORD &windowWidth, DWORD &windowHeight, LONG desiredWidth, LONG desiredHeight, DWORD windowStyle, HMENU menus, IGpLogDriver *logger)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "ResizeD3DWindow: %i x %i", static_cast<int>(desiredWidth), static_cast<int>(desiredHeight));
if (desiredWidth < 640)
desiredWidth = 640;
else if (desiredWidth > MAXDWORD)
@@ -172,6 +185,9 @@ bool ResizeD3DWindow(HWND hWnd, DWORD &windowWidth, DWORD &windowHeight, LONG de
else if (desiredHeight > MAXDWORD)
desiredHeight = MAXDWORD;
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "ResizeD3DWindow: Adjusted dimensions: %i x %i", static_cast<int>(desiredWidth), static_cast<int>(desiredHeight));
RECT windowRect;
GetClientRect(hWnd, &windowRect);
windowRect.right = windowRect.left + desiredWidth;
@@ -180,9 +196,20 @@ bool ResizeD3DWindow(HWND hWnd, DWORD &windowWidth, DWORD &windowHeight, LONG de
LONG_PTR style = GetWindowLongPtrA(hWnd, GWL_STYLE);
if (!AdjustWindowRect(&windowRect, static_cast<DWORD>(style), menus != nullptr))
return false;
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "ResizeD3DWindow: AdjustWindowRect failed");
SetWindowPos(hWnd, HWND_TOP, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOZORDER | SWP_NOMOVE);
return false;
}
if (!SetWindowPos(hWnd, HWND_TOP, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOZORDER | SWP_NOMOVE))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "ResizeD3DWindow: SetWindowPos failed");
return false;
}
windowWidth = desiredWidth;
windowHeight = desiredHeight;
@@ -192,6 +219,11 @@ bool ResizeD3DWindow(HWND hWnd, DWORD &windowWidth, DWORD &windowHeight, LONG de
bool GpDisplayDriverD3D11::DetachSwapChain()
{
IGpLogDriver *logger = m_properties.m_logger;
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "GpDisplayDriverD3D11::DetachSwapChain");
m_deviceContext->OMSetRenderTargets(0, nullptr, nullptr);
m_backBufferRTV = nullptr;
m_backBufferTexture = nullptr;
@@ -204,6 +236,11 @@ bool GpDisplayDriverD3D11::DetachSwapChain()
bool GpDisplayDriverD3D11::InitBackBuffer(uint32_t virtualWidth, uint32_t virtualHeight)
{
IGpLogDriver *logger = m_properties.m_logger;
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "GpDisplayDriverD3D11::InitBackBuffer");
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<LPVOID*>(m_backBufferTexture.GetMutablePtr()));
{
@@ -216,8 +253,14 @@ bool GpDisplayDriverD3D11::InitBackBuffer(uint32_t virtualWidth, uint32_t virtua
rtvDesc.Texture2D.MipSlice = 0;
m_backBufferRTV = nullptr;
if (m_device->CreateRenderTargetView(m_backBufferTexture, &rtvDesc, m_backBufferRTV.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateRenderTargetView(m_backBufferTexture, &rtvDesc, m_backBufferRTV.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitBackBuffer: CreateRenderTargetView for back buffer failed with code %lx", result);
return false;
}
}
DXGI_FORMAT vbbFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
@@ -237,8 +280,14 @@ bool GpDisplayDriverD3D11::InitBackBuffer(uint32_t virtualWidth, uint32_t virtua
vbbTextureDesc.MiscFlags = 0;
m_virtualScreenTexture = nullptr;
if (m_device->CreateTexture2D(&vbbTextureDesc, nullptr, m_virtualScreenTexture.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateTexture2D(&vbbTextureDesc, nullptr, m_virtualScreenTexture.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitBackBuffer: CreateTexture2D for virtual screen texture failed with code %lx", result);
return false;
}
}
{
@@ -248,8 +297,14 @@ bool GpDisplayDriverD3D11::InitBackBuffer(uint32_t virtualWidth, uint32_t virtua
rtvDesc.Texture2D.MipSlice = 0;
m_virtualScreenTextureRTV = nullptr;
if (m_device->CreateRenderTargetView(m_virtualScreenTexture, &rtvDesc, m_virtualScreenTextureRTV.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateRenderTargetView(m_virtualScreenTexture, &rtvDesc, m_virtualScreenTextureRTV.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitBackBuffer: CreateRenderTargetView for virtual screen texture failed with code %lx", result);
return false;
}
}
{
@@ -260,8 +315,14 @@ bool GpDisplayDriverD3D11::InitBackBuffer(uint32_t virtualWidth, uint32_t virtua
srvDesc.Texture2D.MostDetailedMip = 0;
m_virtualScreenTextureSRV = nullptr;
if (m_device->CreateShaderResourceView(m_virtualScreenTexture, &srvDesc, m_virtualScreenTextureSRV.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateShaderResourceView(m_virtualScreenTexture, &srvDesc, m_virtualScreenTextureSRV.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitBackBuffer: CreateRenderTargetView for virtual screen texture failed with code %lx", result);
return false;
}
}
return true;
@@ -269,6 +330,11 @@ bool GpDisplayDriverD3D11::InitBackBuffer(uint32_t virtualWidth, uint32_t virtua
bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtualHeight)
{
IGpLogDriver *logger = m_properties.m_logger;
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "GpDisplayDriverD3D11::InitResources");
if (!InitBackBuffer(virtualWidth, virtualHeight))
return false;
@@ -282,8 +348,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
if (m_device->CreateBuffer(&bufferDesc, nullptr, m_drawQuadVertexConstantBuffer.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateBuffer(&bufferDesc, nullptr, m_drawQuadVertexConstantBuffer.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateBuffer for draw quad vertex constant buffer failed with code %lx", result);
return false;
}
}
// Quad pixel constant buffer
@@ -296,8 +368,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
if (m_device->CreateBuffer(&bufferDesc, nullptr, m_drawQuadPixelConstantBuffer.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateBuffer(&bufferDesc, nullptr, m_drawQuadPixelConstantBuffer.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateBuffer for draw quad pixel constant buffer failed with code %lx", result);
return false;
}
}
// Quad index buffer
@@ -317,8 +395,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
initialData.SysMemPitch = 0;
initialData.SysMemSlicePitch = 0;
if (m_device->CreateBuffer(&bufferDesc, &initialData, m_quadIndexBuffer.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateBuffer(&bufferDesc, &initialData, m_quadIndexBuffer.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateBuffer for draw quad index buffer failed with code %lx", result);
return false;
}
}
// Quad vertex buffer
@@ -344,8 +428,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
initialData.SysMemPitch = 0;
initialData.SysMemSlicePitch = 0;
if (m_device->CreateBuffer(&bufferDesc, &initialData, m_quadVertexBuffer.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateBuffer(&bufferDesc, &initialData, m_quadVertexBuffer.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateBuffer for draw quad vertex buffer failed with code %lx", result);
return false;
}
}
{
@@ -357,8 +447,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
if (m_device->CreateBuffer(&bufferDesc, nullptr, m_scaleQuadPixelConstantBuffer.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateBuffer(&bufferDesc, nullptr, m_scaleQuadPixelConstantBuffer.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateBuffer for scale quad pixel constant buffer failed with code %lx", result);
return false;
}
}
const GpShaderCodeBlob drawQuadVBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuadV_D3D11);
@@ -386,7 +482,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
0 // Instance data step rate
};
m_device->CreateInputLayout(descs, sizeof(descs) / sizeof(descs[0]), drawQuadVBlob.m_data, drawQuadVBlob.m_size, m_drawQuadInputLayout.GetMutablePtr());
HRESULT result = m_device->CreateInputLayout(descs, sizeof(descs) / sizeof(descs[0]), drawQuadVBlob.m_data, drawQuadVBlob.m_size, m_drawQuadInputLayout.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateInputLayout for draw quad input failed with code %lx", result);
return false;
}
}
// Quad depth stencil state
@@ -407,8 +510,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
if (m_device->CreateDepthStencilState(&desc, m_drawQuadDepthStencilState.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateDepthStencilState(&desc, m_drawQuadDepthStencilState.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateDepthStencilState for draw quad with code %lx", result);
return false;
}
}
// Nearest neighbor sampler desc
@@ -425,8 +534,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
samplerDesc.MinLOD = -FLT_MAX;
samplerDesc.MaxLOD = FLT_MAX;
if (m_device->CreateSamplerState(&samplerDesc, m_nearestNeighborSamplerState.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateSamplerState(&samplerDesc, m_nearestNeighborSamplerState.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateSamplerState for nearest neighbor failed with code %lx", result);
return false;
}
}
DXGI_FORMAT paletteTextureFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
@@ -455,8 +570,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
initialData.SysMemPitch = 256 * 4;
initialData.SysMemSlicePitch = 256 * 4;
if (m_device->CreateTexture1D(&desc, &initialData, m_paletteTexture.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateTexture1D(&desc, &initialData, m_paletteTexture.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateTexture1D for palette failed with code %lx", result);
return false;
}
}
// Palette texture SRV
@@ -467,8 +588,14 @@ bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtual
desc.Texture1D.MostDetailedMip = 0;
desc.Texture1D.MipLevels = 1;
if (m_device->CreateShaderResourceView(m_paletteTexture, &desc, m_paletteTextureSRV.GetMutablePtr()) != S_OK)
HRESULT result = m_device->CreateShaderResourceView(m_paletteTexture, &desc, m_paletteTextureSRV.GetMutablePtr());
if (result != S_OK)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::InitResources: CreateShaderResourceView for palette failed with code %lx", result);
return false;
}
}
return true;
@@ -791,11 +918,21 @@ void GpDisplayDriverD3D11::ChangeToStandardCursor(EGpStandardCursor_t cursor)
void GpDisplayDriverD3D11::BecomeFullScreen(LONG &windowStyle)
{
IGpLogDriver *logger = m_properties.m_logger;
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "GpDisplayDriverD3D11::BecomeFullScreen");
assert(!m_isFullScreen);
RECT windowRect;
if (!GetWindowRect(m_osGlobals->m_hwnd, &windowRect))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::BecomeFullScreen: GetWindowRect failed");
return; // ???
}
HMONITOR monitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONULL);
if (!monitor)
@@ -810,17 +947,31 @@ void GpDisplayDriverD3D11::BecomeFullScreen(LONG &windowStyle)
}
if (!monitor)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::BecomeFullScreen: Couldn't find any monitors");
return; // No monitor?
}
MONITORINFO monitorInfo;
monitorInfo.cbSize = sizeof(monitorInfo);
if (!GetMonitorInfoA(monitor, &monitorInfo))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::BecomeFullScreen: GetMonitorInfoA failed");
return;
}
m_windowModeRevertRect = windowRect;
SetWindowLongPtr(m_osGlobals->m_hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
SetWindowPos(m_osGlobals->m_hwnd, HWND_TOP, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top, SWP_FRAMECHANGED);
if (!SetWindowPos(m_osGlobals->m_hwnd, HWND_TOP, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top, SWP_FRAMECHANGED))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::BecomeFullScreen: SetWindowPos failed");
}
m_isFullScreen = true;
windowStyle = (WS_VISIBLE | WS_POPUP);
@@ -828,6 +979,11 @@ void GpDisplayDriverD3D11::BecomeFullScreen(LONG &windowStyle)
void GpDisplayDriverD3D11::BecomeWindowed(LONG &windowStyle)
{
IGpLogDriver *logger = m_properties.m_logger;
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "GpDisplayDriverD3D11::BecomeWindowed");
assert(m_isFullScreen);
RECT revertRect = m_windowModeRevertRect;
@@ -838,12 +994,22 @@ void GpDisplayDriverD3D11::BecomeWindowed(LONG &windowStyle)
// If the window is off-screen, use the primary monitor
monitor = MonitorFromRect(&revertRect, MONITOR_DEFAULTTOPRIMARY);
if (!monitor)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::BecomeWindowed: MonitorFromRect fallback failed");
return;
}
MONITORINFO monitorInfo;
monitorInfo.cbSize = sizeof(monitorInfo);
if (!GetMonitorInfoA(monitor, &monitorInfo))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::BecomeWindowed: GetMonitorInfoA failed");
return;
}
RECT monitorRect = monitorInfo.rcWork;
LONG monitorWidth = monitorRect.right - monitorRect.left;
@@ -880,9 +1046,13 @@ void GpDisplayDriverD3D11::BecomeWindowed(LONG &windowStyle)
revertRect.right = revertRect.right + revertWidth;
}
SetWindowLongPtr(m_osGlobals->m_hwnd, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW);
SetWindowLongPtrW(m_osGlobals->m_hwnd, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW);
SetWindowPos(m_osGlobals->m_hwnd, HWND_TOP, revertRect.left, revertRect.top, revertRect.right - revertRect.left, revertRect.bottom - revertRect.top, SWP_FRAMECHANGED);
if (!SetWindowPos(m_osGlobals->m_hwnd, HWND_TOP, revertRect.left, revertRect.top, revertRect.right - revertRect.left, revertRect.bottom - revertRect.top, SWP_FRAMECHANGED))
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriverD3D11::BecomeWindowed: SetWindowPos failed");
}
m_isFullScreen = false;
windowStyle = (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
@@ -890,11 +1060,18 @@ void GpDisplayDriverD3D11::BecomeWindowed(LONG &windowStyle)
void GpDisplayDriverD3D11::Run()
{
IGpLogDriver *logger = m_properties.m_logger;
WNDCLASSEX wc;
LPVOID fiber = ConvertThreadToFiberEx(this, 0);
if (!fiber)
{
if (logger)
logger->Printf(IGpLogDriver::Category_Error, "ConvertThreadToFiberEx failed");
return; // ???
}
m_vosFiber = m_osGlobals->m_createFiberFunc(fiber);
@@ -923,7 +1100,7 @@ void GpDisplayDriverD3D11::Run()
ShowWindow(m_osGlobals->m_hwnd, m_osGlobals->m_nCmdShow);
StartD3DForWindow(m_osGlobals->m_hwnd, m_swapChain, m_device, m_deviceContext);
StartD3DForWindow(m_osGlobals->m_hwnd, m_swapChain, m_device, m_deviceContext, logger);
InitResources(m_windowWidthVirtual, m_windowHeightVirtual);
@@ -988,7 +1165,7 @@ void GpDisplayDriverD3D11::Run()
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
{
bool resizedOK = ResizeD3DWindow(m_osGlobals->m_hwnd, m_windowWidthPhysical, m_windowHeightPhysical, desiredWidth, desiredHeight, windowStyle, menus);
bool resizedOK = ResizeD3DWindow(m_osGlobals->m_hwnd, m_windowWidthPhysical, m_windowHeightPhysical, desiredWidth, desiredHeight, windowStyle, menus, logger);
resizedOK = resizedOK && DetachSwapChain();
resizedOK = resizedOK && ResizeSwapChain(m_swapChain, m_windowWidthPhysical, m_windowHeightPhysical);
resizedOK = resizedOK && InitBackBuffer(virtualWidth, virtualHeight);
@@ -1239,7 +1416,7 @@ void GpDisplayDriverD3D11::SetBackgroundColor(uint8_t r, uint8_t g, uint8_t b, u
void GpDisplayDriverD3D11::RequestToggleFullScreen(uint32_t timestamp)
{
// Alt-Enter gets re-sent after a full-screen toggle, so we ignore toggle requests until half a second has seconds have elapsed
// Alt-Enter gets re-sent after a full-screen toggle, so we ignore toggle requests until half a second has elapsed
if (timestamp > m_lastFullScreenToggleTimeStamp + 30)
{
m_isFullScreenDesired = !m_isFullScreenDesired;

View File

@@ -65,6 +65,7 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\GpCommon.props" />
<Import Project="..\Common.props" />
<Import Project="..\Release.props" />
</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" />
@@ -75,6 +76,7 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\GpCommon.props" />
<Import Project="..\Common.props" />
<Import Project="..\Release.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />

View File

@@ -63,6 +63,7 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\GpCommon.props" />
<Import Project="..\Release.props" />
</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" />
@@ -71,6 +72,7 @@
<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="..\GpCommon.props" />
<Import Project="..\Release.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />

View File

@@ -1,5 +1,7 @@
rmdir /S /Q ReleasePkg
mkdir ReleasePkg\PDBs
mkdir ReleasePkg\Aerofoil
mkdir ReleasePkg\Aerofoil\Packaged
mkdir ReleasePkg\Aerofoil\Resources
@@ -21,6 +23,9 @@ copy /Y x64\Release\FTagData.exe ReleasePkg\Aerofoil\Tools
copy /Y x64\Release\gpr2gpa.exe ReleasePkg\Aerofoil\Tools
copy /Y x64\Release\unpacktool.exe ReleasePkg\Aerofoil\Tools
copy /Y x64\Release\*.pdb ReleasePkg\PDBs
xcopy /I /E /Y /K Packaged ReleasePkg\Aerofoil\Packaged
xcopy /I /E /Y /K Resources ReleasePkg\Aerofoil\Resources
xcopy /I /E /Y /K Documentation ReleasePkg\Aerofoil\Documentation

View File

@@ -93,8 +93,15 @@ namespace PortabilityLayer
fclose(m_file);
m_file = nullptr;
}
}
void CFileStream::Flush()
{
if (m_file)
fflush(m_file);
}
UFilePos_t CFileStream::Size() const
{
if (!m_file || !m_seekable)

View File

@@ -27,7 +27,8 @@ namespace PortabilityLayer
bool Truncate(UFilePos_t loc) override;
UFilePos_t Size() const override;
UFilePos_t Tell() const override;
void Close() override;
void Close() override;
void Flush() override;
private:
CFileStream(const CFileStream &other) GP_DELETED;

View File

@@ -20,6 +20,7 @@
#endif
struct IGpAudioDriver;
struct IGpLogDriver;
namespace PortabilityLayer
{
@@ -41,6 +42,7 @@ public:
virtual void PL_HostAudioDriver_SetInstance(IGpAudioDriver *instance) = 0;
virtual void PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) = 0;
virtual void PL_HostDisplayDriver_SetInstance(IGpDisplayDriver *instance) = 0;
virtual void PL_HostLogDriver_SetInstance(IGpLogDriver *instance) = 0;
virtual void PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) = 0;
virtual void PL_HostFontHandler_SetInstance(PortabilityLayer::HostFontHandler *instance) = 0;
virtual void PL_HostVOSEventQueue_SetInstance(PortabilityLayer::HostVOSEventQueue *instance) = 0;

View File

@@ -0,0 +1,16 @@
#include "HostLogDriver.h"
namespace PortabilityLayer
{
void HostLogDriver::SetInstance(IGpLogDriver *instance)
{
ms_instance = instance;
}
IGpLogDriver *HostLogDriver::GetInstance()
{
return ms_instance;
}
IGpLogDriver *HostLogDriver::ms_instance;
}

View File

@@ -0,0 +1,16 @@
#pragma once
struct IGpLogDriver;
namespace PortabilityLayer
{
class HostLogDriver
{
public:
static void SetInstance(IGpLogDriver *instance);
static IGpLogDriver *GetInstance();
private:
static IGpLogDriver *ms_instance;
};
}

View File

@@ -23,6 +23,7 @@ namespace PortabilityLayer
virtual UFilePos_t Size() const = 0;
virtual UFilePos_t Tell() const = 0;
virtual void Close() = 0;
virtual void Flush() = 0;
};
}

View File

@@ -107,4 +107,8 @@ namespace PortabilityLayer
void MemReaderStream::Close()
{
}
void MemReaderStream::Flush()
{
}
}

View File

@@ -24,6 +24,7 @@ namespace PortabilityLayer
UFilePos_t Size() const override;
UFilePos_t Tell() const override;
void Close() override;
void Flush() override;
private:
MemReaderStream() GP_DELETED;

View File

@@ -353,12 +353,15 @@ namespace PortabilityLayer
AudioChannel *SoundSystemImpl::CreateChannel()
{
IGpAudioDriver *audioDriver = PortabilityLayer::HostAudioDriver::GetInstance();
if (!audioDriver)
return nullptr;
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
void *storage = mm->Alloc(sizeof(PortabilityLayer::AudioChannelImpl));
if (!storage)
return nullptr;
IGpAudioDriver *audioDriver = PortabilityLayer::HostAudioDriver::GetInstance();
IGpAudioChannel *audioChannel = audioDriver->CreateChannel();
if (!audioChannel)
{
@@ -388,7 +391,12 @@ namespace PortabilityLayer
void SoundSystemImpl::SetVolume(uint8_t vol)
{
PortabilityLayer::HostAudioDriver::GetInstance()->SetMasterVolume(vol, 255);
IGpAudioDriver *audioDriver = PortabilityLayer::HostAudioDriver::GetInstance();
if (!audioDriver)
return;
audioDriver->SetMasterVolume(vol, 255);
m_volume = vol;
}

View File

@@ -176,6 +176,7 @@
<ClInclude Include="HostFontHandler.h" />
<ClInclude Include="HostFontRenderedGlyph.h" />
<ClInclude Include="HostInputDriver.h" />
<ClInclude Include="HostLogDriver.h" />
<ClInclude Include="HostMutex.h" />
<ClInclude Include="HostSuspendCallArgument.h" />
<ClInclude Include="HostSuspendCallID.h" />
@@ -321,6 +322,7 @@
<ClCompile Include="HostDisplayDriver.cpp" />
<ClCompile Include="HostFileSystem.cpp" />
<ClCompile Include="HostFontHandler.cpp" />
<ClCompile Include="HostLogDriver.cpp" />
<ClCompile Include="HostSuspendHook.cpp" />
<ClCompile Include="HostSystemServices.cpp" />
<ClCompile Include="HostVOSEventQueue.cpp" />

View File

@@ -483,6 +483,9 @@
<ClInclude Include="ResolveCachingColor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HostLogDriver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CFileStream.cpp">
@@ -758,5 +761,8 @@
<ClCompile Include="ResolveCachingColor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HostLogDriver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -16,6 +16,7 @@ namespace PortabilityLayer
kFonts,
kCursors,
kHighScores,
kLogs,
};
}

View File

@@ -1342,10 +1342,10 @@ int ConvertDirectory(const std::string &basePath, const PortabilityLayer::Combin
int PrintUsage()
{
fprintf(stderr, "Usage: gpr2gpa <input.gpr> <input.ts> <output.gpa> [patch.json]");
fprintf(stderr, " gpr2gpa <input dir>\* <input.ts>");
fprintf(stderr, " gpr2gpa <input dir>/* <input.ts>");
fprintf(stderr, " gpr2gpa * <input.ts>");
fprintf(stderr, "Usage: gpr2gpa <input.gpr> <input.ts> <output.gpa> [patch.json]\n");
fprintf(stderr, " gpr2gpa <input dir>\* <input.ts>\n");
fprintf(stderr, " gpr2gpa <input dir>/* <input.ts>\n");
fprintf(stderr, " gpr2gpa * <input.ts>\n");
return -1;
}