rlm@1: #include "stdafx.h" rlm@1: rlm@1: #define DIRECT3D_VERSION 0x0800 rlm@1: #include "d3d8.h" rlm@1: #include "d3dx8.h" rlm@1: rlm@1: #include "resource.h" rlm@1: #include "MainWnd.h" rlm@1: #include "Reg.h" rlm@1: #include "VBA.h" rlm@1: rlm@1: //#include "../common/System.h" rlm@1: #include "../gba/GBAGlobals.h" rlm@1: #include "../gb/gbGlobals.h" rlm@1: #include "../common/Text.h" rlm@1: #include "../version.h" rlm@1: rlm@1: #ifdef MMX rlm@1: extern "C" bool cpu_mmx; rlm@1: rlm@1: extern bool detectMMX(); rlm@1: #endif rlm@1: rlm@1: extern int Init_2xSaI(u32); rlm@1: extern void directXMessage(const char *); rlm@1: extern void winlog(const char *, ...); rlm@1: rlm@1: typedef struct _D3DTLVERTEX rlm@1: { rlm@1: float sx; /* Screen coordinates */ rlm@1: float sy; rlm@1: float sz; rlm@1: float rhw; /* Reciprocal of homogeneous w */ rlm@1: D3DCOLOR color; /* Vertex color */ rlm@1: float tu; /* Texture coordinates */ rlm@1: float tv; rlm@1: _D3DTLVERTEX() { } rlm@1: _D3DTLVERTEX(const D3DVECTOR& v, float _rhw, rlm@1: D3DCOLOR _color, rlm@1: float _tu, float _tv) rlm@1: { rlm@1: sx = v.x; sy = v.y; sz = v.z; rhw = _rhw; rlm@1: color = _color; rlm@1: tu = _tu; tv = _tv; rlm@1: } rlm@1: } D3DTLVERTEX, *LPD3DTLVERTEX; rlm@1: rlm@1: #define D3DFVF_TLVERTEX D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1 rlm@1: rlm@1: class Direct3DDisplay : public IDisplay rlm@1: { rlm@1: public: rlm@1: Direct3DDisplay(); rlm@1: virtual ~Direct3DDisplay(); rlm@1: rlm@1: virtual bool initialize(); rlm@1: virtual void cleanup(); rlm@1: virtual void render(); rlm@1: virtual void checkFullScreen(); rlm@1: virtual void renderMenu(); rlm@1: virtual void clear(); rlm@1: virtual bool changeRenderSize(int w, int h); rlm@1: virtual void resize(int w, int h); rlm@1: virtual DISPLAY_TYPE getType() { return DIRECT_3D; }; rlm@1: virtual void setOption(const char *, int); rlm@1: virtual int selectFullScreenMode(GUID * *); rlm@1: rlm@1: private: rlm@1: HINSTANCE d3dDLL; rlm@1: LPDIRECT3D8 pD3D; rlm@1: LPDIRECT3DDEVICE8 pDevice; rlm@1: LPDIRECT3DTEXTURE8 pTexture; rlm@1: D3DSURFACE_DESC dsdBackBuffer; rlm@1: D3DPRESENT_PARAMETERS dpp; rlm@1: D3DFORMAT screenFormat; rlm@1: int width; rlm@1: int height; rlm@1: bool filterDisabled; rlm@1: ID3DXFont *pFont; rlm@1: bool failed; rlm@1: unsigned int textureSize; rlm@1: D3DTLVERTEX verts[4]; rlm@1: rlm@1: rlm@1: void restoreDeviceObjects(); rlm@1: void invalidateDeviceObjects(); rlm@1: bool initializeOffscreen(int w, int h); rlm@1: void updateFiltering(int); rlm@1: void calculateVertices(); rlm@1: }; rlm@1: rlm@1: Direct3DDisplay::Direct3DDisplay() rlm@1: { rlm@1: d3dDLL = NULL; rlm@1: pD3D = NULL; rlm@1: pDevice = NULL; rlm@1: pTexture = NULL; rlm@1: pFont = NULL; rlm@1: screenFormat = D3DFMT_R5G6B5; rlm@1: width = 0; rlm@1: height = 0; rlm@1: filterDisabled = false; rlm@1: failed = false; rlm@1: textureSize = 0; rlm@1: } rlm@1: rlm@1: Direct3DDisplay::~Direct3DDisplay() rlm@1: { rlm@1: cleanup(); rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::cleanup() rlm@1: { rlm@1: if (pD3D != NULL) rlm@1: { rlm@1: if (pFont) rlm@1: { rlm@1: pFont->Release(); rlm@1: pFont = NULL; rlm@1: } rlm@1: rlm@1: if (pTexture) rlm@1: { rlm@1: pTexture->Release(); rlm@1: pTexture = NULL; rlm@1: } rlm@1: rlm@1: if (pDevice) rlm@1: { rlm@1: pDevice->Release(); rlm@1: pDevice = NULL; rlm@1: } rlm@1: rlm@1: pD3D->Release(); rlm@1: pD3D = NULL; rlm@1: rlm@1: if (d3dDLL != NULL) rlm@1: { rlm@1: FreeLibrary(d3dDLL); rlm@1: d3dDLL = NULL; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: bool Direct3DDisplay::initialize() rlm@1: { rlm@1: CWnd *pWnd = theApp.m_pMainWnd; rlm@1: rlm@1: d3dDLL = LoadLibrary("D3D8.DLL"); rlm@1: LPDIRECT3D8 (WINAPI *D3DCreate)(UINT); rlm@1: if (d3dDLL != NULL) rlm@1: { rlm@1: D3DCreate = (LPDIRECT3D8 (WINAPI *)(UINT)) rlm@1: GetProcAddress(d3dDLL, "Direct3DCreate8"); rlm@1: rlm@1: if (D3DCreate == NULL) rlm@1: { rlm@1: directXMessage("Direct3DCreate8"); rlm@1: return FALSE; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: directXMessage("D3D8.DLL"); rlm@1: return FALSE; rlm@1: } rlm@1: rlm@1: pD3D = D3DCreate(120); rlm@1: rlm@1: if (pD3D == NULL) rlm@1: { rlm@1: winlog("Error creating Direct3D object\n"); rlm@1: return FALSE; rlm@1: } rlm@1: rlm@1: theApp.mode320Available = false; rlm@1: theApp.mode640Available = false; rlm@1: theApp.mode800Available = false; rlm@1: rlm@1: D3DDISPLAYMODE mode; rlm@1: pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode); rlm@1: rlm@1: switch (mode.Format) rlm@1: { rlm@1: case D3DFMT_R8G8B8: rlm@1: systemColorDepth = 24; rlm@1: systemRedShift = 19; rlm@1: systemGreenShift = 11; rlm@1: systemBlueShift = 3; rlm@1: break; rlm@1: case D3DFMT_X8R8G8B8: rlm@1: systemColorDepth = 32; rlm@1: systemRedShift = 19; rlm@1: systemGreenShift = 11; rlm@1: systemBlueShift = 3; rlm@1: Init_2xSaI(32); rlm@1: break; rlm@1: case D3DFMT_R5G6B5: rlm@1: systemColorDepth = 16; rlm@1: systemRedShift = 11; rlm@1: systemGreenShift = 6; rlm@1: systemBlueShift = 0; rlm@1: Init_2xSaI(565); rlm@1: break; rlm@1: case D3DFMT_X1R5G5B5: rlm@1: systemColorDepth = 16; rlm@1: systemRedShift = 10; rlm@1: systemGreenShift = 5; rlm@1: systemBlueShift = 0; rlm@1: Init_2xSaI(555); rlm@1: break; rlm@1: default: rlm@1: systemMessage(0, "Unsupport D3D format %d", mode.Format); rlm@1: return false; rlm@1: } rlm@1: theApp.fsColorDepth = systemColorDepth; rlm@1: rlm@1: #ifdef MMX rlm@1: if (!theApp.disableMMX) rlm@1: cpu_mmx = theApp.detectMMX(); rlm@1: else rlm@1: cpu_mmx = 0; rlm@1: #endif rlm@1: rlm@1: screenFormat = mode.Format; rlm@1: rlm@1: // check for available fullscreen modes rlm@1: ZeroMemory(&dpp, sizeof(dpp)); rlm@1: dpp.Windowed = TRUE; rlm@1: dpp.BackBufferFormat = mode.Format; rlm@1: dpp.BackBufferCount = 1; rlm@1: dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; rlm@1: dpp.BackBufferWidth = theApp.surfaceSizeX; rlm@1: dpp.BackBufferHeight = theApp.surfaceSizeY; rlm@1: rlm@1: HRESULT hret = pD3D->CreateDevice(D3DADAPTER_DEFAULT, rlm@1: D3DDEVTYPE_HAL, rlm@1: pWnd->GetSafeHwnd(), rlm@1: D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, rlm@1: &dpp, rlm@1: &pDevice); rlm@1: if (!SUCCEEDED(hret)) rlm@1: { rlm@1: winlog("Error creating Direct3DDevice %08x\n", hret); rlm@1: return false; rlm@1: } rlm@1: rlm@1: restoreDeviceObjects(); rlm@1: rlm@1: switch (systemColorDepth) rlm@1: { rlm@1: case 16: rlm@1: { rlm@1: for (int i = 0; i < 0x10000; i++) rlm@1: { rlm@1: systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | rlm@1: (((i & 0x3e0) >> 5) << systemGreenShift) | rlm@1: (((i & 0x7c00) >> 10) << systemBlueShift); rlm@1: } rlm@1: break; rlm@1: } rlm@1: case 24: rlm@1: case 32: rlm@1: { rlm@1: for (int i = 0; i < 0x10000; i++) rlm@1: { rlm@1: systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | rlm@1: (((i & 0x3e0) >> 5) << systemGreenShift) | rlm@1: (((i & 0x7c00) >> 10) << systemBlueShift); rlm@1: } rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: theApp.updateFilter(); rlm@1: theApp.updateIFB(); rlm@1: rlm@1: if (failed) rlm@1: return false; rlm@1: rlm@1: pWnd->DragAcceptFiles(TRUE); rlm@1: rlm@1: return TRUE; rlm@1: } rlm@1: rlm@1: bool Direct3DDisplay::initializeOffscreen(int w, int h) rlm@1: { rlm@1: int size = 256; rlm@1: if (w > 512 || h > 512) rlm@1: size = 1024; rlm@1: else if (w > 256 || h > 256) rlm@1: size = 512; rlm@1: textureSize = size; rlm@1: rlm@1: UINT ww = size; rlm@1: UINT hh = size; rlm@1: D3DFORMAT format = screenFormat; rlm@1: rlm@1: if (SUCCEEDED(D3DXCheckTextureRequirements(pDevice, rlm@1: &ww, rlm@1: &hh, rlm@1: NULL, rlm@1: 0, rlm@1: &format, rlm@1: D3DPOOL_MANAGED))) rlm@1: { rlm@1: if ((int)ww < w || (int)hh < h) rlm@1: { rlm@1: if (theApp.filterFunction) rlm@1: { rlm@1: filterDisabled = true; rlm@1: theApp.filterFunction = NULL; rlm@1: systemMessage(0, "3D card cannot support needed texture size for filter function. Disabling it"); rlm@1: } rlm@1: } rlm@1: else rlm@1: filterDisabled = false; rlm@1: if (SUCCEEDED(D3DXCreateTexture(pDevice, rlm@1: ww, rlm@1: hh, rlm@1: 0, rlm@1: 0, rlm@1: format, rlm@1: D3DPOOL_MANAGED, rlm@1: &pTexture))) rlm@1: { rlm@1: width = w; rlm@1: height = h; rlm@1: return true; rlm@1: } rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::updateFiltering(int filter) rlm@1: { rlm@1: switch (filter) rlm@1: { rlm@1: default: rlm@1: case 0: rlm@1: // point filtering rlm@1: pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); rlm@1: pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); rlm@1: pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); rlm@1: break; rlm@1: case 1: rlm@1: // bilinear rlm@1: pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); rlm@1: pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); rlm@1: pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::restoreDeviceObjects() rlm@1: { rlm@1: // Store render target surface desc rlm@1: LPDIRECT3DSURFACE8 pBackBuffer; rlm@1: HRESULT hr; rlm@1: if (SUCCEEDED(hr = pDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer))) rlm@1: { rlm@1: pBackBuffer->GetDesc(&dsdBackBuffer); rlm@1: pBackBuffer->Release(); rlm@1: } rlm@1: else rlm@1: systemMessage(0, "Failed GetBackBuffer %08x", hr); rlm@1: rlm@1: // Set up the texture rlm@1: pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); rlm@1: pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); rlm@1: pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); rlm@1: rlm@1: int filter = regQueryDwordValue("d3dFilter", 0); rlm@1: if (filter < 0 || filter > 3) rlm@1: filter = 0; rlm@1: updateFiltering(filter); rlm@1: rlm@1: // Set miscellaneous render states rlm@1: pDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE); rlm@1: pDevice->SetRenderState(D3DRS_ZENABLE, FALSE); rlm@1: rlm@1: // Set the projection matrix rlm@1: D3DXMATRIX matProj; rlm@1: FLOAT fAspect = ((FLOAT)dsdBackBuffer.Width) / dsdBackBuffer.Height; rlm@1: D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f); rlm@1: pDevice->SetTransform(D3DTS_PROJECTION, &matProj); rlm@1: rlm@1: // turn off lighting rlm@1: pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); rlm@1: rlm@1: if (pFont) rlm@1: { rlm@1: pFont->Release(); rlm@1: pFont = NULL; rlm@1: } rlm@1: // Create a D3D font using D3DX rlm@1: HFONT hFont = CreateFont(14, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, rlm@1: ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, rlm@1: ANTIALIASED_QUALITY, FF_DONTCARE, "Arial"); rlm@1: D3DXCreateFont(pDevice, hFont, &pFont); rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::clear() rlm@1: {} rlm@1: rlm@1: void Direct3DDisplay::renderMenu() rlm@1: { rlm@1: checkFullScreen(); rlm@1: if (theApp.m_pMainWnd) rlm@1: theApp.m_pMainWnd->DrawMenuBar(); rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::checkFullScreen() rlm@1: { rlm@1: // if(tripleBuffering) rlm@1: // pDirect3D->FlipToGDISurface(); rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::calculateVertices() rlm@1: { rlm@1: // color rlm@1: D3DCOLOR col = 0xFFFFFFFF; rlm@1: rlm@1: // calculate rhw rlm@1: FLOAT z = 1.0f; rlm@1: FLOAT rhw = 1.0f / (z * 990.0f + 10.0f); rlm@1: rlm@1: // -0.5f is necessary in order to match texture alignment to display pixels rlm@1: FLOAT left = -0.5f; rlm@1: FLOAT right = dpp.BackBufferWidth - 0.5f; rlm@1: FLOAT top = -0.5f; rlm@1: FLOAT bottom = dpp.BackBufferHeight - 0.5f; rlm@1: rlm@1: FLOAT textureX = (FLOAT)theApp.rect.right / (FLOAT)textureSize; rlm@1: FLOAT textureY = (FLOAT)theApp.rect.bottom / (FLOAT)textureSize; rlm@1: rlm@1: //#define D3D_DRAW_SINGLE_RECTANGLE rlm@1: #ifdef D3D_DRAW_SINGLE_RECTANGLE rlm@1: // set up a rectangle rlm@1: verts[0] = D3DTLVERTEX(D3DXVECTOR3(left, top, z), rhw, col, 0.0f, 0.0f); rlm@1: verts[1] = D3DTLVERTEX(D3DXVECTOR3(right, top, z), rhw, col, textureX, 0.0f); rlm@1: verts[2] = D3DTLVERTEX(D3DXVECTOR3(right, bottom, z), rhw, col, textureX, textureY); rlm@1: verts[3] = D3DTLVERTEX(D3DXVECTOR3(left, bottom, z), rhw, col, 0.0f, textureY); rlm@1: #else rlm@1: // set up triangles rlm@1: verts[0] = D3DTLVERTEX(D3DXVECTOR3(left, bottom, z), rhw, col, 0.0f, textureY); rlm@1: verts[1] = D3DTLVERTEX(D3DXVECTOR3(left, top, z), rhw, col, 0.0f, 0.0f); rlm@1: verts[2] = D3DTLVERTEX(D3DXVECTOR3(right, bottom, z), rhw, col, textureX, textureY); rlm@1: verts[3] = D3DTLVERTEX(D3DXVECTOR3(right, top, z), rhw, col, textureX, 0.0f); rlm@1: #endif rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::render() rlm@1: { rlm@1: if (!pDevice) rlm@1: return; rlm@1: rlm@1: // Test the cooperative level to see if it's okay to render rlm@1: if (FAILED(pDevice->TestCooperativeLevel())) rlm@1: { rlm@1: return; rlm@1: } rlm@1: pDevice->Clear(0L, NULL, D3DCLEAR_TARGET, 0x000000ff, 1.0f, 0L); rlm@1: rlm@1: if (SUCCEEDED(pDevice->BeginScene())) rlm@1: { rlm@1: D3DLOCKED_RECT locked; rlm@1: if (pTexture && SUCCEEDED(pTexture->LockRect(0, &locked, NULL, 0))) rlm@1: { rlm@1: if (theApp.filterFunction) rlm@1: { rlm@1: if (systemColorDepth == 16) rlm@1: theApp.filterFunction(pix + theApp.filterWidth * 2 + 4, rlm@1: theApp.filterWidth*2 + 4, rlm@1: (u8 *)theApp.delta, rlm@1: (u8 *)locked.pBits, rlm@1: locked.Pitch, rlm@1: theApp.filterWidth, rlm@1: theApp.filterHeight); rlm@1: else rlm@1: theApp.filterFunction(pix + theApp.filterWidth * 4 + 4, rlm@1: theApp.filterWidth * 4 + 4, rlm@1: (u8 *)theApp.delta, rlm@1: (u8 *)locked.pBits, rlm@1: locked.Pitch, rlm@1: theApp.filterWidth, rlm@1: theApp.filterHeight); rlm@1: } rlm@1: else rlm@1: { rlm@1: int copyX = 240; rlm@1: int copyY = 160; rlm@1: rlm@1: if (systemCartridgeType == 1) rlm@1: { rlm@1: if (gbBorderOn) rlm@1: { rlm@1: copyX = 256; rlm@1: copyY = 224; rlm@1: } rlm@1: else rlm@1: { rlm@1: copyX = 160; rlm@1: copyY = 144; rlm@1: } rlm@1: } rlm@1: // MMX doesn't seem to be faster to copy the data rlm@1: __asm { rlm@1: mov eax, copyX; rlm@1: mov ebx, copyY; rlm@1: rlm@1: mov esi, pix; rlm@1: mov edi, locked.pBits; rlm@1: mov edx, locked.Pitch; rlm@1: cmp systemColorDepth, 16; rlm@1: jnz gbaOtherColor; rlm@1: sub edx, eax; rlm@1: sub edx, eax; rlm@1: lea esi, [esi+2*eax+4]; rlm@1: shr eax, 1; rlm@1: gbaLoop16bit: rlm@1: mov ecx, eax; rlm@1: repz movsd; rlm@1: inc esi; rlm@1: inc esi; rlm@1: inc esi; rlm@1: inc esi; rlm@1: add edi, edx; rlm@1: dec ebx; rlm@1: jnz gbaLoop16bit; rlm@1: jmp gbaLoopEnd; rlm@1: gbaOtherColor: rlm@1: cmp systemColorDepth, 32; rlm@1: jnz gbaOtherColor2; rlm@1: rlm@1: sub edx, eax; rlm@1: sub edx, eax; rlm@1: sub edx, eax; rlm@1: sub edx, eax; rlm@1: lea esi, [esi+4*eax+4]; rlm@1: gbaLoop32bit: rlm@1: mov ecx, eax; rlm@1: repz movsd; rlm@1: add esi, 4; rlm@1: add edi, edx; rlm@1: dec ebx; rlm@1: jnz gbaLoop32bit; rlm@1: jmp gbaLoopEnd; rlm@1: gbaOtherColor2: rlm@1: lea eax, [eax+2*eax]; rlm@1: sub edx, eax; rlm@1: gbaLoop24bit: rlm@1: mov ecx, eax; rlm@1: shr ecx, 2; rlm@1: repz movsd; rlm@1: add edi, edx; rlm@1: dec ebx; rlm@1: jnz gbaLoop24bit; rlm@1: gbaLoopEnd: rlm@1: } rlm@1: } rlm@1: rlm@1: if (theApp.videoOption > VIDEO_4X && theApp.showSpeed) rlm@1: { rlm@1: char buffer[30]; rlm@1: if (theApp.showSpeed == 1) rlm@1: sprintf(buffer, "%3d%%", systemSpeed); rlm@1: else rlm@1: sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed, rlm@1: systemFrameSkip, rlm@1: theApp.showRenderedFrames); rlm@1: if (theApp.showSpeedTransparent) rlm@1: drawTextTransp((u8 *)locked.pBits, rlm@1: locked.Pitch, rlm@1: theApp.rect.left+10, rlm@1: theApp.rect.bottom-10, rlm@1: buffer); rlm@1: else rlm@1: drawText((u8 *)locked.pBits, rlm@1: locked.Pitch, rlm@1: theApp.rect.left+10, rlm@1: theApp.rect.bottom-10, rlm@1: buffer); rlm@1: } rlm@1: rlm@1: if (textMethod == 1) rlm@1: { rlm@1: DrawTextMessages((u8 *)locked.pBits, locked.Pitch, theApp.rect.left, theApp.rect.bottom); rlm@1: } rlm@1: rlm@1: pTexture->UnlockRect(0); rlm@1: rlm@1: // set the texture rlm@1: pDevice->SetTexture(0, pTexture); rlm@1: rlm@1: // configure shader for vertex type rlm@1: pDevice->SetVertexShader(D3DFVF_TLVERTEX); rlm@1: rlm@1: #ifdef D3D_DRAW_SINGLE_RECTANGLE rlm@1: // draw the rectangle rlm@1: pDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(D3DTLVERTEX)); rlm@1: //#undef D3D_DRAW_RECT rlm@1: #else rlm@1: // draw the triangles rlm@1: pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(D3DTLVERTEX)); rlm@1: #endif rlm@1: } rlm@1: rlm@1: if (textMethod == 2) rlm@1: { rlm@1: for (int slot = 0; slot < SCREEN_MESSAGE_SLOTS; slot++) rlm@1: { rlm@1: if (theApp.screenMessage[slot]) rlm@1: { rlm@1: if ((theApp.screenMessageDuration[slot] < 0 || rlm@1: (int)(GetTickCount() - theApp.screenMessageTime[slot]) < theApp.screenMessageDuration[slot]) && rlm@1: (!theApp.disableStatusMessage || slot == 1 || slot == 2) && pFont) rlm@1: { rlm@1: pFont->Begin(); rlm@1: RECT r; rlm@1: D3DCOLOR color; rlm@1: rlm@1: r.left = 10; rlm@1: r.top = dpp.BackBufferHeight - 20*(slot+1); rlm@1: r.right = dpp.BackBufferWidth - 10; rlm@1: r.bottom = r.top + 20; rlm@1: rlm@1: if (outlinedText) rlm@1: { rlm@1: color = textColor != 7 ? D3DCOLOR_ARGB(255, 0, 0, 0) : D3DCOLOR_ARGB(255, 255, 255, 255); rlm@1: rlm@1: // draw outline rlm@1: const static int xd [8] = {-1, 0, 1, 1, 1, 0, -1, -1}; rlm@1: const static int yd [8] = {-1, -1, -1, 0, 1, 1, 1, 0}; rlm@1: for (int i = 0; i < 8; i++) rlm@1: { rlm@1: RECT r2 = r; rlm@1: r2.left += xd[i]; r2.right += xd[i]; rlm@1: r2.top += yd[i]; r2.bottom += yd[i]; rlm@1: rlm@1: pFont->DrawText(theApp.screenMessageBuffer[slot], -1, &r2, 0, color); rlm@1: } rlm@1: } rlm@1: rlm@1: // draw center text rlm@1: switch (textColor) rlm@1: { rlm@1: case 0: rlm@1: color = D3DCOLOR_ARGB(255, 255, 255, 255); break; rlm@1: case 1: rlm@1: color = D3DCOLOR_ARGB(255, 255, 0, 0); break; rlm@1: case 2: rlm@1: color = D3DCOLOR_ARGB(255, 255, 255, 0); break; rlm@1: case 3: rlm@1: color = D3DCOLOR_ARGB(255, 0, 255, 0); break; rlm@1: case 4: rlm@1: color = D3DCOLOR_ARGB(255, 0, 255, 255); break; rlm@1: case 5: rlm@1: color = D3DCOLOR_ARGB(255, 0, 0, 255); break; rlm@1: case 6: rlm@1: color = D3DCOLOR_ARGB(255, 255, 0, 255); break; rlm@1: case 7: rlm@1: color = D3DCOLOR_ARGB(255, 0, 0, 0); break; rlm@1: } rlm@1: pFont->DrawText(theApp.screenMessageBuffer[slot], -1, &r, 0, color); rlm@1: rlm@1: pFont->End(); rlm@1: } rlm@1: else rlm@1: { rlm@1: theApp.screenMessage[slot] = false; rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: pDevice->EndScene(); rlm@1: rlm@1: pDevice->Present(NULL, NULL, NULL, NULL); rlm@1: } rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::invalidateDeviceObjects() rlm@1: { rlm@1: if (pFont) rlm@1: pFont->Release(); rlm@1: pFont = NULL; rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::resize(int w, int h) rlm@1: { rlm@1: if (pDevice && w > 0 && h > 0) rlm@1: { rlm@1: dpp.BackBufferWidth = w; rlm@1: dpp.BackBufferHeight = h; rlm@1: HRESULT hr; rlm@1: invalidateDeviceObjects(); rlm@1: if (SUCCEEDED(hr = pDevice->Reset(&dpp))) rlm@1: { rlm@1: restoreDeviceObjects(); rlm@1: } rlm@1: else rlm@1: systemMessage(0, "Failed device reset %08x", hr); rlm@1: } rlm@1: calculateVertices(); rlm@1: } rlm@1: rlm@1: bool Direct3DDisplay::changeRenderSize(int w, int h) rlm@1: { rlm@1: if (w != width || h != height) rlm@1: { rlm@1: if (pTexture) rlm@1: { rlm@1: pTexture->Release(); rlm@1: pTexture = NULL; rlm@1: } rlm@1: if (!initializeOffscreen(w, h)) rlm@1: { rlm@1: failed = true; rlm@1: return false; rlm@1: } rlm@1: } rlm@1: calculateVertices(); rlm@1: rlm@1: return true; rlm@1: } rlm@1: rlm@1: void Direct3DDisplay::setOption(const char *option, int value) rlm@1: { rlm@1: if (!strcmp(option, "d3dFilter")) rlm@1: updateFiltering(value); rlm@1: } rlm@1: rlm@1: int Direct3DDisplay::selectFullScreenMode(GUID * *) rlm@1: { rlm@1: HWND wnd = GetDesktopWindow(); rlm@1: RECT r; rlm@1: GetWindowRect(wnd, &r); rlm@1: int w = (r.right - r.left) & 4095; rlm@1: int h = (r.bottom - r.top) & 4095; rlm@1: HDC dc = GetDC(wnd); rlm@1: int c = GetDeviceCaps(dc, BITSPIXEL); rlm@1: ReleaseDC(wnd, dc); rlm@1: rlm@1: return (c << 24) | (w << 12) | h; rlm@1: } rlm@1: rlm@1: IDisplay *newDirect3DDisplay() rlm@1: { rlm@1: return new Direct3DDisplay(); rlm@1: } rlm@1: