mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 06:53:43 +00:00
Add mouse cursor handling
This commit is contained in:
252
ConvertColorCursors/ConvertColorCursors.cpp
Normal file
252
ConvertColorCursors/ConvertColorCursors.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
#include "CFileStream.h"
|
||||
#include "MMHandleBlock.h"
|
||||
#include "ResourceCompiledTypeList.h"
|
||||
#include "ResourceFile.h"
|
||||
#include "SharedTypes.h"
|
||||
#include "PLBigEndian.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "stb_image_write.h"
|
||||
|
||||
// This extracts all of the color cursors from a resource file and converts them to
|
||||
// Windows cursor format.
|
||||
//
|
||||
// Windows only supports loading color cursors by loading them from an executable or DLL resource,
|
||||
// or by loading them from a file, so we can't just do the conversion/construction at runtime.
|
||||
//
|
||||
// Also, classic Mac cursor features are not fully supported by newer operating systems.
|
||||
// The classic Mac cursor function is basically (existing ^ color) where the mask bit isn't set,
|
||||
// so it supports inversion masking and colors with the same cursor.
|
||||
//
|
||||
// Fortunately, none of the Glider PRO cursors use this combination.
|
||||
//
|
||||
// The color cursor format is not fully documented. Appears to be:
|
||||
// Header
|
||||
// CursorPixMapPrefix (at pixMapOffset)
|
||||
// BEPixMap
|
||||
// Pixel data
|
||||
// BEColorTableHeader
|
||||
// BEColorTableItem[...]
|
||||
|
||||
struct CursorPixMapPrefix
|
||||
{
|
||||
BEUInt32_t m_unknown; // Seems to always be zero
|
||||
BEUInt16_t m_subFormat; // 0x8002 = 2 colors, 0x8004 = 4 colors, 0x8008 = 16 colors, 0x8010 = 256 colors
|
||||
};
|
||||
|
||||
struct CursorHeader
|
||||
{
|
||||
BEUInt16_t m_cursorType;
|
||||
BEUInt32_t m_pixMapOffset;
|
||||
BEUInt32_t m_pixDataOffset;
|
||||
BEUInt32_t m_expandedData;
|
||||
BEUInt16_t m_expandedDataDepth;
|
||||
BEUInt32_t m_unused;
|
||||
uint8_t m_bwCursor[32];
|
||||
uint8_t m_mask[32];
|
||||
BEUInt16_t m_hotSpotY;
|
||||
BEUInt16_t m_hotSpotX;
|
||||
BEUInt32_t m_colorTableResourceID;
|
||||
BEUInt32_t m_cursorResourceID;
|
||||
};
|
||||
|
||||
struct IconDir
|
||||
{
|
||||
uint16_t m_reserved;
|
||||
uint16_t m_type;
|
||||
uint16_t m_numImages;
|
||||
};
|
||||
|
||||
struct IconDirEntry
|
||||
{
|
||||
uint8_t m_width;
|
||||
uint8_t m_height;
|
||||
uint8_t m_numColors;
|
||||
uint8_t m_reserved;
|
||||
uint16_t m_numPlanes_HotSpotX;
|
||||
uint16_t m_bpp_HotSpotY;
|
||||
uint32_t m_imageDataSize;
|
||||
uint32_t m_imageDataOffset;
|
||||
};
|
||||
|
||||
uint8_t CompactChannel(const uint8_t *doublet)
|
||||
{
|
||||
unsigned int doubletValue = (doublet[0] << 8) + doublet[1];
|
||||
|
||||
return (doubletValue * 2 + 0x101) / 0x202;
|
||||
}
|
||||
|
||||
void WriteToFileCallback(void *context, void *data, int size)
|
||||
{
|
||||
fwrite(data, 1, size, static_cast<FILE*>(context));
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
FILE *f = nullptr;
|
||||
errno_t err = fopen_s(&f, "Packaged\\ApplicationResources.gpr", "rb");
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
PortabilityLayer::CFileStream stream(f);
|
||||
|
||||
PortabilityLayer::ResourceFile *resFile = new PortabilityLayer::ResourceFile();
|
||||
if (!resFile->Load(&stream))
|
||||
return -1;
|
||||
|
||||
stream.Close();
|
||||
|
||||
const PortabilityLayer::ResourceCompiledTypeList *typeList = resFile->GetResourceTypeList('crsr');
|
||||
if (!typeList)
|
||||
return -1;
|
||||
|
||||
const size_t numRefs = typeList->m_numRefs;
|
||||
for (size_t i = 0; i < numRefs; i++)
|
||||
{
|
||||
const int resID = typeList->m_firstRef[i].m_resID;
|
||||
const PortabilityLayer::MMHandleBlock *hBlock = resFile->GetResource('crsr', resID, true);
|
||||
const void *cursorDataBase = hBlock->m_contents;
|
||||
const void *cursorData = cursorDataBase;
|
||||
|
||||
const CursorHeader *cursorHeader = static_cast<const CursorHeader *>(cursorData);
|
||||
cursorData = cursorHeader + 1;
|
||||
cursorData = static_cast<const void*>(reinterpret_cast<const uint8_t*>(cursorDataBase) + cursorHeader->m_pixMapOffset);
|
||||
|
||||
const CursorPixMapPrefix *cursorPixMapPrefix = static_cast<const CursorPixMapPrefix *>(cursorData);
|
||||
|
||||
cursorData = cursorPixMapPrefix + 1;
|
||||
|
||||
const BEPixMap *pixMap = reinterpret_cast<const BEPixMap*>(reinterpret_cast<const uint8_t*>(cursorData));
|
||||
cursorData = pixMap + 1;
|
||||
|
||||
cursorData = static_cast<const void*>(reinterpret_cast<const uint8_t*>(cursorDataBase) + cursorHeader->m_pixDataOffset);
|
||||
const uint8_t *pixMapDataBytes = static_cast<const uint8_t*>(cursorData);
|
||||
|
||||
const Rect rect = pixMap->m_bounds.ToRect();
|
||||
const int width = rect.right - rect.left;
|
||||
const int height = rect.bottom - rect.top;
|
||||
const int componentSize = static_cast<int>(pixMap->m_componentSize);
|
||||
|
||||
switch (componentSize)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
const int bitsRequired = width * height * componentSize;
|
||||
const int bytesRequired = (bitsRequired + 7) / 8;
|
||||
|
||||
uint8_t *colorValues = new uint8_t[width * height];
|
||||
|
||||
const int numPixels = width * height;
|
||||
|
||||
switch (componentSize)
|
||||
{
|
||||
case 1:
|
||||
for (int i = 0; i < numPixels; i++)
|
||||
colorValues[i] = (pixMapDataBytes[i / 8] >> (7 - (i & 7) * 1)) & 0x1;
|
||||
break;
|
||||
case 2:
|
||||
for (int i = 0; i < numPixels; i++)
|
||||
colorValues[i] = (pixMapDataBytes[i / 4] >> (6 - (i & 3) * 2)) & 0x3;
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i < numPixels; i++)
|
||||
colorValues[i] = (pixMapDataBytes[i / 2] >> (4 - (i & 1) * 4)) & 0xf;
|
||||
break;
|
||||
case 8:
|
||||
for (int i = 0; i < numPixels; i++)
|
||||
colorValues[i] = pixMapDataBytes[i];
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
cursorData = static_cast<const void*>(pixMapDataBytes + bytesRequired);
|
||||
const BEColorTableHeader *colorTableHeader = static_cast<const BEColorTableHeader *>(cursorData);
|
||||
|
||||
cursorData = colorTableHeader + 1;
|
||||
|
||||
const BEColorTableItem *ctabItems = static_cast<const BEColorTableItem *>(cursorData);
|
||||
|
||||
uint32_t decodedCTabItems[256];
|
||||
const int numCTabItems = colorTableHeader->m_numItemsMinusOne + 1;
|
||||
|
||||
for (int i = 0; i < numCTabItems; i++)
|
||||
{
|
||||
const BEColorTableItem &item = ctabItems[i];
|
||||
unsigned char rgba[4];
|
||||
rgba[0] = CompactChannel(item.m_red);
|
||||
rgba[1] = CompactChannel(item.m_green);
|
||||
rgba[2] = CompactChannel(item.m_blue);
|
||||
rgba[3] = 255;
|
||||
|
||||
int index = item.m_index;
|
||||
assert(index >= 0 && index < 256);
|
||||
|
||||
memcpy(decodedCTabItems + index, rgba, 4);
|
||||
}
|
||||
|
||||
uint32_t *pixelDataRGBA = new uint32_t[width * height * 4];
|
||||
|
||||
for (int i = 0; i < numPixels; i++)
|
||||
{
|
||||
const uint8_t ctabIndex = colorValues[i];
|
||||
pixelDataRGBA[i] = decodedCTabItems[ctabIndex];
|
||||
|
||||
if (((cursorHeader->m_mask[i / 8] >> (7 - (i & 7))) & 1) == 0)
|
||||
reinterpret_cast<uint8_t*>(pixelDataRGBA + i)[3] = 0;
|
||||
}
|
||||
|
||||
char outPath[64];
|
||||
sprintf_s(outPath, "Packaged\\WinCursors\\%i.cur", resID);
|
||||
|
||||
FILE *outF = nullptr;
|
||||
errno_t outErr = fopen_s(&outF, outPath, "wb");
|
||||
|
||||
if (!outErr)
|
||||
{
|
||||
IconDir iconDir;
|
||||
iconDir.m_reserved = 0;
|
||||
iconDir.m_type = 2;
|
||||
iconDir.m_numImages = 1;
|
||||
|
||||
IconDirEntry iconDirEntry;
|
||||
iconDirEntry.m_width = width;
|
||||
iconDirEntry.m_height = height;
|
||||
iconDirEntry.m_numColors = 0;
|
||||
iconDirEntry.m_reserved = 0;
|
||||
iconDirEntry.m_numPlanes_HotSpotX = cursorHeader->m_hotSpotX;
|
||||
iconDirEntry.m_bpp_HotSpotY = cursorHeader->m_hotSpotY;
|
||||
iconDirEntry.m_imageDataSize = 0;
|
||||
iconDirEntry.m_imageDataOffset = sizeof(IconDir) + sizeof(IconDirEntry);
|
||||
|
||||
fwrite(&iconDir, 1, sizeof(IconDir), outF);
|
||||
fwrite(&iconDirEntry, 1, sizeof(IconDirEntry), outF);
|
||||
|
||||
long imageDataStart = ftell(outF);
|
||||
stbi_write_png_to_func(WriteToFileCallback, outF, width, height, 4, pixelDataRGBA, width * 4);
|
||||
long imageDataEnd = ftell(outF);
|
||||
|
||||
fseek(outF, sizeof(IconDir), SEEK_SET);
|
||||
|
||||
iconDirEntry.m_imageDataSize = static_cast<uint32_t>(imageDataEnd - imageDataStart);
|
||||
fwrite(&iconDirEntry, 1, sizeof(IconDirEntry), outF);
|
||||
fclose(outF);
|
||||
}
|
||||
|
||||
delete[] colorValues;
|
||||
delete[] pixelDataRGBA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
145
ConvertColorCursors/ConvertColorCursors.vcxproj
Normal file
145
ConvertColorCursors/ConvertColorCursors.vcxproj
Normal file
@@ -0,0 +1,145 @@
|
||||
<?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|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<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>{B852D549-4020-4477-8BFB-E199FF78B047}</ProjectGuid>
|
||||
<RootNamespace>ConvertColorCursors</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<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|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="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\stb.props" />
|
||||
</ImportGroup>
|
||||
<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="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\stb.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" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\stb.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="..\GpCommon.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\stb.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>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<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>
|
||||
</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>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PortabilityLayer\PortabilityLayer.vcxproj">
|
||||
<Project>{6ec62b0f-9353-40a4-a510-3788f1368b33}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\stb\stb_image_write.c" />
|
||||
<ClCompile Include="ConvertColorCursors.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
25
ConvertColorCursors/ConvertColorCursors.vcxproj.filters
Normal file
25
ConvertColorCursors/ConvertColorCursors.vcxproj.filters
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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="ConvertColorCursors.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\stb\stb_image_write.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -1,4 +1,7 @@
|
||||
x64\Release\MiniRez.exe "GpApp2\Glider PRO.r" Packaged\ApplicationResources.gpr
|
||||
|
||||
x64\Release\ConvertColorCursors.exe
|
||||
|
||||
x64\Release\hqx2gp.exe "GpApp2\Houses\Art Museum.binhex" "Packaged\Houses\Art Museum"
|
||||
x64\Release\hqx2gp.exe "GpApp2\Houses\California or Bust!.binhex" "Packaged\Houses\California or Bust!"
|
||||
x64\Release\hqx2gp.exe "GpApp2\Houses\Castle o' the Air.binhex" "Packaged\Houses\Castle o' the Air"
|
||||
|
@@ -25,6 +25,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeType", "FreeType\FreeTy
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CompileShadersD3D11", "CompileShadersD3D11\CompileShadersD3D11.vcxproj", "{ED2F91E1-673A-4590-82B2-EB157927D3E3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConvertColorCursors", "ConvertColorCursors\ConvertColorCursors.vcxproj", "{B852D549-4020-4477-8BFB-E199FF78B047}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -121,6 +123,14 @@ Global
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Release|x64.Build.0 = Release|x64
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Release|x86.ActiveCfg = Release|Win32
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Release|x86.Build.0 = Release|Win32
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Debug|x64.Build.0 = Debug|x64
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Release|x64.ActiveCfg = Release|x64
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Release|x64.Build.0 = Release|x64
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
12
GpCommon/EGpStandardCursor.h
Normal file
12
GpCommon/EGpStandardCursor.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace EGpStandardCursors
|
||||
{
|
||||
enum EGpStandardCursor
|
||||
{
|
||||
kArrow,
|
||||
kHidden,
|
||||
};
|
||||
}
|
||||
|
||||
typedef EGpStandardCursors::EGpStandardCursor EGpStandardCursor_t;
|
58
GpCommon/GpColorCursor_Win32.cpp
Normal file
58
GpCommon/GpColorCursor_Win32.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "GpColorCursor_Win32.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <new>
|
||||
|
||||
void GpColorCursor_Win32::Destroy()
|
||||
{
|
||||
this->DecRef();
|
||||
}
|
||||
|
||||
GpColorCursor_Win32 *GpColorCursor_Win32::Load(const wchar_t *path)
|
||||
{
|
||||
HANDLE imageH = LoadImageW(nullptr, path, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
|
||||
|
||||
if (imageH == nullptr)
|
||||
return nullptr;
|
||||
|
||||
HCURSOR cursor = reinterpret_cast<HCURSOR>(imageH);
|
||||
void *storage = malloc(sizeof(GpColorCursor_Win32));
|
||||
if (!storage)
|
||||
{
|
||||
DestroyCursor(cursor);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new (storage) GpColorCursor_Win32(reinterpret_cast<HCURSOR>(cursor));
|
||||
}
|
||||
|
||||
GpColorCursor_Win32::GpColorCursor_Win32(HCURSOR cursor)
|
||||
: m_cursor(cursor)
|
||||
, m_refCount(1)
|
||||
{
|
||||
}
|
||||
|
||||
GpColorCursor_Win32::~GpColorCursor_Win32()
|
||||
{
|
||||
DestroyCursor(m_cursor);
|
||||
}
|
||||
|
||||
const HCURSOR &GpColorCursor_Win32::GetHCursor() const
|
||||
{
|
||||
return m_cursor;
|
||||
}
|
||||
|
||||
void GpColorCursor_Win32::IncRef()
|
||||
{
|
||||
m_refCount++;
|
||||
}
|
||||
|
||||
void GpColorCursor_Win32::DecRef()
|
||||
{
|
||||
m_refCount--;
|
||||
if (m_refCount == 0)
|
||||
{
|
||||
this->~GpColorCursor_Win32();
|
||||
free(this);
|
||||
}
|
||||
}
|
24
GpCommon/GpColorCursor_Win32.h
Normal file
24
GpCommon/GpColorCursor_Win32.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpColorCursor.h"
|
||||
#include "GpWindows.h"
|
||||
|
||||
class GpColorCursor_Win32 final : public IGpColorCursor
|
||||
{
|
||||
public:
|
||||
void Destroy() override;
|
||||
|
||||
const HCURSOR &GetHCursor() const;
|
||||
|
||||
void IncRef();
|
||||
void DecRef();
|
||||
|
||||
static GpColorCursor_Win32 *Load(const wchar_t *path);
|
||||
|
||||
private:
|
||||
GpColorCursor_Win32(HCURSOR cursor);
|
||||
~GpColorCursor_Win32();
|
||||
|
||||
HCURSOR m_cursor;
|
||||
int m_refCount;
|
||||
};
|
@@ -21,6 +21,8 @@ struct GpDisplayDriverProperties
|
||||
unsigned int m_frameTimeLockMaxNumerator;
|
||||
unsigned int m_frameTimeLockMaxDenominator;
|
||||
|
||||
void *m_osGlobals;
|
||||
|
||||
// Tick function and context to call when a frame needs to be served.
|
||||
TickFunc_t m_tickFunc;
|
||||
void *m_tickFuncContext;
|
||||
|
@@ -2,17 +2,19 @@
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define OEMRESOURCE
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
struct GPWindowsGlobals
|
||||
struct GpWindowsGlobals
|
||||
{
|
||||
HINSTANCE m_hInstance;
|
||||
HINSTANCE m_hPrevInstance;
|
||||
LPSTR m_cmdLine;
|
||||
LPCSTR m_cmdLine;
|
||||
LPCWSTR m_baseDir;
|
||||
int m_nCmdShow;
|
||||
};
|
||||
|
||||
extern GPWindowsGlobals g_gpWindowsGlobals;
|
||||
extern GpWindowsGlobals g_gpWindowsGlobals;
|
||||
|
||||
#undef CreateMutex
|
||||
|
6
GpCommon/IGpColorCursor.h
Normal file
6
GpCommon/IGpColorCursor.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct IGpColorCursor
|
||||
{
|
||||
virtual void Destroy() = 0;
|
||||
};
|
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "PixelFormat.h"
|
||||
#include "EGpStandardCursor.h"
|
||||
|
||||
struct IGpDisplayDriverSurface;
|
||||
struct IGpColorCursor;
|
||||
|
||||
// Display drivers are responsible for timing and calling the game tick function.
|
||||
struct IGpDisplayDriver
|
||||
@@ -16,5 +18,9 @@ public:
|
||||
virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat) = 0;
|
||||
virtual void DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height) = 0;
|
||||
|
||||
virtual IGpColorCursor *LoadColorCursor(int cursorID) = 0;
|
||||
virtual void SetColorCursor(IGpColorCursor *colorCursor) = 0;
|
||||
virtual void SetStandardCursor(EGpStandardCursor_t standardCursor) = 0;
|
||||
|
||||
virtual void UpdatePalette(const void *paletteData) = 0;
|
||||
};
|
||||
|
@@ -143,6 +143,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\GpCommon\GpColorCursor_Win32.cpp" />
|
||||
<ClCompile Include="GpAppEnvironment.cpp" />
|
||||
<ClCompile Include="GpAudioDriverFactory.cpp" />
|
||||
<ClCompile Include="GpDisplayDriverFactory.cpp" />
|
||||
@@ -172,7 +173,10 @@
|
||||
<ClCompile Include="ShadersD3D11\DrawQuadV_D3D11.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\GpCommon\EGpStandardCursor.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpColorCursor.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpAudioChannelCallbacks.h" />
|
||||
<ClInclude Include="..\GpCommon\GpColorCursor_Win32.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpDisplayDriverSurface.h" />
|
||||
<ClInclude Include="EGpAudioDriverType.h" />
|
||||
<ClInclude Include="EGpDisplayDriverType.h" />
|
||||
|
@@ -99,6 +99,9 @@
|
||||
<ClCompile Include="ShadersD3D11\DrawQuadRGBP_D3D11.cpp">
|
||||
<Filter>Source Files\CompiledShaders</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\GpCommon\GpColorCursor_Win32.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GpWindows.h">
|
||||
@@ -212,5 +215,14 @@
|
||||
<ClInclude Include="GpComPtr.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\IGpColorCursor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\GpColorCursor_Win32.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\EGpStandardCursor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -1,6 +1,8 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include "GpDisplayDriverD3D11.h"
|
||||
#include "GpDisplayDriverSurfaceD3D11.h"
|
||||
#include "GpWindows.h"
|
||||
#include "GpColorCursor_Win32.h"
|
||||
#include "GpFiber_Win32.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
@@ -308,6 +310,8 @@ bool GpDisplayDriverD3D11::InitResources()
|
||||
|
||||
bool GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
{
|
||||
SynchronizeCursors();
|
||||
|
||||
float clearColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
|
||||
m_deviceContext->ClearRenderTargetView(m_backBufferRTV, clearColor);
|
||||
@@ -443,9 +447,74 @@ bool GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
return true;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::SynchronizeCursors()
|
||||
{
|
||||
HCURSOR replacementCursor = nullptr;
|
||||
|
||||
if (m_activeCursor)
|
||||
{
|
||||
if (m_pendingCursor != m_activeCursor)
|
||||
{
|
||||
if (m_pendingCursor == nullptr)
|
||||
{
|
||||
m_currentStandardCursor = m_pendingStandardCursor;
|
||||
ChangeToStandardCursor(m_currentStandardCursor);
|
||||
|
||||
m_activeCursor->DecRef();
|
||||
m_activeCursor = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeToCursor(m_pendingCursor->GetHCursor());
|
||||
|
||||
m_pendingCursor->IncRef();
|
||||
m_activeCursor->DecRef();
|
||||
m_activeCursor = m_pendingCursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pendingCursor)
|
||||
{
|
||||
m_pendingCursor->IncRef();
|
||||
m_activeCursor = m_pendingCursor;
|
||||
|
||||
ChangeToCursor(m_activeCursor->GetHCursor());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pendingStandardCursor != m_currentStandardCursor)
|
||||
{
|
||||
ChangeToStandardCursor(m_pendingStandardCursor);
|
||||
m_currentStandardCursor = m_pendingStandardCursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpDisplayDriverD3D11::ChangeToCursor(HCURSOR cursor)
|
||||
{
|
||||
if (m_mouseIsInClientArea)
|
||||
SetCursor(cursor);
|
||||
|
||||
SetClassLongPtrW(m_hwnd, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(cursor));
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::ChangeToStandardCursor(EGpStandardCursor_t cursor)
|
||||
{
|
||||
switch (cursor)
|
||||
{
|
||||
case EGpStandardCursors::kArrow:
|
||||
default:
|
||||
ChangeToCursor(m_arrowCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::Run()
|
||||
{
|
||||
HWND hWnd;
|
||||
WNDCLASSEX wc;
|
||||
|
||||
LPVOID fiber = ConvertThreadToFiberEx(this, 0);
|
||||
@@ -460,7 +529,7 @@ void GpDisplayDriverD3D11::Run()
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WinProc;
|
||||
wc.hInstance = g_gpWindowsGlobals.m_hInstance;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hCursor = m_arrowCursor;
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = "GPD3D11WindowClass";
|
||||
|
||||
@@ -473,11 +542,11 @@ void GpDisplayDriverD3D11::Run()
|
||||
RECT wr = { 0, 0, m_windowWidth, m_windowHeight };
|
||||
AdjustWindowRect(&wr, windowStyle, menus != NULL);
|
||||
|
||||
hWnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL);
|
||||
m_hwnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL);
|
||||
|
||||
ShowWindow(hWnd, g_gpWindowsGlobals.m_nCmdShow);
|
||||
ShowWindow(m_hwnd, g_gpWindowsGlobals.m_nCmdShow);
|
||||
|
||||
StartD3DForWindow(hWnd, m_swapChain, m_device, m_deviceContext);
|
||||
StartD3DForWindow(m_hwnd, m_swapChain, m_device, m_deviceContext);
|
||||
|
||||
InitResources();
|
||||
|
||||
@@ -495,6 +564,10 @@ void GpDisplayDriverD3D11::Run()
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
else if (msg.message == WM_MOUSEMOVE)
|
||||
m_mouseIsInClientArea = true;
|
||||
else if (msg.message == WM_MOUSELEAVE)
|
||||
m_mouseIsInClientArea = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -612,6 +685,44 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, size_t
|
||||
m_deviceContext->DrawIndexed(6, 0, 0);
|
||||
}
|
||||
|
||||
IGpColorCursor *GpDisplayDriverD3D11::LoadColorCursor(int cursorID)
|
||||
{
|
||||
const size_t bufSize = MAX_PATH;
|
||||
wchar_t path[bufSize];
|
||||
|
||||
int sz = _snwprintf(path, bufSize, L"%sPackaged\\WinCursors\\%i.cur", m_osGlobals->m_baseDir, cursorID);
|
||||
if (sz < 0 || static_cast<size_t>(sz) >= bufSize)
|
||||
return nullptr;
|
||||
|
||||
return GpColorCursor_Win32::Load(path);
|
||||
}
|
||||
|
||||
// We can't just set the cursor because we want to post WM_SETCURSOR to keep it limited
|
||||
// to the game window area, but depending on the fiber implementation, this may not be
|
||||
// the window thread.
|
||||
void GpDisplayDriverD3D11::SetColorCursor(IGpColorCursor *colorCursor)
|
||||
{
|
||||
GpColorCursor_Win32 *winCursor = static_cast<GpColorCursor_Win32*>(colorCursor);
|
||||
|
||||
winCursor->IncRef();
|
||||
|
||||
if (m_pendingCursor)
|
||||
m_pendingCursor->DecRef();
|
||||
|
||||
m_pendingCursor = winCursor;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::SetStandardCursor(EGpStandardCursor_t standardCursor)
|
||||
{
|
||||
if (m_pendingCursor)
|
||||
{
|
||||
m_pendingCursor->DecRef();
|
||||
m_pendingCursor = nullptr;
|
||||
}
|
||||
|
||||
m_pendingStandardCursor = standardCursor;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::UpdatePalette(const void *paletteData)
|
||||
{
|
||||
const size_t dataSize = 256 * 4;
|
||||
@@ -643,14 +754,23 @@ GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &prop
|
||||
, m_windowWidth(640)
|
||||
, m_windowHeight(480)
|
||||
, m_vosFiber(nullptr)
|
||||
, m_osGlobals(static_cast<GpWindowsGlobals*>(properties.m_osGlobals))
|
||||
, m_pendingCursor(nullptr)
|
||||
, m_activeCursor(nullptr)
|
||||
, m_currentStandardCursor(EGpStandardCursors::kArrow)
|
||||
, m_pendingStandardCursor(EGpStandardCursors::kArrow)
|
||||
, m_mouseIsInClientArea(false)
|
||||
{
|
||||
memset(&m_syncTimeBase, 0, sizeof(m_syncTimeBase));
|
||||
|
||||
QueryPerformanceFrequency(&m_QPFrequency);
|
||||
|
||||
m_frameTimeSliceSize = m_QPFrequency.QuadPart * static_cast<LONGLONG>(properties.m_frameTimeLockNumerator) / static_cast<LONGLONG>(properties.m_frameTimeLockDenominator);
|
||||
|
||||
m_arrowCursor = reinterpret_cast<HCURSOR>(LoadImageW(nullptr, MAKEINTRESOURCEW(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11::~GpDisplayDriverD3D11()
|
||||
{
|
||||
// GP TODO: Sloppy cleanup... Close the window!!
|
||||
}
|
||||
|
@@ -10,6 +10,9 @@
|
||||
|
||||
#include "PixelFormat.h"
|
||||
|
||||
struct GpWindowsGlobals;
|
||||
class GpColorCursor_Win32;
|
||||
|
||||
struct IDXGISwapChain1;
|
||||
struct ID3D11Buffer;
|
||||
struct ID3D11DepthStencilState;
|
||||
@@ -35,6 +38,10 @@ public:
|
||||
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat) override;
|
||||
void DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height) override;
|
||||
|
||||
IGpColorCursor *LoadColorCursor(int cursorID) override;
|
||||
void SetColorCursor(IGpColorCursor *colorCursor) override;
|
||||
void SetStandardCursor(EGpStandardCursor_t standardCursor) override;
|
||||
|
||||
void UpdatePalette(const void *paletteData) override;
|
||||
|
||||
static GpDisplayDriverD3D11 *Create(const GpDisplayDriverProperties &properties);
|
||||
@@ -52,12 +59,22 @@ private:
|
||||
float m_unused[2];
|
||||
};
|
||||
|
||||
struct CompactedPresentHistoryItem
|
||||
{
|
||||
LARGE_INTEGER m_timestamp;
|
||||
unsigned int m_numFrames;
|
||||
};
|
||||
|
||||
GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties);
|
||||
~GpDisplayDriverD3D11();
|
||||
|
||||
bool InitResources();
|
||||
bool PresentFrameAndSync();
|
||||
|
||||
void SynchronizeCursors();
|
||||
void ChangeToCursor(HCURSOR cursor);
|
||||
void ChangeToStandardCursor(EGpStandardCursor_t cursor);
|
||||
|
||||
GpComPtr<IDXGISwapChain1> m_swapChain;
|
||||
GpComPtr<ID3D11Device> m_device;
|
||||
GpComPtr<ID3D11DeviceContext> m_deviceContext;
|
||||
@@ -77,12 +94,6 @@ private:
|
||||
GpComPtr<ID3D11Texture2D> m_backBufferTexture;
|
||||
GpComPtr<ID3D11RenderTargetView> m_backBufferRTV;
|
||||
|
||||
struct CompactedPresentHistoryItem
|
||||
{
|
||||
LARGE_INTEGER m_timestamp;
|
||||
unsigned int m_numFrames;
|
||||
};
|
||||
|
||||
GpRingBuffer<CompactedPresentHistoryItem, 60> m_presentHistory;
|
||||
GpDisplayDriverProperties m_properties;
|
||||
|
||||
@@ -97,5 +108,15 @@ private:
|
||||
DWORD m_windowWidth;
|
||||
DWORD m_windowHeight;
|
||||
|
||||
GpColorCursor_Win32 *m_activeCursor;
|
||||
GpColorCursor_Win32 *m_pendingCursor;
|
||||
EGpStandardCursor_t m_currentStandardCursor;
|
||||
EGpStandardCursor_t m_pendingStandardCursor;
|
||||
bool m_mouseIsInClientArea;
|
||||
|
||||
GpFiber *m_vosFiber;
|
||||
GpWindowsGlobals *m_osGlobals;
|
||||
|
||||
HCURSOR m_arrowCursor;
|
||||
HWND m_hwnd;
|
||||
};
|
||||
|
@@ -95,6 +95,7 @@ GpDirectoryCursor_Win32::~GpDirectoryCursor_Win32()
|
||||
|
||||
GpFileSystem_Win32::GpFileSystem_Win32()
|
||||
{
|
||||
// GP TODO: This shouldn't be static init since it allocates memory
|
||||
m_executablePath[0] = 0;
|
||||
|
||||
PWSTR docsPath;
|
||||
@@ -201,6 +202,11 @@ PortabilityLayer::HostDirectoryCursor *GpFileSystem_Win32::ScanDirectory(Portabi
|
||||
return GpDirectoryCursor_Win32::Create(ff, findData);
|
||||
}
|
||||
|
||||
const wchar_t *GpFileSystem_Win32::GetBasePath() const
|
||||
{
|
||||
return m_executablePath;
|
||||
}
|
||||
|
||||
GpFileSystem_Win32 *GpFileSystem_Win32::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
|
@@ -16,6 +16,8 @@ public:
|
||||
PortabilityLayer::IOStream *OpenFile(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) override;
|
||||
PortabilityLayer::HostDirectoryCursor *ScanDirectory(PortabilityLayer::EVirtualDirectory virtualDirectory) override;
|
||||
|
||||
const wchar_t *GetBasePath() const;
|
||||
|
||||
static GpFileSystem_Win32 *GetInstance();
|
||||
|
||||
private:
|
||||
|
@@ -5,6 +5,7 @@
|
||||
struct GpGlobalConfig
|
||||
{
|
||||
EGpDisplayDriverType m_displayDriverType;
|
||||
void *m_osGlobals;
|
||||
};
|
||||
|
||||
extern GpGlobalConfig g_gpGlobalConfig;
|
||||
|
@@ -49,6 +49,7 @@ int GpMain::Run()
|
||||
ddProps.m_renderFuncContext = appEnvironment;
|
||||
|
||||
ddProps.m_type = g_gpGlobalConfig.m_displayDriverType;
|
||||
ddProps.m_osGlobals = g_gpGlobalConfig.m_osGlobals;
|
||||
|
||||
GpAudioDriverProperties adProps;
|
||||
memset(&adProps, 0, sizeof(adProps));
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
GPWindowsGlobals g_gpWindowsGlobals;
|
||||
GpWindowsGlobals g_gpWindowsGlobals;
|
||||
|
||||
extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAudio2(const GpAudioDriverProperties &properties);
|
||||
|
||||
@@ -26,8 +26,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
g_gpWindowsGlobals.m_hPrevInstance = hPrevInstance;
|
||||
g_gpWindowsGlobals.m_cmdLine = lpCmdLine;
|
||||
g_gpWindowsGlobals.m_nCmdShow = nCmdShow;
|
||||
g_gpWindowsGlobals.m_baseDir = GpFileSystem_Win32::GetInstance()->GetBasePath();
|
||||
|
||||
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11;
|
||||
g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals;
|
||||
|
||||
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDisplayDriverFactoryD3D11::Create);
|
||||
GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_XAudio2, GpDriver_CreateAudioDriver_XAudio2);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "GpPLGlueDisplayDriver.h"
|
||||
#include "VirtualDirectory.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
|
||||
GpPLGlueDisplayDriver::GpPLGlueDisplayDriver()
|
||||
@@ -11,8 +12,19 @@ void GpPLGlueDisplayDriver::GetDisplayResolution(unsigned int *width, unsigned i
|
||||
m_displayDriver->GetDisplayResolution(width, height, bpp);
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::HideCursor()
|
||||
IGpColorCursor *GpPLGlueDisplayDriver::LoadColorCursor(int cursorID)
|
||||
{
|
||||
return m_displayDriver->LoadColorCursor(cursorID);
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::SetColorCursor(IGpColorCursor *colorCursor)
|
||||
{
|
||||
m_displayDriver->SetColorCursor(colorCursor);
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::SetStandardCursor(EGpStandardCursor_t standardCursor)
|
||||
{
|
||||
m_displayDriver->SetStandardCursor(standardCursor);
|
||||
}
|
||||
|
||||
GpPLGlueDisplayDriver *GpPLGlueDisplayDriver::GetInstance()
|
||||
|
@@ -10,7 +10,9 @@ public:
|
||||
GpPLGlueDisplayDriver();
|
||||
|
||||
void GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *bpp) override;
|
||||
void HideCursor() override;
|
||||
IGpColorCursor *LoadColorCursor(int id) override;
|
||||
void SetColorCursor(IGpColorCursor *colorCursor) override;
|
||||
void SetStandardCursor(EGpStandardCursor_t standardCursor) override;
|
||||
|
||||
void SetGpDisplayDriver(IGpDisplayDriver *displayDriver);
|
||||
|
||||
|
@@ -60,21 +60,25 @@
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\stb.props" />
|
||||
</ImportGroup>
|
||||
<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="..\Common.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\stb.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" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\stb.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="..\PortabilityLayer.props" />
|
||||
<Import Project="..\stb.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
@@ -123,8 +127,8 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\stb\stb_image_write.c" />
|
||||
<ClCompile Include="PictChecker.cpp" />
|
||||
<ClCompile Include="stb_image_write.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PortabilityLayer\PortabilityLayer.vcxproj">
|
||||
|
@@ -18,7 +18,7 @@
|
||||
<ClCompile Include="PictChecker.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stb_image_write.c">
|
||||
<ClCompile Include="..\stb\stb_image_write.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
@@ -3,6 +3,9 @@
|
||||
#define __PL_HOST_DISPLAY_DRIVER_H__
|
||||
|
||||
#include "PixelFormat.h"
|
||||
#include "EGpStandardCursor.h"
|
||||
|
||||
struct IGpColorCursor;
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
@@ -10,7 +13,9 @@ namespace PortabilityLayer
|
||||
{
|
||||
public:
|
||||
virtual void GetDisplayResolution(unsigned int *width, unsigned int *height, PixelFormat *pixelFormat) = 0;
|
||||
virtual void HideCursor() = 0;
|
||||
virtual IGpColorCursor *LoadColorCursor(int id) = 0;
|
||||
virtual void SetColorCursor(IGpColorCursor *colorCursor) = 0;
|
||||
virtual void SetStandardCursor(EGpStandardCursor_t standardCursor) = 0;
|
||||
|
||||
static void SetInstance(HostDisplayDriver *instance);
|
||||
static HostDisplayDriver *GetInstance();
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "HostDisplayDriver.h"
|
||||
#include "HostSystemServices.h"
|
||||
#include "HostVOSEventQueue.h"
|
||||
#include "IGpColorCursor.h"
|
||||
#include "InputManager.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "MacFileInfo.h"
|
||||
@@ -64,6 +65,7 @@ static void ImportVOSEvents()
|
||||
|
||||
void InitCursor()
|
||||
{
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kArrow);
|
||||
}
|
||||
|
||||
Rect BERect::ToRect() const
|
||||
@@ -90,26 +92,34 @@ CursHandle GetCursor(int cursorID)
|
||||
|
||||
CCrsrHandle GetCCursor(int cursorID)
|
||||
{
|
||||
PortabilityLayer::ResourceManager *resManager = PortabilityLayer::ResourceManager::GetInstance();
|
||||
PortabilityLayer::MMHandleBlock *ccRes = resManager->GetResource('crsr', cursorID);
|
||||
PortabilityLayer::HostDisplayDriver *driver = PortabilityLayer::HostDisplayDriver::GetInstance();
|
||||
IGpColorCursor *hwCursor = driver->LoadColorCursor(cursorID);
|
||||
|
||||
if (!ccRes)
|
||||
if (!hwCursor)
|
||||
return nullptr;
|
||||
|
||||
PortabilityLayer::MMHandleBlock *copy = PortabilityLayer::MemoryManager::GetInstance()->AllocHandle(ccRes->m_size);
|
||||
memcpy(copy->m_contents, ccRes->m_contents, ccRes->m_size);
|
||||
CCrsrHandle hdl = PortabilityLayer::MemoryManager::GetInstance()->NewHandle<CCursor>();
|
||||
if (!hdl)
|
||||
{
|
||||
hwCursor->Destroy();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<CCrsrHandle>(copy);
|
||||
CCursor *ccursor = *hdl;
|
||||
ccursor->hwCursor = hwCursor;
|
||||
|
||||
return hdl;
|
||||
}
|
||||
|
||||
void SetCCursor(CCrsrHandle handle)
|
||||
{
|
||||
PL_NotYetImplemented_Minor();
|
||||
assert(handle);
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->SetColorCursor((*handle)->hwCursor);
|
||||
}
|
||||
|
||||
void HideCursor()
|
||||
{
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->HideCursor();
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kHidden);
|
||||
}
|
||||
|
||||
void SetCursor(CursPtr cursor)
|
||||
@@ -124,7 +134,9 @@ void SetBuiltinCursor(int builtinCursor)
|
||||
|
||||
void DisposeCCursor(CCrsrHandle handle)
|
||||
{
|
||||
PL_NotYetImplemented();
|
||||
(*handle)->hwCursor->Destroy();
|
||||
|
||||
PortabilityLayer::MemoryManager::GetInstance()->ReleaseHandle(reinterpret_cast<PortabilityLayer::MMHandleBlock*>(handle));
|
||||
}
|
||||
|
||||
void Delay(int ticks, UInt32 *endTickCount)
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#pragma warning(error:4311) // Pointer truncation to int
|
||||
#endif
|
||||
|
||||
struct IGpColorCursor;
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
struct MMHandleBlock;
|
||||
@@ -92,6 +94,7 @@ struct Cursor
|
||||
|
||||
struct CCursor
|
||||
{
|
||||
IGpColorCursor *hwCursor;
|
||||
};
|
||||
|
||||
struct Window
|
||||
|
@@ -11,5 +11,6 @@ namespace PortabilityLayer
|
||||
EVirtualDirectory_UserData,
|
||||
EVirtualDirectory_Prefs,
|
||||
EVirtualDirectory_Fonts,
|
||||
EVirtualDirectory_Cursors,
|
||||
};
|
||||
}
|
||||
|
10
stb.props
Normal file
10
stb.props
Normal file
@@ -0,0 +1,10 @@
|
||||
<?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>
|
||||
<IncludePath>$(SolutionDir)stb;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
</Project>
|
Reference in New Issue
Block a user