From 55e5cd6272dffe1212c1615c50c367b019712a54 Mon Sep 17 00:00:00 2001 From: OV2 Date: Tue, 7 Aug 2018 01:16:41 +0200 Subject: [PATCH] win32: switch to DirectXMath to remove d3d9x dependency, remove HLSL --- .gitmodules | 3 + win32/CD3DCG.cpp | 75 ++++------ win32/CD3DCG.h | 21 +-- win32/CDirect3D.cpp | 274 ++++------------------------------ win32/CDirect3D.h | 4 - win32/CGLCG.cpp | 188 ----------------------- win32/CGLCG.h | 19 +-- win32/CXAudio2.cpp | 2 +- win32/DirectXMath | 1 + win32/image_functions.cpp | 245 ++++++++++++++++++++++++++++++ win32/image_functions.h | 25 ++++ win32/snes9xw.vcxproj | 2 + win32/snes9xw.vcxproj.filters | 6 + 13 files changed, 355 insertions(+), 510 deletions(-) create mode 160000 win32/DirectXMath create mode 100644 win32/image_functions.cpp create mode 100644 win32/image_functions.h diff --git a/.gitmodules b/.gitmodules index 069f2b92..93b155a1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "win32/zlib/src"] path = win32/zlib/src url = https://github.com/madler/zlib.git +[submodule "win32/DirectXMath"] + path = win32/DirectXMath + url = https://github.com/Microsoft/DirectXMath diff --git a/win32/CD3DCG.cpp b/win32/CD3DCG.cpp index 106635ee..b9a65b48 100644 --- a/win32/CD3DCG.cpp +++ b/win32/CD3DCG.cpp @@ -192,9 +192,10 @@ #include "wsnes9x.h" #include "win32_display.h" #include "snes9x.h" -#include +#include "dxerr.h" #include #include "CDirect3D.h" +#include "image_functions.h" #ifndef max #define max(a, b) (((a) > (b)) ? (a) : (b)) @@ -405,22 +406,7 @@ bool CD3DCG::LoadShader(const TCHAR *shaderFile) _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH); - hr = D3DXCreateTextureFromFileEx( - pDevice, - tempPath, - D3DX_DEFAULT_NONPOW2, - D3DX_DEFAULT_NONPOW2, - 0, - 0, - D3DFMT_FROM_FILE, - D3DPOOL_MANAGED, - it->linearfilter?D3DX_FILTER_LINEAR:D3DX_FILTER_POINT, - 0, - 0, - NULL, - NULL, - &tex.tex); - if FAILED(hr){ + if(!d3d_create_texture_from_file(pDevice, tempPath, &tex.tex)){ tex.tex = NULL; } lookupTextures.push_back(tex); @@ -431,12 +417,12 @@ bool CD3DCG::LoadShader(const TCHAR *shaderFile) return true; } -void CD3DCG::ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, D3DXVECTOR2 &texSize, - D3DXVECTOR2 wantedSize,bool renderTarget,bool useFloat) +void CD3DCG::ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, XMFLOAT2 &texSize, + XMFLOAT2 wantedSize,bool renderTarget,bool useFloat) { HRESULT hr; - if(!tex || texSize != wantedSize) { + if(!tex || texSize.x != wantedSize.x || texSize.y != wantedSize.y) { if(tex) tex->Release(); @@ -459,7 +445,7 @@ void CD3DCG::ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, D3DXVECTOR2 &texSize, } void CD3DCG::setVertexStream(IDirect3DVertexBuffer9 *vertexBuffer, - D3DXVECTOR2 inputSize,D3DXVECTOR2 textureSize,D3DXVECTOR2 outputSize) + XMFLOAT2 inputSize, XMFLOAT2 textureSize, XMFLOAT2 outputSize) { float tX = inputSize.x / textureSize.x; float tY = inputSize.y / textureSize.y; @@ -500,8 +486,8 @@ void CD3DCG::setVertexStream(IDirect3DVertexBuffer9 *vertexBuffer, pDevice->SetStreamSource(3,vertexBuffer,0,sizeof(VERTEX)); } -void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, D3DXVECTOR2 textureSize, - D3DXVECTOR2 inputSize, D3DXVECTOR2 viewportSize, D3DXVECTOR2 windowSize) +void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, XMFLOAT2 textureSize, + XMFLOAT2 inputSize, XMFLOAT2 viewportSize, XMFLOAT2 windowSize) { LPDIRECT3DSURFACE9 pRenderSurface = NULL,pBackBuffer = NULL; frameCnt++; @@ -553,7 +539,7 @@ void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, D3DXVECTOR2 textureSize, /* make sure the render target exists and has an appropriate size, then set as current render target with last pass as source */ - ensureTextureSize(shaderPasses[i].tex,shaderPasses[i].textureSize,D3DXVECTOR2(texSize,texSize),true,shaderPasses[i].useFloatTex); + ensureTextureSize(shaderPasses[i].tex,shaderPasses[i].textureSize, XMFLOAT2(texSize,texSize),true,shaderPasses[i].useFloatTex); shaderPasses[i].tex->GetSurfaceLevel(0,&pRenderSurface); pDevice->SetTexture(0, shaderPasses[i-1].tex); pDevice->SetRenderTarget(0,pRenderSurface); @@ -623,23 +609,22 @@ void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, D3DXVECTOR2 textureSize, setViewport(displayRect.left,displayRect.top,displayRect.right - displayRect.left,displayRect.bottom - displayRect.top); setVertexStream(shaderPasses.back().vertexBuffer, shaderPasses.back().outputSize,shaderPasses.back().textureSize, - D3DXVECTOR2(displayRect.right - displayRect.left,displayRect.bottom - displayRect.top)); + XMFLOAT2(displayRect.right - displayRect.left,displayRect.bottom - displayRect.top)); pDevice->SetVertexShader(NULL); pDevice->SetPixelShader(NULL); } void CD3DCG::calculateMatrix() { - D3DXMATRIX matWorld; - D3DXMATRIX matView; - D3DXMATRIX matProj; + XMMATRIX matWorld; + XMMATRIX matView; + XMMATRIX matProj; - pDevice->GetTransform(D3DTS_WORLD,&matWorld); - pDevice->GetTransform(D3DTS_VIEW,&matView); - pDevice->GetTransform(D3DTS_PROJECTION,&matProj); + pDevice->GetTransform(D3DTS_WORLD, (D3DMATRIX*)&matWorld); + pDevice->GetTransform(D3DTS_VIEW, (D3DMATRIX*)&matView); + pDevice->GetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&matProj); - mvp = matWorld * matView * matProj; - D3DXMatrixTranspose(&mvp,&mvp); + XMStoreFloat4x4(&mvp, XMMatrixTranspose(XMMatrixMultiply(matProj, XMMatrixMultiply(matWorld, matView)))); } void CD3DCG::setViewport(DWORD x, DWORD y, DWORD width, DWORD height) @@ -656,16 +641,16 @@ void CD3DCG::setViewport(DWORD x, DWORD y, DWORD width, DWORD height) void CD3DCG::setShaderVars(int pass) { - D3DXVECTOR2 inputSize = shaderPasses[pass-1].outputSize; - D3DXVECTOR2 textureSize = shaderPasses[pass-1].textureSize; - D3DXVECTOR2 outputSize = shaderPasses[pass].outputSize; + XMFLOAT2 inputSize = shaderPasses[pass-1].outputSize; + XMFLOAT2 textureSize = shaderPasses[pass-1].textureSize; + XMFLOAT2 outputSize = shaderPasses[pass].outputSize; /* mvp paramater */ CGparameter cgpModelViewProj = cgGetNamedParameter(shaderPasses[pass].cgVertexProgram, "modelViewProj"); if(cgpModelViewProj) - cgD3D9SetUniformMatrix(cgpModelViewProj,&mvp); + cgD3D9SetUniformMatrix(cgpModelViewProj,(D3DMATRIX*)&mvp); #define setProgramUniform(pass,varname,floats)\ {\ @@ -720,16 +705,16 @@ void CD3DCG::setShaderVars(int pass) /* ORIG parameter */ - setProgramUniform(pass,"ORIG.video_size",shaderPasses[0].outputSize); - setProgramUniform(pass,"ORIG.texture_size",shaderPasses[0].textureSize); + setProgramUniform(pass,"ORIG.video_size",&shaderPasses[0].outputSize); + setProgramUniform(pass,"ORIG.texture_size",&shaderPasses[0].textureSize); setTextureParameter(pass,"ORIG.texture",shaderPasses[0].tex,shaderPasses[1].linearFilter); setTexCoordsParameter(pass,"ORIG.tex_coord",shaderPasses[1].vertexBuffer); /* PREV parameter */ if(prevPasses[0].tex) { - setProgramUniform(pass,"PREV.video_size",prevPasses[0].imageSize); - setProgramUniform(pass,"PREV.texture_size",prevPasses[0].textureSize); + setProgramUniform(pass,"PREV.video_size",&prevPasses[0].imageSize); + setProgramUniform(pass,"PREV.texture_size",&prevPasses[0].textureSize); setTextureParameter(pass,"PREV.texture",prevPasses[0].tex,shaderPasses[1].linearFilter); setTexCoordsParameter(pass,"PREV.tex_coord",prevPasses[0].vertexBuffer); } @@ -741,9 +726,9 @@ void CD3DCG::setShaderVars(int pass) break; char varname[100]; sprintf(varname,"PREV%d.video_size",i); - setProgramUniform(pass,varname,prevPasses[i].imageSize); + setProgramUniform(pass,varname,&prevPasses[i].imageSize); sprintf(varname,"PREV%d.texture_size",i); - setProgramUniform(pass,varname,prevPasses[i].textureSize); + setProgramUniform(pass,varname,&prevPasses[i].textureSize); sprintf(varname,"PREV%d.texture",i); setTextureParameter(pass,varname,prevPasses[i].tex,shaderPasses[1].linearFilter); sprintf(varname,"PREV%d.tex_coord",i); @@ -762,9 +747,9 @@ void CD3DCG::setShaderVars(int pass) for(int i=1;i #include -#include #include #include "CCGShader.h" #include #include +#undef Zero // DirectXMath uses Zero as a variable name +#include "DirectXMath/Inc/DirectXMath.h" + +using namespace DirectX; class CD3DCG { @@ -219,8 +222,8 @@ private: LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration; std::vector parameterMap; - D3DXVECTOR2 outputSize; - D3DXVECTOR2 textureSize; + XMFLOAT2 outputSize; + XMFLOAT2 textureSize; _shaderPass() {cgVertexProgram=NULL; cgFragmentProgram=NULL; @@ -231,8 +234,8 @@ private: typedef struct _prevPass { LPDIRECT3DTEXTURE9 tex; LPDIRECT3DVERTEXBUFFER9 vertexBuffer; - D3DXVECTOR2 imageSize; - D3DXVECTOR2 textureSize; + XMFLOAT2 imageSize; + XMFLOAT2 textureSize; _prevPass() {tex=NULL; vertexBuffer=NULL;} _prevPass(const shaderPass &pass) {tex = pass.tex; @@ -253,10 +256,10 @@ private: bool shaderLoaded; void checkForCgError(const char *situation); - void setVertexStream(IDirect3DVertexBuffer9 *vertexBuffer,D3DXVECTOR2 inputSize,D3DXVECTOR2 textureSize,D3DXVECTOR2 outputSize); + void setVertexStream(IDirect3DVertexBuffer9 *vertexBuffer, XMFLOAT2 inputSize, XMFLOAT2 textureSize, XMFLOAT2 outputSize); void setViewport(DWORD x, DWORD y, DWORD width, DWORD height); void setShaderVars(int pass); - void ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, D3DXVECTOR2 &texSize, D3DXVECTOR2 wantedSize,bool renderTarget, bool useFloat = false); + void ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, XMFLOAT2 &texSize, XMFLOAT2 wantedSize,bool renderTarget, bool useFloat = false); void fillParameterMap(std::vector &map, CGparameter param); void setupVertexDeclaration(shaderPass &pass); void calculateMatrix(); @@ -264,14 +267,14 @@ private: LPDIRECT3DDEVICE9 pDevice; CGcontext cgContext; unsigned int frameCnt; - D3DXMATRIX mvp; + XMFLOAT4X4 mvp; public: CD3DCG(CGcontext cgContext,LPDIRECT3DDEVICE9 pDevice); ~CD3DCG(void); bool LoadShader(const TCHAR *shaderFile); - void Render(LPDIRECT3DTEXTURE9 &origTex, D3DXVECTOR2 textureSize, D3DXVECTOR2 inputSize, D3DXVECTOR2 viewportSize, D3DXVECTOR2 windowSize); + void Render(LPDIRECT3DTEXTURE9 &origTex, XMFLOAT2 textureSize, XMFLOAT2 inputSize, XMFLOAT2 viewportSize, XMFLOAT2 windowSize); void ClearPasses(); void OnLostDevice(); void OnResetDevice(); diff --git a/win32/CDirect3D.cpp b/win32/CDirect3D.cpp index 1f415781..2e28883a 100644 --- a/win32/CDirect3D.cpp +++ b/win32/CDirect3D.cpp @@ -190,7 +190,6 @@ ***********************************************************************************/ #pragma comment( lib, "d3d9" ) -#pragma comment( lib, "d3dx9" ) #include "cdirect3d.h" #include "win32_display.h" @@ -198,7 +197,7 @@ #include "../gfx.h" #include "../display.h" #include "wsnes9x.h" -#include +#include "dxerr.h" #include #include "CXML.h" @@ -239,7 +238,6 @@ CDirect3D::CDirect3D() for(int i = 0; i < MAX_SHADER_TEXTURES; i++) { rubyLUT[i] = NULL; } - effect=NULL; shader_type = D3D_SHADER_NONE; shaderTimer = 1.0f; shaderTimeStart = 0; @@ -384,15 +382,14 @@ void CDirect3D::DeInitialize() bool CDirect3D::SetShader(const TCHAR *file) { SetShaderCG(NULL); - SetShaderHLSL(NULL); shader_type = D3D_SHADER_NONE; if(file!=NULL && (lstrlen(file)>3 && _tcsncicmp(&file[lstrlen(file)-3],TEXT(".cg"),3)==0) || (lstrlen(file)>4 && _tcsncicmp(&file[lstrlen(file)-4],TEXT(".cgp"),4)==0)){ return SetShaderCG(file); - } else { - return SetShaderHLSL(file); } + + return true; } void CDirect3D::checkForCgError(const char *situation) @@ -432,194 +429,6 @@ bool CDirect3D::SetShaderCG(const TCHAR *file) return true; } -bool CDirect3D::SetShaderHLSL(const TCHAR *file) -{ - //MUDLORD: the guts - //Compiles a shader from files on disc - //Sets LUT textures to texture files in PNG format. - - TCHAR folder[MAX_PATH]; - TCHAR rubyLUTfileName[MAX_PATH]; - TCHAR *slash; - - TCHAR errorMsg[MAX_PATH + 50]; - - shaderTimer = 1.0f; - shaderTimeStart = 0; - shaderTimeElapsed = 0; - - if(effect) { - effect->Release(); - effect = NULL; - } - for(int i = 0; i < MAX_SHADER_TEXTURES; i++) { - if (rubyLUT[i] != NULL) { - rubyLUT[i]->Release(); - rubyLUT[i] = NULL; - } - } - if (file == NULL || *file==TEXT('\0')) - return true; - - CXML xml; - - if(!xml.loadXmlFile(file)) - return false; - - TCHAR *lang = xml.getAttribute(TEXT("/shader"),TEXT("language")); - - if(lstrcmpi(lang,TEXT("hlsl"))) { - _stprintf(errorMsg,TEXT("Shader language is <%s>, expected in file:\n%s"),lang,file); - MessageBox(NULL, errorMsg, TEXT("Shader Loading Error"), MB_OK|MB_ICONEXCLAMATION); - return false; - } - - TCHAR *shaderText = xml.getNodeContent(TEXT("/shader/source")); - - if(!shaderText) { - _stprintf(errorMsg,TEXT("No HLSL shader program in file:\n%s"),file); - MessageBox(NULL, errorMsg, TEXT("Shader Loading Error"), - MB_OK|MB_ICONEXCLAMATION); - return false; - } - - LPD3DXBUFFER pBufferErrors = NULL; -#ifdef UNICODE - HRESULT hr = D3DXCreateEffect( pDevice,WideToCP(shaderText,CP_ACP),strlen(WideToCP(shaderText,CP_ACP)),NULL, NULL, - D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, NULL, &effect, - &pBufferErrors ); -#else - HRESULT hr = D3DXCreateEffect( pDevice,shaderText,strlen(shaderText),NULL, NULL, - D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, NULL, &effect, - &pBufferErrors ); -#endif - - if( FAILED(hr) ) { - _stprintf(errorMsg,TEXT("Error parsing HLSL shader file:\n%s"),file); - MessageBox(NULL, errorMsg, TEXT("Shader Loading Error"), MB_OK|MB_ICONEXCLAMATION); - if(pBufferErrors) { - LPVOID pCompilErrors = pBufferErrors->GetBufferPointer(); - MessageBox(NULL, (const TCHAR*)pCompilErrors, TEXT("FX Compile Error"), - MB_OK|MB_ICONEXCLAMATION); - } - return false; - } - - lstrcpy(folder,file); - slash = _tcsrchr(folder,TEXT('\\')); - if(slash) - *(slash+1)=TEXT('\0'); - else - *folder=TEXT('\0'); - SetCurrentDirectory(S9xGetDirectoryT(DEFAULT_DIR)); - - for(int i = 0; i < MAX_SHADER_TEXTURES; i++) { - _stprintf(rubyLUTfileName, TEXT("%srubyLUT%d.png"), folder, i); - hr = D3DXCreateTextureFromFile(pDevice,rubyLUTfileName,&rubyLUT[i]); - if FAILED(hr){ - rubyLUT[i] = NULL; - } - } - - D3DXHANDLE hTech; - effect->FindNextValidTechnique(NULL,&hTech); - effect->SetTechnique( hTech ); - shader_type = D3D_SHADER_HLSL; - return true; -} - -void CDirect3D::SetShaderVars(bool setMatrix) -{ - if(shader_type == D3D_SHADER_HLSL) { - D3DXVECTOR4 rubyTextureSize; - D3DXVECTOR4 rubyInputSize; - D3DXVECTOR4 rubyOutputSize; - D3DXHANDLE rubyTimer; - - int shaderTime = GetTickCount(); - shaderTimeElapsed += shaderTime - shaderTimeStart; - shaderTimeStart = shaderTime; - if(shaderTimeElapsed > 100) { - shaderTimeElapsed = 0; - shaderTimer += 0.01f; - } - rubyTextureSize.x = rubyTextureSize.y = (float)quadTextureSize; - rubyTextureSize.z = rubyTextureSize.w = 1.0 / quadTextureSize; - rubyInputSize.x = (float)afterRenderWidth; - rubyInputSize.y = (float)afterRenderHeight; - rubyInputSize.z = 1.0 / rubyInputSize.y; - rubyInputSize.w = 1.0 / rubyInputSize.z; - rubyOutputSize.x = GUI.Stretch?(float)dPresentParams.BackBufferWidth:(float)afterRenderWidth; - rubyOutputSize.y = GUI.Stretch?(float)dPresentParams.BackBufferHeight:(float)afterRenderHeight; - rubyOutputSize.z = 1.0 / rubyOutputSize.y; - rubyOutputSize.w = 1.0 / rubyOutputSize.x; - rubyTimer = effect->GetParameterByName(0, "rubyTimer"); - - effect->SetFloat(rubyTimer, shaderTimer); - effect->SetVector("rubyTextureSize", &rubyTextureSize); - effect->SetVector("rubyInputSize", &rubyInputSize); - effect->SetVector("rubyOutputSize", &rubyOutputSize); - - effect->SetTexture("rubyTexture", drawSurface); - for(int i = 0; i < MAX_SHADER_TEXTURES; i++) { - char rubyLUTName[256]; - sprintf(rubyLUTName, "rubyLUT%d", i); - if (rubyLUT[i] != NULL) { - effect->SetTexture( rubyLUTName, rubyLUT[i] ); - } - } - }/* else if(shader_type == D3D_SHADER_CG) { - - D3DXVECTOR2 videoSize; - D3DXVECTOR2 textureSize; - D3DXVECTOR2 outputSize; - float frameCnt; - videoSize.x = (float)afterRenderWidth; - videoSize.y = (float)afterRenderHeight; - textureSize.x = textureSize.y = (float)quadTextureSize; - outputSize.x = GUI.Stretch?(float)dPresentParams.BackBufferWidth:(float)afterRenderWidth; - outputSize.y = GUI.Stretch?(float)dPresentParams.BackBufferHeight:(float)afterRenderHeight; - frameCnt = (float)++frameCount; - videoSize = textureSize; - -#define setProgramUniform(program,varname,floats)\ -{\ - CGparameter cgp = cgGetNamedParameter(program, varname);\ - if(cgp)\ - cgD3D9SetUniform(cgp,floats);\ -}\ - - setProgramUniform(cgFragmentProgram,"IN.video_size",&videoSize); - setProgramUniform(cgFragmentProgram,"IN.texture_size",&textureSize); - setProgramUniform(cgFragmentProgram,"IN.output_size",&outputSize); - setProgramUniform(cgFragmentProgram,"IN.frame_count",&frameCnt); - - setProgramUniform(cgVertexProgram,"IN.video_size",&videoSize); - setProgramUniform(cgVertexProgram,"IN.texture_size",&textureSize); - setProgramUniform(cgVertexProgram,"IN.output_size",&outputSize); - setProgramUniform(cgVertexProgram,"IN.frame_count",&frameCnt); - - if(setMatrix) { - D3DXMATRIX matWorld; - D3DXMATRIX matView; - D3DXMATRIX matProj; - D3DXMATRIX mvp; - - pDevice->GetTransform(D3DTS_WORLD,&matWorld); - pDevice->GetTransform(D3DTS_VIEW,&matView); - pDevice->GetTransform(D3DTS_PROJECTION,&matProj); - - mvp = matWorld * matView * matProj; - D3DXMatrixTranspose(&mvp,&mvp); - - CGparameter cgpModelViewProj = cgGetNamedParameter(cgVertexProgram, "modelViewProj"); - - if(cgpModelViewProj) - cgD3D9SetUniformMatrix(cgpModelViewProj,&mvp); - } - }*/ -} - /* CDirect3D::Render does the actual rendering, changes the draw surface if necessary and recalculates the vertex information if filter output size changes @@ -691,44 +500,27 @@ void CDirect3D::Render(SSurface Src) pDevice->SetVertexDeclaration(vertexDeclaration); pDevice->SetStreamSource(0,vertexBuffer,0,sizeof(VERTEX)); - if (shader_type == D3D_SHADER_HLSL) { - SetShaderVars(); - SetFiltering(); - - UINT passes; - pDevice->BeginScene(); - hr = effect->Begin(&passes, 0); - for(UINT pass = 0; pass < passes; pass++ ) { - effect->BeginPass(pass); - pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2); - effect->EndPass(); - } - effect->End(); - pDevice->EndScene(); - - } else { - if(shader_type == D3D_SHADER_CG) { - RECT displayRect; - //Get maximum rect respecting AR setting - displayRect=CalculateDisplayRect(dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight, - dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight); - cgShader->Render(drawSurface, - D3DXVECTOR2((float)quadTextureSize, (float)quadTextureSize), - D3DXVECTOR2((float)afterRenderWidth, (float)afterRenderHeight), - D3DXVECTOR2((float)(displayRect.right - displayRect.left), - (float)(displayRect.bottom - displayRect.top)), - D3DXVECTOR2((float)dPresentParams.BackBufferWidth, (float)dPresentParams.BackBufferHeight)); - } - - SetFiltering(); - - pDevice->SetVertexDeclaration(vertexDeclaration); - - pDevice->BeginScene(); - pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2); - pDevice->EndScene(); + if(shader_type == D3D_SHADER_CG) { + RECT displayRect; + //Get maximum rect respecting AR setting + displayRect=CalculateDisplayRect(dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight, + dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight); + cgShader->Render(drawSurface, + XMFLOAT2((float)quadTextureSize, (float)quadTextureSize), + XMFLOAT2((float)afterRenderWidth, (float)afterRenderHeight), + XMFLOAT2((float)(displayRect.right - displayRect.left), + (float)(displayRect.bottom - displayRect.top)), + XMFLOAT2((float)dPresentParams.BackBufferWidth, (float)dPresentParams.BackBufferHeight)); } + SetFiltering(); + + pDevice->SetVertexDeclaration(vertexDeclaration); + + pDevice->BeginScene(); + pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2); + pDevice->EndScene(); + pDevice->Present(NULL, NULL, NULL, NULL); if (GUI.ReduceInputLag) @@ -863,16 +655,14 @@ void CDirect3D::SetupVertices() void CDirect3D::SetViewport() { - D3DXMATRIX matIdentity; - D3DXMATRIX matProjection; + XMMATRIX matIdentity; + XMMATRIX matProjection; - D3DXMatrixOrthoOffCenterLH(&matProjection,0.0f,1.0f,0.0f,1.0f,0.0f,1.0f); - D3DXMatrixIdentity(&matIdentity); - pDevice->SetTransform(D3DTS_WORLD,&matIdentity); - pDevice->SetTransform(D3DTS_VIEW,&matIdentity); - pDevice->SetTransform(D3DTS_PROJECTION,&matProjection); - - SetShaderVars(true); + matProjection = XMMatrixOrthographicOffCenterLH(0.0f,1.0f,0.0f,1.0f,0.0f,1.0f); + matIdentity = XMMatrixIdentity(); + pDevice->SetTransform(D3DTS_WORLD,(D3DMATRIX*)&matIdentity); + pDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&matIdentity); + pDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&matProjection); RECT drawRect = CalculateDisplayRect(afterRenderWidth,afterRenderHeight,dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight); D3DVIEWPORT9 viewport; @@ -931,9 +721,6 @@ bool CDirect3D::ResetDevice() cgD3D9SetDevice(NULL); } - if(effect) - effect->OnLostDevice(); - //zero or unknown values result in the current window size/display settings dPresentParams.BackBufferWidth = 0; dPresentParams.BackBufferHeight = 0; @@ -961,9 +748,6 @@ bool CDirect3D::ResetDevice() return false; } - if(effect) - effect->OnResetDevice(); - if(cgAvailable) { cgD3D9SetDevice(pDevice); cgShader->OnResetDevice(); diff --git a/win32/CDirect3D.h b/win32/CDirect3D.h index 904318fe..5af71d08 100644 --- a/win32/CDirect3D.h +++ b/win32/CDirect3D.h @@ -195,7 +195,6 @@ #define MAX_SHADER_TEXTURES 8 #include -#include #include #include "cgFunctions.h" @@ -239,7 +238,6 @@ private: static const D3DVERTEXELEMENT9 vertexElems[4]; LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration; - LPD3DXEFFECT effect; LPDIRECT3DTEXTURE9 rubyLUT[MAX_SHADER_TEXTURES]; CGcontext cgContext; current_d3d_shader_type shader_type; @@ -260,9 +258,7 @@ private: void SetupVertices(); bool ResetDevice(); void SetFiltering(); - void SetShaderVars(bool setMatrix = false); bool SetShader(const TCHAR *file); - bool SetShaderHLSL(const TCHAR *file); void checkForCgError(const char *situation); bool SetShaderCG(const TCHAR *file); diff --git a/win32/CGLCG.cpp b/win32/CGLCG.cpp index 01eb6628..d7a5e538 100644 --- a/win32/CGLCG.cpp +++ b/win32/CGLCG.cpp @@ -755,191 +755,3 @@ void CGLCG::resetAttribParams() cgAttribParams.clear(); } -#ifdef HAVE_LIBPNG -bool CGLCG::loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, GLubyte **outData) { - png_structp png_ptr; - png_infop info_ptr; - unsigned int sig_read = 0; - int color_type, interlace_type; - FILE *fp; - - if ((fp = _tfopen(name, TEXT("rb"))) == NULL) - return false; - - /* Create and initialize the png_struct - * with the desired error handler - * functions. If you want to use the - * default stderr and longjump method, - * you can supply NULL for the last - * three parameters. We also supply the - * the compiler header file version, so - * that we know if the application - * was compiled with a compatible version - * of the library. REQUIRED - */ - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); - - if (png_ptr == NULL) { - fclose(fp); - return false; - } - - /* Allocate/initialize the memory - * for image information. REQUIRED. */ - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - fclose(fp); - png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - return false; - } - - /* Set error handling if you are - * using the setjmp/longjmp method - * (this is the normal method of - * doing things with libpng). - * REQUIRED unless you set up - * your own error handlers in - * the png_create_read_struct() - * earlier. - */ - if (setjmp(png_jmpbuf(png_ptr))) { - /* Free all of the memory associated - * with the png_ptr and info_ptr */ - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - fclose(fp); - /* If we get here, we had a - * problem reading the file */ - return false; - } - - /* Set up the output control if - * you are using standard C streams */ - png_init_io(png_ptr, fp); - - /* If we have already - * read some of the signature */ - png_set_sig_bytes(png_ptr, sig_read); - - /* - * If you have enough memory to read - * in the entire image at once, and - * you need to specify only - * transforms that can be controlled - * with one of the PNG_TRANSFORM_* - * bits (this presently excludes - * dithering, filling, setting - * background, and doing gamma - * adjustment), then you can read the - * entire image (including pixels) - * into the info structure with this - * call - * - * PNG_TRANSFORM_STRIP_16 | - * PNG_TRANSFORM_PACKING forces 8 bit - * PNG_TRANSFORM_EXPAND forces to - * expand a palette into RGB - */ - png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, (png_voidp)NULL); - - outWidth = png_get_image_width(png_ptr, info_ptr); - outHeight = png_get_image_height(png_ptr, info_ptr); - switch (png_get_color_type(png_ptr, info_ptr)) { - case PNG_COLOR_TYPE_RGBA: - outHasAlpha = true; - break; - case PNG_COLOR_TYPE_RGB: - outHasAlpha = false; - break; - default: - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - fclose(fp); - return false; - } - unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr); - *outData = (unsigned char*) malloc(row_bytes * outHeight); - - png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr); - - for (int i = 0; i < outHeight; i++) { - memcpy(*outData+(row_bytes * i), row_pointers[i], row_bytes); - } - - /* Clean up after the read, - * and free any memory allocated */ - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - - /* Close the file */ - fclose(fp); - - /* That's it */ - return true; -} -#else -bool CGLCG::loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, GLubyte **outData) { - /* No PNG support */ - return false; -} -#endif - -bool CGLCG::loadTGA(const TCHAR *filename, STGA& tgaFile) -{ - FILE *file; - unsigned char type[4]; - unsigned char info[6]; - - file = _tfopen(filename, TEXT("rb")); - - if (!file) - return false; - - fread (&type, sizeof (char), 3, file); - fseek (file, 12, SEEK_SET); - fread (&info, sizeof (char), 6, file); - - //image type either 2 (color) or 3 (greyscale) - if (type[1] != 0 || (type[2] != 2 && type[2] != 3)) - { - fclose(file); - return false; - } - - tgaFile.width = info[0] + info[1] * 256; - tgaFile.height = info[2] + info[3] * 256; - tgaFile.byteCount = info[4] / 8; - - if (tgaFile.byteCount != 3 && tgaFile.byteCount != 4) { - fclose(file); - return false; - } - - long imageSize = tgaFile.width * tgaFile.height * tgaFile.byteCount; - - //allocate memory for image data - unsigned char *tempBuf = new unsigned char[imageSize]; - tgaFile.data = new unsigned char[tgaFile.width * tgaFile.height * 4]; - - //read in image data - fread(tempBuf, sizeof(unsigned char), imageSize, file); - - //swap line order and convert to RBGA - for(int i=0;i #include +#include "image_functions.h" typedef struct _xySize { double x; double y; - operator CONST FLOAT* () const; } xySize; class CGLCG { private: - typedef struct _STGA { - _STGA() {data = (unsigned char*)0; - width = 0; - height = 0; - byteCount = 0;} - - ~_STGA() { delete[] data; data = 0; } - - void destroy() { delete[] data; data = 0; } - - int width; - int height; - unsigned char byteCount; - unsigned char* data; - } STGA; typedef struct _shaderPass { cgScaleParams scaleParams; bool linearFilter; @@ -267,8 +252,6 @@ private: void setTexCoords(int pass,xySize inputSize,xySize textureSize,bool topdown=false); void setShaderVars(int pass); void resetAttribParams(); - bool loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, GLubyte **outData); - bool loadTGA(const TCHAR *filename, STGA& tgaFile); CGcontext cgContext; unsigned int frameCnt; diff --git a/win32/CXAudio2.cpp b/win32/CXAudio2.cpp index 3c55e36e..9ba80ef1 100644 --- a/win32/CXAudio2.cpp +++ b/win32/CXAudio2.cpp @@ -195,7 +195,7 @@ #include "../apu/apu.h" #include "wsnes9x.h" #include -#include +#include "dxerr.h" /* CXAudio2 Implements audio output through XAudio2. diff --git a/win32/DirectXMath b/win32/DirectXMath new file mode 160000 index 00000000..ffb2edbd --- /dev/null +++ b/win32/DirectXMath @@ -0,0 +1 @@ +Subproject commit ffb2edbd1627e9eec75f68b4ff00e0861ad84ebe diff --git a/win32/image_functions.cpp b/win32/image_functions.cpp new file mode 100644 index 00000000..cc95fc74 --- /dev/null +++ b/win32/image_functions.cpp @@ -0,0 +1,245 @@ +#include "snes9x.h" +#include +#include +#include "dxerr.h" +#include "image_functions.h" + +#ifdef HAVE_LIBPNG +bool loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, unsigned char **outData) { + png_structp png_ptr; + png_infop info_ptr; + unsigned int sig_read = 0; + int color_type, interlace_type; + FILE *fp; + + if ((fp = _tfopen(name, TEXT("rb"))) == NULL) + return false; + + /* Create and initialize the png_struct + * with the desired error handler + * functions. If you want to use the + * default stderr and longjump method, + * you can supply NULL for the last + * three parameters. We also supply the + * the compiler header file version, so + * that we know if the application + * was compiled with a compatible version + * of the library. REQUIRED + */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL); + + if (png_ptr == NULL) { + fclose(fp); + return false; + } + + /* Allocate/initialize the memory + * for image information. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + fclose(fp); + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + return false; + } + + /* Set error handling if you are + * using the setjmp/longjmp method + * (this is the normal method of + * doing things with libpng). + * REQUIRED unless you set up + * your own error handlers in + * the png_create_read_struct() + * earlier. + */ + if (setjmp(png_jmpbuf(png_ptr))) { + /* Free all of the memory associated + * with the png_ptr and info_ptr */ + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fp); + /* If we get here, we had a + * problem reading the file */ + return false; + } + + /* Set up the output control if + * you are using standard C streams */ + png_init_io(png_ptr, fp); + + /* If we have already + * read some of the signature */ + png_set_sig_bytes(png_ptr, sig_read); + + /* + * If you have enough memory to read + * in the entire image at once, and + * you need to specify only + * transforms that can be controlled + * with one of the PNG_TRANSFORM_* + * bits (this presently excludes + * dithering, filling, setting + * background, and doing gamma + * adjustment), then you can read the + * entire image (including pixels) + * into the info structure with this + * call + * + * PNG_TRANSFORM_STRIP_16 | + * PNG_TRANSFORM_PACKING forces 8 bit + * PNG_TRANSFORM_EXPAND forces to + * expand a palette into RGB + */ + png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, (png_voidp)NULL); + + outWidth = png_get_image_width(png_ptr, info_ptr); + outHeight = png_get_image_height(png_ptr, info_ptr); + switch (png_get_color_type(png_ptr, info_ptr)) { + case PNG_COLOR_TYPE_RGBA: + outHasAlpha = true; + break; + case PNG_COLOR_TYPE_RGB: + outHasAlpha = false; + break; + default: + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + fclose(fp); + return false; + } + unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr); + *outData = (unsigned char*)malloc(row_bytes * outHeight); + + png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr); + + for (int i = 0; i < outHeight; i++) { + memcpy(*outData + (row_bytes * i), row_pointers[i], row_bytes); + } + + /* Clean up after the read, + * and free any memory allocated */ + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + + /* Close the file */ + fclose(fp); + + /* That's it */ + return true; +} +#else +bool loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, GLubyte **outData) { + /* No PNG support */ + return false; +} +#endif + +bool loadTGA(const TCHAR *filename, STGA& tgaFile) +{ + FILE *file; + unsigned char type[4]; + unsigned char info[6]; + + file = _tfopen(filename, TEXT("rb")); + + if (!file) + return false; + + fread(&type, sizeof(char), 3, file); + fseek(file, 12, SEEK_SET); + fread(&info, sizeof(char), 6, file); + + //image type either 2 (color) or 3 (greyscale) + if (type[1] != 0 || (type[2] != 2 && type[2] != 3)) + { + fclose(file); + return false; + } + + tgaFile.width = info[0] + info[1] * 256; + tgaFile.height = info[2] + info[3] * 256; + tgaFile.byteCount = info[4] / 8; + + if (tgaFile.byteCount != 3 && tgaFile.byteCount != 4) { + fclose(file); + return false; + } + + long imageSize = tgaFile.width * tgaFile.height * tgaFile.byteCount; + + //allocate memory for image data + unsigned char *tempBuf = new unsigned char[imageSize]; + tgaFile.data = new unsigned char[tgaFile.width * tgaFile.height * 4]; + + //read in image data + fread(tempBuf, sizeof(unsigned char), imageSize, file); + + //swap line order and convert to RBGA + for (int i = 0; iCreateTexture(width, height, 1, 0, hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, ppTexture, NULL); + if (SUCCEEDED(hr)) { + LPDIRECT3DTEXTURE9 pTexture = *ppTexture; + D3DLOCKED_RECT lr; + HRESULT hr; + + if (FAILED(hr = pTexture->LockRect(0, &lr, NULL, 0))) { + pTexture->Release(); + DXTRACE_ERR_MSGBOX(TEXT("Unable to lock texture"), hr); + } + else { + memcpy(lr.pBits, bytes, lr.Pitch * height); + pTexture->UnlockRect(0); + ret = true; + } + } + + if (needFree) + free(bytes); + + return ret; +} diff --git a/win32/image_functions.h b/win32/image_functions.h new file mode 100644 index 00000000..981873aa --- /dev/null +++ b/win32/image_functions.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +typedef struct _STGA { + _STGA() { + data = (unsigned char*)0; + width = 0; + height = 0; + byteCount = 0; + } + + ~_STGA() { destroy(); } + + void destroy() { if (data) { delete[] data; data = 0; } } + + int width; + int height; + unsigned char byteCount; + unsigned char* data; +} STGA; + +bool loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, unsigned char **outData); +bool loadTGA(const TCHAR *filename, STGA& tgaFile); +bool d3d_create_texture_from_file(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, LPDIRECT3DTEXTURE9 *ppTexture); diff --git a/win32/snes9xw.vcxproj b/win32/snes9xw.vcxproj index 65a43641..914dc713 100644 --- a/win32/snes9xw.vcxproj +++ b/win32/snes9xw.vcxproj @@ -433,6 +433,7 @@ + @@ -566,6 +567,7 @@ + diff --git a/win32/snes9xw.vcxproj.filters b/win32/snes9xw.vcxproj.filters index 9be9a5ca..84f147ef 100644 --- a/win32/snes9xw.vcxproj.filters +++ b/win32/snes9xw.vcxproj.filters @@ -273,6 +273,9 @@ GUI\VideoDriver + + GUI\VideoDriver + @@ -587,6 +590,9 @@ GUI\VideoDriver + + GUI\VideoDriver +