feat(render): DoScreenGrabOnNextPresent now properly saves the file into the GameHDD folder

feat(storage): save files now filter out the file extension and all save to .ms files to avoid confusion
chore(render): make names more accurate
This commit is contained in:
Patoke
2026-03-09 01:15:33 -03:00
parent 3ead2bb093
commit 8716df6eee
5 changed files with 133 additions and 95 deletions

View File

@@ -35,11 +35,17 @@ SOFTWARE.
#define MATRIX_MODE_MODELVIEW_CBUFF 3
#define MATRIX_MODE_MODELVIEW_MAX 4
#define STACK_TYPES 4
#define STACK_SIZE 16
#define MAX_MIP_LEVELS 5
#define STACK_TYPES 4
#define STACK_SIZE 16
#define MAX_TEXTURES 512
#define NUM_THUMBNAIL_DOWNSAMPLES 4 // the amount of downsamples we do to the thumbnail texture
#define THUMBNAIL_MAX_QUALITY 0 // 1920x1080
#define THUMBNAIL_DOWNSAMPLE_QUALITY_1 1 // 512x512
#define THUMBNAIL_DOWNSAMPLE_QUALITY_2 2 // 256x256
#define THUMBNAIL_DOWNSAMPLE_QUALITY_3 3 // 128x128
#define THUMBNAIL_DOWNSAMPLE_TARGET 4 // 64x64
#define NUM_COMMAND_HANDLES 0x800000
#define MAX_COMMAND_BUFFERS 16000
@@ -164,6 +170,15 @@ private:
void DeleteInternalBuffer(int index);
Renderer::Context &getContext();
public:
enum eTextureSamplerFlags
{
SAMPLER_PARAM_CLAMP_U = 1 << 0,
SAMPLER_PARAM_CLAMP_V = 1 << 1,
SAMPLER_PARAM_LINEAR_FILTER = 1 << 2,
SAMPLER_PARAM_LINEAR_MIPS = 1 << 3,
};
struct Texture
{
bool allocated;
@@ -422,11 +437,11 @@ public:
ID3D11Device *m_pDevice;
ID3D11DeviceContext *m_pDeviceContext;
IDXGISwapChain *m_pSwapChain;
ID3D11RenderTargetView *renderTargetView;
ID3D11RenderTargetView *renderTargetViews[4];
ID3D11ShaderResourceView *renderTargetShaderResourceView;
ID3D11ShaderResourceView *renderTargetShaderResourceViews[4];
ID3D11Texture2D *renderTargetTextures[4];
ID3D11RenderTargetView *mainRenderTargetView;
ID3D11RenderTargetView *downSampleRenderTargetViews[NUM_THUMBNAIL_DOWNSAMPLES];
ID3D11ShaderResourceView *mainShaderResourceView;
ID3D11ShaderResourceView *downSampleShaderResourceViews[NUM_THUMBNAIL_DOWNSAMPLES];
ID3D11Texture2D *downSampleTextures[NUM_THUMBNAIL_DOWNSAMPLES];
ID3D11DepthStencilView *depthStencilView;
ID3D11VertexShader **vertexShaderTable;
ID3D11VertexShader *screenSpaceVertexShader;
@@ -456,14 +471,14 @@ public:
BYTE reservedRendererByte1;
BYTE paddingAfterRendererByte1[3];
DWORD reservedRendererDword1;
int16_t *m_commandHandleToIndex;
int16_t *m_vertexIdxToBufferIdx;
CommandBuffer **m_commandBuffers;
DirectX::XMMATRIX *m_commandMatrices;
int *m_commandIndexToHandle;
int *m_bufferIdxToVertexIdx;
uint8_t *m_commandPrimitiveTypes;
uint8_t *m_commandVertexTypes;
DWORD reservedRendererDword2;
DWORD reservedRendererDword3;
DWORD m_currentCommandBuffer;
DWORD m_numBuffersToDeallocate;
std::unordered_map<int, ID3D11BlendState *> managedBlendStates;
std::unordered_map<int, ID3D11DepthStencilState *> managedDepthStencilStates;
std::unordered_map<int, ID3D11SamplerState *> managedSamplerStates;

View File

@@ -114,7 +114,7 @@ bool Renderer::CBuffCall(int index, bool full)
EnterCriticalSection(&m_commandBufferCS);
bool result = false;
const int commandIndex = m_commandHandleToIndex[index];
const int commandIndex = m_vertexIdxToBufferIdx[index];
if (commandIndex >= 0)
{
Renderer::Context &c = getContext();
@@ -210,12 +210,11 @@ void Renderer::CBuffClear(int index)
{
EnterCriticalSection(&m_commandBufferCS);
std::int16_t *externalToInternal = static_cast<std::int16_t*>(m_commandHandleToIndex);
const int internalIndex = externalToInternal[index];
const int internalIndex = m_vertexIdxToBufferIdx[index];
if (internalIndex >= 0)
{
DeleteInternalBuffer(internalIndex);
externalToInternal[index] = static_cast<std::int16_t>(-2);
m_vertexIdxToBufferIdx[index] = static_cast<std::int16_t>(-2);
}
LeaveCriticalSection(&m_commandBufferCS);
@@ -235,7 +234,7 @@ int Renderer::CBuffCreate(int count)
assert(first < NUM_COMMAND_HANDLES);
int cursor = probe;
while (cursor < end && cursor < NUM_COMMAND_HANDLES && m_commandHandleToIndex[cursor] == static_cast<std::int16_t>(-1))
while (cursor < end && cursor < NUM_COMMAND_HANDLES && m_vertexIdxToBufferIdx[cursor] == static_cast<std::int16_t>(-1))
{
++cursor;
}
@@ -257,7 +256,7 @@ int Renderer::CBuffCreate(int count)
{
const int allocationEnd = first + count;
for (int i = first; i < allocationEnd; ++i)
m_commandHandleToIndex[i] = static_cast<std::int16_t>(-2);
m_vertexIdxToBufferIdx[i] = static_cast<std::int16_t>(-2);
if (reservedRendererByte1)
reservedRendererDword1 = allocationEnd;
@@ -284,18 +283,18 @@ void Renderer::CBuffDeferredModeEnd()
for (std::vector<Renderer::DeferredCBuff>::const_iterator it = c.deferredBuffers.begin(); it != c.deferredBuffers.end(); ++it)
{
const Renderer::DeferredCBuff &deferred = *it;
const int existingIndex = m_commandHandleToIndex[deferred.m_vertex_index];
const int existingIndex = m_vertexIdxToBufferIdx[deferred.m_vertex_index];
if (existingIndex >= 0)
DeleteInternalBuffer(existingIndex);
if (static_cast<int>(reservedRendererDword2 + reservedRendererDword3 + 10) > MAX_COMMAND_BUFFERS)
if (static_cast<int>(m_currentCommandBuffer + m_numBuffersToDeallocate + 10) > MAX_COMMAND_BUFFERS)
DebugBreak();
const int internalSlot = reservedRendererDword2;
++reservedRendererDword2;
const int internalSlot = m_currentCommandBuffer;
++m_currentCommandBuffer;
m_commandHandleToIndex[deferred.m_vertex_index] = static_cast<std::int16_t>(internalSlot);
m_commandIndexToHandle[internalSlot] = deferred.m_vertex_index;
m_vertexIdxToBufferIdx[deferred.m_vertex_index] = static_cast<std::int16_t>(internalSlot);
m_bufferIdxToVertexIdx[internalSlot] = deferred.m_vertex_index;
m_commandVertexTypes[internalSlot] = static_cast<std::uint8_t>(deferred.m_vertex_type);
m_commandPrimitiveTypes[internalSlot] = static_cast<std::uint8_t>(deferred.m_primitive_type);
m_commandBuffers[internalSlot] = deferred.m_command_buf;
@@ -318,11 +317,11 @@ void Renderer::CBuffDelete(int first, int count)
const int end = first + count;
for (int i = first; i < end; ++i)
{
const int internalIndex = m_commandHandleToIndex[i];
const int internalIndex = m_vertexIdxToBufferIdx[i];
if (internalIndex >= 0)
DeleteInternalBuffer(internalIndex);
m_commandHandleToIndex[i] = static_cast<std::int16_t>(-1);
m_vertexIdxToBufferIdx[i] = static_cast<std::int16_t>(-1);
}
LeaveCriticalSection(&m_commandBufferCS);
@@ -349,18 +348,18 @@ void Renderer::CBuffEnd()
}
else
{
const int existingIndex = m_commandHandleToIndex[c.recordingBufferIndex];
const int existingIndex = m_vertexIdxToBufferIdx[c.recordingBufferIndex];
if (existingIndex >= 0)
DeleteInternalBuffer(existingIndex);
if (static_cast<int>(reservedRendererDword2 + reservedRendererDword3 + 10) > MAX_COMMAND_BUFFERS)
if (static_cast<int>(m_currentCommandBuffer + m_numBuffersToDeallocate + 10) > MAX_COMMAND_BUFFERS)
DebugBreak();
const int internalSlot = reservedRendererDword2;
++reservedRendererDword2;
const int internalSlot = m_currentCommandBuffer;
++m_currentCommandBuffer;
m_commandHandleToIndex[c.recordingBufferIndex] = static_cast<std::int16_t>(internalSlot);
m_commandIndexToHandle[internalSlot] = c.recordingBufferIndex;
m_vertexIdxToBufferIdx[c.recordingBufferIndex] = static_cast<std::int16_t>(internalSlot);
m_bufferIdxToVertexIdx[internalSlot] = c.recordingBufferIndex;
m_commandVertexTypes[internalSlot] = static_cast<std::uint8_t>(c.recordingVertexType);
m_commandPrimitiveTypes[internalSlot] = static_cast<std::uint8_t>(c.recordingPrimitiveType);
m_commandBuffers[internalSlot] = c.commandBuffer;
@@ -386,7 +385,7 @@ int Renderer::CBuffSize(int index)
unsigned int size = 0;
EnterCriticalSection(&m_commandBufferCS);
const int commandIndex = m_commandHandleToIndex[index];
const int commandIndex = m_vertexIdxToBufferIdx[index];
if (commandIndex >= 0)
size = static_cast<unsigned int>(m_commandBuffers[commandIndex]->GetAllocated());
LeaveCriticalSection(&m_commandBufferCS);
@@ -412,26 +411,26 @@ void Renderer::CBuffTick()
EnterCriticalSection(&m_commandBufferCS);
int completedDeletes = 0;
if (reservedRendererDword3 > 0)
if (m_numBuffersToDeallocate > 0)
{
int tailSlot = MAX_COMMAND_BUFFERS - 1;
int deleteIdx = MAX_COMMAND_BUFFERS - 1;
do
{
Renderer::CommandBuffer *buffer = m_commandBuffers[tailSlot];
Renderer::CommandBuffer *buffer = m_commandBuffers[deleteIdx];
if (buffer)
delete buffer;
m_commandBuffers[tailSlot] = NULL;
m_commandBuffers[deleteIdx] = NULL;
if (--reservedRendererDword3 == 0)
if (--m_numBuffersToDeallocate == 0)
{
++completedDeletes;
--tailSlot;
--deleteIdx;
}
else
{
m_commandBuffers[tailSlot] = m_commandBuffers[(MAX_COMMAND_BUFFERS - 1) - static_cast<int>(reservedRendererDword3)];
m_commandBuffers[deleteIdx] = m_commandBuffers[(MAX_COMMAND_BUFFERS - 1) - static_cast<int>(m_numBuffersToDeallocate)];
}
} while (completedDeletes < static_cast<int>(reservedRendererDword3));
} while (completedDeletes < static_cast<int>(m_numBuffersToDeallocate));
}
LeaveCriticalSection(&m_commandBufferCS);
@@ -441,24 +440,24 @@ void Renderer::DeleteInternalBuffer(int index)
{
EnterCriticalSection(&m_commandBufferCS);
++reservedRendererDword3;
const int recycledSlot = MAX_COMMAND_BUFFERS - static_cast<int>(reservedRendererDword3);
++m_numBuffersToDeallocate;
const int index_delete = MAX_COMMAND_BUFFERS - static_cast<int>(m_numBuffersToDeallocate);
m_commandBuffers[recycledSlot] = m_commandBuffers[index];
m_commandMatrices[recycledSlot] = m_commandMatrices[index];
m_commandBuffers[index_delete] = m_commandBuffers[index];
m_commandMatrices[index_delete] = m_commandMatrices[index];
if (reservedRendererDword2-- != 1)
if (m_currentCommandBuffer-- != 1)
{
const int lastActive = reservedRendererDword2;
const int mappedFrom = m_currentCommandBuffer;
m_commandBuffers[index] = m_commandBuffers[lastActive];
m_commandMatrices[index] = m_commandMatrices[lastActive];
m_commandVertexTypes[index] = m_commandVertexTypes[lastActive];
m_commandPrimitiveTypes[index] = m_commandPrimitiveTypes[lastActive];
m_commandBuffers[index] = m_commandBuffers[mappedFrom];
m_commandMatrices[index] = m_commandMatrices[mappedFrom];
m_commandVertexTypes[index] = m_commandVertexTypes[mappedFrom];
m_commandPrimitiveTypes[index] = m_commandPrimitiveTypes[mappedFrom];
const int commandIndex = m_commandIndexToHandle[lastActive];
m_commandHandleToIndex[commandIndex] = static_cast<std::int16_t>(index);
m_commandIndexToHandle[index] = commandIndex;
const int commandIndex = m_bufferIdxToVertexIdx[mappedFrom];
m_vertexIdxToBufferIdx[commandIndex] = static_cast<std::int16_t>(index);
m_bufferIdxToVertexIdx[index] = commandIndex;
}
LeaveCriticalSection(&m_commandBufferCS);

View File

@@ -31,7 +31,7 @@ Renderer InternalRenderManager;
DWORD Renderer::tlsIdx = TlsAlloc();
_RTL_CRITICAL_SECTION Renderer::totalAllocCS = {};
DWORD Renderer::s_auiWidths[] = { 1920, 512, 256, 128, 64, 0 };
DWORD Renderer::s_auiWidths[] = { 1920, 512, 256, 128, 64 };
DWORD Renderer::s_auiHeights[] = { 1080, 512, 256, 128, 64 };
int Renderer::totalAlloc = 0;
const float Renderer::PI = 3.14159274f;
@@ -265,7 +265,7 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
// @Patoke fix: bind render target to a proper backbuffer texture
ID3D11Resource *actualBackBuffer = NULL;
renderTargetView->GetResource(&actualBackBuffer);
mainRenderTargetView->GetResource(&actualBackBuffer);
// copy the backbuffer contents
c.m_pDeviceContext->CopyResource(m_backBufferTexture, actualBackBuffer);
@@ -423,7 +423,7 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
ID3D11ShaderResourceView *nullSRV[1] = {nullptr};
c.m_pDeviceContext->PSSetShaderResources(0, 1, nullSRV);
for (UINT i = 0; i < MAX_MIP_LEVELS - 1; ++i)
for (UINT i = 0; i < NUM_THUMBNAIL_DOWNSAMPLES; ++i)
{
D3D11_VIEWPORT viewport = {};
viewport.TopLeftX = 0.0f;
@@ -435,10 +435,10 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
c.m_pDeviceContext->PSSetShaderResources(0, 1, nullSRV);
c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetViews[i], NULL);
c.m_pDeviceContext->OMSetRenderTargets(1, &downSampleRenderTargetViews[i], NULL);
c.m_pDeviceContext->RSSetViewports(1, &viewport);
ID3D11ShaderResourceView *inputTexture = (i == 0) ? renderTargetShaderResourceView : renderTargetShaderResourceViews[i - 1];
ID3D11ShaderResourceView *inputTexture = (i == 0) ? mainShaderResourceView : downSampleShaderResourceViews[i - 1];
c.m_pDeviceContext->PSSetShaderResources(0, 1, &inputTexture);
c.m_pDeviceContext->PSSetSamplers(0, 1, &samplerState);
c.m_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
@@ -475,7 +475,7 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
}
D3D11_TEXTURE2D_DESC texDesc = {};
renderTargetTextures[MAX_MIP_LEVELS - 2]->GetDesc(&texDesc);
downSampleTextures[THUMBNAIL_DOWNSAMPLE_QUALITY_3]->GetDesc(&texDesc);
texDesc.Usage = D3D11_USAGE_STAGING;
texDesc.BindFlags = 0;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
@@ -487,7 +487,7 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
if (stagingTexture)
{
c.m_pDeviceContext->CopyResource(stagingTexture, renderTargetTextures[MAX_MIP_LEVELS - 2]);
c.m_pDeviceContext->CopyResource(stagingTexture, downSampleTextures[THUMBNAIL_DOWNSAMPLE_QUALITY_3]);
D3D11_MAPPED_SUBRESOURCE mapped = {};
if (SUCCEEDED(c.m_pDeviceContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mapped)))
@@ -538,7 +538,7 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
viewport.MaxDepth = 1.0f;
c.m_pDeviceContext->RSSetViewports(1, &viewport);
c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
c.m_pDeviceContext->OMSetRenderTargets(1, &mainRenderTargetView, depthStencilView);
activeVertexType = -1;
activePixelType = -1;
@@ -680,27 +680,27 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
PROFILER_INIT();
m_commandHandleToIndex = new int16_t[NUM_COMMAND_HANDLES];
m_vertexIdxToBufferIdx = new int16_t[NUM_COMMAND_HANDLES];
m_commandBuffers = new CommandBuffer *[MAX_COMMAND_BUFFERS];
m_commandMatrices = new DirectX::XMMATRIX[MAX_COMMAND_BUFFERS];
m_commandIndexToHandle = new int[MAX_COMMAND_BUFFERS];
m_bufferIdxToVertexIdx = new int[MAX_COMMAND_BUFFERS];
m_commandPrimitiveTypes = new uint8_t[MAX_COMMAND_BUFFERS];
m_commandVertexTypes = new uint8_t[MAX_COMMAND_BUFFERS];
std::memset(m_commandHandleToIndex, 0xFF, 0x1000000u);
std::memset(m_commandBuffers, 0, 0xFA00u);
std::memset(m_commandIndexToHandle, 0, 0xFA00u);
std::memset(m_commandPrimitiveTypes, 0, 0x3E80u);
std::memset(m_commandVertexTypes, 0, 0x3E80u);
std::memset(m_vertexIdxToBufferIdx, 0xFF, NUM_COMMAND_HANDLES * sizeof(int16_t));
std::memset(m_commandBuffers, 0, MAX_COMMAND_BUFFERS * sizeof(CommandBuffer *));
std::memset(m_bufferIdxToVertexIdx, 0, MAX_COMMAND_BUFFERS * sizeof(int));
std::memset(m_commandPrimitiveTypes, 0, MAX_COMMAND_BUFFERS * sizeof(uint8_t));
std::memset(m_commandVertexTypes, 0, MAX_COMMAND_BUFFERS * sizeof(uint8_t));
reservedRendererDword3 = 0;
m_numBuffersToDeallocate = 0;
m_bShouldScreenGrabNextFrame = false;
SetupShaders();
const float clearColour[4] = {0.0f, 0.0f, 0.0f, 0.0f};
SetClearColour(clearColour);
m_pDeviceContext->OMGetRenderTargets(1, &renderTargetView, &depthStencilView);
m_pDeviceContext->OMGetRenderTargets(1, &mainRenderTargetView, &depthStencilView);
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc = {};
std::memset(&rtvDesc, 0, sizeof(rtvDesc));
@@ -717,7 +717,7 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
ID3D11Resource *backBufferResource = NULL;
ID3D11Texture2D *backBufferTexture = NULL;
renderTargetView->GetResource(&backBufferResource);
mainRenderTargetView->GetResource(&backBufferResource);
backBufferResource->QueryInterface(IID_PPV_ARGS(&backBufferTexture));
D3D11_TEXTURE2D_DESC backDesc = {};
@@ -735,9 +735,9 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
m_pDevice->CreateTexture2D(&safeDesc, NULL, &m_backBufferTexture);
m_pDevice->CreateShaderResourceView(m_backBufferTexture, NULL, &renderTargetShaderResourceView);
m_pDevice->CreateShaderResourceView(m_backBufferTexture, NULL, &mainShaderResourceView);
renderTargetTextures[0] = m_backBufferTexture;
downSampleTextures[THUMBNAIL_MAX_QUALITY] = m_backBufferTexture;
//m_pDevice->CreateRenderTargetView(backBufferTexture, &rtvDesc, &renderTargetView);
@@ -756,15 +756,15 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
for (UINT i = 0; i < MAX_MIP_LEVELS - 1; ++i)
for (UINT i = 0; i < NUM_THUMBNAIL_DOWNSAMPLES; ++i)
{
desc.Width = s_auiWidths[i + 1];
desc.Height = s_auiHeights[i + 1];
// @Patoke fix: before these would fail and our views would be nullptrs
m_pDevice->CreateTexture2D(&desc, NULL, &renderTargetTextures[i]);
m_pDevice->CreateRenderTargetView(renderTargetTextures[i], NULL, &renderTargetViews[i]);
m_pDevice->CreateShaderResourceView(renderTargetTextures[i], NULL, &renderTargetShaderResourceViews[i]);
m_pDevice->CreateTexture2D(&desc, NULL, &downSampleTextures[i]);
m_pDevice->CreateRenderTargetView(downSampleTextures[i], NULL, &downSampleRenderTargetViews[i]);
m_pDevice->CreateShaderResourceView(downSampleTextures[i], NULL, &downSampleShaderResourceViews[i]);
}
std::memset(m_textures, 0, sizeof(m_textures));
@@ -878,7 +878,7 @@ void Renderer::Present()
ID3D11Texture2D *backBuffer = NULL;
ID3D11Texture2D *stagingTexture = NULL;
renderTargetView->GetResource(&backBufferResource);
mainRenderTargetView->GetResource(&backBufferResource);
backBufferResource->QueryInterface(IID_PPV_ARGS(&backBuffer));
D3D11_TEXTURE2D_DESC desc = {};
backBuffer->GetDesc(&desc);
@@ -911,9 +911,19 @@ void Renderer::Present()
m_pDeviceContext->Unmap(stagingTexture, 0);
}
static int count = 0;
// @Patoke add
char curDir[256];
GetCurrentDirectoryA(sizeof(curDir), curDir);
char ssPath[512];
sprintf(ssPath, "%s/Windows64/GameHDD/", curDir);
_SYSTEMTIME UTCSysTime;
GetSystemTime(&UTCSysTime);
char fileName[304];
sprintf(fileName, "d:\\screen%d.png", count++);
sprintf(fileName, "%s/%4d-%02d-%02d-%02d-%02d-%02d.png", ssPath, UTCSysTime.wYear, UTCSysTime.wMonth, UTCSysTime.wDay, UTCSysTime.wHour, UTCSysTime.wMinute,
UTCSysTime.wSecond);
D3DXIMAGE_INFO info;
info.Width = kScreenGrabWidth;
@@ -1015,7 +1025,7 @@ void Renderer::StartFrame()
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
c.m_pDeviceContext->RSSetViewports(1, &viewport);
c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
c.m_pDeviceContext->OMSetRenderTargets(1, &mainRenderTargetView, depthStencilView);
PROFILER_FLIP();
}

View File

@@ -98,14 +98,15 @@ ID3D11SamplerState *Renderer::GetManagedSamplerState()
if (it != managedSamplerStates.end())
return it->second;
const bool clampU = (key & 0x01) != 0;
const bool clampV = (key & 0x02) != 0;
const bool linearFilter = (key & 0x04) != 0;
const bool mipLinear = (key & 0x08) != 0;
const int filterBits = (mipLinear ? 0x08 : 0x00) | (linearFilter ? 0x22 : 0x02);
const bool clampU = (key & SAMPLER_PARAM_CLAMP_U) != 0;
const bool clampV = (key & SAMPLER_PARAM_CLAMP_V) != 0;
const bool linearFilter = (key & SAMPLER_PARAM_LINEAR_FILTER) != 0;
const bool mipLinear = (key & SAMPLER_PARAM_LINEAR_MIPS) != 0;
const int filterBits = (mipLinear != 0 ? (linearFilter ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR)
: (linearFilter ? D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR : D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR));
D3D11_SAMPLER_DESC desc = {};
desc.Filter = static_cast<D3D11_FILTER>(filterBits >> 1);
desc.Filter = static_cast<D3D11_FILTER>(filterBits);
desc.AddressU = clampU ? D3D11_TEXTURE_ADDRESS_CLAMP : D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = clampV ? D3D11_TEXTURE_ADDRESS_CLAMP : D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
@@ -577,7 +578,7 @@ void Renderer::StateSetViewport(C4JRender::eViewportType viewportType)
viewport.MaxDepth = 1.0f;
m_pDeviceContext->RSSetViewports(1, &viewport);
m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
m_pDeviceContext->OMSetRenderTargets(1, &mainRenderTargetView, depthStencilView);
}

View File

@@ -146,8 +146,21 @@ C4JStorage::ESaveGameState CSaveGame::GetSavesInfo(int iPad, int (*Func)(LPVOID
// too but this is good enough for now
if (!(saveFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
strcpy_s(szTitleName, sizeof(szTitleName), saveFileData.cFileName);
strcpy_s(this->m_szSaveTitle, saveFileData.cFileName); // populate the save title
// remove the file extension
std::string decoratedSaveTitle = saveFileData.cFileName;
uint64_t extensionDot = decoratedSaveTitle.rfind('.');
// populate the save title
if (extensionDot != std::string::npos)
{
strcpy_s(this->m_szSaveTitle, decoratedSaveTitle.substr(0, extensionDot).c_str());
}
else
{
strcpy_s(this->m_szSaveTitle, decoratedSaveTitle.c_str());
}
strcpy_s(szTitleName, sizeof(szTitleName), this->m_szSaveTitle);
break;
}
} while (FindNextFileA(hSaveFile, &saveFileData));
@@ -159,7 +172,7 @@ C4JStorage::ESaveGameState CSaveGame::GetSavesInfo(int iPad, int (*Func)(LPVOID
strcpy_s(m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, szTitleName);
char fileName[280];
sprintf(fileName, "%s\\Windows64\\GameHDD\\%s\\%s", dirName, findFileData.cFileName, szTitleName);
sprintf(fileName, "%s\\Windows64\\GameHDD\\%s\\%s.ms", dirName, findFileData.cFileName, szTitleName);
GetFileAttributesExA(fileName, GetFileExInfoStandard, &fileInfoBuffer);
m_pSaveDetails->SaveInfoA[i].metaData.dataSize = fileInfoBuffer.nFileSizeLow;
@@ -275,7 +288,7 @@ C4JStorage::ESaveGameState CSaveGame::LoadSaveData(PSAVE_INFO pSaveInfo, int (*F
GetCurrentDirectoryA(sizeof(curDir), curDir);
sprintf(dirName, "%s/Windows64/GameHDD/%s", curDir, m_szSaveUniqueName);
CreateDirectoryA(dirName, 0);
sprintf(fileName, "%s/%s", dirName, this->m_szSaveTitle); // @Patoke add
sprintf(fileName, "%s/%s.ms", dirName, this->m_szSaveTitle); // @Patoke add
HANDLE h = CreateFileA(fileName, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
@@ -490,7 +503,7 @@ C4JStorage::ESaveGameState CSaveGame::SaveSaveData(int (*Func)(LPVOID, const boo
GetCurrentDirectoryA(sizeof(curDir), curDir);
sprintf(dirName, "%s/Windows64/GameHDD/%s", curDir, m_szSaveUniqueName);
CreateDirectoryA(dirName, 0);
sprintf(fileName, "%s/%s", dirName, this->m_szSaveTitle); // @Patoke add
sprintf(fileName, "%s/%s.ms", dirName, this->m_szSaveTitle); // @Patoke add
HANDLE h = CreateFileA(fileName, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
@@ -534,7 +547,7 @@ C4JStorage::ESaveGameState CSaveGame::DeleteSaveData(PSAVE_INFO pSaveInfo, int (
GetCurrentDirectoryA(sizeof(curDir), curDir);
sprintf(dirName, "%s/Windows64/GameHDD/%s", curDir, pSaveInfo->UTF8SaveFilename);
sprintf(fileName, "%s/%s", dirName, pSaveInfo->UTF8SaveTitle);
sprintf(fileName, "%s/%s.ms", dirName, pSaveInfo->UTF8SaveTitle);
sprintf(thumbName, "%s/thumbnails/thumbData.png", dirName);
DeleteFileA(fileName);