2018-09-28 22:40:44 +02:00
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <d3d9.h>
|
|
|
|
#include "main.h"
|
|
|
|
#include "surface.h"
|
2018-10-06 12:24:43 +02:00
|
|
|
#include "d3d9shader.h"
|
2018-10-15 03:31:57 +02:00
|
|
|
#include "render_d3d9.h"
|
2018-09-28 22:40:44 +02:00
|
|
|
|
2018-11-12 00:18:26 +01:00
|
|
|
#define TEXTURE_COUNT 2
|
2018-10-01 13:10:10 +02:00
|
|
|
|
2018-10-15 00:57:05 +02:00
|
|
|
HMODULE Direct3D9_hModule;
|
2018-10-07 13:42:32 +02:00
|
|
|
|
2018-10-07 16:49:35 +02:00
|
|
|
static D3DPRESENT_PARAMETERS D3dpp;
|
2018-10-01 13:10:10 +02:00
|
|
|
static LPDIRECT3D9 D3d;
|
2018-10-08 08:42:08 +02:00
|
|
|
static LPDIRECT3DDEVICE9 D3dDev;
|
|
|
|
static LPDIRECT3DVERTEXBUFFER9 VertexBuf;
|
2018-11-12 00:18:26 +01:00
|
|
|
static IDirect3DTexture9 *SurfaceTex[TEXTURE_COUNT];
|
|
|
|
static IDirect3DTexture9 *PaletteTex[TEXTURE_COUNT];
|
2018-10-01 13:10:10 +02:00
|
|
|
static IDirect3DPixelShader9 *PixelShader;
|
|
|
|
static float ScaleW;
|
|
|
|
static float ScaleH;
|
2018-10-09 11:46:40 +02:00
|
|
|
static int BitsPerPixel;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
|
|
|
static BOOL CreateResources();
|
2018-10-07 13:42:32 +02:00
|
|
|
static BOOL SetStates();
|
2018-11-16 06:37:11 +01:00
|
|
|
static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch);
|
2018-10-07 13:42:32 +02:00
|
|
|
static void SetMaxFPS();
|
2018-09-28 22:40:44 +02:00
|
|
|
|
2018-10-15 00:57:05 +02:00
|
|
|
BOOL Direct3D9_Create()
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2018-10-15 00:57:05 +02:00
|
|
|
if (!Direct3D9_Release())
|
2018-10-03 08:50:00 +02:00
|
|
|
return FALSE;
|
|
|
|
|
2018-10-15 00:57:05 +02:00
|
|
|
if (!Direct3D9_hModule)
|
|
|
|
Direct3D9_hModule = LoadLibrary("d3d9.dll");
|
2018-10-03 08:50:00 +02:00
|
|
|
|
2018-10-15 00:57:05 +02:00
|
|
|
if (Direct3D9_hModule)
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2018-10-02 03:25:34 +02:00
|
|
|
IDirect3D9 *(WINAPI *D3DCreate9)(UINT) =
|
2018-10-15 00:57:05 +02:00
|
|
|
(IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(Direct3D9_hModule, "Direct3DCreate9");
|
2018-09-28 22:40:44 +02:00
|
|
|
|
|
|
|
if (D3DCreate9 && (D3d = D3DCreate9(D3D_SDK_VERSION)))
|
|
|
|
{
|
2018-10-09 11:46:40 +02:00
|
|
|
BitsPerPixel = ddraw->render.bpp ? ddraw->render.bpp : ddraw->mode.dmBitsPerPel;
|
|
|
|
|
2018-10-03 08:50:00 +02:00
|
|
|
D3dpp.Windowed = ddraw->windowed;
|
2018-09-28 22:40:44 +02:00
|
|
|
D3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
|
|
D3dpp.hDeviceWindow = ddraw->hWnd;
|
2018-09-28 23:10:58 +02:00
|
|
|
D3dpp.PresentationInterval = ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
2018-10-07 13:42:32 +02:00
|
|
|
D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
|
|
|
|
D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
|
2018-10-09 11:46:40 +02:00
|
|
|
D3dpp.BackBufferFormat = BitsPerPixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
|
2018-09-28 22:40:44 +02:00
|
|
|
D3dpp.BackBufferCount = 1;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-09-30 07:29:51 +02:00
|
|
|
DWORD behaviorFlags[] = {
|
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;
|
2018-10-02 03:25:34 +02:00
|
|
|
for (i = 0; i < sizeof(behaviorFlags) / sizeof(behaviorFlags[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(
|
2018-10-09 08:56:58 +02:00
|
|
|
D3d,
|
|
|
|
D3DADAPTER_DEFAULT,
|
|
|
|
D3DDEVTYPE_HAL,
|
|
|
|
ddraw->hWnd,
|
2018-11-12 00:18:26 +01:00
|
|
|
D3DCREATE_MULTITHREADED | behaviorFlags[i],
|
2018-10-09 08:56:58 +02:00
|
|
|
&D3dpp,
|
|
|
|
&D3dDev)))
|
|
|
|
return D3dDev && CreateResources() && SetStates();
|
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
|
|
|
}
|
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
BOOL Direct3D9_OnDeviceLost()
|
2018-10-15 00:57:05 +02:00
|
|
|
{
|
2018-11-12 00:39:47 +01:00
|
|
|
if (D3dDev && IDirect3DDevice9_TestCooperativeLevel(D3dDev) == D3DERR_DEVICENOTRESET)
|
2018-10-15 00:57:05 +02:00
|
|
|
return Direct3D9_Reset();
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL Direct3D9_Reset()
|
|
|
|
{
|
|
|
|
D3dpp.Windowed = ddraw->windowed;
|
|
|
|
D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
|
|
|
|
D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
|
|
|
|
D3dpp.BackBufferFormat = BitsPerPixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
|
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
if (D3dDev && SUCCEEDED(IDirect3DDevice9_Reset(D3dDev, &D3dpp)))
|
2018-10-15 00:57:05 +02:00
|
|
|
return SetStates();
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL Direct3D9_Release()
|
|
|
|
{
|
|
|
|
if (VertexBuf)
|
|
|
|
{
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DVertexBuffer9_Release(VertexBuf);
|
2018-10-15 00:57:05 +02:00
|
|
|
VertexBuf = NULL;
|
|
|
|
}
|
2018-11-12 00:39:47 +01:00
|
|
|
|
2018-11-12 00:18:26 +01:00
|
|
|
int i;
|
|
|
|
for (i = 0; i < TEXTURE_COUNT; i++)
|
2018-10-15 00:57:05 +02:00
|
|
|
{
|
2018-11-12 00:18:26 +01:00
|
|
|
if (SurfaceTex[i])
|
|
|
|
{
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DTexture9_Release(SurfaceTex[i]);
|
2018-11-12 00:18:26 +01:00
|
|
|
SurfaceTex[i] = NULL;
|
|
|
|
}
|
2018-10-15 00:57:05 +02:00
|
|
|
|
2018-11-12 00:18:26 +01:00
|
|
|
if (PaletteTex[i])
|
|
|
|
{
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DTexture9_Release(PaletteTex[i]);
|
2018-11-12 00:18:26 +01:00
|
|
|
PaletteTex[i] = NULL;
|
|
|
|
}
|
2018-10-15 00:57:05 +02:00
|
|
|
}
|
2018-11-12 00:39:47 +01:00
|
|
|
|
2018-10-15 00:57:05 +02:00
|
|
|
if (PixelShader)
|
|
|
|
{
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DPixelShader9_Release(PixelShader);
|
2018-10-15 00:57:05 +02:00
|
|
|
PixelShader = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (D3dDev)
|
|
|
|
{
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DDevice9_Release(D3dDev);
|
2018-10-15 00:57:05 +02:00
|
|
|
D3dDev = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (D3d)
|
|
|
|
{
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3D9_Release(D3d);
|
2018-10-15 00:57:05 +02:00
|
|
|
D3d = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2018-10-02 03:25:34 +02:00
|
|
|
static BOOL CreateResources()
|
|
|
|
{
|
2018-10-09 08:56:58 +02:00
|
|
|
BOOL err = FALSE;
|
|
|
|
|
2018-10-02 03:25:34 +02:00
|
|
|
int width = ddraw->width;
|
|
|
|
int height = ddraw->height;
|
|
|
|
|
|
|
|
int texWidth =
|
|
|
|
width <= 1024 ? 1024 : width <= 2048 ? 2048 : width <= 4096 ? 4096 : width;
|
|
|
|
|
|
|
|
int texHeight =
|
|
|
|
height <= texWidth ? texWidth : height <= 2048 ? 2048 : height <= 4096 ? 4096 : height;
|
|
|
|
|
|
|
|
texWidth = texWidth > texHeight ? texWidth : texHeight;
|
|
|
|
|
|
|
|
ScaleW = (float)width / texWidth;;
|
|
|
|
ScaleH = (float)height / texHeight;
|
|
|
|
|
2018-10-09 08:56:58 +02:00
|
|
|
err = err || FAILED(
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DDevice9_CreateVertexBuffer(
|
2018-10-09 08:56:58 +02:00
|
|
|
D3dDev, sizeof(CUSTOMVERTEX) * 4, 0, D3DFVF_XYZRHW | D3DFVF_TEX1, D3DPOOL_MANAGED, &VertexBuf, NULL));
|
|
|
|
|
2018-11-16 06:37:11 +01:00
|
|
|
err = err || !UpdateVertices(InterlockedExchangeAdd(&ddraw->incutscene, 0), TRUE);
|
2018-10-09 08:56:58 +02:00
|
|
|
|
2018-11-12 00:18:26 +01:00
|
|
|
int i;
|
|
|
|
for (i = 0; i < TEXTURE_COUNT; i++)
|
|
|
|
{
|
|
|
|
err = err || FAILED(
|
2018-11-14 05:35:59 +01:00
|
|
|
IDirect3DDevice9_CreateTexture(
|
|
|
|
D3dDev,
|
|
|
|
texWidth,
|
|
|
|
texHeight,
|
|
|
|
1,
|
|
|
|
0,
|
|
|
|
ddraw->bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_L8,
|
|
|
|
D3DPOOL_MANAGED,
|
|
|
|
&SurfaceTex[i],
|
|
|
|
0));
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-11-12 00:18:26 +01:00
|
|
|
err = err || !SurfaceTex[i];
|
|
|
|
|
2018-11-14 05:35:59 +01:00
|
|
|
if (ddraw->bpp == 8)
|
|
|
|
{
|
|
|
|
err = err || FAILED(
|
|
|
|
IDirect3DDevice9_CreateTexture(
|
|
|
|
D3dDev,
|
|
|
|
256,
|
|
|
|
256,
|
|
|
|
1,
|
|
|
|
0,
|
|
|
|
D3DFMT_X8R8G8B8,
|
|
|
|
D3DPOOL_MANAGED,
|
|
|
|
&PaletteTex[i],
|
|
|
|
0));
|
|
|
|
|
|
|
|
err = err || !PaletteTex[i];
|
|
|
|
}
|
2018-11-12 00:18:26 +01:00
|
|
|
}
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-11-14 05:35:59 +01:00
|
|
|
if (ddraw->bpp == 8)
|
|
|
|
{
|
|
|
|
err = err || FAILED(
|
|
|
|
IDirect3DDevice9_CreatePixelShader(D3dDev, (DWORD *)PalettePixelShaderSrc, &PixelShader));
|
|
|
|
}
|
2018-10-09 08:56:58 +02:00
|
|
|
|
2018-11-14 05:35:59 +01:00
|
|
|
return VertexBuf && (PixelShader || ddraw->bpp == 16) && !err;
|
2018-10-02 03:25:34 +02:00
|
|
|
}
|
|
|
|
|
2018-10-07 13:42:32 +02:00
|
|
|
static BOOL SetStates()
|
2018-10-02 03:25:34 +02:00
|
|
|
{
|
2018-10-07 13:42:32 +02:00
|
|
|
BOOL err = FALSE;
|
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
err = err || FAILED(IDirect3DDevice9_SetFVF(D3dDev, D3DFVF_XYZRHW | D3DFVF_TEX1));
|
|
|
|
err = err || FAILED(IDirect3DDevice9_SetStreamSource(D3dDev, 0, VertexBuf, 0, sizeof(CUSTOMVERTEX)));
|
|
|
|
err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 0, (IDirect3DBaseTexture9 *)SurfaceTex[0]));
|
2018-11-14 05:35:59 +01:00
|
|
|
|
|
|
|
if (ddraw->bpp == 8)
|
|
|
|
{
|
|
|
|
err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 1, (IDirect3DBaseTexture9 *)PaletteTex[0]));
|
|
|
|
err = err || FAILED(IDirect3DDevice9_SetPixelShader(D3dDev, PixelShader));
|
|
|
|
}
|
2018-10-02 03:25:34 +02:00
|
|
|
|
|
|
|
D3DVIEWPORT9 viewData = {
|
|
|
|
ddraw->render.viewport.x,
|
|
|
|
ddraw->render.viewport.y,
|
|
|
|
ddraw->render.viewport.width,
|
|
|
|
ddraw->render.viewport.height,
|
|
|
|
0.0f,
|
|
|
|
1.0f };
|
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
err = err || FAILED(IDirect3DDevice9_SetViewport(D3dDev, &viewData));
|
2018-10-07 13:42:32 +02:00
|
|
|
|
|
|
|
return !err;
|
2018-10-02 03:25:34 +02:00
|
|
|
}
|
|
|
|
|
2018-11-16 06:37:11 +01:00
|
|
|
static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch)
|
2018-10-02 03:25:34 +02:00
|
|
|
{
|
2018-11-16 06:37:11 +01:00
|
|
|
float vpX = stretch ? (float)ddraw->render.viewport.x : 0.0f;
|
|
|
|
float vpY = stretch ? (float)ddraw->render.viewport.y : 0.0f;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-11-16 06:37:11 +01:00
|
|
|
float vpW = stretch ? (float)(ddraw->render.viewport.width + ddraw->render.viewport.x) : (float)ddraw->width;
|
|
|
|
float vpH = stretch ? (float)(ddraw->render.viewport.height + ddraw->render.viewport.y) : (float)ddraw->height;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
|
|
|
float sH = inCutscene ? ScaleH * ((float)CUTSCENE_HEIGHT / ddraw->height) : ScaleH;
|
|
|
|
float sW = inCutscene ? ScaleW * ((float)CUTSCENE_WIDTH / ddraw->width) : ScaleW;
|
|
|
|
|
|
|
|
CUSTOMVERTEX vertices[] =
|
|
|
|
{
|
|
|
|
{ vpX - 0.5f, vpH - 0.5f, 0.0f, 1.0f, 0.0f, sH },
|
|
|
|
{ vpX - 0.5f, vpY - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f },
|
|
|
|
{ vpW - 0.5f, vpH - 0.5f, 0.0f, 1.0f, sW, sH },
|
|
|
|
{ vpW - 0.5f, vpY - 0.5f, 0.0f, 1.0f, sW, 0.0f }
|
|
|
|
};
|
|
|
|
|
|
|
|
void *data;
|
2018-11-12 00:39:47 +01:00
|
|
|
if (VertexBuf && SUCCEEDED(IDirect3DVertexBuffer9_Lock(VertexBuf, 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
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DVertexBuffer9_Unlock(VertexBuf);
|
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
|
|
|
}
|
|
|
|
|
2018-10-07 13:42:32 +02:00
|
|
|
static void SetMaxFPS()
|
2018-10-02 03:25:34 +02:00
|
|
|
{
|
2018-11-29 21:26:43 +01:00
|
|
|
int maxFPS = ddraw->render.maxfps;
|
|
|
|
ddraw->fpsLimiter.tickLengthNs = 0;
|
|
|
|
ddraw->fpsLimiter.ticklength = 0;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-12-10 04:24:30 +01:00
|
|
|
if (maxFPS < 0 || ddraw->vsync)
|
2018-11-29 21:26:43 +01:00
|
|
|
maxFPS = ddraw->mode.dmDisplayFrequency;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-12-10 04:24:30 +01:00
|
|
|
if (maxFPS > 1000)
|
2018-11-29 21:26:43 +01:00
|
|
|
maxFPS = 0;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-11-29 21:26:43 +01:00
|
|
|
if (maxFPS > 0)
|
|
|
|
{
|
|
|
|
float len = 1000.0f / maxFPS;
|
|
|
|
ddraw->fpsLimiter.tickLengthNs = len * 10000;
|
2018-11-30 02:55:51 +01:00
|
|
|
ddraw->fpsLimiter.ticklength = len;// + 0.5f;
|
2018-11-29 21:26:43 +01:00
|
|
|
}
|
2018-10-02 03:25:34 +02:00
|
|
|
}
|
|
|
|
|
2018-10-16 07:07:49 +02:00
|
|
|
DWORD WINAPI render_d3d9_main(void)
|
2018-10-02 03:25:34 +02:00
|
|
|
{
|
2018-10-16 07:07:49 +02:00
|
|
|
Sleep(500);
|
|
|
|
|
|
|
|
SetMaxFPS();
|
|
|
|
|
2018-10-07 16:49:35 +02:00
|
|
|
DWORD tickStart = 0;
|
|
|
|
DWORD tickEnd = 0;
|
2018-11-16 11:56:56 +01:00
|
|
|
BOOL needsUpdate = FALSE;
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-10-03 12:12:11 +02:00
|
|
|
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, 200) != WAIT_FAILED)
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2018-10-15 00:01:31 +02:00
|
|
|
if (InterlockedExchangeAdd(&ddraw->minimized, 0))
|
2018-10-07 13:42:32 +02:00
|
|
|
{
|
2018-10-08 14:11:58 +02:00
|
|
|
Sleep(500);
|
2018-10-07 13:42:32 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-09-28 22:40:44 +02:00
|
|
|
#if _DEBUG
|
2018-10-02 11:38:38 +02:00
|
|
|
DrawFrameInfoStart();
|
2018-09-28 22:40:44 +02:00
|
|
|
#endif
|
|
|
|
|
2018-11-12 00:18:26 +01:00
|
|
|
static int texIndex = 0, palIndex = 0;
|
|
|
|
|
2018-11-29 21:26:43 +01:00
|
|
|
if (ddraw->fpsLimiter.ticklength > 0)
|
2018-10-07 16:49:35 +02:00
|
|
|
tickStart = timeGetTime();
|
2018-09-28 22:40:44 +02:00
|
|
|
|
|
|
|
EnterCriticalSection(&ddraw->cs);
|
|
|
|
|
2018-11-14 05:35:59 +01:00
|
|
|
if (ddraw->primary && (ddraw->bpp == 16 || (ddraw->primary->palette && ddraw->primary->palette->data_rgb)))
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2018-10-01 13:10:10 +02:00
|
|
|
if (ddraw->vhack)
|
|
|
|
{
|
|
|
|
if (detect_cutscene())
|
|
|
|
{
|
|
|
|
if (!InterlockedExchange(&ddraw->incutscene, TRUE))
|
2018-11-16 06:37:11 +01:00
|
|
|
UpdateVertices(TRUE, TRUE);
|
2018-10-01 13:10:10 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (InterlockedExchange(&ddraw->incutscene, FALSE))
|
2018-11-16 06:37:11 +01:00
|
|
|
UpdateVertices(FALSE, TRUE);
|
2018-10-01 13:10:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-28 22:40:44 +02:00
|
|
|
D3DLOCKED_RECT lock_rc;
|
|
|
|
|
|
|
|
if (InterlockedExchange(&ddraw->render.surfaceUpdated, FALSE))
|
|
|
|
{
|
2018-11-12 00:18:26 +01:00
|
|
|
if (++texIndex >= TEXTURE_COUNT)
|
|
|
|
texIndex = 0;
|
|
|
|
|
2018-09-28 22:40:44 +02:00
|
|
|
RECT rc = { 0,0,ddraw->width,ddraw->height };
|
2018-10-03 09:51:15 +02:00
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
if (SUCCEEDED(IDirect3DDevice9_SetTexture(D3dDev, 0, (IDirect3DBaseTexture9 *)SurfaceTex[texIndex])) &&
|
|
|
|
SUCCEEDED(IDirect3DTexture9_LockRect(SurfaceTex[texIndex], 0, &lock_rc, &rc, 0)))
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
|
|
|
unsigned char *src = (unsigned char *)ddraw->primary->surface;
|
|
|
|
unsigned char *dst = (unsigned char *)lock_rc.pBits;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ddraw->height; i++)
|
|
|
|
{
|
2018-11-29 01:39:03 +01:00
|
|
|
memcpy(dst, src, ddraw->primary->lPitch);
|
2018-10-02 03:25:34 +02:00
|
|
|
|
2018-11-14 05:35:59 +01:00
|
|
|
src += ddraw->primary->lPitch;
|
2018-09-28 22:40:44 +02:00
|
|
|
dst += lock_rc.Pitch;
|
|
|
|
}
|
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DTexture9_UnlockRect(SurfaceTex[texIndex], 0);
|
2018-09-28 22:40:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-14 05:35:59 +01:00
|
|
|
if (ddraw->bpp == 8 && InterlockedExchange(&ddraw->render.paletteUpdated, FALSE))
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2018-11-12 00:18:26 +01:00
|
|
|
if (++palIndex >= TEXTURE_COUNT)
|
|
|
|
palIndex = 0;
|
|
|
|
|
2018-09-28 22:40:44 +02:00
|
|
|
RECT rc = { 0,0,256,1 };
|
2018-10-03 09:51:15 +02:00
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
if (SUCCEEDED(IDirect3DDevice9_SetTexture(D3dDev, 1, (IDirect3DBaseTexture9 *)PaletteTex[palIndex])) &&
|
|
|
|
SUCCEEDED(IDirect3DTexture9_LockRect(PaletteTex[palIndex], 0, &lock_rc, &rc, 0)))
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2018-11-12 00:18:26 +01:00
|
|
|
memcpy(lock_rc.pBits, ddraw->primary->palette->data_rgb, 256 * sizeof(int));
|
2018-10-03 09:51:15 +02:00
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DTexture9_UnlockRect(PaletteTex[palIndex], 0);
|
2018-09-28 22:40:44 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-15 09:45:24 +01:00
|
|
|
|
2018-11-16 08:58:39 +01:00
|
|
|
if (!ddraw->handlemouse)
|
2018-11-16 06:37:11 +01:00
|
|
|
{
|
|
|
|
ChildWindowExists = FALSE;
|
2018-11-15 09:45:24 +01:00
|
|
|
EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary);
|
2018-11-16 06:37:11 +01:00
|
|
|
|
|
|
|
if (ddraw->render.width != ddraw->width || ddraw->render.height != ddraw->height)
|
|
|
|
{
|
|
|
|
if (ChildWindowExists)
|
|
|
|
{
|
|
|
|
IDirect3DDevice9_Clear(D3dDev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
|
2018-11-16 07:02:27 +01:00
|
|
|
|
|
|
|
if (!needsUpdate && UpdateVertices(FALSE, FALSE))
|
|
|
|
needsUpdate = TRUE;
|
|
|
|
}
|
|
|
|
else if (needsUpdate)
|
|
|
|
{
|
|
|
|
if (UpdateVertices(FALSE, TRUE))
|
|
|
|
needsUpdate = FALSE;
|
2018-11-16 06:37:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-28 22:40:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LeaveCriticalSection(&ddraw->cs);
|
|
|
|
|
2018-11-12 00:39:47 +01:00
|
|
|
IDirect3DDevice9_BeginScene(D3dDev);
|
|
|
|
IDirect3DDevice9_DrawPrimitive(D3dDev, D3DPT_TRIANGLESTRIP, 0, 2);
|
|
|
|
IDirect3DDevice9_EndScene(D3dDev);
|
2018-09-28 22:40:44 +02:00
|
|
|
|
2018-12-10 03:46:12 +01:00
|
|
|
if (FAILED(IDirect3DDevice9_Present(D3dDev, NULL, NULL, NULL, NULL)))
|
2018-10-07 13:42:32 +02:00
|
|
|
{
|
2018-10-15 00:01:31 +02:00
|
|
|
DWORD_PTR dwResult;
|
|
|
|
SendMessageTimeout(ddraw->hWnd, WM_D3D9DEVICELOST, 0, 0, 0, 1000, &dwResult);
|
2018-09-28 22:40:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#if _DEBUG
|
2018-10-02 11:38:38 +02:00
|
|
|
DrawFrameInfoEnd();
|
2018-09-28 22:40:44 +02:00
|
|
|
#endif
|
2018-12-10 04:24:30 +01:00
|
|
|
|
2018-11-29 21:26:43 +01:00
|
|
|
if (ddraw->fpsLimiter.ticklength > 0)
|
2018-09-28 22:40:44 +02:00
|
|
|
{
|
2018-11-29 21:26:43 +01:00
|
|
|
if (ddraw->fpsLimiter.hTimer)
|
|
|
|
{
|
2018-12-10 04:24:30 +01:00
|
|
|
if (ddraw->vsync)
|
2018-11-29 21:26:43 +01:00
|
|
|
{
|
2018-12-10 04:24:30 +01:00
|
|
|
WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
|
|
|
|
LARGE_INTEGER liDueTime = { .QuadPart = -ddraw->fpsLimiter.tickLengthNs };
|
|
|
|
SetWaitableTimer(ddraw->fpsLimiter.hTimer, &liDueTime, 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
|
|
|
|
2018-12-10 04:24:30 +01:00
|
|
|
if (CompareFileTime((FILETIME *)&ddraw->fpsLimiter.dueTime, &ft) == -1)
|
|
|
|
{
|
|
|
|
memcpy(&ddraw->fpsLimiter.dueTime, &ft, sizeof(LARGE_INTEGER));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
ddraw->fpsLimiter.dueTime.QuadPart += ddraw->fpsLimiter.tickLengthNs;
|
|
|
|
SetWaitableTimer(ddraw->fpsLimiter.hTimer, &ddraw->fpsLimiter.dueTime, 0, NULL, NULL, FALSE);
|
|
|
|
}
|
2018-11-29 21:26:43 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tickEnd = timeGetTime();
|
|
|
|
|
|
|
|
if (tickEnd - tickStart < ddraw->fpsLimiter.ticklength)
|
|
|
|
Sleep(ddraw->fpsLimiter.ticklength - (tickEnd - tickStart));
|
|
|
|
}
|
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
|
|
|
}
|