2009-07-28 21:32:10 +00:00
|
|
|
// Copyright (C) 2003 Dolphin Project.
|
2008-12-08 05:25:12 +00:00
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, version 2.0.
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official SVN repository and contact information can be found at
|
|
|
|
// http://code.google.com/p/dolphin-emu/
|
|
|
|
|
|
|
|
#include "D3DBase.h"
|
2009-09-13 17:46:33 +00:00
|
|
|
#include "VideoConfig.h"
|
2008-12-08 05:25:12 +00:00
|
|
|
#include "Render.h"
|
2009-09-06 17:47:48 +00:00
|
|
|
#include "XFStructs.h"
|
2008-12-08 05:25:12 +00:00
|
|
|
|
|
|
|
namespace D3D
|
|
|
|
{
|
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
LPDIRECT3D9 D3D = NULL; // Used to create the D3DDevice
|
|
|
|
LPDIRECT3DDEVICE9 dev = NULL; // Our rendering device
|
2009-09-13 17:46:33 +00:00
|
|
|
LPDIRECT3DSURFACE9 back_buffer;
|
|
|
|
LPDIRECT3DSURFACE9 back_buffer_z;
|
2009-09-13 08:21:35 +00:00
|
|
|
D3DCAPS9 caps;
|
|
|
|
HWND hWnd;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
static bool fullScreen = false;
|
|
|
|
static bool nextFullScreen = false;
|
|
|
|
static int multisample;
|
|
|
|
static int resolution;
|
|
|
|
static int xres, yres;
|
2009-09-15 19:53:22 +00:00
|
|
|
static bool auto_depth_stencil = false;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
#define VENDOR_NVIDIA 4318
|
|
|
|
#define VENDOR_ATI 4098
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-18 02:03:56 +00:00
|
|
|
bool bFrameInProgress = false;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
#define MAX_ADAPTERS 4
|
|
|
|
static Adapter adapters[MAX_ADAPTERS];
|
|
|
|
static int numAdapters;
|
|
|
|
static int cur_adapter;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
// Value caches for state filtering
|
|
|
|
const int MaxTextureStages = 9;
|
2009-09-16 20:12:14 +00:00
|
|
|
const int MaxRenderStates = 210 + 46;
|
|
|
|
const int MaxTextureTypes = 33;
|
|
|
|
const int MaxSamplerSize = 13;
|
|
|
|
const int MaxSamplerTypes = 15;
|
|
|
|
static bool m_RenderStatesSet[MaxRenderStates];
|
|
|
|
static DWORD m_RenderStates[MaxRenderStates];
|
2009-09-13 08:21:35 +00:00
|
|
|
static DWORD m_TextureStageStates[MaxTextureStages][MaxTextureTypes];
|
|
|
|
static DWORD m_SamplerStates[MaxSamplerSize][MaxSamplerTypes];
|
|
|
|
LPDIRECT3DBASETEXTURE9 m_Textures[16];
|
2009-09-19 10:46:25 +00:00
|
|
|
LPDIRECT3DVERTEXDECLARATION9 m_VtxDecl;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
void Enumerate();
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
int GetNumAdapters() { return numAdapters; }
|
|
|
|
const Adapter &GetAdapter(int i) { return adapters[i]; }
|
|
|
|
const Adapter &GetCurAdapter() { return adapters[cur_adapter]; }
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
HRESULT Init()
|
|
|
|
{
|
|
|
|
// Create the D3D object, which is needed to create the D3DDevice.
|
|
|
|
D3D = Direct3DCreate9(D3D_SDK_VERSION);
|
|
|
|
if (!D3D)
|
|
|
|
return E_FAIL;
|
|
|
|
Enumerate();
|
|
|
|
return S_OK;
|
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
void Shutdown()
|
|
|
|
{
|
|
|
|
D3D->Release();
|
|
|
|
D3D = 0;
|
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
void EnableAlphaToCoverage()
|
|
|
|
{
|
|
|
|
// Each vendor has their own specific little hack.
|
|
|
|
if (GetCurAdapter().ident.VendorId == VENDOR_ATI)
|
|
|
|
D3D::SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1'));
|
|
|
|
else
|
|
|
|
D3D::SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
|
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp)
|
|
|
|
{
|
|
|
|
int FSResX = adapters[adapter].resolutions[resolution].xres;
|
|
|
|
int FSResY = adapters[adapter].resolutions[resolution].yres;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS));
|
|
|
|
pp->hDeviceWindow = hWnd;
|
|
|
|
if (auto_depth_stencil)
|
|
|
|
{
|
|
|
|
pp->EnableAutoDepthStencil = TRUE;
|
|
|
|
pp->AutoDepthStencilFormat = D3DFMT_D24S8;
|
|
|
|
} else {
|
|
|
|
pp->EnableAutoDepthStencil = FALSE;
|
|
|
|
pp->AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
pp->BackBufferFormat = D3DFMT_A8R8G8B8;
|
|
|
|
if (aa_mode >= (int)adapters[adapter].aa_levels.size())
|
|
|
|
aa_mode = 0;
|
|
|
|
|
|
|
|
pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_setting;
|
|
|
|
pp->MultiSampleQuality = adapters[adapter].aa_levels[aa_mode].qual_setting;
|
2009-10-17 09:09:52 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
pp->Flags = auto_depth_stencil ? D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL : 0;
|
|
|
|
if (fullScreen)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
xres = pp->BackBufferWidth = FSResX;
|
|
|
|
yres = pp->BackBufferHeight = FSResY;
|
|
|
|
pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
|
|
pp->Windowed = FALSE;
|
2009-12-30 16:20:41 +00:00
|
|
|
//if(g_Config.bHideCursor)
|
Now you can switch between Emulated and Real WiiMotes, connect more Real Wiimotes and even pair them up (if you have MS BT Stack) during gameplay!
All you gotta do is Pause the emulation! That's useful for when your batteries run out during gameplay, for example...
But if you change the WiiMote source (between Emulated, Real or Inactive) you must disconnect and reconnect (Menu Tools -> Connect WiiMote) the WiiMotes affected by the change...
Thanks to jack.fr0st who did all the emulation state notification work!
Now every plugin has a way to know the current emulation state (paused, stopped or playing)
@ayuanx: I thought about doing a PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, current_number); so that the user gets asked to reconnect that WiiMote, trying to avoid having to disconnect and reconnect, but it didn't work because shooting that message only asks to reconnect, doesn't do a disconnect... Do you have any ideas on how to accomplish that?
Also, if anyone could check if Issue 1916 is finally fixed... Or at least when is the cursor being hidden or not...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4789 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-06 19:26:52 +00:00
|
|
|
//if(!g_Config.RenderToMainframe)
|
|
|
|
ShowCursor(FALSE);
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RECT client;
|
|
|
|
GetClientRect(hWnd, &client);
|
|
|
|
xres = pp->BackBufferWidth = client.right - client.left;
|
|
|
|
yres = pp->BackBufferHeight = client.bottom - client.top;
|
|
|
|
pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
|
|
pp->PresentationInterval = g_Config.bVSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
|
|
pp->Windowed = TRUE;
|
2010-01-05 17:38:37 +00:00
|
|
|
ShowCursor(TRUE);
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
void Enumerate()
|
|
|
|
{
|
|
|
|
numAdapters = D3D::D3D->GetAdapterCount();
|
2009-10-17 09:09:52 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
for (int i = 0; i < std::min(MAX_ADAPTERS, numAdapters); i++)
|
|
|
|
{
|
|
|
|
Adapter &a = adapters[i];
|
2009-10-17 09:09:52 +00:00
|
|
|
a.aa_levels.clear();
|
|
|
|
a.resolutions.clear();
|
2009-09-15 21:25:34 +00:00
|
|
|
D3D::D3D->GetAdapterIdentifier(i, 0, &a.ident);
|
|
|
|
bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA;
|
|
|
|
|
|
|
|
// Add multisample modes
|
|
|
|
a.aa_levels.push_back(AALevel("None", D3DMULTISAMPLE_NONE, 0));
|
|
|
|
|
|
|
|
DWORD qlevels = 0;
|
|
|
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
|
|
|
|
if (qlevels > 0)
|
|
|
|
a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0));
|
|
|
|
|
|
|
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
|
|
|
|
if (qlevels > 0)
|
|
|
|
a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0));
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
|
|
|
|
if (qlevels > 0)
|
|
|
|
a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
if (isNvidia)
|
|
|
|
{
|
|
|
|
// CSAA support
|
2008-12-08 05:25:12 +00:00
|
|
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
2009-09-15 21:25:34 +00:00
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels))
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
if (qlevels > 2)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
// 8x, 8xQ are available
|
|
|
|
// See http://developer.nvidia.com/object/coverage-sampled-aa.html
|
|
|
|
a.aa_levels.push_back(AALevel("8x CSAA", D3DMULTISAMPLE_4_SAMPLES, 2));
|
|
|
|
a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
|
|
|
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
|
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
|
|
|
|
{
|
|
|
|
if (qlevels > 2)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
// 16x, 16xQ are available
|
|
|
|
// See http://developer.nvidia.com/object/coverage-sampled-aa.html
|
|
|
|
a.aa_levels.push_back(AALevel("16x CSAA", D3DMULTISAMPLE_4_SAMPLES, 4));
|
|
|
|
a.aa_levels.push_back(AALevel("16xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 2));
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
2009-09-16 20:12:14 +00:00
|
|
|
|
|
|
|
// Determine if INTZ is supported. Code from ATI's doc.
|
|
|
|
// http://developer.amd.com/gpu_assets/Advanced%20DX9%20Capabilities%20for%20ATI%20Radeon%20Cards.pdf
|
|
|
|
a.supports_intz = D3D_OK == D3D->CheckDeviceFormat(
|
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
|
|
|
|
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ);
|
|
|
|
// Also check for RAWZ (nvidia only, but the only option to get Z24 textures on sub GF8800
|
|
|
|
a.supports_rawz = D3D_OK == D3D->CheckDeviceFormat(
|
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
|
|
|
|
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_RAWZ);
|
|
|
|
// Might as well check for RESZ and NULL too.
|
|
|
|
a.supports_resz = D3D_OK == D3D->CheckDeviceFormat(
|
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
|
|
|
|
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_RESZ);
|
2009-09-28 16:39:29 +00:00
|
|
|
a.supports_null = D3D_OK == D3D->CheckDeviceFormat(
|
2009-09-16 20:12:14 +00:00
|
|
|
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
|
|
|
|
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_NULL);
|
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
if (a.aa_levels.size() == 1)
|
|
|
|
{
|
|
|
|
strcpy(a.aa_levels[0].name, "(Not supported on this device)");
|
|
|
|
}
|
|
|
|
int numModes = D3D::D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8);
|
|
|
|
for (int m = 0; m < numModes; m++)
|
|
|
|
{
|
|
|
|
D3DDISPLAYMODE mode;
|
|
|
|
D3D::D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode);
|
|
|
|
|
|
|
|
int found = -1;
|
|
|
|
for (int x = 0; x < (int)a.resolutions.size(); x++)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
if (a.resolutions[x].xres == mode.Width && a.resolutions[x].yres == mode.Height)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
found = x;
|
|
|
|
break;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
Resolution temp;
|
|
|
|
Resolution &r = found==-1 ? temp : a.resolutions[found];
|
|
|
|
|
|
|
|
sprintf(r.name, "%ix%i", mode.Width, mode.Height);
|
|
|
|
r.bitdepths.insert(mode.Format);
|
|
|
|
r.refreshes.insert(mode.RefreshRate);
|
|
|
|
if (found == -1 && mode.Width >= 640 && mode.Height >= 480)
|
|
|
|
{
|
|
|
|
r.xres = mode.Width;
|
|
|
|
r.yres = mode.Height;
|
|
|
|
a.resolutions.push_back(r);
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
HRESULT Create(int adapter, HWND wnd, bool _fullscreen, int _resolution, int aa_mode, bool auto_depth)
|
|
|
|
{
|
|
|
|
hWnd = wnd;
|
|
|
|
fullScreen = _fullscreen;
|
|
|
|
nextFullScreen = _fullscreen;
|
|
|
|
multisample = aa_mode;
|
|
|
|
resolution = _resolution;
|
|
|
|
auto_depth_stencil = auto_depth;
|
|
|
|
cur_adapter = adapter;
|
|
|
|
D3DPRESENT_PARAMETERS d3dpp;
|
|
|
|
InitPP(adapter, resolution, aa_mode, &d3dpp);
|
|
|
|
|
|
|
|
if (FAILED(D3D->CreateDevice(
|
|
|
|
adapter,
|
|
|
|
D3DDEVTYPE_HAL,
|
|
|
|
wnd,
|
2009-09-19 10:46:25 +00:00
|
|
|
D3DCREATE_HARDWARE_VERTEXPROCESSING, // | D3DCREATE_PUREDEVICE, doesn't seem to make a difference
|
2009-09-15 21:25:34 +00:00
|
|
|
&d3dpp, &dev)))
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-13 08:21:35 +00:00
|
|
|
if (FAILED(D3D->CreateDevice(
|
2008-12-08 05:25:12 +00:00
|
|
|
adapter,
|
|
|
|
D3DDEVTYPE_HAL,
|
|
|
|
wnd,
|
2009-09-19 10:46:25 +00:00
|
|
|
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
|
2009-09-13 08:21:35 +00:00
|
|
|
&d3dpp, &dev)))
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 08:13:45 +00:00
|
|
|
MessageBox(wnd,
|
2009-09-19 10:46:25 +00:00
|
|
|
_T("Failed to initialize Direct3D."),
|
2009-09-15 08:13:45 +00:00
|
|
|
_T("Dolphin Direct3D plugin"), MB_OK | MB_ICONERROR);
|
2009-09-15 21:25:34 +00:00
|
|
|
return E_FAIL;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
|
|
|
}
|
2009-09-16 20:12:14 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
dev->GetDeviceCaps(&caps);
|
|
|
|
dev->GetRenderTarget(0, &back_buffer);
|
|
|
|
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
|
|
|
|
back_buffer_z = NULL;
|
2009-09-29 19:15:34 +00:00
|
|
|
dev->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE );
|
2009-10-30 11:03:50 +00:00
|
|
|
|
|
|
|
dev->SetRenderState(D3DRS_FILLMODE, g_Config.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
// Device state would normally be set here
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Close()
|
|
|
|
{
|
|
|
|
dev->Release();
|
|
|
|
dev = 0;
|
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
const D3DCAPS9 &GetCaps()
|
|
|
|
{
|
|
|
|
return caps;
|
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
const char *VertexShaderVersionString()
|
|
|
|
{
|
|
|
|
static const char *versions[5] = {"ERROR", "vs_1_4", "vs_2_0", "vs_3_0", "vs_4_0"};
|
|
|
|
int version = ((D3D::caps.VertexShaderVersion >> 8) & 0xFF);
|
|
|
|
return versions[std::min(4, version)];
|
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
const char *PixelShaderVersionString()
|
|
|
|
{
|
|
|
|
static const char *versions[5] = {"ERROR", "ps_1_4", "ps_2_0", "ps_3_0", "ps_4_0"};
|
|
|
|
int version = ((D3D::caps.PixelShaderVersion >> 8) & 0xFF);
|
|
|
|
return versions[std::min(4, version)];
|
|
|
|
}
|
|
|
|
|
|
|
|
LPDIRECT3DSURFACE9 GetBackBufferSurface()
|
|
|
|
{
|
2009-09-13 17:46:33 +00:00
|
|
|
return back_buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
LPDIRECT3DSURFACE9 GetBackBufferDepthSurface()
|
|
|
|
{
|
|
|
|
return back_buffer_z;
|
2009-09-13 08:21:35 +00:00
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-13 08:21:35 +00:00
|
|
|
void ShowD3DError(HRESULT err)
|
|
|
|
{
|
|
|
|
switch (err)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-13 08:21:35 +00:00
|
|
|
case D3DERR_DEVICELOST: PanicAlert("Device Lost"); break;
|
|
|
|
case D3DERR_INVALIDCALL: PanicAlert("Invalid Call"); break;
|
|
|
|
case D3DERR_DRIVERINTERNALERROR: PanicAlert("Driver Internal Error"); break;
|
|
|
|
case D3DERR_OUTOFVIDEOMEMORY: PanicAlert("Out of vid mem"); break;
|
|
|
|
default:
|
|
|
|
// MessageBoxA(0,"Other error or success","ERROR",0);
|
|
|
|
break;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-13 08:21:35 +00:00
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
void Reset()
|
|
|
|
{
|
|
|
|
if (dev)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-16 20:12:14 +00:00
|
|
|
// ForgetCachedState();
|
2009-09-15 19:53:22 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
// Can't keep a pointer around to the backbuffer surface when resetting.
|
|
|
|
if (back_buffer_z)
|
|
|
|
back_buffer_z->Release();
|
|
|
|
back_buffer_z = NULL;
|
|
|
|
back_buffer->Release();
|
|
|
|
back_buffer = NULL;
|
2009-09-15 19:53:22 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
D3DPRESENT_PARAMETERS d3dpp;
|
|
|
|
InitPP(cur_adapter, resolution, multisample, &d3dpp);
|
|
|
|
HRESULT hr = dev->Reset(&d3dpp);
|
|
|
|
ShowD3DError(hr);
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
dev->GetRenderTarget(0, &back_buffer);
|
|
|
|
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
|
|
|
|
back_buffer_z = NULL;
|
2009-09-16 20:12:14 +00:00
|
|
|
ApplyCachedState();
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool IsFullscreen()
|
|
|
|
{
|
|
|
|
return fullScreen;
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetBackBufferWidth()
|
|
|
|
{
|
|
|
|
return xres;
|
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
int GetBackBufferHeight()
|
|
|
|
{
|
|
|
|
return yres;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwitchFullscreen(bool fullscreen)
|
|
|
|
{
|
|
|
|
nextFullScreen = fullscreen;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool BeginFrame()
|
|
|
|
{
|
|
|
|
if (bFrameInProgress)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
PanicAlert("BeginFrame WTF");
|
|
|
|
return false;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
bFrameInProgress = true;
|
|
|
|
if (dev)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
dev->BeginScene();
|
|
|
|
return true;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
2008-12-26 17:02:46 +00:00
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
void EndFrame()
|
|
|
|
{
|
|
|
|
if (!bFrameInProgress)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
PanicAlert("EndFrame WTF");
|
|
|
|
return;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
bFrameInProgress = false;
|
2009-09-20 05:04:45 +00:00
|
|
|
dev->EndScene();
|
2009-09-20 03:29:43 +00:00
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-20 03:29:43 +00:00
|
|
|
void Present()
|
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
if (dev)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
dev->Present(NULL, NULL, NULL, NULL);
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
|
|
|
|
2009-09-15 21:25:34 +00:00
|
|
|
if (fullScreen != nextFullScreen)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-09-15 21:25:34 +00:00
|
|
|
fullScreen = nextFullScreen;
|
|
|
|
Reset();
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
|
|
|
|
2009-09-16 20:12:14 +00:00
|
|
|
void ApplyCachedState()
|
2009-09-15 21:25:34 +00:00
|
|
|
{
|
2009-09-16 20:12:14 +00:00
|
|
|
for (int sampler = 0; sampler < 8; sampler++)
|
|
|
|
{
|
|
|
|
for (int type = 0; type < MaxSamplerTypes; type++)
|
|
|
|
{
|
|
|
|
D3D::dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int rs = 0; rs < MaxRenderStates; rs++)
|
|
|
|
{
|
|
|
|
if (m_RenderStatesSet[rs])
|
|
|
|
D3D::dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't bother restoring these so let's just wipe the state copy
|
|
|
|
// so no stale state is around.
|
2009-09-15 21:25:34 +00:00
|
|
|
memset(m_Textures, 0, sizeof(m_Textures));
|
|
|
|
memset(m_TextureStageStates, 0xFF, sizeof(m_TextureStageStates));
|
2009-09-19 10:46:25 +00:00
|
|
|
m_VtxDecl = NULL;
|
2009-09-15 21:25:34 +00:00
|
|
|
}
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-09-03 19:24:16 +00:00
|
|
|
void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
|
|
|
|
{
|
|
|
|
if (m_Textures[Stage] != pTexture)
|
|
|
|
{
|
|
|
|
m_Textures[Stage] = pTexture;
|
|
|
|
D3D::dev->SetTexture(Stage, pTexture);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-15 01:40:54 +00:00
|
|
|
void RefreshRenderState(D3DRENDERSTATETYPE State)
|
|
|
|
{
|
|
|
|
D3D::dev->SetRenderState(State, m_RenderStates[State]);
|
|
|
|
}
|
|
|
|
|
2009-09-03 19:24:16 +00:00
|
|
|
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
|
|
|
|
{
|
|
|
|
if (m_RenderStates[State] != Value)
|
|
|
|
{
|
|
|
|
m_RenderStates[State] = Value;
|
2009-09-16 20:12:14 +00:00
|
|
|
m_RenderStatesSet[State] = true;
|
2009-09-03 19:24:16 +00:00
|
|
|
D3D::dev->SetRenderState(State, Value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
|
|
|
|
{
|
|
|
|
if (m_TextureStageStates[Stage][Type] != Value)
|
|
|
|
{
|
|
|
|
m_TextureStageStates[Stage][Type] = Value;
|
|
|
|
D3D::dev->SetTextureStageState(Stage, Type, Value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-22 02:37:00 +00:00
|
|
|
void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type)
|
|
|
|
{
|
|
|
|
D3D::dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]);
|
|
|
|
}
|
|
|
|
|
2009-09-03 19:24:16 +00:00
|
|
|
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
|
|
|
|
{
|
|
|
|
if (m_SamplerStates[Sampler][Type] != Value)
|
|
|
|
{
|
|
|
|
m_SamplerStates[Sampler][Type] = Value;
|
|
|
|
D3D::dev->SetSamplerState(Sampler, Type, Value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
void RefreshVertexDeclaration()
|
|
|
|
{
|
|
|
|
if (m_VtxDecl)
|
|
|
|
{
|
|
|
|
D3D::dev->SetVertexDeclaration(m_VtxDecl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-19 10:46:25 +00:00
|
|
|
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl)
|
|
|
|
{
|
|
|
|
if (!decl) {
|
|
|
|
m_VtxDecl = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (decl != m_VtxDecl)
|
|
|
|
{
|
|
|
|
D3D::dev->SetVertexDeclaration(decl);
|
|
|
|
m_VtxDecl = decl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-26 17:02:46 +00:00
|
|
|
} // namespace
|