engine/engine/d3d/vid_d3d.c

1304 lines
31 KiB
C

#include "quakedef.h"
#include "gl_draw.h"
#include "shader.h"
#ifdef D3DQUAKE
#include "winquake.h"
//#include "d3d9quake.h"
#include "d3d9.h"
//#pragma comment(lib, "../libs/dxsdk9/lib/d3d9.lib")
/*Fixup outdated windows headers*/
#ifndef WM_XBUTTONDOWN
#define WM_XBUTTONDOWN 0x020B
#define WM_XBUTTONUP 0x020C
#endif
#ifndef MK_XBUTTON1
#define MK_XBUTTON1 0x0020
#endif
#ifndef MK_XBUTTON2
#define MK_XBUTTON2 0x0040
#endif
// copied from DarkPlaces in an attempt to grab more buttons
#ifndef MK_XBUTTON3
#define MK_XBUTTON3 0x0080
#endif
#ifndef MK_XBUTTON4
#define MK_XBUTTON4 0x0100
#endif
#ifndef MK_XBUTTON5
#define MK_XBUTTON5 0x0200
#endif
#ifndef MK_XBUTTON6
#define MK_XBUTTON6 0x0400
#endif
#ifndef MK_XBUTTON7
#define MK_XBUTTON7 0x0800
#endif
#ifndef WM_INPUT
#define WM_INPUT 255
#endif
int gl_bumpmappingpossible;
static void D3D9_GetBufferSize(int *width, int *height);
static LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pD3DDev9;
//static LPDIRECTDRAWGAMMACONTROL pGammaControl;
static qboolean vid_initializing;
extern qboolean scr_initialized; // ready to draw
extern qboolean scr_drawloading;
cvar_t vid_hardwaregamma;
//sound/error code needs this
HWND mainwindow;
//input code needs these
int window_center_x, window_center_y;
RECT window_rect;
int window_x, window_y;
void BuildGammaTable (float g, float c);
static void D3D9_VID_GenPaletteTables (unsigned char *palette)
{
extern unsigned short ramps[3][256];
qbyte *pal;
unsigned r,g,b;
unsigned v;
unsigned short i;
unsigned *table;
extern qbyte gammatable[256];
if (palette)
{
extern cvar_t v_contrast;
BuildGammaTable(v_gamma.value, v_contrast.value);
//
// 8 8 8 encoding
//
if (1)//vid_hardwaregamma.value)
{
// don't built in the gamma table
pal = palette;
table = d_8to24rgbtable;
for (i=0 ; i<256 ; i++)
{
r = pal[0];
g = pal[1];
b = pal[2];
pal += 3;
// v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
// v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
*table++ = v;
}
d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent
}
else
{
//computer has no hardware gamma (poor suckers) increase table accordingly
pal = palette;
table = d_8to24rgbtable;
for (i=0 ; i<256 ; i++)
{
r = gammatable[pal[0]];
g = gammatable[pal[1]];
b = gammatable[pal[2]];
pal += 3;
// v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
// v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
*table++ = v;
}
d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent
}
if (LittleLong(1) != 1)
{
for (i=0 ; i<256 ; i++)
d_8to24rgbtable[i] = LittleLong(d_8to24rgbtable[i]);
}
}
if (pD3DDev9)
IDirect3DDevice9_SetGammaRamp(pD3DDev9, 0, D3DSGR_NO_CALIBRATION, (D3DGAMMARAMP *)ramps);
}
typedef enum {MS_WINDOWED, MS_FULLSCREEN, MS_FULLDIB, MS_UNINIT} modestate_t;
static modestate_t modestate;
static qboolean D3D9AppActivate(BOOL fActive, BOOL minimize)
/****************************************************************************
*
* Function: AppActivate
* Parameters: fActive - True if app is activating
*
* Description: If the application is activating, then swap the system
* into SYSPAL_NOSTATIC mode so that our palettes will display
* correctly.
*
****************************************************************************/
{
static BOOL sound_active;
if (ActiveApp == fActive && Minimized == minimize)
return false; //so windows doesn't crash us over and over again.
ActiveApp = fActive;
Minimized = minimize;
// enable/disable sound on focus gain/loss
if (!ActiveApp && sound_active)
{
S_BlockSound ();
sound_active = false;
}
else if (ActiveApp && !sound_active)
{
S_UnblockSound ();
sound_active = true;
}
IN_UpdateGrabs(modestate != MS_WINDOWED, ActiveApp);
if (fActive)
{
Cvar_ForceCallback(&v_gamma);
}
if (!fActive)
{
Cvar_ForceCallback(&v_gamma); //wham bam thanks.
}
return true;
}
static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LONG lRet = 1;
int fActive, fMinimized, temp;
extern unsigned int uiWheelMessage;
if ( uMsg == uiWheelMessage )
uMsg = WM_MOUSEWHEEL;
switch (uMsg)
{
case WM_KILLFOCUS:
if (modestate == MS_FULLDIB)
ShowWindow(mainwindow, SW_SHOWMINNOACTIVE);
break;
case WM_CREATE:
break;
case WM_MOVE:
GetWindowRect(mainwindow, &window_rect);
//window_x = (int) LOWORD(lParam);
//window_y = (int) HIWORD(lParam);
// VID_UpdateWindowStatus ();
break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if (!vid_initializing)
IN_TranslateKeyEvent (wParam, lParam, true);
break;
case WM_KEYUP:
case WM_SYSKEYUP:
if (!vid_initializing)
IN_TranslateKeyEvent (wParam, lParam, false);
break;
case WM_SYSCHAR:
// keep Alt-Space from happening
break;
// this is complicated because Win32 seems to pack multiple mouse events into
// one update sometimes, so we always check all states and look for events
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEMOVE:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP:
temp = 0;
if (wParam & MK_LBUTTON)
temp |= 1;
if (wParam & MK_RBUTTON)
temp |= 2;
if (wParam & MK_MBUTTON)
temp |= 4;
if (wParam & MK_XBUTTON1)
temp |= 8;
if (wParam & MK_XBUTTON2)
temp |= 16;
if (wParam & MK_XBUTTON3)
temp |= 32;
if (wParam & MK_XBUTTON4)
temp |= 64;
if (wParam & MK_XBUTTON5)
temp |= 128;
if (wParam & MK_XBUTTON6)
temp |= 256;
if (wParam & MK_XBUTTON7)
temp |= 512;
if (!vid_initializing)
IN_MouseEvent (temp);
break;
// JACK: This is the mouse wheel with the Intellimouse
// Its delta is either positive or neg, and we generate the proper
// Event.
case WM_MOUSEWHEEL:
if (!vid_initializing)
{
if ((short) HIWORD(wParam) > 0)
{
Key_Event(K_MWHEELUP, 0, true);
Key_Event(K_MWHEELUP, 0, false);
}
else
{
Key_Event(K_MWHEELDOWN, 0, true);
Key_Event(K_MWHEELDOWN, 0, false);
}
}
break;
case WM_INPUT:
// raw input handling
IN_RawInput_MouseRead((HANDLE)lParam);
break;
case WM_SIZE:
if (!vid_initializing)
{
GetClientRect(mainwindow, &window_rect);
// force width/height to be updated
vid.pixelwidth = window_rect.right - window_rect.left;
vid.pixelheight = window_rect.bottom - window_rect.top;
// Cvar_ForceCallback(&vid_conautoscale);
// Cvar_ForceCallback(&vid_conwidth);
}
break;
case WM_CLOSE:
if (!vid_initializing)
if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit",
MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES)
{
Sys_Quit ();
}
break;
case WM_ACTIVATE:
fActive = LOWORD(wParam);
fMinimized = (BOOL) HIWORD(wParam);
if (!D3D9AppActivate(!(fActive == WA_INACTIVE), fMinimized))
break;//so, urm, tell me microsoft, what changed?
if (modestate == MS_FULLDIB)
ShowWindow(mainwindow, SW_SHOWNORMAL);
// fix the leftover Alt from any Alt-Tab or the like that switched us away
// ClearAllStates ();
break;
case WM_DESTROY:
{
// if (dibwindow)
// DestroyWindow (dibwindow);
}
break;
case MM_MCINOTIFY:
lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam);
break;
case WM_MWHOOK:
if (!vid_initializing)
MW_Hook_Message (lParam);
break;
default:
/* pass all unhandled messages to DefWindowProc */
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
/* return 1 if handled message, 0 if not */
return lRet;
}
static D3DPRESENT_PARAMETERS d3dpp;
static void resetD3D9(void)
{
IDirect3DDevice9_Reset(pD3DDev9, &d3dpp);
/*clear the screen to black as soon as we start up, so there's no lingering framebuffer state*/
IDirect3DDevice9_BeginScene(pD3DDev9);
IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
//IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_DITHERENABLE, FALSE);
//IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_SPECULARENABLE, FALSE);
//IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_LIGHTING, FALSE);
}
#if (WINVER < 0x500) && !defined(__GNUC__)
typedef struct tagMONITORINFO
{
DWORD cbSize;
RECT rcMonitor;
RECT rcWork;
DWORD dwFlags;
} MONITORINFO, *LPMONITORINFO;
#endif
static void initD3D9(HWND hWnd, rendererstate_t *info)
{
int i;
int numadaptors;
int err;
RECT rect;
D3DADAPTER_IDENTIFIER9 inf;
extern cvar_t _vid_wait_override;
static HMODULE d3d9dll;
LPDIRECT3D9 (WINAPI *pDirect3DCreate9) (int version);
if (!d3d9dll)
d3d9dll = LoadLibrary("d3d9.dll");
if (!d3d9dll)
{
Con_Printf("Direct3d 9 does not appear to be installed\n");
return;
}
pDirect3DCreate9 = (void*)GetProcAddress(d3d9dll, "Direct3DCreate9");
if (!pDirect3DCreate9)
{
Con_Printf("Direct3d 9 does not appear to be installed properly\n");
return;
}
pD3D = pDirect3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
if (!pD3D)
return;
numadaptors = IDirect3D9_GetAdapterCount(pD3D);
for (i = 0; i < numadaptors; i++)
{ //try each adaptor in turn until we get one that actually works
memset(&d3dpp, 0, sizeof(d3dpp)); // clear out the struct for use
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
d3dpp.BackBufferWidth = info->width;
d3dpp.BackBufferHeight = info->height;
d3dpp.MultiSampleType = info->multisample;
d3dpp.BackBufferCount = 3;
d3dpp.FullScreen_RefreshRateInHz = info->fullscreen?info->rate:0; //don't pass a rate if not fullscreen, d3d doesn't like it.
d3dpp.Windowed = !info->fullscreen;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.BackBufferFormat = info->fullscreen?D3DFMT_X8R8G8B8:D3DFMT_UNKNOWN;
if (!*_vid_wait_override.string)
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
else
{
if (_vid_wait_override.value == 1)
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
else if (_vid_wait_override.value == 2)
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
else if (_vid_wait_override.value == 3)
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_THREE;
else if (_vid_wait_override.value == 4)
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_FOUR;
else
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
}
memset(&inf, 0, sizeof(inf));
err = IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &inf);
// create a device class using this information and information from the d3dpp stuct
IDirect3D9_CreateDevice(pD3D,
i,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&pD3DDev9);
if (pD3DDev9)
{
HMONITOR hm;
MONITORINFO mi;
char *s;
for (s = inf.Description + strlen(inf.Description)-1; s >= inf.Description && *s <= ' '; s--)
*s = 0;
Con_Printf("D3D9: Using device %s\n", inf.Description);
vid.numpages = d3dpp.BackBufferCount;
if (d3dpp.Windowed) //fullscreen we get positioned automagically.
{ //windowed, we get positioned at 0,0... which is often going to be on the wrong screen
//the user can figure it out from here
static HANDLE huser32;
BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR hMonitor, LPMONITORINFO lpmi);
if (!huser32)
huser32 = LoadLibrary("user32.dll");
if (!huser32)
return;
pGetMonitorInfoA = (void*)GetProcAddress(huser32, "GetMonitorInfoA");
if (!pGetMonitorInfoA)
return;
hm = IDirect3D9_GetAdapterMonitor(pD3D, i);
memset(&mi, 0, sizeof(mi));
mi.cbSize = sizeof(mi);
pGetMonitorInfoA(hm, &mi);
rect.left = rect.top = 0;
rect.right = d3dpp.BackBufferWidth;
rect.bottom = d3dpp.BackBufferHeight;
AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, 0);
MoveWindow(d3dpp.hDeviceWindow, mi.rcWork.left, mi.rcWork.top, rect.right-rect.left, rect.bottom-rect.top, false);
}
return; //successful
}
}
Con_Printf("IDirect3D9_CreateDevice failed\n");
return;
}
static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette)
{
DWORD width = info->width;
DWORD height = info->height;
DWORD bpp = info->bpp;
DWORD zbpp = 16;
DWORD flags = 0;
DWORD wstyle;
RECT rect;
MSG msg;
extern cvar_t vid_conwidth;
extern cvar_t vid_conheight;
//DDGAMMARAMP gammaramp;
//int i;
char *CLASSNAME = "FTED3D9QUAKE";
WNDCLASS wc = {
0,
&D3D9_WindowProc,
0,
0,
NULL,
NULL,
NULL,
NULL,
NULL,
CLASSNAME
};
vid_initializing = true;
RegisterClass(&wc);
if (info->fullscreen)
wstyle = 0;
else
wstyle = WS_OVERLAPPEDWINDOW;
rect.left = rect.top = 0;
rect.right = info->width;
rect.bottom = info->height;
AdjustWindowRectEx(&rect, wstyle, FALSE, 0);
mainwindow = CreateWindow(CLASSNAME, "Direct3D", wstyle, 0, 0, rect.right-rect.left, rect.bottom-rect.top, NULL, NULL, NULL, NULL);
// Try as specified.
initD3D9(mainwindow, info);
if (!pD3DDev9)
return false;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ShowWindow(mainwindow, SW_NORMAL);
//IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1, 0);
//IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
IDirect3DDevice9_BeginScene(pD3DDev9);
IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
// pD3DX->lpVtbl->GetBufferSize((void*)pD3DX, &width, &height);
vid.pixelwidth = width;
vid.pixelheight = height;
vid.recalc_refdef = true;
vid.width = vid.conwidth = width;
vid.height = vid.conheight = height;
// pDD->lpVtbl->QueryInterface ((void*)pDD, &IID_IDirectDrawGammaControl, (void**)&pGammaControl);
/* if (pGammaControl)
{
for (i = 0; i < 256; i++)
gammaramp.red[i] = i*2;
pGammaControl->lpVtbl->SetGammaRamp(pGammaControl, 0, &gammaramp);
}
else*/
Con_Printf("Couldn't get gamma controls\n");
vid_initializing = false;
resetD3D9();
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHAFUNC, D3DCMP_GREATER );
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHAREF, 0.666*256 );
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE );
//IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_DITHERENABLE, FALSE);
//IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_SPECULARENABLE, FALSE);
//IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_LIGHTING, FALSE);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, TRUE);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
GetWindowRect(mainwindow, &window_rect);
D3D9_VID_GenPaletteTables(palette);
{
extern qboolean mouseactive;
mouseactive = false;
}
{
extern cvar_t v_contrast;
void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue);
Cvar_Hook(&v_gamma, GLV_Gamma_Callback);
Cvar_Hook(&v_contrast, GLV_Gamma_Callback);
Cvar_ForceCallback(&v_gamma);
}
return true;
}
/*a new model has been loaded*/
static void (D3D9_R_NewMap) (void)
{
int i;
r_worldentity.model = cl.worldmodel;
R_AnimateLight();
Surf_BuildLightmaps();
/*wipe any lingering particles*/
P_ClearParticles();
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
{
if (!cl.worldmodel->textures[i])
continue;
cl.worldmodel->textures[i]->texturechain = NULL;
}
}
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
extern mleaf_t *r_viewleaf2, *r_oldviewleaf2;
static void (D3D9_R_PreNewMap) (void)
{
r_viewleaf = NULL;
r_oldviewleaf = NULL;
r_viewleaf2 = NULL;
r_oldviewleaf2 = NULL;
}
static int (D3D9_R_LightPoint) (vec3_t point)
{
return 0;
}
static void (D3D9_R_PushDlights) (void)
{
}
static void (D3D9_R_AddStain) (vec3_t org, float red, float green, float blue, float radius)
{
}
static void (D3D9_R_LessenStains) (void)
{
}
static void (D3D9_VID_DeInit) (void)
{
/*final shutdown, kill the video stuff*/
if (pD3DDev9)
{
IDirect3DDevice9_Release(pD3DDev9);
pD3DDev9 = NULL;
}
if (pD3D)
{
IDirect3D9_Release(pD3D);
pD3D = NULL;
}
if (mainwindow)
{
DestroyWindow(mainwindow);
mainwindow = NULL;
}
}
static void (D3D9_VID_LockBuffer) (void)
{
}
static void (D3D9_VID_UnlockBuffer) (void)
{
}
static void (D3D9_D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height)
{
}
static void (D3D9_D_EndDirectRect) (int x, int y, int width, int height)
{
}
static void (D3D9_VID_ForceLockState) (int lk)
{
}
static int (D3D9_VID_ForceUnlockedAndReturnState) (void)
{
return 0;
}
static void (D3D9_VID_SetPalette) (unsigned char *palette)
{
D3D9_VID_GenPaletteTables(palette);
}
static void (D3D9_VID_ShiftPalette) (unsigned char *palette)
{
D3D9_VID_GenPaletteTables(palette);
}
static char *(D3D9_VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight)
{
return NULL;
}
static void (D3D9_VID_SetWindowCaption) (char *msg)
{
SetWindowText(mainwindow, msg);
}
void Matrix4_OrthographicD3D(float *proj, float xmin, float xmax, float ymax, float ymin,
float znear, float zfar);
void d3dx_ortho(float *m);
static void D3D9_Set2D (void)
{
float m[16];
D3DVIEWPORT9 vport;
// IDirect3DDevice9_EndScene(pD3DDev9);
Matrix4_OrthographicD3D(m, 0 + (0.5*vid.width/vid.pixelwidth), vid.width + (0.5*vid.width/vid.pixelwidth), 0 + (0.5*vid.height/vid.pixelheight), vid.height + (0.5*vid.height/vid.pixelheight), -100, 100);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)m);
Matrix4_Identity(m);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m);
Matrix4_Identity(m);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)m);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CCW);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
vport.X = 0;
vport.Y = 0;
vport.Width = vid.pixelwidth;
vport.Height = vid.pixelheight;
vport.MinZ = 0;
vport.MaxZ = 1;
IDirect3DDevice9_SetViewport(pD3DDev9, &vport);
}
static int d3d9error(int i)
{
if (FAILED(i))// != D3D_OK)
Con_Printf("D3D error: %x %i\n", i);
return i;
}
typedef struct {
float x, y, z;
unsigned int colour;
} d3d9bsvert_t;
static void D3D9_BrightenScreen (void)
{
d3d9bsvert_t d3d9bsvert[4];
index_t d3d9quadindexes[6] = {
0, 1, 2,
0, 2, 3
};
extern cvar_t gl_contrast;
float f;
unsigned int colour;
RSpeedMark();
if (gl_contrast.value <= 1.0)
return;
f = gl_contrast.value;
f = min (f, 3);
IDirect3DDevice9_SetTexture (pD3DDev9, 0, NULL);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_ONE);
while (f > 1)
{
if (f >= 2)
colour = 0xffffffff;
else
{
colour = (f-1)*255;
colour = (colour * 0x010101) | 0xff000000;
}
d3d9bsvert[0].x = 0;
d3d9bsvert[0].y = 0;
d3d9bsvert[0].z = 0;
d3d9bsvert[0].colour = colour;
d3d9bsvert[1].x = vid.width;
d3d9bsvert[1].y = 0;
d3d9bsvert[1].z = 0;
d3d9bsvert[1].colour = colour;
d3d9bsvert[2].x = vid.width;
d3d9bsvert[2].y = vid.height;
d3d9bsvert[2].z = 0;
d3d9bsvert[2].colour = colour;
d3d9bsvert[3].x = 0;
d3d9bsvert[3].y = vid.height;
d3d9bsvert[3].z = 0;
d3d9bsvert[3].colour = colour;
IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE);
IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9bsvert, sizeof(d3d9bsvert[0]));
f *= 0.5;
}
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, FALSE);
RSpeedEnd(RSPEED_PALETTEFLASHES);
}
static void (D3D9_SCR_UpdateScreen) (void)
{
extern int keydown[];
extern cvar_t vid_conheight;
int uimenu;
#ifdef TEXTEDITOR
extern qboolean editormodal;
#endif
qboolean nohud;
RSpeedMark();
switch (IDirect3DDevice9_TestCooperativeLevel(pD3DDev9))
{
case D3DERR_DEVICELOST:
//the user has task switched away from us or something
return;
case D3DERR_DEVICENOTRESET:
resetD3D9();
if (FAILED(IDirect3DDevice9_TestCooperativeLevel(pD3DDev9)))
Sys_Error("D3D9 Device lost. Additionally restoration failed.\n");
// D3DSucks();
// scr_disabled_for_loading = false;
VID_ShiftPalette (NULL);
break;
default:
break;
}
if (keydown['k'])
{
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(rand()&255, rand()&255, rand()&255), 1.0f, 0));
d3d9error(IDirect3DDevice9_BeginScene(pD3DDev9));
d3d9error(IDirect3DDevice9_EndScene(pD3DDev9));
d3d9error(IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL));
VID_ShiftPalette (NULL);
}
if (scr_disabled_for_loading)
{
extern float scr_disabled_time;
if (Sys_DoubleTime() - scr_disabled_time > 60 || key_dest != key_game)
{
scr_disabled_for_loading = false;
}
else
{
IDirect3DDevice9_BeginScene(pD3DDev9);
scr_drawloading = true;
SCR_DrawLoading ();
scr_drawloading = false;
IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
RSpeedEnd(RSPEED_TOTALREFRESH);
return;
}
}
if (!scr_initialized || !con_initialized)
{
RSpeedEnd(RSPEED_TOTALREFRESH);
return; // not initialized yet
}
#pragma message("Fixme: remove the code from here...")
{
extern cvar_t vid_conwidth, vid_conheight, vid_conautoscale;
if (vid_conautoscale.value)
{
vid.conwidth = vid.pixelwidth*vid_conautoscale.value;
vid.conheight = vid.pixelheight*vid_conautoscale.value;
}
else
{
vid.conwidth = vid_conwidth.value;
vid.conheight = vid_conheight.value;
}
if (!vid.conwidth)
vid.conwidth = vid.pixelwidth;
if (!vid.conheight)
vid.conheight = vid.pixelheight;
if (vid.width != vid.conwidth || vid.height != vid.conheight)
vid.recalc_refdef = true;
vid.width = vid.conwidth;
vid.height = vid.conheight;
}
#ifdef VM_UI
uimenu = UI_MenuState();
#else
uimenu = 0;
#endif
d3d9error(IDirect3DDevice9_BeginScene(pD3DDev9));
D3D9_Set2D ();
/*
#ifdef TEXTEDITOR
if (editormodal)
{
Editor_Draw();
GLV_UpdatePalette (false, host_frametime);
#if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame();
#endif
GLR_BrightenScreen();
if (key_dest == key_console)
Con_DrawConsole(vid_conheight.value/2, false);
GL_EndRendering ();
GL_DoSwap();
RSpeedEnd(RSPEED_TOTALREFRESH);
return;
}
#endif
*/
if (Media_ShowFilm())
{
M_Draw(0);
// GLV_UpdatePalette (false, host_frametime);
#if defined(_WIN32)
Media_RecordFrame();
#endif
// GLR_BrightenScreen();
IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
// pD3DDev->lpVtbl->BeginScene(pD3DDev);
RSpeedEnd(RSPEED_TOTALREFRESH);
return;
}
//
// determine size of refresh window
//
if (vid.recalc_refdef)
SCR_CalcRefdef ();
//
// do 3D refresh drawing, and then update the screen
//
SCR_SetUpToDrawConsole ();
nohud = false;
#ifdef VM_CG
if (CG_Refresh())
nohud = true;
else
#endif
#ifdef CSQC_DAT
if (cls.state == ca_active && CSQC_DrawView())
nohud = true;
else
#endif
if (r_worldentity.model && uimenu != 1)
{
V_RenderView ();
// Q1BSP_TestClipDecal();
}
D3D9_Set2D ();
D3D9_BrightenScreen();
if (!nohud)
SCR_TileClear ();
SCR_DrawTwoDimensional(uimenu, nohud);
GLV_UpdatePalette (false, host_frametime);
#if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame();
#endif
RSpeedEnd(RSPEED_TOTALREFRESH);
RSpeedShow();
#pragma message("Fixme: ... to here")
d3d9error(IDirect3DDevice9_EndScene(pD3DDev9));
d3d9error(IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL));
window_center_x = (window_rect.left + window_rect.right)/2;
window_center_y = (window_rect.top + window_rect.bottom)/2;
IN_UpdateGrabs(modestate != MS_WINDOWED, ActiveApp);
VID_ShiftPalette (NULL);
}
static void (D3D9_Draw_BeginDisc) (void)
{
}
static void (D3D9_Draw_EndDisc) (void)
{
}
static void (D3D9_Draw_Init) (void)
{
R2D_Init();
}
static void (D3D9_Draw_ReInit) (void)
{
}
static void (D3D9_Draw_Crosshair) (void)
{
}
static void (D3D9_Draw_TransPicTranslate) (int x, int y, int w, int h, qbyte *pic, qbyte *translation)
{
}
static void (D3D9_Draw_Fill) (int x, int y, int w, int h, unsigned int c)
{
}
static void (D3D9_Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b)
{
}
static void (D3D9_Draw_FadeScreen) (void)
{
}
static void (D3D9_Draw_BeginDisc) (void);
static void (D3D9_Draw_EndDisc) (void);
static void (D3D9_R_Init) (void)
{
}
static void (D3D9_R_DeInit) (void)
{
Surf_DeInit();
}
static void D3D9_SetupViewPort(void)
{
extern cvar_t gl_mindist;
float screenaspect;
int x, x2, y2, y, w, h;
float fov_x, fov_y;
D3DVIEWPORT9 vport;
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
//
// set up viewpoint
//
x = r_refdef.vrect.x * vid.pixelwidth/(int)vid.width;
x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * vid.pixelwidth/(int)vid.width;
y = (r_refdef.vrect.y) * vid.pixelheight/(int)vid.height;
y2 = ((int)(r_refdef.vrect.y + r_refdef.vrect.height)) * vid.pixelheight/(int)vid.height;
// fudge around because of frac screen scale
if (x > 0)
x--;
if (x2 < vid.pixelwidth)
x2++;
if (y < 0)
y--;
if (y2 < vid.pixelheight)
y2++;
w = x2 - x;
h = y2 - y;
vport.X = x;
vport.Y = y;
vport.Width = w;
vport.Height = h;
vport.MinZ = 0;
vport.MaxZ = 1;
IDirect3DDevice9_SetViewport(pD3DDev9, &vport);
fov_x = r_refdef.fov_x;//+sin(cl.time)*5;
fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5;
if (r_waterwarp.value<0 && r_viewleaf->contents <= Q1CONTENTS_WATER)
{
fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
}
screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
GL_InfinatePerspective(fov_x, fov_y, gl_mindist.value);
Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_projection_matrix);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_view_matrix);
}
static void (D3D9_R_RenderView) (void)
{
D3D9_SetupViewPort();
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
Surf_DrawWorld();
P_DrawParticles ();
}
void (D3D9_R_NewMap) (void);
void (D3D9_R_PreNewMap) (void);
int (D3D9_R_LightPoint) (vec3_t point);
void (D3D9_R_PushDlights) (void);
void (D3D9_R_AddStain) (vec3_t org, float red, float green, float blue, float radius);
void (D3D9_R_LessenStains) (void);
qboolean (D3D9_VID_Init) (rendererstate_t *info, unsigned char *palette);
void (D3D9_VID_DeInit) (void);
void (D3D9_VID_LockBuffer) (void);
void (D3D9_VID_UnlockBuffer) (void);
void (D3D9_D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height);
void (D3D9_D_EndDirectRect) (int x, int y, int width, int height);
void (D3D9_VID_ForceLockState) (int lk);
int (D3D9_VID_ForceUnlockedAndReturnState) (void);
void (D3D9_VID_SetPalette) (unsigned char *palette);
void (D3D9_VID_ShiftPalette) (unsigned char *palette);
char *(D3D9_VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight);
void (D3D9_VID_SetWindowCaption) (char *msg);
void (D3D9_SCR_UpdateScreen) (void);
rendererinfo_t d3drendererinfo =
{
"Direct3D9 Native",
{
"D3D",
"Direct3d",
"DirectX",
"DX"
},
QR_DIRECT3D,
R2D_SafePicFromWad,
R2D_SafeCachePic,
D3D9_Draw_Init,
D3D9_Draw_ReInit,
D3D9_Draw_Crosshair,
R2D_ScalePic,
R2D_SubPic,
D3D9_Draw_TransPicTranslate,
R2D_ConsoleBackground,
R2D_EditorBackground,
R2D_TileClear,
D3D9_Draw_Fill,
D3D9_Draw_FillRGB,
D3D9_Draw_FadeScreen,
D3D9_Draw_BeginDisc,
D3D9_Draw_EndDisc,
R2D_Image,
R2D_ImageColours,
D3D9_R_Init,
D3D9_R_DeInit,
D3D9_R_RenderView,
D3D9_R_NewMap,
D3D9_R_PreNewMap,
D3D9_R_LightPoint,
D3D9_R_PushDlights,
D3D9_R_AddStain,
D3D9_R_LessenStains,
NULL,
NULL,
NULL,
RMod_Init,
RMod_ClearAll,
RMod_ForName,
RMod_FindName,
RMod_Extradata,
RMod_TouchModel,
RMod_NowLoadExternal,
RMod_Think,
Mod_GetTag,
Mod_TagNumForName,
Mod_SkinNumForName,
Mod_FrameNumForName,
Mod_FrameDuration,
D3D9_VID_Init,
D3D9_VID_DeInit,
D3D9_VID_LockBuffer,
D3D9_VID_UnlockBuffer,
D3D9_D_BeginDirectRect,
D3D9_D_EndDirectRect,
D3D9_VID_ForceLockState,
D3D9_VID_ForceUnlockedAndReturnState,
D3D9_VID_SetPalette,
D3D9_VID_ShiftPalette,
D3D9_VID_GetRGBInfo,
D3D9_VID_SetWindowCaption,
D3D9_SCR_UpdateScreen,
"no more"
};
#endif