Mercurial > vba-clojure
diff src/win32/Direct3D.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/Direct3D.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,752 @@ 1.4 +#include "stdafx.h" 1.5 + 1.6 +#define DIRECT3D_VERSION 0x0800 1.7 +#include "d3d8.h" 1.8 +#include "d3dx8.h" 1.9 + 1.10 +#include "resource.h" 1.11 +#include "MainWnd.h" 1.12 +#include "Reg.h" 1.13 +#include "VBA.h" 1.14 + 1.15 +//#include "../common/System.h" 1.16 +#include "../gba/GBAGlobals.h" 1.17 +#include "../gb/gbGlobals.h" 1.18 +#include "../common/Text.h" 1.19 +#include "../version.h" 1.20 + 1.21 +#ifdef MMX 1.22 +extern "C" bool cpu_mmx; 1.23 + 1.24 +extern bool detectMMX(); 1.25 +#endif 1.26 + 1.27 +extern int Init_2xSaI(u32); 1.28 +extern void directXMessage(const char *); 1.29 +extern void winlog(const char *, ...); 1.30 + 1.31 +typedef struct _D3DTLVERTEX 1.32 +{ 1.33 + float sx; /* Screen coordinates */ 1.34 + float sy; 1.35 + float sz; 1.36 + float rhw; /* Reciprocal of homogeneous w */ 1.37 + D3DCOLOR color; /* Vertex color */ 1.38 + float tu; /* Texture coordinates */ 1.39 + float tv; 1.40 + _D3DTLVERTEX() { } 1.41 + _D3DTLVERTEX(const D3DVECTOR& v, float _rhw, 1.42 + D3DCOLOR _color, 1.43 + float _tu, float _tv) 1.44 + { 1.45 + sx = v.x; sy = v.y; sz = v.z; rhw = _rhw; 1.46 + color = _color; 1.47 + tu = _tu; tv = _tv; 1.48 + } 1.49 +} D3DTLVERTEX, *LPD3DTLVERTEX; 1.50 + 1.51 +#define D3DFVF_TLVERTEX D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1 1.52 + 1.53 +class Direct3DDisplay : public IDisplay 1.54 +{ 1.55 +public: 1.56 + Direct3DDisplay(); 1.57 + virtual ~Direct3DDisplay(); 1.58 + 1.59 + virtual bool initialize(); 1.60 + virtual void cleanup(); 1.61 + virtual void render(); 1.62 + virtual void checkFullScreen(); 1.63 + virtual void renderMenu(); 1.64 + virtual void clear(); 1.65 + virtual bool changeRenderSize(int w, int h); 1.66 + virtual void resize(int w, int h); 1.67 + virtual DISPLAY_TYPE getType() { return DIRECT_3D; }; 1.68 + virtual void setOption(const char *, int); 1.69 + virtual int selectFullScreenMode(GUID * *); 1.70 + 1.71 +private: 1.72 + HINSTANCE d3dDLL; 1.73 + LPDIRECT3D8 pD3D; 1.74 + LPDIRECT3DDEVICE8 pDevice; 1.75 + LPDIRECT3DTEXTURE8 pTexture; 1.76 + D3DSURFACE_DESC dsdBackBuffer; 1.77 + D3DPRESENT_PARAMETERS dpp; 1.78 + D3DFORMAT screenFormat; 1.79 + int width; 1.80 + int height; 1.81 + bool filterDisabled; 1.82 + ID3DXFont *pFont; 1.83 + bool failed; 1.84 + unsigned int textureSize; 1.85 + D3DTLVERTEX verts[4]; 1.86 + 1.87 + 1.88 + void restoreDeviceObjects(); 1.89 + void invalidateDeviceObjects(); 1.90 + bool initializeOffscreen(int w, int h); 1.91 + void updateFiltering(int); 1.92 + void calculateVertices(); 1.93 +}; 1.94 + 1.95 +Direct3DDisplay::Direct3DDisplay() 1.96 +{ 1.97 + d3dDLL = NULL; 1.98 + pD3D = NULL; 1.99 + pDevice = NULL; 1.100 + pTexture = NULL; 1.101 + pFont = NULL; 1.102 + screenFormat = D3DFMT_R5G6B5; 1.103 + width = 0; 1.104 + height = 0; 1.105 + filterDisabled = false; 1.106 + failed = false; 1.107 + textureSize = 0; 1.108 +} 1.109 + 1.110 +Direct3DDisplay::~Direct3DDisplay() 1.111 +{ 1.112 + cleanup(); 1.113 +} 1.114 + 1.115 +void Direct3DDisplay::cleanup() 1.116 +{ 1.117 + if (pD3D != NULL) 1.118 + { 1.119 + if (pFont) 1.120 + { 1.121 + pFont->Release(); 1.122 + pFont = NULL; 1.123 + } 1.124 + 1.125 + if (pTexture) 1.126 + { 1.127 + pTexture->Release(); 1.128 + pTexture = NULL; 1.129 + } 1.130 + 1.131 + if (pDevice) 1.132 + { 1.133 + pDevice->Release(); 1.134 + pDevice = NULL; 1.135 + } 1.136 + 1.137 + pD3D->Release(); 1.138 + pD3D = NULL; 1.139 + 1.140 + if (d3dDLL != NULL) 1.141 + { 1.142 + FreeLibrary(d3dDLL); 1.143 + d3dDLL = NULL; 1.144 + } 1.145 + } 1.146 +} 1.147 + 1.148 +bool Direct3DDisplay::initialize() 1.149 +{ 1.150 + CWnd *pWnd = theApp.m_pMainWnd; 1.151 + 1.152 + d3dDLL = LoadLibrary("D3D8.DLL"); 1.153 + LPDIRECT3D8 (WINAPI *D3DCreate)(UINT); 1.154 + if (d3dDLL != NULL) 1.155 + { 1.156 + D3DCreate = (LPDIRECT3D8 (WINAPI *)(UINT)) 1.157 + GetProcAddress(d3dDLL, "Direct3DCreate8"); 1.158 + 1.159 + if (D3DCreate == NULL) 1.160 + { 1.161 + directXMessage("Direct3DCreate8"); 1.162 + return FALSE; 1.163 + } 1.164 + } 1.165 + else 1.166 + { 1.167 + directXMessage("D3D8.DLL"); 1.168 + return FALSE; 1.169 + } 1.170 + 1.171 + pD3D = D3DCreate(120); 1.172 + 1.173 + if (pD3D == NULL) 1.174 + { 1.175 + winlog("Error creating Direct3D object\n"); 1.176 + return FALSE; 1.177 + } 1.178 + 1.179 + theApp.mode320Available = false; 1.180 + theApp.mode640Available = false; 1.181 + theApp.mode800Available = false; 1.182 + 1.183 + D3DDISPLAYMODE mode; 1.184 + pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode); 1.185 + 1.186 + switch (mode.Format) 1.187 + { 1.188 + case D3DFMT_R8G8B8: 1.189 + systemColorDepth = 24; 1.190 + systemRedShift = 19; 1.191 + systemGreenShift = 11; 1.192 + systemBlueShift = 3; 1.193 + break; 1.194 + case D3DFMT_X8R8G8B8: 1.195 + systemColorDepth = 32; 1.196 + systemRedShift = 19; 1.197 + systemGreenShift = 11; 1.198 + systemBlueShift = 3; 1.199 + Init_2xSaI(32); 1.200 + break; 1.201 + case D3DFMT_R5G6B5: 1.202 + systemColorDepth = 16; 1.203 + systemRedShift = 11; 1.204 + systemGreenShift = 6; 1.205 + systemBlueShift = 0; 1.206 + Init_2xSaI(565); 1.207 + break; 1.208 + case D3DFMT_X1R5G5B5: 1.209 + systemColorDepth = 16; 1.210 + systemRedShift = 10; 1.211 + systemGreenShift = 5; 1.212 + systemBlueShift = 0; 1.213 + Init_2xSaI(555); 1.214 + break; 1.215 + default: 1.216 + systemMessage(0, "Unsupport D3D format %d", mode.Format); 1.217 + return false; 1.218 + } 1.219 + theApp.fsColorDepth = systemColorDepth; 1.220 + 1.221 +#ifdef MMX 1.222 + if (!theApp.disableMMX) 1.223 + cpu_mmx = theApp.detectMMX(); 1.224 + else 1.225 + cpu_mmx = 0; 1.226 +#endif 1.227 + 1.228 + screenFormat = mode.Format; 1.229 + 1.230 + // check for available fullscreen modes 1.231 + ZeroMemory(&dpp, sizeof(dpp)); 1.232 + dpp.Windowed = TRUE; 1.233 + dpp.BackBufferFormat = mode.Format; 1.234 + dpp.BackBufferCount = 1; 1.235 + dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 1.236 + dpp.BackBufferWidth = theApp.surfaceSizeX; 1.237 + dpp.BackBufferHeight = theApp.surfaceSizeY; 1.238 + 1.239 + HRESULT hret = pD3D->CreateDevice(D3DADAPTER_DEFAULT, 1.240 + D3DDEVTYPE_HAL, 1.241 + pWnd->GetSafeHwnd(), 1.242 + D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, 1.243 + &dpp, 1.244 + &pDevice); 1.245 + if (!SUCCEEDED(hret)) 1.246 + { 1.247 + winlog("Error creating Direct3DDevice %08x\n", hret); 1.248 + return false; 1.249 + } 1.250 + 1.251 + restoreDeviceObjects(); 1.252 + 1.253 + switch (systemColorDepth) 1.254 + { 1.255 + case 16: 1.256 + { 1.257 + for (int i = 0; i < 0x10000; i++) 1.258 + { 1.259 + systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | 1.260 + (((i & 0x3e0) >> 5) << systemGreenShift) | 1.261 + (((i & 0x7c00) >> 10) << systemBlueShift); 1.262 + } 1.263 + break; 1.264 + } 1.265 + case 24: 1.266 + case 32: 1.267 + { 1.268 + for (int i = 0; i < 0x10000; i++) 1.269 + { 1.270 + systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | 1.271 + (((i & 0x3e0) >> 5) << systemGreenShift) | 1.272 + (((i & 0x7c00) >> 10) << systemBlueShift); 1.273 + } 1.274 + break; 1.275 + } 1.276 + } 1.277 + 1.278 + theApp.updateFilter(); 1.279 + theApp.updateIFB(); 1.280 + 1.281 + if (failed) 1.282 + return false; 1.283 + 1.284 + pWnd->DragAcceptFiles(TRUE); 1.285 + 1.286 + return TRUE; 1.287 +} 1.288 + 1.289 +bool Direct3DDisplay::initializeOffscreen(int w, int h) 1.290 +{ 1.291 + int size = 256; 1.292 + if (w > 512 || h > 512) 1.293 + size = 1024; 1.294 + else if (w > 256 || h > 256) 1.295 + size = 512; 1.296 + textureSize = size; 1.297 + 1.298 + UINT ww = size; 1.299 + UINT hh = size; 1.300 + D3DFORMAT format = screenFormat; 1.301 + 1.302 + if (SUCCEEDED(D3DXCheckTextureRequirements(pDevice, 1.303 + &ww, 1.304 + &hh, 1.305 + NULL, 1.306 + 0, 1.307 + &format, 1.308 + D3DPOOL_MANAGED))) 1.309 + { 1.310 + if ((int)ww < w || (int)hh < h) 1.311 + { 1.312 + if (theApp.filterFunction) 1.313 + { 1.314 + filterDisabled = true; 1.315 + theApp.filterFunction = NULL; 1.316 + systemMessage(0, "3D card cannot support needed texture size for filter function. Disabling it"); 1.317 + } 1.318 + } 1.319 + else 1.320 + filterDisabled = false; 1.321 + if (SUCCEEDED(D3DXCreateTexture(pDevice, 1.322 + ww, 1.323 + hh, 1.324 + 0, 1.325 + 0, 1.326 + format, 1.327 + D3DPOOL_MANAGED, 1.328 + &pTexture))) 1.329 + { 1.330 + width = w; 1.331 + height = h; 1.332 + return true; 1.333 + } 1.334 + } 1.335 + return false; 1.336 +} 1.337 + 1.338 +void Direct3DDisplay::updateFiltering(int filter) 1.339 +{ 1.340 + switch (filter) 1.341 + { 1.342 + default: 1.343 + case 0: 1.344 + // point filtering 1.345 + pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); 1.346 + pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); 1.347 + pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); 1.348 + break; 1.349 + case 1: 1.350 + // bilinear 1.351 + pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); 1.352 + pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); 1.353 + pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); 1.354 + break; 1.355 + } 1.356 +} 1.357 + 1.358 +void Direct3DDisplay::restoreDeviceObjects() 1.359 +{ 1.360 + // Store render target surface desc 1.361 + LPDIRECT3DSURFACE8 pBackBuffer; 1.362 + HRESULT hr; 1.363 + if (SUCCEEDED(hr = pDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer))) 1.364 + { 1.365 + pBackBuffer->GetDesc(&dsdBackBuffer); 1.366 + pBackBuffer->Release(); 1.367 + } 1.368 + else 1.369 + systemMessage(0, "Failed GetBackBuffer %08x", hr); 1.370 + 1.371 + // Set up the texture 1.372 + pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); 1.373 + pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 1.374 + pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); 1.375 + 1.376 + int filter = regQueryDwordValue("d3dFilter", 0); 1.377 + if (filter < 0 || filter > 3) 1.378 + filter = 0; 1.379 + updateFiltering(filter); 1.380 + 1.381 + // Set miscellaneous render states 1.382 + pDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE); 1.383 + pDevice->SetRenderState(D3DRS_ZENABLE, FALSE); 1.384 + 1.385 + // Set the projection matrix 1.386 + D3DXMATRIX matProj; 1.387 + FLOAT fAspect = ((FLOAT)dsdBackBuffer.Width) / dsdBackBuffer.Height; 1.388 + D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f); 1.389 + pDevice->SetTransform(D3DTS_PROJECTION, &matProj); 1.390 + 1.391 + // turn off lighting 1.392 + pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); 1.393 + 1.394 + if (pFont) 1.395 + { 1.396 + pFont->Release(); 1.397 + pFont = NULL; 1.398 + } 1.399 + // Create a D3D font using D3DX 1.400 + HFONT hFont = CreateFont(14, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, 1.401 + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 1.402 + ANTIALIASED_QUALITY, FF_DONTCARE, "Arial"); 1.403 + D3DXCreateFont(pDevice, hFont, &pFont); 1.404 +} 1.405 + 1.406 +void Direct3DDisplay::clear() 1.407 +{} 1.408 + 1.409 +void Direct3DDisplay::renderMenu() 1.410 +{ 1.411 + checkFullScreen(); 1.412 + if (theApp.m_pMainWnd) 1.413 + theApp.m_pMainWnd->DrawMenuBar(); 1.414 +} 1.415 + 1.416 +void Direct3DDisplay::checkFullScreen() 1.417 +{ 1.418 + // if(tripleBuffering) 1.419 + // pDirect3D->FlipToGDISurface(); 1.420 +} 1.421 + 1.422 +void Direct3DDisplay::calculateVertices() 1.423 +{ 1.424 + // color 1.425 + D3DCOLOR col = 0xFFFFFFFF; 1.426 + 1.427 + // calculate rhw 1.428 + FLOAT z = 1.0f; 1.429 + FLOAT rhw = 1.0f / (z * 990.0f + 10.0f); 1.430 + 1.431 + // -0.5f is necessary in order to match texture alignment to display pixels 1.432 + FLOAT left = -0.5f; 1.433 + FLOAT right = dpp.BackBufferWidth - 0.5f; 1.434 + FLOAT top = -0.5f; 1.435 + FLOAT bottom = dpp.BackBufferHeight - 0.5f; 1.436 + 1.437 + FLOAT textureX = (FLOAT)theApp.rect.right / (FLOAT)textureSize; 1.438 + FLOAT textureY = (FLOAT)theApp.rect.bottom / (FLOAT)textureSize; 1.439 + 1.440 +//#define D3D_DRAW_SINGLE_RECTANGLE 1.441 +#ifdef D3D_DRAW_SINGLE_RECTANGLE 1.442 + // set up a rectangle 1.443 + verts[0] = D3DTLVERTEX(D3DXVECTOR3(left, top, z), rhw, col, 0.0f, 0.0f); 1.444 + verts[1] = D3DTLVERTEX(D3DXVECTOR3(right, top, z), rhw, col, textureX, 0.0f); 1.445 + verts[2] = D3DTLVERTEX(D3DXVECTOR3(right, bottom, z), rhw, col, textureX, textureY); 1.446 + verts[3] = D3DTLVERTEX(D3DXVECTOR3(left, bottom, z), rhw, col, 0.0f, textureY); 1.447 +#else 1.448 + // set up triangles 1.449 + verts[0] = D3DTLVERTEX(D3DXVECTOR3(left, bottom, z), rhw, col, 0.0f, textureY); 1.450 + verts[1] = D3DTLVERTEX(D3DXVECTOR3(left, top, z), rhw, col, 0.0f, 0.0f); 1.451 + verts[2] = D3DTLVERTEX(D3DXVECTOR3(right, bottom, z), rhw, col, textureX, textureY); 1.452 + verts[3] = D3DTLVERTEX(D3DXVECTOR3(right, top, z), rhw, col, textureX, 0.0f); 1.453 +#endif 1.454 +} 1.455 + 1.456 +void Direct3DDisplay::render() 1.457 +{ 1.458 + if (!pDevice) 1.459 + return; 1.460 + 1.461 + // Test the cooperative level to see if it's okay to render 1.462 + if (FAILED(pDevice->TestCooperativeLevel())) 1.463 + { 1.464 + return; 1.465 + } 1.466 + pDevice->Clear(0L, NULL, D3DCLEAR_TARGET, 0x000000ff, 1.0f, 0L); 1.467 + 1.468 + if (SUCCEEDED(pDevice->BeginScene())) 1.469 + { 1.470 + D3DLOCKED_RECT locked; 1.471 + if (pTexture && SUCCEEDED(pTexture->LockRect(0, &locked, NULL, 0))) 1.472 + { 1.473 + if (theApp.filterFunction) 1.474 + { 1.475 + if (systemColorDepth == 16) 1.476 + theApp.filterFunction(pix + theApp.filterWidth * 2 + 4, 1.477 + theApp.filterWidth*2 + 4, 1.478 + (u8 *)theApp.delta, 1.479 + (u8 *)locked.pBits, 1.480 + locked.Pitch, 1.481 + theApp.filterWidth, 1.482 + theApp.filterHeight); 1.483 + else 1.484 + theApp.filterFunction(pix + theApp.filterWidth * 4 + 4, 1.485 + theApp.filterWidth * 4 + 4, 1.486 + (u8 *)theApp.delta, 1.487 + (u8 *)locked.pBits, 1.488 + locked.Pitch, 1.489 + theApp.filterWidth, 1.490 + theApp.filterHeight); 1.491 + } 1.492 + else 1.493 + { 1.494 + int copyX = 240; 1.495 + int copyY = 160; 1.496 + 1.497 + if (systemCartridgeType == 1) 1.498 + { 1.499 + if (gbBorderOn) 1.500 + { 1.501 + copyX = 256; 1.502 + copyY = 224; 1.503 + } 1.504 + else 1.505 + { 1.506 + copyX = 160; 1.507 + copyY = 144; 1.508 + } 1.509 + } 1.510 + // MMX doesn't seem to be faster to copy the data 1.511 + __asm { 1.512 + mov eax, copyX; 1.513 + mov ebx, copyY; 1.514 + 1.515 + mov esi, pix; 1.516 + mov edi, locked.pBits; 1.517 + mov edx, locked.Pitch; 1.518 + cmp systemColorDepth, 16; 1.519 + jnz gbaOtherColor; 1.520 + sub edx, eax; 1.521 + sub edx, eax; 1.522 + lea esi, [esi+2*eax+4]; 1.523 + shr eax, 1; 1.524 +gbaLoop16bit: 1.525 + mov ecx, eax; 1.526 + repz movsd; 1.527 + inc esi; 1.528 + inc esi; 1.529 + inc esi; 1.530 + inc esi; 1.531 + add edi, edx; 1.532 + dec ebx; 1.533 + jnz gbaLoop16bit; 1.534 + jmp gbaLoopEnd; 1.535 +gbaOtherColor: 1.536 + cmp systemColorDepth, 32; 1.537 + jnz gbaOtherColor2; 1.538 + 1.539 + sub edx, eax; 1.540 + sub edx, eax; 1.541 + sub edx, eax; 1.542 + sub edx, eax; 1.543 + lea esi, [esi+4*eax+4]; 1.544 +gbaLoop32bit: 1.545 + mov ecx, eax; 1.546 + repz movsd; 1.547 + add esi, 4; 1.548 + add edi, edx; 1.549 + dec ebx; 1.550 + jnz gbaLoop32bit; 1.551 + jmp gbaLoopEnd; 1.552 +gbaOtherColor2: 1.553 + lea eax, [eax+2*eax]; 1.554 + sub edx, eax; 1.555 +gbaLoop24bit: 1.556 + mov ecx, eax; 1.557 + shr ecx, 2; 1.558 + repz movsd; 1.559 + add edi, edx; 1.560 + dec ebx; 1.561 + jnz gbaLoop24bit; 1.562 +gbaLoopEnd: 1.563 + } 1.564 + } 1.565 + 1.566 + if (theApp.videoOption > VIDEO_4X && theApp.showSpeed) 1.567 + { 1.568 + char buffer[30]; 1.569 + if (theApp.showSpeed == 1) 1.570 + sprintf(buffer, "%3d%%", systemSpeed); 1.571 + else 1.572 + sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed, 1.573 + systemFrameSkip, 1.574 + theApp.showRenderedFrames); 1.575 + if (theApp.showSpeedTransparent) 1.576 + drawTextTransp((u8 *)locked.pBits, 1.577 + locked.Pitch, 1.578 + theApp.rect.left+10, 1.579 + theApp.rect.bottom-10, 1.580 + buffer); 1.581 + else 1.582 + drawText((u8 *)locked.pBits, 1.583 + locked.Pitch, 1.584 + theApp.rect.left+10, 1.585 + theApp.rect.bottom-10, 1.586 + buffer); 1.587 + } 1.588 + 1.589 + if (textMethod == 1) 1.590 + { 1.591 + DrawTextMessages((u8 *)locked.pBits, locked.Pitch, theApp.rect.left, theApp.rect.bottom); 1.592 + } 1.593 + 1.594 + pTexture->UnlockRect(0); 1.595 + 1.596 + // set the texture 1.597 + pDevice->SetTexture(0, pTexture); 1.598 + 1.599 + // configure shader for vertex type 1.600 + pDevice->SetVertexShader(D3DFVF_TLVERTEX); 1.601 + 1.602 +#ifdef D3D_DRAW_SINGLE_RECTANGLE 1.603 + // draw the rectangle 1.604 + pDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(D3DTLVERTEX)); 1.605 + //#undef D3D_DRAW_RECT 1.606 +#else 1.607 + // draw the triangles 1.608 + pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(D3DTLVERTEX)); 1.609 +#endif 1.610 + } 1.611 + 1.612 + if (textMethod == 2) 1.613 + { 1.614 + for (int slot = 0; slot < SCREEN_MESSAGE_SLOTS; slot++) 1.615 + { 1.616 + if (theApp.screenMessage[slot]) 1.617 + { 1.618 + if ((theApp.screenMessageDuration[slot] < 0 || 1.619 + (int)(GetTickCount() - theApp.screenMessageTime[slot]) < theApp.screenMessageDuration[slot]) && 1.620 + (!theApp.disableStatusMessage || slot == 1 || slot == 2) && pFont) 1.621 + { 1.622 + pFont->Begin(); 1.623 + RECT r; 1.624 + D3DCOLOR color; 1.625 + 1.626 + r.left = 10; 1.627 + r.top = dpp.BackBufferHeight - 20*(slot+1); 1.628 + r.right = dpp.BackBufferWidth - 10; 1.629 + r.bottom = r.top + 20; 1.630 + 1.631 + if (outlinedText) 1.632 + { 1.633 + color = textColor != 7 ? D3DCOLOR_ARGB(255, 0, 0, 0) : D3DCOLOR_ARGB(255, 255, 255, 255); 1.634 + 1.635 + // draw outline 1.636 + const static int xd [8] = {-1, 0, 1, 1, 1, 0, -1, -1}; 1.637 + const static int yd [8] = {-1, -1, -1, 0, 1, 1, 1, 0}; 1.638 + for (int i = 0; i < 8; i++) 1.639 + { 1.640 + RECT r2 = r; 1.641 + r2.left += xd[i]; r2.right += xd[i]; 1.642 + r2.top += yd[i]; r2.bottom += yd[i]; 1.643 + 1.644 + pFont->DrawText(theApp.screenMessageBuffer[slot], -1, &r2, 0, color); 1.645 + } 1.646 + } 1.647 + 1.648 + // draw center text 1.649 + switch (textColor) 1.650 + { 1.651 + case 0: 1.652 + color = D3DCOLOR_ARGB(255, 255, 255, 255); break; 1.653 + case 1: 1.654 + color = D3DCOLOR_ARGB(255, 255, 0, 0); break; 1.655 + case 2: 1.656 + color = D3DCOLOR_ARGB(255, 255, 255, 0); break; 1.657 + case 3: 1.658 + color = D3DCOLOR_ARGB(255, 0, 255, 0); break; 1.659 + case 4: 1.660 + color = D3DCOLOR_ARGB(255, 0, 255, 255); break; 1.661 + case 5: 1.662 + color = D3DCOLOR_ARGB(255, 0, 0, 255); break; 1.663 + case 6: 1.664 + color = D3DCOLOR_ARGB(255, 255, 0, 255); break; 1.665 + case 7: 1.666 + color = D3DCOLOR_ARGB(255, 0, 0, 0); break; 1.667 + } 1.668 + pFont->DrawText(theApp.screenMessageBuffer[slot], -1, &r, 0, color); 1.669 + 1.670 + pFont->End(); 1.671 + } 1.672 + else 1.673 + { 1.674 + theApp.screenMessage[slot] = false; 1.675 + } 1.676 + } 1.677 + } 1.678 + } 1.679 + 1.680 + pDevice->EndScene(); 1.681 + 1.682 + pDevice->Present(NULL, NULL, NULL, NULL); 1.683 + } 1.684 +} 1.685 + 1.686 +void Direct3DDisplay::invalidateDeviceObjects() 1.687 +{ 1.688 + if (pFont) 1.689 + pFont->Release(); 1.690 + pFont = NULL; 1.691 +} 1.692 + 1.693 +void Direct3DDisplay::resize(int w, int h) 1.694 +{ 1.695 + if (pDevice && w > 0 && h > 0) 1.696 + { 1.697 + dpp.BackBufferWidth = w; 1.698 + dpp.BackBufferHeight = h; 1.699 + HRESULT hr; 1.700 + invalidateDeviceObjects(); 1.701 + if (SUCCEEDED(hr = pDevice->Reset(&dpp))) 1.702 + { 1.703 + restoreDeviceObjects(); 1.704 + } 1.705 + else 1.706 + systemMessage(0, "Failed device reset %08x", hr); 1.707 + } 1.708 + calculateVertices(); 1.709 +} 1.710 + 1.711 +bool Direct3DDisplay::changeRenderSize(int w, int h) 1.712 +{ 1.713 + if (w != width || h != height) 1.714 + { 1.715 + if (pTexture) 1.716 + { 1.717 + pTexture->Release(); 1.718 + pTexture = NULL; 1.719 + } 1.720 + if (!initializeOffscreen(w, h)) 1.721 + { 1.722 + failed = true; 1.723 + return false; 1.724 + } 1.725 + } 1.726 + calculateVertices(); 1.727 + 1.728 + return true; 1.729 +} 1.730 + 1.731 +void Direct3DDisplay::setOption(const char *option, int value) 1.732 +{ 1.733 + if (!strcmp(option, "d3dFilter")) 1.734 + updateFiltering(value); 1.735 +} 1.736 + 1.737 +int Direct3DDisplay::selectFullScreenMode(GUID * *) 1.738 +{ 1.739 + HWND wnd = GetDesktopWindow(); 1.740 + RECT r; 1.741 + GetWindowRect(wnd, &r); 1.742 + int w = (r.right - r.left) & 4095; 1.743 + int h = (r.bottom - r.top) & 4095; 1.744 + HDC dc = GetDC(wnd); 1.745 + int c = GetDeviceCaps(dc, BITSPIXEL); 1.746 + ReleaseDC(wnd, dc); 1.747 + 1.748 + return (c << 24) | (w << 12) | h; 1.749 +} 1.750 + 1.751 +IDisplay *newDirect3DDisplay() 1.752 +{ 1.753 + return new Direct3DDisplay(); 1.754 +} 1.755 +