Mercurial > vba-linux
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 #include "stdafx.h" | |
2 | |
3 #define DIRECT3D_VERSION 0x0800 | |
4 #include "d3d8.h" | |
5 #include "d3dx8.h" | |
6 | |
7 #include "resource.h" | |
8 #include "MainWnd.h" | |
9 #include "Reg.h" | |
10 #include "VBA.h" | |
11 | |
12 //#include "../common/System.h" | |
13 #include "../gba/GBAGlobals.h" | |
14 #include "../gb/gbGlobals.h" | |
15 #include "../common/Text.h" | |
16 #include "../version.h" | |
17 | |
18 #ifdef MMX | |
19 extern "C" bool cpu_mmx; | |
20 | |
21 extern bool detectMMX(); | |
22 #endif | |
23 | |
24 extern int Init_2xSaI(u32); | |
25 extern void directXMessage(const char *); | |
26 extern void winlog(const char *, ...); | |
27 | |
28 typedef struct _D3DTLVERTEX | |
29 { | |
30 float sx; /* Screen coordinates */ | |
31 float sy; | |
32 float sz; | |
33 float rhw; /* Reciprocal of homogeneous w */ | |
34 D3DCOLOR color; /* Vertex color */ | |
35 float tu; /* Texture coordinates */ | |
36 float tv; | |
37 _D3DTLVERTEX() { } | |
38 _D3DTLVERTEX(const D3DVECTOR& v, float _rhw, | |
39 D3DCOLOR _color, | |
40 float _tu, float _tv) | |
41 { | |
42 sx = v.x; sy = v.y; sz = v.z; rhw = _rhw; | |
43 color = _color; | |
44 tu = _tu; tv = _tv; | |
45 } | |
46 } D3DTLVERTEX, *LPD3DTLVERTEX; | |
47 | |
48 #define D3DFVF_TLVERTEX D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1 | |
49 | |
50 class Direct3DDisplay : public IDisplay | |
51 { | |
52 public: | |
53 Direct3DDisplay(); | |
54 virtual ~Direct3DDisplay(); | |
55 | |
56 virtual bool initialize(); | |
57 virtual void cleanup(); | |
58 virtual void render(); | |
59 virtual void checkFullScreen(); | |
60 virtual void renderMenu(); | |
61 virtual void clear(); | |
62 virtual bool changeRenderSize(int w, int h); | |
63 virtual void resize(int w, int h); | |
64 virtual DISPLAY_TYPE getType() { return DIRECT_3D; }; | |
65 virtual void setOption(const char *, int); | |
66 virtual int selectFullScreenMode(GUID * *); | |
67 | |
68 private: | |
69 HINSTANCE d3dDLL; | |
70 LPDIRECT3D8 pD3D; | |
71 LPDIRECT3DDEVICE8 pDevice; | |
72 LPDIRECT3DTEXTURE8 pTexture; | |
73 D3DSURFACE_DESC dsdBackBuffer; | |
74 D3DPRESENT_PARAMETERS dpp; | |
75 D3DFORMAT screenFormat; | |
76 int width; | |
77 int height; | |
78 bool filterDisabled; | |
79 ID3DXFont *pFont; | |
80 bool failed; | |
81 unsigned int textureSize; | |
82 D3DTLVERTEX verts[4]; | |
83 | |
84 | |
85 void restoreDeviceObjects(); | |
86 void invalidateDeviceObjects(); | |
87 bool initializeOffscreen(int w, int h); | |
88 void updateFiltering(int); | |
89 void calculateVertices(); | |
90 }; | |
91 | |
92 Direct3DDisplay::Direct3DDisplay() | |
93 { | |
94 d3dDLL = NULL; | |
95 pD3D = NULL; | |
96 pDevice = NULL; | |
97 pTexture = NULL; | |
98 pFont = NULL; | |
99 screenFormat = D3DFMT_R5G6B5; | |
100 width = 0; | |
101 height = 0; | |
102 filterDisabled = false; | |
103 failed = false; | |
104 textureSize = 0; | |
105 } | |
106 | |
107 Direct3DDisplay::~Direct3DDisplay() | |
108 { | |
109 cleanup(); | |
110 } | |
111 | |
112 void Direct3DDisplay::cleanup() | |
113 { | |
114 if (pD3D != NULL) | |
115 { | |
116 if (pFont) | |
117 { | |
118 pFont->Release(); | |
119 pFont = NULL; | |
120 } | |
121 | |
122 if (pTexture) | |
123 { | |
124 pTexture->Release(); | |
125 pTexture = NULL; | |
126 } | |
127 | |
128 if (pDevice) | |
129 { | |
130 pDevice->Release(); | |
131 pDevice = NULL; | |
132 } | |
133 | |
134 pD3D->Release(); | |
135 pD3D = NULL; | |
136 | |
137 if (d3dDLL != NULL) | |
138 { | |
139 FreeLibrary(d3dDLL); | |
140 d3dDLL = NULL; | |
141 } | |
142 } | |
143 } | |
144 | |
145 bool Direct3DDisplay::initialize() | |
146 { | |
147 CWnd *pWnd = theApp.m_pMainWnd; | |
148 | |
149 d3dDLL = LoadLibrary("D3D8.DLL"); | |
150 LPDIRECT3D8 (WINAPI *D3DCreate)(UINT); | |
151 if (d3dDLL != NULL) | |
152 { | |
153 D3DCreate = (LPDIRECT3D8 (WINAPI *)(UINT)) | |
154 GetProcAddress(d3dDLL, "Direct3DCreate8"); | |
155 | |
156 if (D3DCreate == NULL) | |
157 { | |
158 directXMessage("Direct3DCreate8"); | |
159 return FALSE; | |
160 } | |
161 } | |
162 else | |
163 { | |
164 directXMessage("D3D8.DLL"); | |
165 return FALSE; | |
166 } | |
167 | |
168 pD3D = D3DCreate(120); | |
169 | |
170 if (pD3D == NULL) | |
171 { | |
172 winlog("Error creating Direct3D object\n"); | |
173 return FALSE; | |
174 } | |
175 | |
176 theApp.mode320Available = false; | |
177 theApp.mode640Available = false; | |
178 theApp.mode800Available = false; | |
179 | |
180 D3DDISPLAYMODE mode; | |
181 pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode); | |
182 | |
183 switch (mode.Format) | |
184 { | |
185 case D3DFMT_R8G8B8: | |
186 systemColorDepth = 24; | |
187 systemRedShift = 19; | |
188 systemGreenShift = 11; | |
189 systemBlueShift = 3; | |
190 break; | |
191 case D3DFMT_X8R8G8B8: | |
192 systemColorDepth = 32; | |
193 systemRedShift = 19; | |
194 systemGreenShift = 11; | |
195 systemBlueShift = 3; | |
196 Init_2xSaI(32); | |
197 break; | |
198 case D3DFMT_R5G6B5: | |
199 systemColorDepth = 16; | |
200 systemRedShift = 11; | |
201 systemGreenShift = 6; | |
202 systemBlueShift = 0; | |
203 Init_2xSaI(565); | |
204 break; | |
205 case D3DFMT_X1R5G5B5: | |
206 systemColorDepth = 16; | |
207 systemRedShift = 10; | |
208 systemGreenShift = 5; | |
209 systemBlueShift = 0; | |
210 Init_2xSaI(555); | |
211 break; | |
212 default: | |
213 systemMessage(0, "Unsupport D3D format %d", mode.Format); | |
214 return false; | |
215 } | |
216 theApp.fsColorDepth = systemColorDepth; | |
217 | |
218 #ifdef MMX | |
219 if (!theApp.disableMMX) | |
220 cpu_mmx = theApp.detectMMX(); | |
221 else | |
222 cpu_mmx = 0; | |
223 #endif | |
224 | |
225 screenFormat = mode.Format; | |
226 | |
227 // check for available fullscreen modes | |
228 ZeroMemory(&dpp, sizeof(dpp)); | |
229 dpp.Windowed = TRUE; | |
230 dpp.BackBufferFormat = mode.Format; | |
231 dpp.BackBufferCount = 1; | |
232 dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; | |
233 dpp.BackBufferWidth = theApp.surfaceSizeX; | |
234 dpp.BackBufferHeight = theApp.surfaceSizeY; | |
235 | |
236 HRESULT hret = pD3D->CreateDevice(D3DADAPTER_DEFAULT, | |
237 D3DDEVTYPE_HAL, | |
238 pWnd->GetSafeHwnd(), | |
239 D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, | |
240 &dpp, | |
241 &pDevice); | |
242 if (!SUCCEEDED(hret)) | |
243 { | |
244 winlog("Error creating Direct3DDevice %08x\n", hret); | |
245 return false; | |
246 } | |
247 | |
248 restoreDeviceObjects(); | |
249 | |
250 switch (systemColorDepth) | |
251 { | |
252 case 16: | |
253 { | |
254 for (int i = 0; i < 0x10000; i++) | |
255 { | |
256 systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | | |
257 (((i & 0x3e0) >> 5) << systemGreenShift) | | |
258 (((i & 0x7c00) >> 10) << systemBlueShift); | |
259 } | |
260 break; | |
261 } | |
262 case 24: | |
263 case 32: | |
264 { | |
265 for (int i = 0; i < 0x10000; i++) | |
266 { | |
267 systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | | |
268 (((i & 0x3e0) >> 5) << systemGreenShift) | | |
269 (((i & 0x7c00) >> 10) << systemBlueShift); | |
270 } | |
271 break; | |
272 } | |
273 } | |
274 | |
275 theApp.updateFilter(); | |
276 theApp.updateIFB(); | |
277 | |
278 if (failed) | |
279 return false; | |
280 | |
281 pWnd->DragAcceptFiles(TRUE); | |
282 | |
283 return TRUE; | |
284 } | |
285 | |
286 bool Direct3DDisplay::initializeOffscreen(int w, int h) | |
287 { | |
288 int size = 256; | |
289 if (w > 512 || h > 512) | |
290 size = 1024; | |
291 else if (w > 256 || h > 256) | |
292 size = 512; | |
293 textureSize = size; | |
294 | |
295 UINT ww = size; | |
296 UINT hh = size; | |
297 D3DFORMAT format = screenFormat; | |
298 | |
299 if (SUCCEEDED(D3DXCheckTextureRequirements(pDevice, | |
300 &ww, | |
301 &hh, | |
302 NULL, | |
303 0, | |
304 &format, | |
305 D3DPOOL_MANAGED))) | |
306 { | |
307 if ((int)ww < w || (int)hh < h) | |
308 { | |
309 if (theApp.filterFunction) | |
310 { | |
311 filterDisabled = true; | |
312 theApp.filterFunction = NULL; | |
313 systemMessage(0, "3D card cannot support needed texture size for filter function. Disabling it"); | |
314 } | |
315 } | |
316 else | |
317 filterDisabled = false; | |
318 if (SUCCEEDED(D3DXCreateTexture(pDevice, | |
319 ww, | |
320 hh, | |
321 0, | |
322 0, | |
323 format, | |
324 D3DPOOL_MANAGED, | |
325 &pTexture))) | |
326 { | |
327 width = w; | |
328 height = h; | |
329 return true; | |
330 } | |
331 } | |
332 return false; | |
333 } | |
334 | |
335 void Direct3DDisplay::updateFiltering(int filter) | |
336 { | |
337 switch (filter) | |
338 { | |
339 default: | |
340 case 0: | |
341 // point filtering | |
342 pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); | |
343 pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); | |
344 pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); | |
345 break; | |
346 case 1: | |
347 // bilinear | |
348 pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); | |
349 pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); | |
350 pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); | |
351 break; | |
352 } | |
353 } | |
354 | |
355 void Direct3DDisplay::restoreDeviceObjects() | |
356 { | |
357 // Store render target surface desc | |
358 LPDIRECT3DSURFACE8 pBackBuffer; | |
359 HRESULT hr; | |
360 if (SUCCEEDED(hr = pDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer))) | |
361 { | |
362 pBackBuffer->GetDesc(&dsdBackBuffer); | |
363 pBackBuffer->Release(); | |
364 } | |
365 else | |
366 systemMessage(0, "Failed GetBackBuffer %08x", hr); | |
367 | |
368 // Set up the texture | |
369 pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); | |
370 pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); | |
371 pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); | |
372 | |
373 int filter = regQueryDwordValue("d3dFilter", 0); | |
374 if (filter < 0 || filter > 3) | |
375 filter = 0; | |
376 updateFiltering(filter); | |
377 | |
378 // Set miscellaneous render states | |
379 pDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE); | |
380 pDevice->SetRenderState(D3DRS_ZENABLE, FALSE); | |
381 | |
382 // Set the projection matrix | |
383 D3DXMATRIX matProj; | |
384 FLOAT fAspect = ((FLOAT)dsdBackBuffer.Width) / dsdBackBuffer.Height; | |
385 D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f); | |
386 pDevice->SetTransform(D3DTS_PROJECTION, &matProj); | |
387 | |
388 // turn off lighting | |
389 pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); | |
390 | |
391 if (pFont) | |
392 { | |
393 pFont->Release(); | |
394 pFont = NULL; | |
395 } | |
396 // Create a D3D font using D3DX | |
397 HFONT hFont = CreateFont(14, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, | |
398 ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, | |
399 ANTIALIASED_QUALITY, FF_DONTCARE, "Arial"); | |
400 D3DXCreateFont(pDevice, hFont, &pFont); | |
401 } | |
402 | |
403 void Direct3DDisplay::clear() | |
404 {} | |
405 | |
406 void Direct3DDisplay::renderMenu() | |
407 { | |
408 checkFullScreen(); | |
409 if (theApp.m_pMainWnd) | |
410 theApp.m_pMainWnd->DrawMenuBar(); | |
411 } | |
412 | |
413 void Direct3DDisplay::checkFullScreen() | |
414 { | |
415 // if(tripleBuffering) | |
416 // pDirect3D->FlipToGDISurface(); | |
417 } | |
418 | |
419 void Direct3DDisplay::calculateVertices() | |
420 { | |
421 // color | |
422 D3DCOLOR col = 0xFFFFFFFF; | |
423 | |
424 // calculate rhw | |
425 FLOAT z = 1.0f; | |
426 FLOAT rhw = 1.0f / (z * 990.0f + 10.0f); | |
427 | |
428 // -0.5f is necessary in order to match texture alignment to display pixels | |
429 FLOAT left = -0.5f; | |
430 FLOAT right = dpp.BackBufferWidth - 0.5f; | |
431 FLOAT top = -0.5f; | |
432 FLOAT bottom = dpp.BackBufferHeight - 0.5f; | |
433 | |
434 FLOAT textureX = (FLOAT)theApp.rect.right / (FLOAT)textureSize; | |
435 FLOAT textureY = (FLOAT)theApp.rect.bottom / (FLOAT)textureSize; | |
436 | |
437 //#define D3D_DRAW_SINGLE_RECTANGLE | |
438 #ifdef D3D_DRAW_SINGLE_RECTANGLE | |
439 // set up a rectangle | |
440 verts[0] = D3DTLVERTEX(D3DXVECTOR3(left, top, z), rhw, col, 0.0f, 0.0f); | |
441 verts[1] = D3DTLVERTEX(D3DXVECTOR3(right, top, z), rhw, col, textureX, 0.0f); | |
442 verts[2] = D3DTLVERTEX(D3DXVECTOR3(right, bottom, z), rhw, col, textureX, textureY); | |
443 verts[3] = D3DTLVERTEX(D3DXVECTOR3(left, bottom, z), rhw, col, 0.0f, textureY); | |
444 #else | |
445 // set up triangles | |
446 verts[0] = D3DTLVERTEX(D3DXVECTOR3(left, bottom, z), rhw, col, 0.0f, textureY); | |
447 verts[1] = D3DTLVERTEX(D3DXVECTOR3(left, top, z), rhw, col, 0.0f, 0.0f); | |
448 verts[2] = D3DTLVERTEX(D3DXVECTOR3(right, bottom, z), rhw, col, textureX, textureY); | |
449 verts[3] = D3DTLVERTEX(D3DXVECTOR3(right, top, z), rhw, col, textureX, 0.0f); | |
450 #endif | |
451 } | |
452 | |
453 void Direct3DDisplay::render() | |
454 { | |
455 if (!pDevice) | |
456 return; | |
457 | |
458 // Test the cooperative level to see if it's okay to render | |
459 if (FAILED(pDevice->TestCooperativeLevel())) | |
460 { | |
461 return; | |
462 } | |
463 pDevice->Clear(0L, NULL, D3DCLEAR_TARGET, 0x000000ff, 1.0f, 0L); | |
464 | |
465 if (SUCCEEDED(pDevice->BeginScene())) | |
466 { | |
467 D3DLOCKED_RECT locked; | |
468 if (pTexture && SUCCEEDED(pTexture->LockRect(0, &locked, NULL, 0))) | |
469 { | |
470 if (theApp.filterFunction) | |
471 { | |
472 if (systemColorDepth == 16) | |
473 theApp.filterFunction(pix + theApp.filterWidth * 2 + 4, | |
474 theApp.filterWidth*2 + 4, | |
475 (u8 *)theApp.delta, | |
476 (u8 *)locked.pBits, | |
477 locked.Pitch, | |
478 theApp.filterWidth, | |
479 theApp.filterHeight); | |
480 else | |
481 theApp.filterFunction(pix + theApp.filterWidth * 4 + 4, | |
482 theApp.filterWidth * 4 + 4, | |
483 (u8 *)theApp.delta, | |
484 (u8 *)locked.pBits, | |
485 locked.Pitch, | |
486 theApp.filterWidth, | |
487 theApp.filterHeight); | |
488 } | |
489 else | |
490 { | |
491 int copyX = 240; | |
492 int copyY = 160; | |
493 | |
494 if (systemCartridgeType == 1) | |
495 { | |
496 if (gbBorderOn) | |
497 { | |
498 copyX = 256; | |
499 copyY = 224; | |
500 } | |
501 else | |
502 { | |
503 copyX = 160; | |
504 copyY = 144; | |
505 } | |
506 } | |
507 // MMX doesn't seem to be faster to copy the data | |
508 __asm { | |
509 mov eax, copyX; | |
510 mov ebx, copyY; | |
511 | |
512 mov esi, pix; | |
513 mov edi, locked.pBits; | |
514 mov edx, locked.Pitch; | |
515 cmp systemColorDepth, 16; | |
516 jnz gbaOtherColor; | |
517 sub edx, eax; | |
518 sub edx, eax; | |
519 lea esi, [esi+2*eax+4]; | |
520 shr eax, 1; | |
521 gbaLoop16bit: | |
522 mov ecx, eax; | |
523 repz movsd; | |
524 inc esi; | |
525 inc esi; | |
526 inc esi; | |
527 inc esi; | |
528 add edi, edx; | |
529 dec ebx; | |
530 jnz gbaLoop16bit; | |
531 jmp gbaLoopEnd; | |
532 gbaOtherColor: | |
533 cmp systemColorDepth, 32; | |
534 jnz gbaOtherColor2; | |
535 | |
536 sub edx, eax; | |
537 sub edx, eax; | |
538 sub edx, eax; | |
539 sub edx, eax; | |
540 lea esi, [esi+4*eax+4]; | |
541 gbaLoop32bit: | |
542 mov ecx, eax; | |
543 repz movsd; | |
544 add esi, 4; | |
545 add edi, edx; | |
546 dec ebx; | |
547 jnz gbaLoop32bit; | |
548 jmp gbaLoopEnd; | |
549 gbaOtherColor2: | |
550 lea eax, [eax+2*eax]; | |
551 sub edx, eax; | |
552 gbaLoop24bit: | |
553 mov ecx, eax; | |
554 shr ecx, 2; | |
555 repz movsd; | |
556 add edi, edx; | |
557 dec ebx; | |
558 jnz gbaLoop24bit; | |
559 gbaLoopEnd: | |
560 } | |
561 } | |
562 | |
563 if (theApp.videoOption > VIDEO_4X && theApp.showSpeed) | |
564 { | |
565 char buffer[30]; | |
566 if (theApp.showSpeed == 1) | |
567 sprintf(buffer, "%3d%%", systemSpeed); | |
568 else | |
569 sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed, | |
570 systemFrameSkip, | |
571 theApp.showRenderedFrames); | |
572 if (theApp.showSpeedTransparent) | |
573 drawTextTransp((u8 *)locked.pBits, | |
574 locked.Pitch, | |
575 theApp.rect.left+10, | |
576 theApp.rect.bottom-10, | |
577 buffer); | |
578 else | |
579 drawText((u8 *)locked.pBits, | |
580 locked.Pitch, | |
581 theApp.rect.left+10, | |
582 theApp.rect.bottom-10, | |
583 buffer); | |
584 } | |
585 | |
586 if (textMethod == 1) | |
587 { | |
588 DrawTextMessages((u8 *)locked.pBits, locked.Pitch, theApp.rect.left, theApp.rect.bottom); | |
589 } | |
590 | |
591 pTexture->UnlockRect(0); | |
592 | |
593 // set the texture | |
594 pDevice->SetTexture(0, pTexture); | |
595 | |
596 // configure shader for vertex type | |
597 pDevice->SetVertexShader(D3DFVF_TLVERTEX); | |
598 | |
599 #ifdef D3D_DRAW_SINGLE_RECTANGLE | |
600 // draw the rectangle | |
601 pDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(D3DTLVERTEX)); | |
602 //#undef D3D_DRAW_RECT | |
603 #else | |
604 // draw the triangles | |
605 pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(D3DTLVERTEX)); | |
606 #endif | |
607 } | |
608 | |
609 if (textMethod == 2) | |
610 { | |
611 for (int slot = 0; slot < SCREEN_MESSAGE_SLOTS; slot++) | |
612 { | |
613 if (theApp.screenMessage[slot]) | |
614 { | |
615 if ((theApp.screenMessageDuration[slot] < 0 || | |
616 (int)(GetTickCount() - theApp.screenMessageTime[slot]) < theApp.screenMessageDuration[slot]) && | |
617 (!theApp.disableStatusMessage || slot == 1 || slot == 2) && pFont) | |
618 { | |
619 pFont->Begin(); | |
620 RECT r; | |
621 D3DCOLOR color; | |
622 | |
623 r.left = 10; | |
624 r.top = dpp.BackBufferHeight - 20*(slot+1); | |
625 r.right = dpp.BackBufferWidth - 10; | |
626 r.bottom = r.top + 20; | |
627 | |
628 if (outlinedText) | |
629 { | |
630 color = textColor != 7 ? D3DCOLOR_ARGB(255, 0, 0, 0) : D3DCOLOR_ARGB(255, 255, 255, 255); | |
631 | |
632 // draw outline | |
633 const static int xd [8] = {-1, 0, 1, 1, 1, 0, -1, -1}; | |
634 const static int yd [8] = {-1, -1, -1, 0, 1, 1, 1, 0}; | |
635 for (int i = 0; i < 8; i++) | |
636 { | |
637 RECT r2 = r; | |
638 r2.left += xd[i]; r2.right += xd[i]; | |
639 r2.top += yd[i]; r2.bottom += yd[i]; | |
640 | |
641 pFont->DrawText(theApp.screenMessageBuffer[slot], -1, &r2, 0, color); | |
642 } | |
643 } | |
644 | |
645 // draw center text | |
646 switch (textColor) | |
647 { | |
648 case 0: | |
649 color = D3DCOLOR_ARGB(255, 255, 255, 255); break; | |
650 case 1: | |
651 color = D3DCOLOR_ARGB(255, 255, 0, 0); break; | |
652 case 2: | |
653 color = D3DCOLOR_ARGB(255, 255, 255, 0); break; | |
654 case 3: | |
655 color = D3DCOLOR_ARGB(255, 0, 255, 0); break; | |
656 case 4: | |
657 color = D3DCOLOR_ARGB(255, 0, 255, 255); break; | |
658 case 5: | |
659 color = D3DCOLOR_ARGB(255, 0, 0, 255); break; | |
660 case 6: | |
661 color = D3DCOLOR_ARGB(255, 255, 0, 255); break; | |
662 case 7: | |
663 color = D3DCOLOR_ARGB(255, 0, 0, 0); break; | |
664 } | |
665 pFont->DrawText(theApp.screenMessageBuffer[slot], -1, &r, 0, color); | |
666 | |
667 pFont->End(); | |
668 } | |
669 else | |
670 { | |
671 theApp.screenMessage[slot] = false; | |
672 } | |
673 } | |
674 } | |
675 } | |
676 | |
677 pDevice->EndScene(); | |
678 | |
679 pDevice->Present(NULL, NULL, NULL, NULL); | |
680 } | |
681 } | |
682 | |
683 void Direct3DDisplay::invalidateDeviceObjects() | |
684 { | |
685 if (pFont) | |
686 pFont->Release(); | |
687 pFont = NULL; | |
688 } | |
689 | |
690 void Direct3DDisplay::resize(int w, int h) | |
691 { | |
692 if (pDevice && w > 0 && h > 0) | |
693 { | |
694 dpp.BackBufferWidth = w; | |
695 dpp.BackBufferHeight = h; | |
696 HRESULT hr; | |
697 invalidateDeviceObjects(); | |
698 if (SUCCEEDED(hr = pDevice->Reset(&dpp))) | |
699 { | |
700 restoreDeviceObjects(); | |
701 } | |
702 else | |
703 systemMessage(0, "Failed device reset %08x", hr); | |
704 } | |
705 calculateVertices(); | |
706 } | |
707 | |
708 bool Direct3DDisplay::changeRenderSize(int w, int h) | |
709 { | |
710 if (w != width || h != height) | |
711 { | |
712 if (pTexture) | |
713 { | |
714 pTexture->Release(); | |
715 pTexture = NULL; | |
716 } | |
717 if (!initializeOffscreen(w, h)) | |
718 { | |
719 failed = true; | |
720 return false; | |
721 } | |
722 } | |
723 calculateVertices(); | |
724 | |
725 return true; | |
726 } | |
727 | |
728 void Direct3DDisplay::setOption(const char *option, int value) | |
729 { | |
730 if (!strcmp(option, "d3dFilter")) | |
731 updateFiltering(value); | |
732 } | |
733 | |
734 int Direct3DDisplay::selectFullScreenMode(GUID * *) | |
735 { | |
736 HWND wnd = GetDesktopWindow(); | |
737 RECT r; | |
738 GetWindowRect(wnd, &r); | |
739 int w = (r.right - r.left) & 4095; | |
740 int h = (r.bottom - r.top) & 4095; | |
741 HDC dc = GetDC(wnd); | |
742 int c = GetDeviceCaps(dc, BITSPIXEL); | |
743 ReleaseDC(wnd, dc); | |
744 | |
745 return (c << 24) | (w << 12) | h; | |
746 } | |
747 | |
748 IDisplay *newDirect3DDisplay() | |
749 { | |
750 return new Direct3DDisplay(); | |
751 } | |
752 |