mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added SupportedTextureFormats setting
This commit is contained in:
parent
25f325ec17
commit
bb0f5c53e9
@ -16,6 +16,16 @@ namespace
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
std::string getTrimmedTypeName(const std::string& typeName)
|
||||
{
|
||||
std::string prefix("struct ");
|
||||
if (prefix == typeName.substr(0, prefix.length()))
|
||||
{
|
||||
return typeName.substr(prefix.length());
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
LogStream operator<<(LogStream os, const void* ptr)
|
||||
{
|
||||
if (ptr)
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@ -178,6 +179,14 @@ namespace Compat
|
||||
return val.elem;
|
||||
}
|
||||
|
||||
std::string getTrimmedTypeName(const std::string& typeName);
|
||||
|
||||
template <typename T>
|
||||
std::string getTypeName()
|
||||
{
|
||||
return getTrimmedTypeName(typeid(T).name());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Hex<T> hex(T val)
|
||||
{
|
||||
|
@ -68,16 +68,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static std::string getVtableTypeName()
|
||||
{
|
||||
std::string name = typeid(Vtable).name();
|
||||
if (0 == name.find("struct "))
|
||||
{
|
||||
name = name.substr(name.find(" ") + 1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
template <auto memberPtr, typename Result, typename FirstParam, typename... Params>
|
||||
static Result STDMETHODCALLTYPE hookFunc(FirstParam firstParam, Params... params)
|
||||
{
|
||||
@ -107,4 +97,4 @@ template <auto memberPtr>
|
||||
std::string VtableHookVisitor<Vtable, Lock>::s_funcName;
|
||||
|
||||
template <typename Vtable, typename Lock>
|
||||
std::string VtableHookVisitor<Vtable, Lock>::s_vtableTypeName(getVtableTypeName());
|
||||
std::string VtableHookVisitor<Vtable, Lock>::s_vtableTypeName(Compat::getTypeName<Vtable>());
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <Config/Settings/SpriteTexCoord.h>
|
||||
#include <Config/Settings/StatsHotKey.h>
|
||||
#include <Config/Settings/SupportedResolutions.h>
|
||||
#include <Config/Settings/SupportedTextureFormats.h>
|
||||
#include <Config/Settings/TerminateHotKey.h>
|
||||
#include <Config/Settings/TextureFilter.h>
|
||||
#include <Config/Settings/ThreadPriorityBoost.h>
|
||||
@ -64,6 +65,7 @@ namespace Config
|
||||
Settings::SpriteTexCoord spriteTexCoord;
|
||||
Settings::StatsHotKey statsHotKey;
|
||||
Settings::SupportedResolutions supportedResolutions;
|
||||
Settings::SupportedTextureFormats supportedTextureFormats;
|
||||
Settings::TerminateHotKey terminateHotKey;
|
||||
Settings::TextureFilter textureFilter;
|
||||
Settings::ThreadPriorityBoost threadPriorityBoost;
|
||||
|
@ -209,6 +209,16 @@ namespace Config
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string toupper(const std::string& str)
|
||||
{
|
||||
std::string result(str);
|
||||
for (auto& c : result)
|
||||
{
|
||||
c = std::toupper(c, std::locale());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string trim(const std::string& str)
|
||||
{
|
||||
auto result(str);
|
||||
|
@ -25,6 +25,7 @@ namespace Config
|
||||
void registerSetting(Setting& setting);
|
||||
std::string removeParam(const std::string& value);
|
||||
std::string tolower(const std::string& str);
|
||||
std::string toupper(const std::string& str);
|
||||
std::string trim(const std::string& str);
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,10 @@ namespace Config
|
||||
unsigned result = 0;
|
||||
for (const auto& value : values)
|
||||
{
|
||||
if ("app" == value || "all" == value)
|
||||
{
|
||||
throw ParsingError("'" + value + "' cannot be combined with other values");
|
||||
}
|
||||
auto num = Parser::parseInt(value, 1, 32);
|
||||
result |= 1U << (num - 1);
|
||||
}
|
||||
|
148
DDrawCompat/Config/Settings/SupportedTextureFormats.cpp
Normal file
148
DDrawCompat/Config/Settings/SupportedTextureFormats.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include <Config/Parser.h>
|
||||
#include <Config/Settings/SupportedTextureFormats.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::map<D3DDDIFORMAT, std::string> g_formatNames = []()
|
||||
{
|
||||
std::map<D3DDDIFORMAT, std::string> names;
|
||||
|
||||
#define ADD_FORMAT(format) names[format] = #format
|
||||
ADD_FORMAT(D3DDDIFMT_R8G8B8);
|
||||
ADD_FORMAT(D3DDDIFMT_A8R8G8B8);
|
||||
ADD_FORMAT(D3DDDIFMT_X8R8G8B8);
|
||||
ADD_FORMAT(D3DDDIFMT_R5G6B5);
|
||||
ADD_FORMAT(D3DDDIFMT_X1R5G5B5);
|
||||
ADD_FORMAT(D3DDDIFMT_A1R5G5B5);
|
||||
ADD_FORMAT(D3DDDIFMT_A4R4G4B4);
|
||||
ADD_FORMAT(D3DDDIFMT_R3G3B2);
|
||||
ADD_FORMAT(D3DDDIFMT_A8);
|
||||
ADD_FORMAT(D3DDDIFMT_A8R3G3B2);
|
||||
ADD_FORMAT(D3DDDIFMT_X4R4G4B4);
|
||||
ADD_FORMAT(D3DDDIFMT_A8P8);
|
||||
ADD_FORMAT(D3DDDIFMT_P8);
|
||||
ADD_FORMAT(D3DDDIFMT_L8);
|
||||
ADD_FORMAT(D3DDDIFMT_A8L8);
|
||||
ADD_FORMAT(D3DDDIFMT_A4L4);
|
||||
ADD_FORMAT(D3DDDIFMT_V8U8);
|
||||
ADD_FORMAT(D3DDDIFMT_L6V5U5);
|
||||
ADD_FORMAT(D3DDDIFMT_X8L8V8U8);
|
||||
#undef ADD_FORMAT
|
||||
|
||||
for (auto& pair : names)
|
||||
{
|
||||
pair.second = Config::Parser::tolower(pair.second.substr(10));
|
||||
}
|
||||
return names;
|
||||
}();
|
||||
|
||||
#define FOURCC(cc) *reinterpret_cast<D3DDDIFORMAT*>(#cc)
|
||||
std::map<std::string, std::vector<D3DDDIFORMAT>> g_formatGroups = {
|
||||
{ "argb", { D3DDDIFMT_A8R8G8B8, D3DDDIFMT_A1R5G5B5, D3DDDIFMT_A4R4G4B4 } },
|
||||
{ "bump", { D3DDDIFMT_V8U8, D3DDDIFMT_L6V5U5, D3DDDIFMT_X8L8V8U8 } },
|
||||
{ "dxt", { FOURCC(DXT1), FOURCC(DXT2), FOURCC(DXT3), FOURCC(DXT4),FOURCC(DXT5) } },
|
||||
{ "lum", { D3DDDIFMT_L8, D3DDDIFMT_A8L8, D3DDDIFMT_A4L4 } },
|
||||
{ "rgb", { D3DDDIFMT_X8R8G8B8, D3DDDIFMT_R5G6B5, D3DDDIFMT_X1R5G5B5, D3DDDIFMT_X4R4G4B4 } }
|
||||
};
|
||||
#undef FOURCC
|
||||
}
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
SupportedTextureFormats::SupportedTextureFormats()
|
||||
: ListSetting("SupportedTextureFormats", "all")
|
||||
{
|
||||
}
|
||||
|
||||
std::string SupportedTextureFormats::getValueStr() const
|
||||
{
|
||||
if (m_formats.empty())
|
||||
{
|
||||
return "all";
|
||||
}
|
||||
|
||||
std::string result;
|
||||
for (const auto& format : m_formats)
|
||||
{
|
||||
result += ", ";
|
||||
auto it = g_formatNames.find(static_cast<D3DDDIFORMAT>(format));
|
||||
if (it != g_formatNames.end())
|
||||
{
|
||||
result += Config::Parser::toupper(it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto p = reinterpret_cast<const char*>(&format);
|
||||
result += std::string(p, p + 4);
|
||||
}
|
||||
}
|
||||
return result.substr(2);
|
||||
}
|
||||
|
||||
bool SupportedTextureFormats::isSupported(UINT format) const
|
||||
{
|
||||
if (m_formats.empty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return m_formats.find(format) != m_formats.end();
|
||||
}
|
||||
|
||||
void SupportedTextureFormats::setValues(const std::vector<std::string>& values)
|
||||
{
|
||||
if (values.empty())
|
||||
{
|
||||
throw ParsingError("empty list is not allowed");
|
||||
}
|
||||
|
||||
if (1 == values.size() && "all" == values[0])
|
||||
{
|
||||
m_formats.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
std::set<UINT> formats;
|
||||
for (const auto& fmt : values)
|
||||
{
|
||||
if ("all" == fmt)
|
||||
{
|
||||
throw ParsingError("'all' cannot be combined with other values");
|
||||
}
|
||||
|
||||
auto group = g_formatGroups.find(fmt);
|
||||
if (group != g_formatGroups.end())
|
||||
{
|
||||
formats.insert(group->second.begin(), group->second.end());
|
||||
continue;
|
||||
}
|
||||
|
||||
auto name = std::find_if(g_formatNames.begin(), g_formatNames.end(),
|
||||
[&](const auto& pair) { return pair.second == fmt; });
|
||||
if (name != g_formatNames.end())
|
||||
{
|
||||
formats.insert(name->first);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (4 == fmt.length() &&
|
||||
fmt.end() == std::find_if(fmt.begin(), fmt.end(), [](const char c) { return !std::isalnum(c); }))
|
||||
{
|
||||
formats.insert(*reinterpret_cast<const UINT*>(Config::Parser::toupper(fmt).c_str()));
|
||||
continue;
|
||||
}
|
||||
|
||||
throw ParsingError("invalid format name: '" + fmt + "'");
|
||||
}
|
||||
|
||||
m_formats = formats;
|
||||
}
|
||||
}
|
||||
}
|
30
DDrawCompat/Config/Settings/SupportedTextureFormats.h
Normal file
30
DDrawCompat/Config/Settings/SupportedTextureFormats.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <Config/ListSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class SupportedTextureFormats : public ListSetting
|
||||
{
|
||||
public:
|
||||
SupportedTextureFormats();
|
||||
|
||||
virtual std::string getValueStr() const override;
|
||||
|
||||
bool isSupported(UINT format) const;
|
||||
|
||||
private:
|
||||
void setValues(const std::vector<std::string>& values) override;
|
||||
|
||||
std::set<UINT> m_formats;
|
||||
};
|
||||
}
|
||||
|
||||
extern Settings::SupportedTextureFormats supportedTextureFormats;
|
||||
}
|
@ -187,6 +187,7 @@
|
||||
<ClInclude Include="Config\Settings\SpriteTexCoord.h" />
|
||||
<ClInclude Include="Config\Settings\StatsHotKey.h" />
|
||||
<ClInclude Include="Config\Settings\SupportedResolutions.h" />
|
||||
<ClInclude Include="Config\Settings\SupportedTextureFormats.h" />
|
||||
<ClInclude Include="Config\Settings\TerminateHotKey.h" />
|
||||
<ClInclude Include="Config\Settings\TextureFilter.h" />
|
||||
<ClInclude Include="Config\Settings\ThreadPriorityBoost.h" />
|
||||
@ -333,6 +334,7 @@
|
||||
<ClCompile Include="Config\Settings\SpriteFilter.cpp" />
|
||||
<ClCompile Include="Config\Settings\SpriteTexCoord.cpp" />
|
||||
<ClCompile Include="Config\Settings\SupportedResolutions.cpp" />
|
||||
<ClCompile Include="Config\Settings\SupportedTextureFormats.cpp" />
|
||||
<ClCompile Include="Config\Settings\TextureFilter.cpp" />
|
||||
<ClCompile Include="Config\Settings\VSync.cpp" />
|
||||
<ClCompile Include="Config\Settings\WinVersionLie.cpp" />
|
||||
|
@ -636,6 +636,9 @@
|
||||
<ClInclude Include="DDraw\LogUsedResourceFormat.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\SupportedTextureFormats.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -1004,6 +1007,9 @@
|
||||
<ClCompile Include="DDraw\LogUsedResourceFormat.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\Settings\SupportedTextureFormats.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DDrawCompat.rc">
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <Common/CompatRef.h>
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Common/Log.h>
|
||||
#include <Config/Settings/SupportedTextureFormats.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/FormatInfo.h>
|
||||
#include <D3dDdi/ScopedCriticalSection.h>
|
||||
#include <DDraw/ScopedThreadLock.h>
|
||||
#include <DDraw/Surfaces/Surface.h>
|
||||
@ -10,6 +13,80 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
struct EnumTextureFormatsArgs
|
||||
{
|
||||
void* callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
bool isSupported(const DDPIXELFORMAT& pf)
|
||||
{
|
||||
if ((pf.dwFlags & DDPF_FOURCC) && pf.dwFourCC < 0x100)
|
||||
{
|
||||
// D3DDDIFMT_A8B8G8R8 and D3DDDIFMT_X8B8G8R8 are enumerated like this, but nobody is expected to use them,
|
||||
// and with proper pixel formats these cannot be created in video memory anyway.
|
||||
return false;
|
||||
}
|
||||
return Config::supportedTextureFormats.isSupported(D3dDdi::getFormat(pf));
|
||||
}
|
||||
|
||||
bool isSupported(const DDSURFACEDESC& desc)
|
||||
{
|
||||
return isSupported(desc.ddpfPixelFormat);
|
||||
}
|
||||
|
||||
template <typename Format>
|
||||
HRESULT CALLBACK enumTextureFormatsCallback(Format* lpFormat, LPVOID lpContext)
|
||||
{
|
||||
if (!isSupported(*lpFormat))
|
||||
{
|
||||
return D3DENUMRET_OK;
|
||||
}
|
||||
auto& args = *static_cast<EnumTextureFormatsArgs*>(lpContext);
|
||||
auto origCallback = static_cast<decltype(&enumTextureFormatsCallback<Format>)>(args.callback);
|
||||
return origCallback(lpFormat, args.context);
|
||||
}
|
||||
|
||||
template <typename TDirect3DDevice>
|
||||
D3DDEVICEDESC getCaps(TDirect3DDevice* This)
|
||||
{
|
||||
D3DDEVICEDESC hwDesc = {};
|
||||
hwDesc.dwSize = sizeof(hwDesc);
|
||||
D3DDEVICEDESC helDesc = {};
|
||||
helDesc.dwSize = sizeof(helDesc);
|
||||
getOrigVtable(This).GetCaps(This, &hwDesc, &helDesc);
|
||||
return hwDesc;
|
||||
}
|
||||
|
||||
D3DDEVICEDESC7 getCaps(IDirect3DDevice7* This)
|
||||
{
|
||||
D3DDEVICEDESC7 desc = {};
|
||||
getOrigVtable(This).GetCaps(This, &desc);
|
||||
return desc;
|
||||
}
|
||||
|
||||
template <typename TDirect3DDevice>
|
||||
bool isHalDevice(TDirect3DDevice* This)
|
||||
{
|
||||
return getCaps(This).dwDevCaps & D3DDEVCAPS_TEXTUREVIDEOMEMORY;
|
||||
}
|
||||
|
||||
template <typename TDirect3DDevice, typename EnumProc>
|
||||
HRESULT STDMETHODCALLTYPE enumTextureFormats(TDirect3DDevice* This, EnumProc* lpd3dEnumPixelProc, LPVOID lpArg)
|
||||
{
|
||||
if (!This || !lpd3dEnumPixelProc || !isHalDevice(This))
|
||||
{
|
||||
if (This && lpd3dEnumPixelProc)
|
||||
{
|
||||
LOG_ONCE("Using feature: enumerating software texture formats via " << Compat::getTypeName<TDirect3DDevice>());
|
||||
}
|
||||
return getOrigVtable(This).EnumTextureFormats(This, lpd3dEnumPixelProc, lpArg);
|
||||
}
|
||||
LOG_ONCE("Using feature: enumerating hardware texture formats via " << Compat::getTypeName<TDirect3DDevice>());
|
||||
EnumTextureFormatsArgs args = { lpd3dEnumPixelProc, lpArg };
|
||||
return getOrigVtable(This).EnumTextureFormats(This, enumTextureFormatsCallback, &args);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE execute(IDirect3DDevice* This,
|
||||
LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags)
|
||||
{
|
||||
@ -48,6 +125,8 @@ namespace
|
||||
{
|
||||
vtable.SetRenderTarget = &setRenderTarget;
|
||||
}
|
||||
|
||||
vtable.EnumTextureFormats = &enumTextureFormats;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user