win32: switch to DirectXMath to remove d3d9x dependency, remove HLSL

This commit is contained in:
OV2 2018-08-07 01:16:41 +02:00
parent ada43c7992
commit 55e5cd6272
13 changed files with 355 additions and 510 deletions

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "win32/zlib/src"] [submodule "win32/zlib/src"]
path = win32/zlib/src path = win32/zlib/src
url = https://github.com/madler/zlib.git url = https://github.com/madler/zlib.git
[submodule "win32/DirectXMath"]
path = win32/DirectXMath
url = https://github.com/Microsoft/DirectXMath

View File

@ -192,9 +192,10 @@
#include "wsnes9x.h" #include "wsnes9x.h"
#include "win32_display.h" #include "win32_display.h"
#include "snes9x.h" #include "snes9x.h"
#include <Dxerr.h> #include "dxerr.h"
#include <png.h> #include <png.h>
#include "CDirect3D.h" #include "CDirect3D.h"
#include "image_functions.h"
#ifndef max #ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b)) #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); _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH);
hr = D3DXCreateTextureFromFileEx( if(!d3d_create_texture_from_file(pDevice, tempPath, &tex.tex)){
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){
tex.tex = NULL; tex.tex = NULL;
} }
lookupTextures.push_back(tex); lookupTextures.push_back(tex);
@ -431,12 +417,12 @@ bool CD3DCG::LoadShader(const TCHAR *shaderFile)
return true; return true;
} }
void CD3DCG::ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, D3DXVECTOR2 &texSize, void CD3DCG::ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, XMFLOAT2 &texSize,
D3DXVECTOR2 wantedSize,bool renderTarget,bool useFloat) XMFLOAT2 wantedSize,bool renderTarget,bool useFloat)
{ {
HRESULT hr; HRESULT hr;
if(!tex || texSize != wantedSize) { if(!tex || texSize.x != wantedSize.x || texSize.y != wantedSize.y) {
if(tex) if(tex)
tex->Release(); tex->Release();
@ -459,7 +445,7 @@ void CD3DCG::ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, D3DXVECTOR2 &texSize,
} }
void CD3DCG::setVertexStream(IDirect3DVertexBuffer9 *vertexBuffer, void CD3DCG::setVertexStream(IDirect3DVertexBuffer9 *vertexBuffer,
D3DXVECTOR2 inputSize,D3DXVECTOR2 textureSize,D3DXVECTOR2 outputSize) XMFLOAT2 inputSize, XMFLOAT2 textureSize, XMFLOAT2 outputSize)
{ {
float tX = inputSize.x / textureSize.x; float tX = inputSize.x / textureSize.x;
float tY = inputSize.y / textureSize.y; float tY = inputSize.y / textureSize.y;
@ -500,8 +486,8 @@ void CD3DCG::setVertexStream(IDirect3DVertexBuffer9 *vertexBuffer,
pDevice->SetStreamSource(3,vertexBuffer,0,sizeof(VERTEX)); pDevice->SetStreamSource(3,vertexBuffer,0,sizeof(VERTEX));
} }
void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, D3DXVECTOR2 textureSize, void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, XMFLOAT2 textureSize,
D3DXVECTOR2 inputSize, D3DXVECTOR2 viewportSize, D3DXVECTOR2 windowSize) XMFLOAT2 inputSize, XMFLOAT2 viewportSize, XMFLOAT2 windowSize)
{ {
LPDIRECT3DSURFACE9 pRenderSurface = NULL,pBackBuffer = NULL; LPDIRECT3DSURFACE9 pRenderSurface = NULL,pBackBuffer = NULL;
frameCnt++; frameCnt++;
@ -553,7 +539,7 @@ void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, D3DXVECTOR2 textureSize,
/* make sure the render target exists and has an appropriate size, /* make sure the render target exists and has an appropriate size,
then set as current render target with last pass as source 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); shaderPasses[i].tex->GetSurfaceLevel(0,&pRenderSurface);
pDevice->SetTexture(0, shaderPasses[i-1].tex); pDevice->SetTexture(0, shaderPasses[i-1].tex);
pDevice->SetRenderTarget(0,pRenderSurface); 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); setViewport(displayRect.left,displayRect.top,displayRect.right - displayRect.left,displayRect.bottom - displayRect.top);
setVertexStream(shaderPasses.back().vertexBuffer, setVertexStream(shaderPasses.back().vertexBuffer,
shaderPasses.back().outputSize,shaderPasses.back().textureSize, 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->SetVertexShader(NULL);
pDevice->SetPixelShader(NULL); pDevice->SetPixelShader(NULL);
} }
void CD3DCG::calculateMatrix() void CD3DCG::calculateMatrix()
{ {
D3DXMATRIX matWorld; XMMATRIX matWorld;
D3DXMATRIX matView; XMMATRIX matView;
D3DXMATRIX matProj; XMMATRIX matProj;
pDevice->GetTransform(D3DTS_WORLD,&matWorld); pDevice->GetTransform(D3DTS_WORLD, (D3DMATRIX*)&matWorld);
pDevice->GetTransform(D3DTS_VIEW,&matView); pDevice->GetTransform(D3DTS_VIEW, (D3DMATRIX*)&matView);
pDevice->GetTransform(D3DTS_PROJECTION,&matProj); pDevice->GetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&matProj);
mvp = matWorld * matView * matProj; XMStoreFloat4x4(&mvp, XMMatrixTranspose(XMMatrixMultiply(matProj, XMMatrixMultiply(matWorld, matView))));
D3DXMatrixTranspose(&mvp,&mvp);
} }
void CD3DCG::setViewport(DWORD x, DWORD y, DWORD width, DWORD height) 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) void CD3DCG::setShaderVars(int pass)
{ {
D3DXVECTOR2 inputSize = shaderPasses[pass-1].outputSize; XMFLOAT2 inputSize = shaderPasses[pass-1].outputSize;
D3DXVECTOR2 textureSize = shaderPasses[pass-1].textureSize; XMFLOAT2 textureSize = shaderPasses[pass-1].textureSize;
D3DXVECTOR2 outputSize = shaderPasses[pass].outputSize; XMFLOAT2 outputSize = shaderPasses[pass].outputSize;
/* mvp paramater /* mvp paramater
*/ */
CGparameter cgpModelViewProj = cgGetNamedParameter(shaderPasses[pass].cgVertexProgram, "modelViewProj"); CGparameter cgpModelViewProj = cgGetNamedParameter(shaderPasses[pass].cgVertexProgram, "modelViewProj");
if(cgpModelViewProj) if(cgpModelViewProj)
cgD3D9SetUniformMatrix(cgpModelViewProj,&mvp); cgD3D9SetUniformMatrix(cgpModelViewProj,(D3DMATRIX*)&mvp);
#define setProgramUniform(pass,varname,floats)\ #define setProgramUniform(pass,varname,floats)\
{\ {\
@ -720,16 +705,16 @@ void CD3DCG::setShaderVars(int pass)
/* ORIG parameter /* ORIG parameter
*/ */
setProgramUniform(pass,"ORIG.video_size",shaderPasses[0].outputSize); setProgramUniform(pass,"ORIG.video_size",&shaderPasses[0].outputSize);
setProgramUniform(pass,"ORIG.texture_size",shaderPasses[0].textureSize); setProgramUniform(pass,"ORIG.texture_size",&shaderPasses[0].textureSize);
setTextureParameter(pass,"ORIG.texture",shaderPasses[0].tex,shaderPasses[1].linearFilter); setTextureParameter(pass,"ORIG.texture",shaderPasses[0].tex,shaderPasses[1].linearFilter);
setTexCoordsParameter(pass,"ORIG.tex_coord",shaderPasses[1].vertexBuffer); setTexCoordsParameter(pass,"ORIG.tex_coord",shaderPasses[1].vertexBuffer);
/* PREV parameter /* PREV parameter
*/ */
if(prevPasses[0].tex) { if(prevPasses[0].tex) {
setProgramUniform(pass,"PREV.video_size",prevPasses[0].imageSize); setProgramUniform(pass,"PREV.video_size",&prevPasses[0].imageSize);
setProgramUniform(pass,"PREV.texture_size",prevPasses[0].textureSize); setProgramUniform(pass,"PREV.texture_size",&prevPasses[0].textureSize);
setTextureParameter(pass,"PREV.texture",prevPasses[0].tex,shaderPasses[1].linearFilter); setTextureParameter(pass,"PREV.texture",prevPasses[0].tex,shaderPasses[1].linearFilter);
setTexCoordsParameter(pass,"PREV.tex_coord",prevPasses[0].vertexBuffer); setTexCoordsParameter(pass,"PREV.tex_coord",prevPasses[0].vertexBuffer);
} }
@ -741,9 +726,9 @@ void CD3DCG::setShaderVars(int pass)
break; break;
char varname[100]; char varname[100];
sprintf(varname,"PREV%d.video_size",i); 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); 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); sprintf(varname,"PREV%d.texture",i);
setTextureParameter(pass,varname,prevPasses[i].tex,shaderPasses[1].linearFilter); setTextureParameter(pass,varname,prevPasses[i].tex,shaderPasses[1].linearFilter);
sprintf(varname,"PREV%d.tex_coord",i); sprintf(varname,"PREV%d.tex_coord",i);
@ -762,9 +747,9 @@ void CD3DCG::setShaderVars(int pass)
for(int i=1;i<pass-1;i++) { for(int i=1;i<pass-1;i++) {
char varname[100]; char varname[100];
sprintf(varname,"PASS%d.video_size",i); sprintf(varname,"PASS%d.video_size",i);
setProgramUniform(pass,varname,shaderPasses[i].outputSize); setProgramUniform(pass,varname,&shaderPasses[i].outputSize);
sprintf(varname,"PASS%d.texture_size",i); sprintf(varname,"PASS%d.texture_size",i);
setProgramUniform(pass,varname,shaderPasses[i].textureSize); setProgramUniform(pass,varname,&shaderPasses[i].textureSize);
sprintf(varname,"PASS%d.texture",i); sprintf(varname,"PASS%d.texture",i);
setTextureParameter(pass,varname,shaderPasses[i].tex,shaderPasses[i+1].linearFilter); setTextureParameter(pass,varname,shaderPasses[i].tex,shaderPasses[i+1].linearFilter);
sprintf(varname,"PASS%d.tex_coord",i); sprintf(varname,"PASS%d.tex_coord",i);

View File

@ -193,11 +193,14 @@
#include <vector> #include <vector>
#include <d3d9.h> #include <d3d9.h>
#include <d3dx9.h>
#include <windows.h> #include <windows.h>
#include "CCGShader.h" #include "CCGShader.h"
#include <vector> #include <vector>
#include <deque> #include <deque>
#undef Zero // DirectXMath uses Zero as a variable name
#include "DirectXMath/Inc/DirectXMath.h"
using namespace DirectX;
class CD3DCG class CD3DCG
{ {
@ -219,8 +222,8 @@ private:
LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration; LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration;
std::vector<parameterEntry> parameterMap; std::vector<parameterEntry> parameterMap;
D3DXVECTOR2 outputSize; XMFLOAT2 outputSize;
D3DXVECTOR2 textureSize; XMFLOAT2 textureSize;
_shaderPass() {cgVertexProgram=NULL; _shaderPass() {cgVertexProgram=NULL;
cgFragmentProgram=NULL; cgFragmentProgram=NULL;
@ -231,8 +234,8 @@ private:
typedef struct _prevPass { typedef struct _prevPass {
LPDIRECT3DTEXTURE9 tex; LPDIRECT3DTEXTURE9 tex;
LPDIRECT3DVERTEXBUFFER9 vertexBuffer; LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
D3DXVECTOR2 imageSize; XMFLOAT2 imageSize;
D3DXVECTOR2 textureSize; XMFLOAT2 textureSize;
_prevPass() {tex=NULL; _prevPass() {tex=NULL;
vertexBuffer=NULL;} vertexBuffer=NULL;}
_prevPass(const shaderPass &pass) {tex = pass.tex; _prevPass(const shaderPass &pass) {tex = pass.tex;
@ -253,10 +256,10 @@ private:
bool shaderLoaded; bool shaderLoaded;
void checkForCgError(const char *situation); 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 setViewport(DWORD x, DWORD y, DWORD width, DWORD height);
void setShaderVars(int pass); 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<parameterEntry> &map, CGparameter param); void fillParameterMap(std::vector<parameterEntry> &map, CGparameter param);
void setupVertexDeclaration(shaderPass &pass); void setupVertexDeclaration(shaderPass &pass);
void calculateMatrix(); void calculateMatrix();
@ -264,14 +267,14 @@ private:
LPDIRECT3DDEVICE9 pDevice; LPDIRECT3DDEVICE9 pDevice;
CGcontext cgContext; CGcontext cgContext;
unsigned int frameCnt; unsigned int frameCnt;
D3DXMATRIX mvp; XMFLOAT4X4 mvp;
public: public:
CD3DCG(CGcontext cgContext,LPDIRECT3DDEVICE9 pDevice); CD3DCG(CGcontext cgContext,LPDIRECT3DDEVICE9 pDevice);
~CD3DCG(void); ~CD3DCG(void);
bool LoadShader(const TCHAR *shaderFile); 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 ClearPasses();
void OnLostDevice(); void OnLostDevice();
void OnResetDevice(); void OnResetDevice();

View File

@ -190,7 +190,6 @@
***********************************************************************************/ ***********************************************************************************/
#pragma comment( lib, "d3d9" ) #pragma comment( lib, "d3d9" )
#pragma comment( lib, "d3dx9" )
#include "cdirect3d.h" #include "cdirect3d.h"
#include "win32_display.h" #include "win32_display.h"
@ -198,7 +197,7 @@
#include "../gfx.h" #include "../gfx.h"
#include "../display.h" #include "../display.h"
#include "wsnes9x.h" #include "wsnes9x.h"
#include <Dxerr.h> #include "dxerr.h"
#include <commctrl.h> #include <commctrl.h>
#include "CXML.h" #include "CXML.h"
@ -239,7 +238,6 @@ CDirect3D::CDirect3D()
for(int i = 0; i < MAX_SHADER_TEXTURES; i++) { for(int i = 0; i < MAX_SHADER_TEXTURES; i++) {
rubyLUT[i] = NULL; rubyLUT[i] = NULL;
} }
effect=NULL;
shader_type = D3D_SHADER_NONE; shader_type = D3D_SHADER_NONE;
shaderTimer = 1.0f; shaderTimer = 1.0f;
shaderTimeStart = 0; shaderTimeStart = 0;
@ -384,15 +382,14 @@ void CDirect3D::DeInitialize()
bool CDirect3D::SetShader(const TCHAR *file) bool CDirect3D::SetShader(const TCHAR *file)
{ {
SetShaderCG(NULL); SetShaderCG(NULL);
SetShaderHLSL(NULL);
shader_type = D3D_SHADER_NONE; shader_type = D3D_SHADER_NONE;
if(file!=NULL && if(file!=NULL &&
(lstrlen(file)>3 && _tcsncicmp(&file[lstrlen(file)-3],TEXT(".cg"),3)==0) || (lstrlen(file)>3 && _tcsncicmp(&file[lstrlen(file)-3],TEXT(".cg"),3)==0) ||
(lstrlen(file)>4 && _tcsncicmp(&file[lstrlen(file)-4],TEXT(".cgp"),4)==0)){ (lstrlen(file)>4 && _tcsncicmp(&file[lstrlen(file)-4],TEXT(".cgp"),4)==0)){
return SetShaderCG(file); return SetShaderCG(file);
} else {
return SetShaderHLSL(file);
} }
return true;
} }
void CDirect3D::checkForCgError(const char *situation) void CDirect3D::checkForCgError(const char *situation)
@ -432,194 +429,6 @@ bool CDirect3D::SetShaderCG(const TCHAR *file)
return true; 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 <HLSL> 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 /* CDirect3D::Render
does the actual rendering, changes the draw surface if necessary and recalculates does the actual rendering, changes the draw surface if necessary and recalculates
the vertex information if filter output size changes the vertex information if filter output size changes
@ -691,33 +500,17 @@ void CDirect3D::Render(SSurface Src)
pDevice->SetVertexDeclaration(vertexDeclaration); pDevice->SetVertexDeclaration(vertexDeclaration);
pDevice->SetStreamSource(0,vertexBuffer,0,sizeof(VERTEX)); 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) { if(shader_type == D3D_SHADER_CG) {
RECT displayRect; RECT displayRect;
//Get maximum rect respecting AR setting //Get maximum rect respecting AR setting
displayRect=CalculateDisplayRect(dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight, displayRect=CalculateDisplayRect(dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight,
dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight); dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight);
cgShader->Render(drawSurface, cgShader->Render(drawSurface,
D3DXVECTOR2((float)quadTextureSize, (float)quadTextureSize), XMFLOAT2((float)quadTextureSize, (float)quadTextureSize),
D3DXVECTOR2((float)afterRenderWidth, (float)afterRenderHeight), XMFLOAT2((float)afterRenderWidth, (float)afterRenderHeight),
D3DXVECTOR2((float)(displayRect.right - displayRect.left), XMFLOAT2((float)(displayRect.right - displayRect.left),
(float)(displayRect.bottom - displayRect.top)), (float)(displayRect.bottom - displayRect.top)),
D3DXVECTOR2((float)dPresentParams.BackBufferWidth, (float)dPresentParams.BackBufferHeight)); XMFLOAT2((float)dPresentParams.BackBufferWidth, (float)dPresentParams.BackBufferHeight));
} }
SetFiltering(); SetFiltering();
@ -727,7 +520,6 @@ void CDirect3D::Render(SSurface Src)
pDevice->BeginScene(); pDevice->BeginScene();
pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2); pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
pDevice->EndScene(); pDevice->EndScene();
}
pDevice->Present(NULL, NULL, NULL, NULL); pDevice->Present(NULL, NULL, NULL, NULL);
@ -863,16 +655,14 @@ void CDirect3D::SetupVertices()
void CDirect3D::SetViewport() void CDirect3D::SetViewport()
{ {
D3DXMATRIX matIdentity; XMMATRIX matIdentity;
D3DXMATRIX matProjection; XMMATRIX matProjection;
D3DXMatrixOrthoOffCenterLH(&matProjection,0.0f,1.0f,0.0f,1.0f,0.0f,1.0f); matProjection = XMMatrixOrthographicOffCenterLH(0.0f,1.0f,0.0f,1.0f,0.0f,1.0f);
D3DXMatrixIdentity(&matIdentity); matIdentity = XMMatrixIdentity();
pDevice->SetTransform(D3DTS_WORLD,&matIdentity); pDevice->SetTransform(D3DTS_WORLD,(D3DMATRIX*)&matIdentity);
pDevice->SetTransform(D3DTS_VIEW,&matIdentity); pDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&matIdentity);
pDevice->SetTransform(D3DTS_PROJECTION,&matProjection); pDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&matProjection);
SetShaderVars(true);
RECT drawRect = CalculateDisplayRect(afterRenderWidth,afterRenderHeight,dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight); RECT drawRect = CalculateDisplayRect(afterRenderWidth,afterRenderHeight,dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight);
D3DVIEWPORT9 viewport; D3DVIEWPORT9 viewport;
@ -931,9 +721,6 @@ bool CDirect3D::ResetDevice()
cgD3D9SetDevice(NULL); cgD3D9SetDevice(NULL);
} }
if(effect)
effect->OnLostDevice();
//zero or unknown values result in the current window size/display settings //zero or unknown values result in the current window size/display settings
dPresentParams.BackBufferWidth = 0; dPresentParams.BackBufferWidth = 0;
dPresentParams.BackBufferHeight = 0; dPresentParams.BackBufferHeight = 0;
@ -961,9 +748,6 @@ bool CDirect3D::ResetDevice()
return false; return false;
} }
if(effect)
effect->OnResetDevice();
if(cgAvailable) { if(cgAvailable) {
cgD3D9SetDevice(pDevice); cgD3D9SetDevice(pDevice);
cgShader->OnResetDevice(); cgShader->OnResetDevice();

View File

@ -195,7 +195,6 @@
#define MAX_SHADER_TEXTURES 8 #define MAX_SHADER_TEXTURES 8
#include <d3d9.h> #include <d3d9.h>
#include <d3dx9.h>
#include <windows.h> #include <windows.h>
#include "cgFunctions.h" #include "cgFunctions.h"
@ -239,7 +238,6 @@ private:
static const D3DVERTEXELEMENT9 vertexElems[4]; static const D3DVERTEXELEMENT9 vertexElems[4];
LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration; LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration;
LPD3DXEFFECT effect;
LPDIRECT3DTEXTURE9 rubyLUT[MAX_SHADER_TEXTURES]; LPDIRECT3DTEXTURE9 rubyLUT[MAX_SHADER_TEXTURES];
CGcontext cgContext; CGcontext cgContext;
current_d3d_shader_type shader_type; current_d3d_shader_type shader_type;
@ -260,9 +258,7 @@ private:
void SetupVertices(); void SetupVertices();
bool ResetDevice(); bool ResetDevice();
void SetFiltering(); void SetFiltering();
void SetShaderVars(bool setMatrix = false);
bool SetShader(const TCHAR *file); bool SetShader(const TCHAR *file);
bool SetShaderHLSL(const TCHAR *file);
void checkForCgError(const char *situation); void checkForCgError(const char *situation);
bool SetShaderCG(const TCHAR *file); bool SetShaderCG(const TCHAR *file);

View File

@ -755,191 +755,3 @@ void CGLCG::resetAttribParams()
cgAttribParams.clear(); 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<tgaFile.height;i++) {
unsigned char* source = tempBuf + tgaFile.width * (tgaFile.height - 1 - i) * tgaFile.byteCount;
unsigned char* destination = tgaFile.data + tgaFile.width * i * 4;
for(int j=0;j<tgaFile.width;j++) {
destination[0]=source[2];
destination[1]=source[1];
destination[2]=source[0];
destination[3]=tgaFile.byteCount==4?source[3]:0xff;
source+=tgaFile.byteCount;
destination+=4;
}
}
delete [] tempBuf;
tgaFile.byteCount = 4;
//close file
fclose(file);
return true;
}

View File

@ -197,31 +197,16 @@
#include "CCGShader.h" #include "CCGShader.h"
#include <vector> #include <vector>
#include <deque> #include <deque>
#include "image_functions.h"
typedef struct _xySize { typedef struct _xySize {
double x; double x;
double y; double y;
operator CONST FLOAT* () const;
} xySize; } xySize;
class CGLCG class CGLCG
{ {
private: 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 { typedef struct _shaderPass {
cgScaleParams scaleParams; cgScaleParams scaleParams;
bool linearFilter; bool linearFilter;
@ -267,8 +252,6 @@ private:
void setTexCoords(int pass,xySize inputSize,xySize textureSize,bool topdown=false); void setTexCoords(int pass,xySize inputSize,xySize textureSize,bool topdown=false);
void setShaderVars(int pass); void setShaderVars(int pass);
void resetAttribParams(); void resetAttribParams();
bool loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, GLubyte **outData);
bool loadTGA(const TCHAR *filename, STGA& tgaFile);
CGcontext cgContext; CGcontext cgContext;
unsigned int frameCnt; unsigned int frameCnt;

View File

@ -195,7 +195,7 @@
#include "../apu/apu.h" #include "../apu/apu.h"
#include "wsnes9x.h" #include "wsnes9x.h"
#include <process.h> #include <process.h>
#include <Dxerr.h> #include "dxerr.h"
/* CXAudio2 /* CXAudio2
Implements audio output through XAudio2. Implements audio output through XAudio2.

1
win32/DirectXMath Submodule

@ -0,0 +1 @@
Subproject commit ffb2edbd1627e9eec75f68b4ff00e0861ad84ebe

245
win32/image_functions.cpp Normal file
View File

@ -0,0 +1,245 @@
#include "snes9x.h"
#include <windows.h>
#include <png.h>
#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; i<tgaFile.height; i++) {
unsigned char* source = tempBuf + tgaFile.width * (tgaFile.height - 1 - i) * tgaFile.byteCount;
unsigned char* destination = tgaFile.data + tgaFile.width * i * 4;
for (int j = 0; j<tgaFile.width; j++) {
destination[0] = source[2];
destination[1] = source[1];
destination[2] = source[0];
destination[3] = tgaFile.byteCount == 4 ? source[3] : 0xff;
source += tgaFile.byteCount;
destination += 4;
}
}
delete[] tempBuf;
tgaFile.byteCount = 4;
//close file
fclose(file);
return true;
}
bool d3d_create_texture_from_file(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, LPDIRECT3DTEXTURE9 *ppTexture)
{
int strLen = lstrlen(pSrcFile);
if (strLen<5)
return false;
int width, height;
bool hasAlpha = false, needFree = false;
STGA stga;
unsigned char *bytes;
if (!_tcsicmp(&pSrcFile[strLen - 4], TEXT(".png"))) {
if (!loadPngImage(pSrcFile, width, height, hasAlpha, &bytes))
return false;
needFree = true;
}
else if (!_tcsicmp(&pSrcFile[strLen - 4], TEXT(".tga"))) {
if (!loadTGA(pSrcFile, stga))
return false;
width = stga.width;
height = stga.height;
bytes = stga.data;
hasAlpha = true;
}
bool ret = false;
HRESULT hr = pDevice->CreateTexture(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;
}

25
win32/image_functions.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include <tchar.h>
#include <d3d9.h>
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);

View File

@ -433,6 +433,7 @@
<ClInclude Include="dxerr.h" /> <ClInclude Include="dxerr.h" />
<ClInclude Include="globals.h" /> <ClInclude Include="globals.h" />
<ClInclude Include="gl_core_3_1.h" /> <ClInclude Include="gl_core_3_1.h" />
<ClInclude Include="image_functions.h" />
<ClInclude Include="InputCustom.h" /> <ClInclude Include="InputCustom.h" />
<ClInclude Include="IS9xDisplayOutput.h" /> <ClInclude Include="IS9xDisplayOutput.h" />
<ClInclude Include="IS9xSoundOutput.h" /> <ClInclude Include="IS9xSoundOutput.h" />
@ -566,6 +567,7 @@
<ClCompile Include="DumpAtEnd.cpp" /> <ClCompile Include="DumpAtEnd.cpp" />
<ClCompile Include="dxerr.cpp" /> <ClCompile Include="dxerr.cpp" />
<ClCompile Include="gl_core_3_1.c" /> <ClCompile Include="gl_core_3_1.c" />
<ClCompile Include="image_functions.cpp" />
<ClCompile Include="InputCustom.cpp" /> <ClCompile Include="InputCustom.cpp" />
<ClCompile Include="render.cpp" /> <ClCompile Include="render.cpp" />
<ClCompile Include="snes_ntsc.c" /> <ClCompile Include="snes_ntsc.c" />

View File

@ -273,6 +273,9 @@
<ClInclude Include="CShaderParamDlg.h"> <ClInclude Include="CShaderParamDlg.h">
<Filter>GUI\VideoDriver</Filter> <Filter>GUI\VideoDriver</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="image_functions.h">
<Filter>GUI\VideoDriver</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\bsx.cpp"> <ClCompile Include="..\bsx.cpp">
@ -587,6 +590,9 @@
<ClCompile Include="CShaderParamDlg.cpp"> <ClCompile Include="CShaderParamDlg.cpp">
<Filter>GUI\VideoDriver</Filter> <Filter>GUI\VideoDriver</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="image_functions.cpp">
<Filter>GUI\VideoDriver</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="rsrc\nodrop.cur"> <None Include="rsrc\nodrop.cur">