2018-09-28 22:40:44 +02:00
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <d3d9.h>
|
2020-10-13 09:20:52 +02:00
|
|
|
#include "dd.h"
|
|
|
|
#include "ddsurface.h"
|
2018-10-06 12:24:43 +02:00
|
|
|
#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"
|
2020-10-13 10:15:42 +02:00
|
|
|
#include "debug.h"
|
2018-09-28 22:40:44 +02:00
|
|
|
|
2018-10-01 13:10:10 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
static BOOL d3d9_create_resouces();
|
|
|
|
static BOOL d3d9_set_states();
|
|
|
|
static BOOL d3d9_update_vertices(BOOL in_cutscene, BOOL stretch);
|
|
|
|
static void d3d9_set_max_fps();
|
2018-10-07 13:42:32 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
static d3d9_renderer 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;
|
|
|
|
|
|
|
|
if ((g_d3d9.hmodule = LoadLibrary("d3d9.dll")))
|
|
|
|
{
|
|
|
|
IDirect3D9* (WINAPI * d3d_create9)(UINT) =
|
|
|
|
(IDirect3D9 * (WINAPI*)(UINT))GetProcAddress(g_d3d9.hmodule, "Direct3DCreate9");
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (!d3d9_release())
|
2018-10-03 08:50:00 +02:00
|
|
|
return FALSE;
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (!g_d3d9.hmodule)
|
|
|
|
g_d3d9.hmodule = LoadLibrary("d3d9.dll");
|
2018-10-03 08:50:00 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_d3d9.hmodule)
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2020-10-21 16:21:15 +02:00
|
|
|
if (g_ddraw->nonexclusive)
|
|
|
|
{
|
|
|
|
int (WINAPI* d3d9_enable_shim)(BOOL) =
|
|
|
|
(int (WINAPI*)(BOOL))GetProcAddress(g_d3d9.hmodule, "Direct3D9EnableMaximizedWindowedModeShim");
|
|
|
|
|
|
|
|
if (d3d9_enable_shim)
|
|
|
|
d3d9_enable_shim(TRUE);
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3D9 *(WINAPI *d3d_create9)(UINT) =
|
|
|
|
(IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(g_d3d9.hmodule, "Direct3DCreate9");
|
2018-09-28 22:40:44 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (d3d_create9 && (g_d3d9.instance = d3d_create9(D3D_SDK_VERSION)))
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
g_d3d9.bits_per_pixel = g_ddraw->render.bpp ? g_ddraw->render.bpp : g_ddraw->mode.dmBitsPerPel;
|
|
|
|
|
|
|
|
g_d3d9.params.Windowed = g_ddraw->windowed;
|
|
|
|
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;
|
|
|
|
g_d3d9.params.BackBufferFormat = g_d3d9.bits_per_pixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
|
|
|
|
g_d3d9.params.BackBufferCount = 1;
|
|
|
|
|
|
|
|
DWORD behavior_flags[] = {
|
2018-10-02 02:27:58 +02:00
|
|
|
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
|
2018-09-30 07:29:51 +02:00
|
|
|
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
|
|
|
|
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
|
|
|
D3DCREATE_MIXED_VERTEXPROCESSING,
|
2018-09-28 22:40:44 +02:00
|
|
|
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
|
2018-09-30 07:29:51 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
int i;
|
2020-10-13 09:20:52 +02:00
|
|
|
for (i = 0; i < sizeof(behavior_flags) / sizeof(behavior_flags[0]); i++)
|
2018-09-30 07:29:51 +02:00
|
|
|
{
|
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,
|
2018-10-09 08:56:58 +02:00
|
|
|
D3DADAPTER_DEFAULT,
|
|
|
|
D3DDEVTYPE_HAL,
|
2020-10-13 09:20:52 +02:00
|
|
|
g_ddraw->hwnd,
|
|
|
|
D3DCREATE_MULTITHREADED | behavior_flags[i],
|
|
|
|
&g_d3d9.params,
|
|
|
|
&g_d3d9.device)))
|
|
|
|
return g_d3d9.device && d3d9_create_resouces() && d3d9_set_states();
|
2018-09-30 07:29:51 +02:00
|
|
|
}
|
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
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
return d3d9_reset();
|
2020-10-13 21:58:04 +02:00
|
|
|
}
|
2018-10-15 00:57:05 +02:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
BOOL d3d9_reset()
|
2018-10-15 00:57:05 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
g_d3d9.params.Windowed = g_ddraw->windowed;
|
|
|
|
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;
|
|
|
|
g_d3d9.params.BackBufferFormat = g_d3d9.bits_per_pixel == 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
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
return d3d9_set_states();
|
2020-10-13 21:58:04 +02:00
|
|
|
}
|
2018-10-15 00:57:05 +02:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
BOOL d3d9_release()
|
2018-10-15 00:57:05 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_d3d9.vertex_buf)
|
2018-10-15 00:57:05 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3DVertexBuffer9_Release(g_d3d9.vertex_buf);
|
|
|
|
g_d3d9.vertex_buf = NULL;
|
2018-10-15 00:57:05 +02:00
|
|
|
}
|
2018-11-12 00:39:47 +01:00
|
|
|
|
2018-11-12 00:18:26 +01:00
|
|
|
int i;
|
2020-10-13 09:20:52 +02:00
|
|
|
for (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])
|
2018-11-12 00:18:26 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3DTexture9_Release(g_d3d9.surface_tex[i]);
|
|
|
|
g_d3d9.surface_tex[i] = NULL;
|
2018-11-12 00:18:26 +01:00
|
|
|
}
|
2018-10-15 00:57:05 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_d3d9.palette_tex[i])
|
2018-11-12 00:18:26 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3DTexture9_Release(g_d3d9.palette_tex[i]);
|
|
|
|
g_d3d9.palette_tex[i] = NULL;
|
2018-11-12 00:18:26 +01:00
|
|
|
}
|
2018-10-15 00:57:05 +02:00
|
|
|
}
|
2018-11-12 00:39:47 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_d3d9.pixel_shader)
|
2018-10-15 00:57:05 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3DPixelShader9_Release(g_d3d9.pixel_shader);
|
|
|
|
g_d3d9.pixel_shader = NULL;
|
2018-10-15 00:57:05 +02:00
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_d3d9.device)
|
2018-10-15 00:57:05 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3DDevice9_Release(g_d3d9.device);
|
|
|
|
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
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3D9_Release(g_d3d9.instance);
|
|
|
|
g_d3d9.instance = NULL;
|
2018-10-15 00:57:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
static BOOL d3d9_create_resouces()
|
2018-10-02 03:25:34 +02:00
|
|
|
{
|
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
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
int tex_width =
|
2018-10-02 03:25:34 +02:00
|
|
|
width <= 1024 ? 1024 : width <= 2048 ? 2048 : width <= 4096 ? 4096 : width;
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
int tex_height =
|
|
|
|
height <= tex_width ? tex_width : height <= 2048 ? 2048 : height <= 4096 ? 4096 : height;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
tex_width = tex_width > tex_height ? tex_width : tex_height;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
g_d3d9.scale_w = (float)width / tex_width;;
|
|
|
|
g_d3d9.scale_h = (float)height / 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(
|
2020-10-13 21:58:04 +02:00
|
|
|
g_d3d9.device,
|
|
|
|
sizeof(CUSTOMVERTEX) * 4, 0,
|
|
|
|
D3DFVF_XYZRHW | D3DFVF_TEX1,
|
|
|
|
D3DPOOL_MANAGED,
|
|
|
|
&g_d3d9.vertex_buf,
|
|
|
|
NULL));
|
2018-10-09 08:56:58 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
err = err || !d3d9_update_vertices(InterlockedExchangeAdd(&g_ddraw->incutscene, 0), TRUE);
|
2018-10-09 08:56:58 +02:00
|
|
|
|
2018-11-12 00:18:26 +01:00
|
|
|
int i;
|
2020-10-13 09:20:52 +02:00
|
|
|
for (i = 0; i < D3D9_TEXTURE_COUNT; i++)
|
2018-11-12 00:18:26 +01:00
|
|
|
{
|
|
|
|
err = err || FAILED(
|
2018-11-14 05:35:59 +01:00
|
|
|
IDirect3DDevice9_CreateTexture(
|
2020-10-13 09:20:52 +02:00
|
|
|
g_d3d9.device,
|
|
|
|
tex_width,
|
|
|
|
tex_height,
|
2018-11-14 05:35:59 +01:00
|
|
|
1,
|
|
|
|
0,
|
2020-10-13 09:20:52 +02:00
|
|
|
g_ddraw->bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_L8,
|
2018-11-14 05:35:59 +01:00
|
|
|
D3DPOOL_MANAGED,
|
2020-10-13 09:20:52 +02:00
|
|
|
&g_d3d9.surface_tex[i],
|
2018-11-14 05:35:59 +01:00
|
|
|
0));
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
err = err || !g_d3d9.surface_tex[i];
|
2018-11-12 00:18:26 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->bpp == 8)
|
2018-11-14 05:35:59 +01:00
|
|
|
{
|
|
|
|
err = err || FAILED(
|
|
|
|
IDirect3DDevice9_CreateTexture(
|
2020-10-13 09:20:52 +02:00
|
|
|
g_d3d9.device,
|
2018-11-14 05:35:59 +01:00
|
|
|
256,
|
|
|
|
256,
|
|
|
|
1,
|
|
|
|
0,
|
|
|
|
D3DFMT_X8R8G8B8,
|
|
|
|
D3DPOOL_MANAGED,
|
2020-10-13 09:20:52 +02:00
|
|
|
&g_d3d9.palette_tex[i],
|
2018-11-14 05:35:59 +01:00
|
|
|
0));
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
err = err || !g_d3d9.palette_tex[i];
|
2018-11-14 05:35:59 +01:00
|
|
|
}
|
2018-11-12 00:18:26 +01:00
|
|
|
}
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->bpp == 8)
|
2018-11-14 05:35:59 +01:00
|
|
|
{
|
|
|
|
err = err || FAILED(
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3DDevice9_CreatePixelShader(g_d3d9.device, (DWORD *)D3D9_PALETTE_SHADER, &g_d3d9.pixel_shader));
|
2018-11-14 05:35:59 +01:00
|
|
|
}
|
2018-10-09 08:56:58 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
return g_d3d9.vertex_buf && (g_d3d9.pixel_shader || g_ddraw->bpp == 16) && !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
|
|
|
{
|
2018-10-07 13:42:32 +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)));
|
|
|
|
err = err || FAILED(IDirect3DDevice9_SetTexture(g_d3d9.device, 0, (IDirect3DBaseTexture9 *)g_d3d9.surface_tex[0]));
|
2018-11-14 05:35:59 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->bpp == 8)
|
2018-11-14 05:35:59 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
err = err || FAILED(IDirect3DDevice9_SetTexture(g_d3d9.device, 1, (IDirect3DBaseTexture9 *)g_d3d9.palette_tex[0]));
|
|
|
|
err = err || FAILED(IDirect3DDevice9_SetPixelShader(g_d3d9.device, g_d3d9.pixel_shader));
|
2018-11-14 05:35:59 +01:00
|
|
|
}
|
2020-10-21 17:14:40 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (g_ddraw->d3d9linear)
|
|
|
|
{
|
|
|
|
IDirect3DDevice9_SetSamplerState(g_d3d9.device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
|
|
|
IDirect3DDevice9_SetSamplerState(g_d3d9.device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
|
|
|
}
|
|
|
|
}
|
2018-10-02 03:25:34 +02: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));
|
2018-10-07 13:42:32 +02:00
|
|
|
|
|
|
|
return !err;
|
2018-10-02 03:25:34 +02:00
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
static BOOL d3d9_update_vertices(BOOL in_cutscene, 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
|
|
|
|
2020-10-13 10:53:30 +02:00
|
|
|
float s_h = in_cutscene ? g_d3d9.scale_h * ((float)CUTSCENE_HEIGHT / g_ddraw->height) : g_d3d9.scale_h;
|
|
|
|
float s_w = in_cutscene ? g_d3d9.scale_w * ((float)CUTSCENE_WIDTH / g_ddraw->width) : g_d3d9.scale_w;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
|
|
|
CUSTOMVERTEX vertices[] =
|
|
|
|
{
|
2020-10-13 10:53:30 +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
|
|
|
};
|
|
|
|
|
|
|
|
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
|
|
|
static void d3d9_set_max_fps()
|
2018-10-02 03:25:34 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
int max_fps = g_ddraw->render.maxfps;
|
|
|
|
|
|
|
|
g_ddraw->fps_limiter.tick_length_ns = 0;
|
|
|
|
g_ddraw->fps_limiter.tick_length = 0;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (max_fps < 0 || g_ddraw->vsync)
|
|
|
|
max_fps = g_ddraw->mode.dmDisplayFrequency;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (max_fps > 1000)
|
|
|
|
max_fps = 0;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (max_fps > 0)
|
2018-11-29 21:26:43 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
float len = 1000.0f / max_fps;
|
|
|
|
g_ddraw->fps_limiter.tick_length_ns = len * 10000;
|
|
|
|
g_ddraw->fps_limiter.tick_length = len;// + 0.5f;
|
2018-11-29 21:26:43 +01:00
|
|
|
}
|
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
|
|
|
{
|
2018-10-16 07:07:49 +02:00
|
|
|
Sleep(500);
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
d3d9_set_max_fps();
|
2018-10-16 07:07:49 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
DWORD tick_start = 0;
|
|
|
|
DWORD tick_end = 0;
|
|
|
|
BOOL needs_update = FALSE;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-18 02:40:45 +02:00
|
|
|
DWORD timeout = g_ddraw->render.minfps > 0 ? g_ddraw->render.minfps_tick_len : 200;
|
|
|
|
|
2020-10-13 09:20:52 +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
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
static int tex_index = 0, palIndex = 0;
|
2018-11-12 00:18:26 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->fps_limiter.tick_length > 0)
|
|
|
|
tick_start = timeGetTime();
|
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
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->primary && (g_ddraw->bpp == 16 || (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)))
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->vhack)
|
2018-10-01 13:10:10 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (util_detect_cutscene())
|
2018-10-01 13:10:10 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (!InterlockedExchange(&g_ddraw->incutscene, TRUE))
|
|
|
|
d3d9_update_vertices(TRUE, TRUE);
|
2018-10-01 13:10:10 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (InterlockedExchange(&g_ddraw->incutscene, FALSE))
|
|
|
|
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;
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (InterlockedExchange(&g_ddraw->render.surface_updated, FALSE))
|
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;
|
2018-11-12 00:18:26 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
RECT rc = { 0, 0, g_ddraw->width, g_ddraw->height };
|
2018-10-03 09:51:15 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (SUCCEEDED(IDirect3DDevice9_SetTexture(g_d3d9.device, 0, (IDirect3DBaseTexture9 *)g_d3d9.surface_tex[tex_index])) &&
|
|
|
|
SUCCEEDED(IDirect3DTexture9_LockRect(g_d3d9.surface_tex[tex_index], 0, &lock_rc, &rc, 0)))
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
unsigned char *src = (unsigned char *)g_ddraw->primary->surface;
|
2018-09-28 22:40:44 +02:00
|
|
|
unsigned char *dst = (unsigned char *)lock_rc.pBits;
|
|
|
|
|
|
|
|
int i;
|
2020-10-13 09:20:52 +02:00
|
|
|
for (i = 0; i < g_ddraw->height; i++)
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
memcpy(dst, src, g_ddraw->primary->l_pitch);
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
src += g_ddraw->primary->l_pitch;
|
2018-09-28 22:40:44 +02:00
|
|
|
dst += lock_rc.Pitch;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->bpp == 8 && InterlockedExchange(&g_ddraw->render.palette_updated, FALSE))
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (++palIndex >= D3D9_TEXTURE_COUNT)
|
2018-11-12 00:18:26 +01:00
|
|
|
palIndex = 0;
|
|
|
|
|
2018-09-28 22:40:44 +02:00
|
|
|
RECT rc = { 0,0,256,1 };
|
2018-10-03 09:51:15 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (SUCCEEDED(IDirect3DDevice9_SetTexture(g_d3d9.device, 1, (IDirect3DBaseTexture9 *)g_d3d9.palette_tex[palIndex])) &&
|
|
|
|
SUCCEEDED(IDirect3DTexture9_LockRect(g_d3d9.palette_tex[palIndex], 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));
|
2018-10-03 09:51:15 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
IDirect3DTexture9_UnlockRect(g_d3d9.palette_tex[palIndex], 0);
|
2018-09-28 22:40:44 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-15 09:45:24 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (!g_ddraw->handlemouse)
|
2018-11-16 06:37:11 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
g_ddraw->child_window_exists = FALSE;
|
|
|
|
EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary);
|
2018-11-16 06:37:11 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height)
|
2018-11-16 06:37:11 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->child_window_exists)
|
2018-11-16 06:37:11 +01: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);
|
2018-11-16 07:02:27 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (!needs_update && d3d9_update_vertices(FALSE, FALSE))
|
|
|
|
needs_update = TRUE;
|
2018-11-16 07:02:27 +01:00
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
else if (needs_update)
|
2018-11-16 07:02:27 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (d3d9_update_vertices(FALSE, TRUE))
|
|
|
|
needs_update = FALSE;
|
2018-11-16 06:37:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
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
|
|
|
}
|
2019-03-17 00:16:09 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (FAILED(IDirect3DDevice9_Present(g_d3d9.device, NULL, NULL, NULL, NULL)))
|
2018-10-07 13:42:32 +02:00
|
|
|
{
|
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
|
2018-12-10 04:24:30 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->fps_limiter.tick_length > 0)
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->fps_limiter.htimer)
|
2018-11-29 21:26:43 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
if (g_ddraw->vsync)
|
2018-11-29 21:26:43 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
|
|
|
|
LARGE_INTEGER due_time = { .QuadPart = -g_ddraw->fps_limiter.tick_length_ns };
|
|
|
|
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &due_time, 0, NULL, NULL, FALSE);
|
2018-11-29 21:26:43 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-10 04:24:30 +01:00
|
|
|
FILETIME ft = { 0 };
|
|
|
|
GetSystemTimeAsFileTime(&ft);
|
2018-11-29 21:26:43 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (CompareFileTime((FILETIME *)&g_ddraw->fps_limiter.due_time, &ft) == -1)
|
2018-12-10 04:24:30 +01:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
memcpy(&g_ddraw->fps_limiter.due_time, &ft, sizeof(LARGE_INTEGER));
|
2018-12-10 04:24:30 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
|
2018-12-10 04:24:30 +01:00
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
g_ddraw->fps_limiter.due_time.QuadPart += g_ddraw->fps_limiter.tick_length_ns;
|
|
|
|
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &g_ddraw->fps_limiter.due_time, 0, NULL, NULL, FALSE);
|
2018-12-10 04:24:30 +01:00
|
|
|
}
|
2018-11-29 21:26:43 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
tick_end = timeGetTime();
|
2018-11-29 21:26:43 +01:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (tick_end - tick_start < g_ddraw->fps_limiter.tick_length)
|
2020-10-13 21:58:04 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
Sleep(g_ddraw->fps_limiter.tick_length - (tick_end - tick_start));
|
2020-10-13 21:58:04 +02:00
|
|
|
}
|
2018-11-29 21:26:43 +01:00
|
|
|
}
|
2018-09-28 22:40:44 +02:00
|
|
|
}
|
|
|
|
}
|
2018-10-16 07:07:49 +02:00
|
|
|
return 0;
|
2018-10-02 03:25:34 +02:00
|
|
|
}
|