1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-20 16:09:12 +01:00
cnc-ddraw/src/render_d3d9.c

570 lines
19 KiB
C
Raw Normal View History

2018-09-28 22:40:44 +02:00
#include <windows.h>
#include <stdio.h>
#include <d3d9.h>
#include "fps_limiter.h"
2020-10-13 09:20:52 +02:00
#include "dd.h"
#include "ddsurface.h"
#include "d3d9shader.h"
2018-10-15 03:31:57 +02:00
#include "render_d3d9.h"
2020-10-13 09:20:52 +02:00
#include "utils.h"
#include "wndproc.h"
#include "blt.h"
2020-10-13 10:15:42 +02:00
#include "debug.h"
#include "D3d9types.h"
2023-08-06 09:37:43 +02:00
#include "hook.h"
2018-09-28 22:40:44 +02:00
2018-10-01 13:10:10 +02:00
2022-09-23 02:45:59 +02:00
static BOOL d3d9_create_resources();
2020-10-13 09:20:52 +02:00
static BOOL d3d9_set_states();
2021-05-15 02:58:07 +02:00
static BOOL d3d9_update_vertices(BOOL upscale_hack, BOOL stretch);
2021-06-11 20:30:43 +02:00
static D3D9RENDERER g_d3d9;
2018-10-02 03:25:34 +02:00
2020-10-13 09:20:52 +02:00
BOOL d3d9_is_available()
{
LPDIRECT3D9 d3d9 = NULL;
2023-08-06 09:41:47 +02:00
if ((g_d3d9.hmodule = real_LoadLibraryA("d3d9.dll")))
2020-10-13 09:20:52 +02:00
{
IDirect3D9* (WINAPI * d3d_create9)(UINT) =
2023-08-06 09:25:34 +02:00
(IDirect3D9 * (WINAPI*)(UINT))real_GetProcAddress(g_d3d9.hmodule, "Direct3DCreate9");
2020-10-13 09:20:52 +02:00
if (d3d_create9 && (d3d9 = d3d_create9(D3D_SDK_VERSION)))
IDirect3D9_Release(d3d9);
}
return d3d9 != NULL;
}
2018-09-28 22:40:44 +02:00
2020-10-13 09:20:52 +02:00
BOOL d3d9_create()
2018-09-28 22:40:44 +02:00
{
2022-09-23 20:58:06 +02:00
if (g_d3d9.hwnd == g_ddraw->hwnd && d3d9_create_resources() && d3d9_reset(g_ddraw->windowed))
{
return TRUE;
}
2022-09-23 20:58:06 +02:00
d3d9_release();
2020-10-13 09:20:52 +02:00
if (!g_d3d9.hmodule)
2023-08-06 09:41:47 +02:00
g_d3d9.hmodule = real_LoadLibraryA("d3d9.dll");
2020-10-13 09:20:52 +02:00
if (g_d3d9.hmodule)
2018-09-28 22:40:44 +02:00
{
2022-09-28 21:35:25 +02:00
LPDIRECT3D9 d3d9on12 = NULL;
D3D9ON12_ARGS args;
memset(&args, 0, sizeof(args));
args.Enable9On12 = TRUE;
IDirect3D9* (WINAPI * d3d_create9on12)(INT, D3D9ON12_ARGS*, UINT) = NULL;
IDirect3D9* (WINAPI * d3d_create9)(UINT) = (void*)real_GetProcAddress(g_d3d9.hmodule, "Direct3DCreate9");
if (g_ddraw->d3d9on12)
{
2023-08-06 09:25:34 +02:00
d3d_create9on12 = (void*)real_GetProcAddress(g_d3d9.hmodule, "Direct3DCreate9On12");
}
2018-09-28 22:40:44 +02:00
2022-09-28 21:35:25 +02:00
if ((d3d_create9on12 && (d3d9on12 = g_d3d9.instance = d3d_create9on12(D3D_SDK_VERSION, &args, 1))) ||
(d3d_create9 && (g_d3d9.instance = d3d_create9(D3D_SDK_VERSION))))
2018-09-28 22:40:44 +02:00
{
2022-09-24 01:08:32 +02:00
#if _DEBUG
D3DADAPTER_IDENTIFIER9 ai = {0};
D3DCAPS9 caps = { 0 };
2023-07-31 07:46:19 +02:00
HRESULT hr = IDirect3D9_GetAdapterIdentifier(g_d3d9.instance, D3DADAPTER_DEFAULT, 0, &ai);
HRESULT hr2 = IDirect3D9_GetDeviceCaps(g_d3d9.instance, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
2022-09-24 01:08:32 +02:00
if (SUCCEEDED(hr))
{
TRACE("+--Direct3D9-------------------------------------\n");
2022-09-28 21:35:25 +02:00
TRACE("| D3D9On12: %s\n", d3d9on12 != NULL ? "True" : "False");
TRACE("| VendorId: 0x%x\n", ai.VendorId);
TRACE("| DeviceId: 0x%x\n", ai.DeviceId);
TRACE("| Revision: 0x%x\n", ai.Revision);
TRACE("| SubSysId: 0x%x\n", ai.SubSysId);
TRACE("| Version: %hu.%hu.%hu.%hu\n",
HIWORD(ai.DriverVersion.HighPart),
LOWORD(ai.DriverVersion.HighPart),
HIWORD(ai.DriverVersion.LowPart),
LOWORD(ai.DriverVersion.LowPart));
TRACE("| Driver: %s\n", ai.Driver);
TRACE("| Description: %s\n", ai.Description);
if (SUCCEEDED(hr2))
{
TRACE("| MaxTextureWidth: %d\n", caps.MaxTextureWidth);
TRACE("| MaxTextureHeight: %d\n", caps.MaxTextureHeight);
TRACE("| VertexShaderVersion: %d.%d\n",
(caps.VertexShaderVersion >> 8) & 0xFF,
caps.VertexShaderVersion & 0xFF);
TRACE("| PixelShaderVersion: %d.%d\n",
(caps.PixelShaderVersion >> 8) & 0xFF,
caps.PixelShaderVersion & 0xFF);
}
2022-09-24 01:08:32 +02:00
TRACE("+------------------------------------------------\n");
}
#endif
g_d3d9.hwnd = g_ddraw->hwnd;
2020-10-13 09:20:52 +02:00
memset(&g_d3d9.params, 0, sizeof(g_d3d9.params));
g_d3d9.params.Windowed = g_ddraw->windowed || g_ddraw->nonexclusive;
2020-10-13 09:20:52 +02:00
g_d3d9.params.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_d3d9.params.hDeviceWindow = g_ddraw->hwnd;
g_d3d9.params.PresentationInterval = g_ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
g_d3d9.params.BackBufferWidth = g_d3d9.params.Windowed ? 0 : g_ddraw->render.width;
g_d3d9.params.BackBufferHeight = g_d3d9.params.Windowed ? 0 : g_ddraw->render.height;
2023-08-01 03:06:09 +02:00
g_d3d9.params.BackBufferFormat = g_ddraw->mode.dmBitsPerPel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
2020-10-13 09:20:52 +02:00
g_d3d9.params.BackBufferCount = 1;
DWORD behavior_flags[] = {
2023-07-31 17:09:23 +02:00
D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_FPU_PRESERVE,
D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_FPU_PRESERVE,
D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
D3DCREATE_MULTITHREADED | D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
};
2021-06-11 20:30:43 +02:00
for (int i = 0; i < sizeof(behavior_flags) / sizeof(behavior_flags[0]); i++)
{
2018-10-09 08:56:58 +02:00
if (SUCCEEDED(
2018-11-12 00:39:47 +01:00
IDirect3D9_CreateDevice(
2020-10-13 09:20:52 +02:00
g_d3d9.instance,
2023-07-31 07:46:19 +02:00
D3DADAPTER_DEFAULT,
2018-10-09 08:56:58 +02:00
D3DDEVTYPE_HAL,
2020-10-13 09:20:52 +02:00
g_ddraw->hwnd,
2023-07-31 07:55:52 +02:00
behavior_flags[i],
2020-10-13 09:20:52 +02:00
&g_d3d9.params,
&g_d3d9.device)))
2022-09-23 02:45:59 +02:00
return g_d3d9.device && d3d9_create_resources() && d3d9_set_states();
}
2018-09-28 22:40:44 +02:00
}
}
2018-10-09 08:56:58 +02:00
return FALSE;
2018-10-02 03:25:34 +02:00
}
2020-10-13 09:20:52 +02:00
BOOL d3d9_on_device_lost()
2018-10-15 00:57:05 +02:00
{
2020-10-13 09:20:52 +02:00
if (g_d3d9.device && IDirect3DDevice9_TestCooperativeLevel(g_d3d9.device) == D3DERR_DEVICENOTRESET)
2020-10-13 21:58:04 +02:00
{
return d3d9_reset(g_ddraw->windowed);
2020-10-13 21:58:04 +02:00
}
2018-10-15 00:57:05 +02:00
return FALSE;
}
BOOL d3d9_reset(BOOL windowed)
2018-10-15 00:57:05 +02:00
{
g_d3d9.params.Windowed = windowed || g_ddraw->nonexclusive;
g_d3d9.params.BackBufferWidth = g_d3d9.params.Windowed ? 0 : g_ddraw->render.width;
g_d3d9.params.BackBufferHeight = g_d3d9.params.Windowed ? 0 : g_ddraw->render.height;
2023-08-01 03:06:09 +02:00
g_d3d9.params.BackBufferFormat = g_ddraw->mode.dmBitsPerPel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
2018-10-15 00:57:05 +02:00
2020-10-13 09:20:52 +02:00
if (g_d3d9.device && SUCCEEDED(IDirect3DDevice9_Reset(g_d3d9.device, &g_d3d9.params)))
2020-10-13 21:58:04 +02:00
{
2022-09-17 09:00:42 +02:00
BOOL result = d3d9_set_states();
if (result)
{
InterlockedExchange(&g_ddraw->render.palette_updated, TRUE);
InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
}
return result;
2020-10-13 21:58:04 +02:00
}
2018-10-15 00:57:05 +02:00
return FALSE;
}
BOOL d3d9_release_resources()
2018-10-15 00:57:05 +02:00
{
if (g_d3d9.pixel_shader)
2018-10-15 00:57:05 +02:00
{
IDirect3DPixelShader9_Release(g_d3d9.pixel_shader);
g_d3d9.pixel_shader = NULL;
2018-10-15 00:57:05 +02:00
}
2023-07-03 10:50:03 +02:00
if (g_d3d9.pixel_shader_upscale)
2021-07-21 14:52:44 +02:00
{
2023-07-03 10:50:03 +02:00
IDirect3DPixelShader9_Release(g_d3d9.pixel_shader_upscale);
g_d3d9.pixel_shader_upscale = NULL;
2021-07-21 14:52:44 +02:00
}
for (int i = 0; i < D3D9_TEXTURE_COUNT; i++)
2018-10-15 00:57:05 +02:00
{
2020-10-13 09:20:52 +02:00
if (g_d3d9.surface_tex[i])
{
2020-10-13 09:20:52 +02:00
IDirect3DTexture9_Release(g_d3d9.surface_tex[i]);
g_d3d9.surface_tex[i] = NULL;
}
2018-10-15 00:57:05 +02:00
2020-10-13 09:20:52 +02:00
if (g_d3d9.palette_tex[i])
{
2020-10-13 09:20:52 +02:00
IDirect3DTexture9_Release(g_d3d9.palette_tex[i]);
g_d3d9.palette_tex[i] = NULL;
}
2018-10-15 00:57:05 +02:00
}
if (g_d3d9.vertex_buf)
2018-10-15 00:57:05 +02:00
{
IDirect3DVertexBuffer9_Release(g_d3d9.vertex_buf);
g_d3d9.vertex_buf = NULL;
2018-10-15 00:57:05 +02:00
}
return TRUE;
}
BOOL d3d9_release()
{
d3d9_release_resources();
2020-10-13 09:20:52 +02:00
if (g_d3d9.device)
2018-10-15 00:57:05 +02:00
{
2022-09-05 02:44:27 +02:00
while (IDirect3DDevice9_Release(g_d3d9.device));
2020-10-13 09:20:52 +02:00
g_d3d9.device = NULL;
2018-10-15 00:57:05 +02:00
}
2020-10-13 09:20:52 +02:00
if (g_d3d9.instance)
2018-10-15 00:57:05 +02:00
{
2022-09-05 02:44:27 +02:00
while (IDirect3D9_Release(g_d3d9.instance));
2020-10-13 09:20:52 +02:00
g_d3d9.instance = NULL;
2018-10-15 00:57:05 +02:00
}
return TRUE;
}
2022-09-23 02:45:59 +02:00
static BOOL d3d9_create_resources()
2018-10-02 03:25:34 +02:00
{
if (!g_d3d9.device)
return FALSE;
d3d9_release_resources();
2018-10-09 08:56:58 +02:00
BOOL err = FALSE;
2020-10-13 09:20:52 +02:00
int width = g_ddraw->width;
int height = g_ddraw->height;
2018-10-02 03:25:34 +02:00
2021-07-21 14:52:44 +02:00
g_d3d9.tex_width =
2018-10-02 03:25:34 +02:00
width <= 1024 ? 1024 : width <= 2048 ? 2048 : width <= 4096 ? 4096 : width;
2021-07-21 14:52:44 +02:00
g_d3d9.tex_height =
height <= g_d3d9.tex_width ? g_d3d9.tex_width : height <= 2048 ? 2048 : height <= 4096 ? 4096 : height;
2018-10-02 03:25:34 +02:00
2021-07-21 14:52:44 +02:00
g_d3d9.tex_width = g_d3d9.tex_width > g_d3d9.tex_height ? g_d3d9.tex_width : g_d3d9.tex_height;
2018-10-02 03:25:34 +02:00
2021-07-21 14:52:44 +02:00
g_d3d9.scale_w = (float)width / g_d3d9.tex_width;;
g_d3d9.scale_h = (float)height / g_d3d9.tex_height;
2018-10-02 03:25:34 +02:00
2018-10-09 08:56:58 +02:00
err = err || FAILED(
2018-11-12 00:39:47 +01:00
IDirect3DDevice9_CreateVertexBuffer(
2021-06-11 20:30:43 +02:00
g_d3d9.device,
sizeof(CUSTOMVERTEX) * 4, 0,
D3DFVF_XYZRHW | D3DFVF_TEX1,
D3DPOOL_MANAGED,
&g_d3d9.vertex_buf,
2020-10-13 21:58:04 +02:00
NULL));
2018-10-09 08:56:58 +02:00
2021-05-15 02:58:07 +02:00
err = err || !d3d9_update_vertices(InterlockedExchangeAdd(&g_ddraw->upscale_hack_active, 0), TRUE);
2018-10-09 08:56:58 +02:00
2021-06-02 14:12:34 +02:00
for (int i = 0; i < D3D9_TEXTURE_COUNT; i++)
{
err = err || FAILED(
IDirect3DDevice9_CreateTexture(
2020-10-13 09:20:52 +02:00
g_d3d9.device,
2021-07-21 14:52:44 +02:00
g_d3d9.tex_width,
g_d3d9.tex_height,
1,
0,
2023-02-17 11:52:10 -08:00
g_ddraw->bpp == 16 ? (g_ddraw->rgb555 ? D3DFMT_A1R5G5B5 : D3DFMT_R5G6B5) : g_ddraw->bpp == 32 ? D3DFMT_X8R8G8B8 : D3DFMT_L8,
D3DPOOL_MANAGED,
2020-10-13 09:20:52 +02:00
&g_d3d9.surface_tex[i],
0));
2018-10-02 03:25:34 +02:00
2020-10-13 09:20:52 +02:00
err = err || !g_d3d9.surface_tex[i];
2020-10-13 09:20:52 +02:00
if (g_ddraw->bpp == 8)
{
err = err || FAILED(
IDirect3DDevice9_CreateTexture(
2020-10-13 09:20:52 +02:00
g_d3d9.device,
256,
256,
1,
0,
D3DFMT_X8R8G8B8,
D3DPOOL_MANAGED,
2020-10-13 09:20:52 +02:00
&g_d3d9.palette_tex[i],
0));
2020-10-13 09:20:52 +02:00
err = err || !g_d3d9.palette_tex[i];
}
}
2018-10-02 03:25:34 +02:00
2020-10-13 09:20:52 +02:00
if (g_ddraw->bpp == 8)
{
err = err || FAILED(
2021-06-11 20:30:43 +02:00
IDirect3DDevice9_CreatePixelShader(g_d3d9.device, (DWORD*)D3D9_PALETTE_SHADER, &g_d3d9.pixel_shader));
2021-07-21 14:52:44 +02:00
IDirect3DDevice9_CreatePixelShader(
g_d3d9.device,
(DWORD*)D3D9_PALETTE_SHADER_BILINEAR,
2023-07-03 10:50:03 +02:00
&g_d3d9.pixel_shader_upscale);
}
else
{
IDirect3DDevice9_CreatePixelShader(
g_d3d9.device,
(DWORD*)D3D9_CATMULL_ROM_SHADER,
&g_d3d9.pixel_shader_upscale);
}
2018-10-09 08:56:58 +02:00
2021-06-02 01:52:45 +02:00
return g_d3d9.vertex_buf && (g_d3d9.pixel_shader || g_ddraw->bpp == 16 || g_ddraw->bpp == 32) && !err;
2018-10-02 03:25:34 +02:00
}
2020-10-13 09:20:52 +02:00
static BOOL d3d9_set_states()
2018-10-02 03:25:34 +02:00
{
BOOL err = FALSE;
2020-10-13 09:20:52 +02:00
err = err || FAILED(IDirect3DDevice9_SetFVF(g_d3d9.device, D3DFVF_XYZRHW | D3DFVF_TEX1));
err = err || FAILED(IDirect3DDevice9_SetStreamSource(g_d3d9.device, 0, g_d3d9.vertex_buf, 0, sizeof(CUSTOMVERTEX)));
2021-06-11 20:30:43 +02:00
err = err || FAILED(IDirect3DDevice9_SetTexture(g_d3d9.device, 0, (IDirect3DBaseTexture9*)g_d3d9.surface_tex[0]));
2020-10-13 09:20:52 +02:00
if (g_ddraw->bpp == 8)
{
2021-06-11 20:30:43 +02:00
err = err || FAILED(IDirect3DDevice9_SetTexture(g_d3d9.device, 1, (IDirect3DBaseTexture9*)g_d3d9.palette_tex[0]));
2021-07-21 14:52:44 +02:00
BOOL bilinear =
2023-07-04 20:13:49 +02:00
g_ddraw->d3d9_filter &&
2023-07-03 10:50:03 +02:00
g_d3d9.pixel_shader_upscale &&
2021-07-21 14:52:44 +02:00
(g_ddraw->render.viewport.width != g_ddraw->width || g_ddraw->render.viewport.height != g_ddraw->height);
err = err || FAILED(
IDirect3DDevice9_SetPixelShader(
g_d3d9.device,
2023-07-03 10:50:03 +02:00
bilinear ? g_d3d9.pixel_shader_upscale : g_d3d9.pixel_shader));
2021-07-21 14:52:44 +02:00
if (bilinear)
{
float texture_size[4] = { (float)g_d3d9.tex_width, (float)g_d3d9.tex_height, 0, 0 };
err = err || FAILED(IDirect3DDevice9_SetPixelShaderConstantF(g_d3d9.device, 0, texture_size, 1));
}
}
else
{
2023-07-04 20:13:49 +02:00
if (g_ddraw->d3d9_filter)
{
2023-07-03 10:50:03 +02:00
if (SUCCEEDED(IDirect3DDevice9_SetSamplerState(g_d3d9.device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR)) &&
SUCCEEDED(IDirect3DDevice9_SetSamplerState(g_d3d9.device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR)) &&
2023-07-04 20:13:49 +02:00
g_ddraw->d3d9_filter == FILTER_CUBIC &&
2023-07-03 10:50:03 +02:00
g_d3d9.pixel_shader_upscale &&
(g_ddraw->render.viewport.width != g_ddraw->width || g_ddraw->render.viewport.height != g_ddraw->height) &&
SUCCEEDED(IDirect3DDevice9_SetPixelShader(g_d3d9.device, g_d3d9.pixel_shader_upscale)))
{
float texture_size[4] = { (float)g_d3d9.tex_width, (float)g_d3d9.tex_height, 0, 0 };
err = err || FAILED(IDirect3DDevice9_SetPixelShaderConstantF(g_d3d9.device, 0, texture_size, 1));
}
}
}
2018-10-02 03:25:34 +02:00
2021-11-05 18:36:50 +01:00
/*
2020-10-13 09:20:52 +02:00
D3DVIEWPORT9 view_data = {
g_ddraw->render.viewport.x,
g_ddraw->render.viewport.y,
g_ddraw->render.viewport.width,
g_ddraw->render.viewport.height,
2018-10-02 03:25:34 +02:00
0.0f,
1.0f };
2020-10-13 09:20:52 +02:00
err = err || FAILED(IDirect3DDevice9_SetViewport(g_d3d9.device, &view_data));
2021-11-05 18:36:50 +01:00
*/
return !err;
2018-10-02 03:25:34 +02:00
}
2021-05-15 02:58:07 +02:00
static BOOL d3d9_update_vertices(BOOL upscale_hack, BOOL stretch)
2018-10-02 03:25:34 +02:00
{
2020-10-13 10:53:30 +02:00
float vp_x = stretch ? (float)g_ddraw->render.viewport.x : 0.0f;
float vp_y = stretch ? (float)g_ddraw->render.viewport.y : 0.0f;
2018-10-02 03:25:34 +02:00
2020-10-13 10:53:30 +02:00
float vp_w = stretch ? (float)(g_ddraw->render.viewport.width + g_ddraw->render.viewport.x) : (float)g_ddraw->width;
float vp_h = stretch ? (float)(g_ddraw->render.viewport.height + g_ddraw->render.viewport.y) : (float)g_ddraw->height;
2018-10-02 03:25:34 +02:00
2021-05-15 02:58:07 +02:00
float s_h = upscale_hack ? g_d3d9.scale_h * ((float)g_ddraw->upscale_hack_height / g_ddraw->height) : g_d3d9.scale_h;
float s_w = upscale_hack ? g_d3d9.scale_w * ((float)g_ddraw->upscale_hack_width / g_ddraw->width) : g_d3d9.scale_w;
2018-10-02 03:25:34 +02:00
CUSTOMVERTEX vertices[] =
{
2023-07-08 09:23:21 +02:00
{ vp_x - 0.5f, vp_h - 0.5f, 0.0f, 1.0f, 0.0f, s_h },
{ vp_x - 0.5f, vp_y - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f },
{ vp_w - 0.5f, vp_h - 0.5f, 0.0f, 1.0f, s_w, s_h },
{ vp_w - 0.5f, vp_y - 0.5f, 0.0f, 1.0f, s_w, 0.0f }
2018-10-02 03:25:34 +02:00
};
2021-06-11 20:30:43 +02:00
void* data;
2020-10-13 09:20:52 +02:00
if (g_d3d9.vertex_buf && SUCCEEDED(IDirect3DVertexBuffer9_Lock(g_d3d9.vertex_buf, 0, 0, (void**)&data, 0)))
2018-10-02 03:25:34 +02:00
{
memcpy(data, vertices, sizeof(vertices));
2018-10-09 08:56:58 +02:00
2020-10-13 09:20:52 +02:00
IDirect3DVertexBuffer9_Unlock(g_d3d9.vertex_buf);
2018-10-09 08:56:58 +02:00
return TRUE;
2018-10-02 03:25:34 +02:00
}
2018-10-09 08:56:58 +02:00
return FALSE;
2018-10-02 03:25:34 +02:00
}
2020-10-13 09:20:52 +02:00
DWORD WINAPI d3d9_render_main(void)
2018-10-02 03:25:34 +02:00
{
2023-07-07 07:22:01 +02:00
Sleep(250);
2018-10-16 07:07:49 +02:00
fpsl_init();
2018-10-16 07:07:49 +02:00
2020-10-13 09:20:52 +02:00
BOOL needs_update = FALSE;
2018-10-02 03:25:34 +02:00
2023-08-15 08:46:14 +02:00
DWORD timeout = g_ddraw->render.minfps > 0 ? g_ddraw->render.minfps_tick_len : INFINITE;
2020-10-18 02:40:45 +02:00
2021-06-11 20:30:43 +02:00
while (g_ddraw->render.run &&
2020-10-18 02:40:45 +02:00
(g_ddraw->render.minfps < 0 || WaitForSingleObject(g_ddraw->render.sem, timeout) != WAIT_FAILED))
2018-09-28 22:40:44 +02:00
{
#if _DEBUG
2020-10-13 10:15:42 +02:00
dbg_draw_frame_info_start();
2018-09-28 22:40:44 +02:00
#endif
2021-05-22 12:23:25 +02:00
static int tex_index = 0, pal_index = 0;
fpsl_frame_start();
2018-09-28 22:40:44 +02:00
2020-10-13 09:20:52 +02:00
EnterCriticalSection(&g_ddraw->cs);
2018-09-28 22:40:44 +02:00
2021-06-15 03:20:41 +02:00
if (g_ddraw->primary &&
g_ddraw->primary->bpp == g_ddraw->bpp &&
g_ddraw->primary->width == g_ddraw->width &&
g_ddraw->primary->height == g_ddraw->height &&
2021-06-15 03:20:41 +02:00
(g_ddraw->bpp == 16 || g_ddraw->bpp == 32 || g_ddraw->primary->palette))
2018-09-28 22:40:44 +02:00
{
2022-09-17 13:46:45 +02:00
if (g_ddraw->lock_surfaces)
EnterCriticalSection(&g_ddraw->primary->cs);
2020-10-13 09:20:52 +02:00
if (g_ddraw->vhack)
2018-10-01 13:10:10 +02:00
{
2021-05-15 02:58:07 +02:00
if (util_detect_low_res_screen())
2018-10-01 13:10:10 +02:00
{
2021-05-15 02:58:07 +02:00
if (!InterlockedExchange(&g_ddraw->upscale_hack_active, TRUE))
2020-10-13 09:20:52 +02:00
d3d9_update_vertices(TRUE, TRUE);
2018-10-01 13:10:10 +02:00
}
else
{
2021-05-15 02:58:07 +02:00
if (InterlockedExchange(&g_ddraw->upscale_hack_active, FALSE))
2020-10-13 09:20:52 +02:00
d3d9_update_vertices(FALSE, TRUE);
2018-10-01 13:10:10 +02:00
}
}
2018-09-28 22:40:44 +02:00
D3DLOCKED_RECT lock_rc;
2021-05-29 15:29:57 +02:00
if (InterlockedExchange(&g_ddraw->render.surface_updated, FALSE) || g_ddraw->render.minfps == -2)
2018-09-28 22:40:44 +02:00
{
2020-10-13 09:20:52 +02:00
if (++tex_index >= D3D9_TEXTURE_COUNT)
tex_index = 0;
2020-10-13 09:20:52 +02:00
RECT rc = { 0, 0, g_ddraw->width, g_ddraw->height };
2021-06-11 20:30:43 +02:00
if (SUCCEEDED(IDirect3DDevice9_SetTexture(g_d3d9.device, 0, (IDirect3DBaseTexture9*)g_d3d9.surface_tex[tex_index])) &&
2020-10-13 09:20:52 +02:00
SUCCEEDED(IDirect3DTexture9_LockRect(g_d3d9.surface_tex[tex_index], 0, &lock_rc, &rc, 0)))
2018-09-28 22:40:44 +02:00
{
blt_clean(
lock_rc.pBits,
0,
0,
2022-09-09 11:30:27 +02:00
g_ddraw->primary->width,
g_ddraw->primary->height,
lock_rc.Pitch,
g_ddraw->primary->surface,
0,
0,
2022-10-19 03:20:31 +02:00
g_ddraw->primary->pitch,
g_ddraw->primary->bpp);
2018-09-28 22:40:44 +02:00
2020-10-13 09:20:52 +02:00
IDirect3DTexture9_UnlockRect(g_d3d9.surface_tex[tex_index], 0);
2018-09-28 22:40:44 +02:00
}
}
2021-06-11 20:30:43 +02:00
if (g_ddraw->bpp == 8 &&
2021-05-29 15:29:57 +02:00
(InterlockedExchange(&g_ddraw->render.palette_updated, FALSE) || g_ddraw->render.minfps == -2))
2018-09-28 22:40:44 +02:00
{
2021-05-22 12:23:25 +02:00
if (++pal_index >= D3D9_TEXTURE_COUNT)
pal_index = 0;
2018-09-28 22:40:44 +02:00
RECT rc = { 0,0,256,1 };
2021-06-11 20:30:43 +02:00
if (SUCCEEDED(IDirect3DDevice9_SetTexture(g_d3d9.device, 1, (IDirect3DBaseTexture9*)g_d3d9.palette_tex[pal_index])) &&
2021-05-22 12:23:25 +02:00
SUCCEEDED(IDirect3DTexture9_LockRect(g_d3d9.palette_tex[pal_index], 0, &lock_rc, &rc, 0)))
2018-09-28 22:40:44 +02:00
{
2020-10-13 09:20:52 +02:00
memcpy(lock_rc.pBits, g_ddraw->primary->palette->data_rgb, 256 * sizeof(int));
2021-05-22 12:23:25 +02:00
IDirect3DTexture9_UnlockRect(g_d3d9.palette_tex[pal_index], 0);
2018-09-28 22:40:44 +02:00
}
}
2018-11-15 09:45:24 +01:00
2021-08-10 14:12:06 +02:00
if (g_ddraw->fixchilds)
2021-06-16 05:57:19 +02:00
{
2021-08-10 14:12:06 +02:00
g_ddraw->child_window_exists = FALSE;
EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary);
2021-08-10 14:12:06 +02:00
if (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height)
2021-06-16 05:57:19 +02:00
{
2021-08-10 14:12:06 +02:00
if (g_ddraw->child_window_exists)
{
IDirect3DDevice9_Clear(g_d3d9.device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
if (!needs_update && d3d9_update_vertices(FALSE, FALSE))
needs_update = TRUE;
}
else if (needs_update)
{
if (d3d9_update_vertices(FALSE, TRUE))
needs_update = FALSE;
}
}
}
2022-09-17 13:46:45 +02:00
if (g_ddraw->lock_surfaces)
LeaveCriticalSection(&g_ddraw->primary->cs);
2018-09-28 22:40:44 +02:00
}
2020-10-13 09:20:52 +02:00
LeaveCriticalSection(&g_ddraw->cs);
2018-09-28 22:40:44 +02:00
2023-02-24 17:08:09 +01:00
if (g_ddraw->render.viewport.x != 0 || g_ddraw->render.viewport.y != 0)
{
IDirect3DDevice9_Clear(g_d3d9.device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
}
2021-11-05 18:36:50 +01:00
2020-10-13 09:20:52 +02:00
IDirect3DDevice9_BeginScene(g_d3d9.device);
IDirect3DDevice9_DrawPrimitive(g_d3d9.device, D3DPT_TRIANGLESTRIP, 0, 2);
IDirect3DDevice9_EndScene(g_d3d9.device);
2018-09-28 22:40:44 +02:00
2020-10-13 09:20:52 +02:00
if (g_ddraw->bnet_active)
2020-10-13 21:58:04 +02:00
{
2020-10-13 09:20:52 +02:00
IDirect3DDevice9_Clear(g_d3d9.device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
2020-10-13 21:58:04 +02:00
}
2020-10-13 09:20:52 +02:00
if (FAILED(IDirect3DDevice9_Present(g_d3d9.device, NULL, NULL, NULL, NULL)))
{
2020-10-13 09:20:52 +02:00
DWORD_PTR result;
SendMessageTimeout(g_ddraw->hwnd, WM_D3D9DEVICELOST, 0, 0, 0, 1000, &result);
2018-09-28 22:40:44 +02:00
}
#if _DEBUG
2020-10-13 10:15:42 +02:00
dbg_draw_frame_info_end();
2018-09-28 22:40:44 +02:00
#endif
2021-06-11 20:30:43 +02:00
fpsl_frame_end();
2018-09-28 22:40:44 +02:00
}
if (g_ddraw->vhack)
InterlockedExchange(&g_ddraw->upscale_hack_active, FALSE);
2018-10-16 07:07:49 +02:00
return 0;
2018-10-02 03:25:34 +02:00
}