Win32: dynamically load the cg runtime; gracefully disable its functionality

The cg runtime is no longer required to run snes9x. If unavailable, no error
message will be displayed unless the user tries to load a cg shader.
This commit is contained in:
OV2 2011-03-20 23:21:12 +01:00
parent 8f63cb0cea
commit 153db86437
7 changed files with 275 additions and 24 deletions

View File

@ -178,9 +178,6 @@
#pragma comment( lib, "d3dx9" )
#pragma comment( lib, "DxErr" )
#pragma comment( lib, "cg.lib" )
#pragma comment( lib, "cgd3d9.lib" )
#include "cdirect3d.h"
#include "win32_display.h"
#include "../snes9x.h"
@ -225,6 +222,7 @@ CDirect3D::CDirect3D()
shaderTimeElapsed = 0;
cgContext = NULL;
cgVertexProgram = cgFragmentProgram = NULL;
cgAvailable = false;
}
/* CDirect3D::~CDirect3D()
@ -278,11 +276,15 @@ bool CDirect3D::Initialize(HWND hWnd)
return false;
}
cgAvailable = loadCgFunctions();
if(cgAvailable) {
cgContext = cgCreateContext();
hr = cgD3D9SetDevice(pDevice);
if(FAILED(hr)) {
DXTRACE_ERR_MSGBOX(TEXT("Error setting cg device"), hr);
}
}
pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
@ -323,6 +325,7 @@ void CDirect3D::DeInitialize()
cgContext = NULL;
}
if(cgAvailable)
cgD3D9SetDevice(NULL);
init_done = false;
@ -331,6 +334,8 @@ void CDirect3D::DeInitialize()
quadTextureSize = 0;
fullscreen = false;
filterScale = 0;
unloadCgLibrary();
cgAvailable = false;
}
bool CDirect3D::SetShader(const TCHAR *file)
@ -382,6 +387,12 @@ bool CDirect3D::SetShaderCG(const TCHAR *file)
if (file == NULL || *file==TEXT('\0'))
return true;
if(!cgAvailable) {
MessageBox(NULL, TEXT("The CG runtime is unavailable, CG shaders will not run.\nConsult the snes9x readme for information on how to obtain the runtime."), TEXT("CG Error"),
MB_OK|MB_ICONEXCLAMATION);
return false;
}
CGprofile vertexProfile = cgD3D9GetLatestVertexProfile();
CGprofile pixelProfile = cgD3D9GetLatestPixelProfile();

View File

@ -183,8 +183,7 @@
#include <d3dx9.h>
#include <windows.h>
#include <Cg/cg.h>
#include <Cg/cgD3D9.h>
#include "cgFunctions.h"
#include "render.h"
#include "wsnes9x.h"
@ -225,6 +224,7 @@ private:
CGcontext cgContext;
CGprogram cgVertexProgram, cgFragmentProgram;
current_d3d_shader_type shader_type;
bool cgAvailable;
float shaderTimer;
int shaderTimeStart;

View File

@ -9,9 +9,6 @@
#include "../filter/hq2x.h"
#include "../filter/2xsai.h"
#pragma comment( lib, "cg.lib" )
#pragma comment( lib, "cggl.lib" )
COpenGL::COpenGL(void)
{
@ -33,6 +30,7 @@ COpenGL::COpenGL(void)
fragmentShader = 0;
cgContext = NULL;
cgVertexProgram = cgFragmentProgram = NULL;
cgAvailable = false;
}
COpenGL::~COpenGL(void)
@ -104,7 +102,10 @@ bool COpenGL::Initialize(HWND hWnd)
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
cgAvailable = loadCgFunctions();
if(cgAvailable) {
cgContext = cgCreateContext();
}
GetClientRect(hWnd,&windowRect);
ChangeRenderSize(windowRect.right,windowRect.bottom);
@ -139,6 +140,8 @@ void COpenGL::DeInitialize()
afterRenderHeight = 0;
shaderFunctionsLoaded = false;
shader_type = OGL_SHADER_NONE;
unloadCgLibrary();
cgAvailable = false;
}
void COpenGL::CreateDrawSurface()
@ -284,10 +287,6 @@ void COpenGL::Render(SSurface Src)
cgGLSetStateMatrixParameter(cgpModelViewProj, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
CGparameter cgpVideoSize = cgGetNamedParameter(cgFragmentProgram, "IN.video_size");
CGparameter cgpTextureSize = cgGetNamedParameter(cgFragmentProgram, "IN.texture_size");
CGparameter cgpOutputSize = cgGetNamedParameter(cgFragmentProgram, "IN.output_size");
#define setProgram2fv(program,varname,floats)\
{\
CGparameter cgp = cgGetNamedParameter(program, varname);\
@ -521,6 +520,7 @@ bool COpenGL::SetShadersCG(const TCHAR *file)
{
TCHAR errorMsg[MAX_PATH + 50];
HRESULT hr;
CGprofile vertexProfile, fragmentProfile;
if(cgFragmentProgram) {
cgDestroyProgram(cgFragmentProgram);
@ -531,15 +531,23 @@ bool COpenGL::SetShadersCG(const TCHAR *file)
cgVertexProgram = NULL;
}
CGprofile vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
CGprofile fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
if(cgAvailable) {
vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
cgGLDisableProfile(vertexProfile);
cgGLDisableProfile(fragmentProfile);
}
if (file == NULL || *file==TEXT('\0'))
return true;
if(!cgAvailable) {
MessageBox(NULL, TEXT("The CG runtime is unavailable, CG shaders will not run.\nConsult the snes9x readme for information on how to obtain the runtime."), TEXT("CG Error"),
MB_OK|MB_ICONEXCLAMATION);
return false;
}
cgGLSetOptimalOptions(vertexProfile);
cgGLSetOptimalOptions(fragmentProfile);

View File

@ -181,8 +181,7 @@
#include <windows.h>
#include <gl\gl.h>
#include <Cg/cg.h>
#include <Cg/cgGL.h>
#include "cgFunctions.h"
#include "glext.h"
#include "wglext.h"
@ -215,6 +214,7 @@ private:
CGcontext cgContext;
CGprogram cgVertexProgram, cgFragmentProgram;
current_ogl_shader_type shader_type;
bool cgAvailable;
GLuint shaderProgram;
GLuint vertexShader;

152
win32/cgFunctions.cpp Normal file
View File

@ -0,0 +1,152 @@
#include "cgFunctions.h"
HMODULE hCgDll = NULL;
HMODULE hCgD3D9Dll = NULL;
HMODULE hCgGLDll = NULL;
//cg.dll
CGCC cgCreateContext = NULL;
CGDC cgDestroyContext = NULL;
CGGNP cgGetNamedParameter = NULL;
CGGE cgGetError = NULL;
CGGES cgGetErrorString = NULL;
CGGLL cgGetLastListing = NULL;
CGCP cgCreateProgram = NULL;
CGDP cgDestroyProgram = NULL;
//cgD3D9.dll
CGD3DSD cgD3D9SetDevice = NULL;
CGD3DBP cgD3D9BindProgram = NULL;
CGD3DGLVP cgD3D9GetLatestVertexProfile = NULL;
CGD3DGLPP cgD3D9GetLatestPixelProfile = NULL;
CGD3DGOO cgD3D9GetOptimalOptions = NULL;
CGD3DLP cgD3D9LoadProgram = NULL;
CGD3DSUM cgD3D9SetUniformMatrix = NULL;
CGD3DSU cgD3D9SetUniform = NULL;
//cggl.dll
CGGLSSMP cgGLSetStateMatrixParameter = NULL;
CGGLSP2FV cgGLSetParameter2fv = NULL;
CGGLGLP cgGLGetLatestProfile = NULL;
CGGLEP cgGLEnableProfile = NULL;
CGGLDP cgGLDisableProfile = NULL;
CGGLSOO cgGLSetOptimalOptions = NULL;
CGGLLP cgGLLoadProgram = NULL;
CGGLBP cgGLBindProgram = NULL;
bool loadCgFunctions()
{
if(hCgDll && hCgD3D9Dll && hCgGLDll)
return true;
hCgDll = LoadLibrary(TEXT("cg.dll"));
if(hCgDll) {
hCgD3D9Dll = LoadLibrary(TEXT("cgD3D9.dll"));
hCgGLDll = LoadLibrary(TEXT("cgGL.dll"));
}
if(!hCgDll || !hCgD3D9Dll || !hCgGLDll) {
unloadCgLibrary();
return false;
}
//cg.dll
cgCreateContext = (CGCC)GetProcAddress(hCgDll,"cgCreateContext");
cgDestroyContext = (CGDC)GetProcAddress(hCgDll,"cgDestroyContext");
cgGetNamedParameter = (CGGNP)GetProcAddress(hCgDll,"cgGetNamedParameter");
cgGetError = (CGGE)GetProcAddress(hCgDll,"cgGetError");
cgGetErrorString = (CGGES)GetProcAddress(hCgDll,"cgGetErrorString");
cgGetLastListing = (CGGLL)GetProcAddress(hCgDll,"cgGetLastListing");
cgCreateProgram = (CGCP)GetProcAddress(hCgDll,"cgCreateProgram");
cgDestroyProgram = (CGDP)GetProcAddress(hCgDll,"cgDestroyProgram");
//cgD3D9.dll
cgD3D9SetDevice = (CGD3DSD)GetProcAddress(hCgD3D9Dll,"cgD3D9SetDevice");
cgD3D9BindProgram = (CGD3DBP)GetProcAddress(hCgD3D9Dll,"cgD3D9BindProgram");
cgD3D9GetLatestVertexProfile = (CGD3DGLVP)GetProcAddress(hCgD3D9Dll,"cgD3D9GetLatestVertexProfile");
cgD3D9GetLatestPixelProfile = (CGD3DGLPP)GetProcAddress(hCgD3D9Dll,"cgD3D9GetLatestPixelProfile");
cgD3D9GetOptimalOptions = (CGD3DGOO)GetProcAddress(hCgD3D9Dll,"cgD3D9GetOptimalOptions");
cgD3D9LoadProgram = (CGD3DLP)GetProcAddress(hCgD3D9Dll,"cgD3D9LoadProgram");
cgD3D9SetUniformMatrix = (CGD3DSUM)GetProcAddress(hCgD3D9Dll,"cgD3D9SetUniformMatrix");
cgD3D9SetUniform = (CGD3DSU)GetProcAddress(hCgD3D9Dll,"cgD3D9SetUniform");
//cggl.dll
cgGLSetStateMatrixParameter = (CGGLSSMP)GetProcAddress(hCgGLDll,"cgGLSetStateMatrixParameter");
cgGLSetParameter2fv = (CGGLSP2FV)GetProcAddress(hCgGLDll,"cgGLSetParameter2fv");
cgGLGetLatestProfile = (CGGLGLP)GetProcAddress(hCgGLDll,"cgGLGetLatestProfile");
cgGLEnableProfile = (CGGLEP)GetProcAddress(hCgGLDll,"cgGLEnableProfile");
cgGLDisableProfile = (CGGLDP)GetProcAddress(hCgGLDll,"cgGLDisableProfile");
cgGLSetOptimalOptions = (CGGLSOO)GetProcAddress(hCgGLDll,"cgGLSetOptimalOptions");
cgGLLoadProgram = (CGGLLP)GetProcAddress(hCgGLDll,"cgGLLoadProgram");
cgGLBindProgram = (CGGLBP)GetProcAddress(hCgGLDll,"cgGLBindProgram");
if(
//cg.dll
!cgCreateContext ||
!cgDestroyContext ||
!cgGetNamedParameter ||
!cgGetError ||
!cgGetErrorString ||
!cgGetLastListing ||
!cgCreateProgram ||
!cgDestroyProgram ||
//cgD3D9.dll
!cgD3D9SetDevice ||
!cgD3D9BindProgram ||
!cgD3D9GetLatestVertexProfile ||
!cgD3D9GetLatestPixelProfile ||
!cgD3D9GetOptimalOptions ||
!cgD3D9LoadProgram ||
!cgD3D9SetUniformMatrix ||
!cgD3D9SetUniform ||
//cggl.dll
!cgGLSetStateMatrixParameter ||
!cgGLSetParameter2fv ||
!cgGLGetLatestProfile ||
!cgGLEnableProfile ||
!cgGLDisableProfile ||
!cgGLSetOptimalOptions ||
!cgGLLoadProgram ||
!cgGLBindProgram) {
unloadCgLibrary();
return false;
}
return true;
}
void unloadCgLibrary()
{
if(hCgDll)
FreeLibrary(hCgDll);
if(hCgD3D9Dll)
FreeLibrary(hCgD3D9Dll);
if(hCgGLDll)
FreeLibrary(hCgGLDll);
hCgDll = hCgD3D9Dll = hCgGLDll = NULL;
//cg.dll
cgCreateContext = NULL;
cgDestroyContext = NULL;
cgGetNamedParameter = NULL;
cgGetError = NULL;
cgGetErrorString = NULL;
cgGetLastListing = NULL;
cgCreateProgram = NULL;
cgDestroyProgram = NULL;
//cgD3D9.dll
cgD3D9SetDevice = NULL;
cgD3D9BindProgram = NULL;
cgD3D9GetLatestVertexProfile = NULL;
cgD3D9GetLatestPixelProfile = NULL;
cgD3D9GetOptimalOptions = NULL;
cgD3D9LoadProgram = NULL;
cgD3D9SetUniformMatrix = NULL;
cgD3D9SetUniform = NULL;
//cggl.dll
cgGLSetStateMatrixParameter = NULL;
cgGLSetParameter2fv = NULL;
cgGLGetLatestProfile = NULL;
cgGLEnableProfile = NULL;
cgGLDisableProfile = NULL;
cgGLSetOptimalOptions = NULL;
cgGLLoadProgram = NULL;
cgGLBindProgram = NULL;
}

72
win32/cgFunctions.h Normal file
View File

@ -0,0 +1,72 @@
#ifndef CGFUNCTIONS_H
#define CGFUNCTIONS_H
#define CG_EXPLICIT
#define CGD3D9_EXPLICIT
#define CGGL_EXPLICIT
#include <cg/cg.h>
#include <cg/cgd3d9.h>
#include <cg/cggl.h>
//cg.dll
typedef CG_API CGcontext (CGENTRY *CGCC)(void);
extern CGCC cgCreateContext;
typedef CG_API void (CGENTRY *CGDC)(CGcontext context);
extern CGDC cgDestroyContext;
typedef CG_API CGparameter (CGENTRY *CGGNP)(CGprogram program, const char *name);
extern CGGNP cgGetNamedParameter;
typedef CG_API CGerror (CGENTRY *CGGE)(void);
extern CGGE cgGetError;
typedef CG_API const char * (CGENTRY *CGGES)(CGerror error);
extern CGGES cgGetErrorString;
typedef CG_API const char * (CGENTRY *CGGLL)(CGcontext context);
extern CGGLL cgGetLastListing;
typedef CG_API CGprogram (CGENTRY *CGCP)(CGcontext context, CGenum program_type, const char *program, CGprofile profile, const char *entry, const char **args);
extern CGCP cgCreateProgram;
typedef CG_API void (CGENTRY *CGDP)(CGprogram program);
extern CGDP cgDestroyProgram;
//cgD3D9.dll
typedef CGD3D9DLL_API HRESULT (CGD3D9ENTRY *CGD3DSD)(IDirect3DDevice9 *pDevice);
extern CGD3DSD cgD3D9SetDevice;
typedef CGD3D9DLL_API HRESULT (CGD3D9ENTRY *CGD3DBP)(CGprogram prog);
extern CGD3DBP cgD3D9BindProgram;
typedef CGD3D9DLL_API CGprofile (CGD3D9ENTRY *CGD3DGLVP)(void);
extern CGD3DGLVP cgD3D9GetLatestVertexProfile;
typedef CGD3D9DLL_API CGprofile (CGD3D9ENTRY *CGD3DGLPP)(void);
extern CGD3DGLPP cgD3D9GetLatestPixelProfile;
typedef CGD3D9DLL_API const char ** (CGD3D9ENTRY *CGD3DGOO)(CGprofile profile);
extern CGD3DGOO cgD3D9GetOptimalOptions;
typedef CGD3D9DLL_API HRESULT (CGD3D9ENTRY *CGD3DLP)(CGprogram prog, CGbool paramShadowing, DWORD assemFlags);
extern CGD3DLP cgD3D9LoadProgram;
typedef CGD3D9DLL_API HRESULT (CGD3D9ENTRY *CGD3DSUM)(CGparameter param, const D3DMATRIX *matrix);
extern CGD3DSUM cgD3D9SetUniformMatrix;
typedef CGD3D9DLL_API HRESULT (CGD3D9ENTRY *CGD3DSU)(CGparameter param, const void *floats);
extern CGD3DSU cgD3D9SetUniform;
//cggl.dll
typedef CGGL_API void (CGGLENTRY *CGGLSSMP)(CGparameter param, CGGLenum matrix, CGGLenum transform);
extern CGGLSSMP cgGLSetStateMatrixParameter;
typedef CGGL_API void (CGGLENTRY *CGGLSP2FV)(CGparameter param, const float *v);
extern CGGLSP2FV cgGLSetParameter2fv;
typedef CGGL_API CGprofile (CGGLENTRY *CGGLGLP)(CGGLenum profile_type);
extern CGGLGLP cgGLGetLatestProfile;
typedef CGGL_API void (CGGLENTRY *CGGLEP)(CGprofile profile);
extern CGGLEP cgGLEnableProfile;
typedef CGGL_API void (CGGLENTRY *CGGLDP)(CGprofile profile);
extern CGGLDP cgGLDisableProfile;
typedef CGGL_API void (CGGLENTRY *CGGLSOO)(CGprofile profile);
extern CGGLSOO cgGLSetOptimalOptions;
typedef CGGL_API void (CGGLENTRY *CGGLLP)(CGprogram program);
extern CGGLLP cgGLLoadProgram;
typedef CGGL_API void (CGGLENTRY *CGGLBP)(CGprogram program);
extern CGGLBP cgGLBindProgram;
//cgfunctions.cpp
bool loadCgFunctions();
void unloadCgLibrary();
#endif

View File

@ -3201,6 +3201,14 @@
RelativePath=".\CDirectDraw.h"
>
</File>
<File
RelativePath=".\cgFunctions.cpp"
>
</File>
<File
RelativePath=".\cgFunctions.h"
>
</File>
<File
RelativePath=".\COpenGL.cpp"
>