mirror of
https://github.com/DxWnd/DxWnd.reloaded
synced 2024-12-30 09:25:35 +01:00
316 lines
11 KiB
C++
316 lines
11 KiB
C++
#include "dxwnd.h"
|
|
#include "dxwcore.hpp"
|
|
#include "syslibs.h"
|
|
#include "dxhook.h"
|
|
|
|
#define DXWDECLARATIONS TRUE
|
|
#include "glhook.h"
|
|
#undef DXWDECLARATIONS
|
|
|
|
static HookEntry_Type Hooks[]={
|
|
{HOOK_IAT_CANDIDATE, "glViewport", NULL, (FARPROC *)&pglViewport, (FARPROC)extglViewport},
|
|
{HOOK_IAT_CANDIDATE, "glScissor", NULL, (FARPROC *)&pglScissor, (FARPROC)extglScissor},
|
|
{HOOK_IAT_CANDIDATE, "glGetIntegerv", NULL, (FARPROC *)&pglGetIntegerv, (FARPROC)&extglGetIntegerv},
|
|
{HOOK_IAT_CANDIDATE, "glDrawBuffer", NULL, (FARPROC *)&pglDrawBuffer, (FARPROC)extglDrawBuffer},
|
|
{HOOK_IAT_CANDIDATE, "glPolygonMode", NULL, (FARPROC *)&pglPolygonMode, (FARPROC)extglPolygonMode},
|
|
{HOOK_IAT_CANDIDATE, "glGetFloatv", NULL, (FARPROC *)&pglGetFloatv, (FARPROC)extglGetFloatv},
|
|
{HOOK_IAT_CANDIDATE, "glClear", NULL, (FARPROC *)&pglClear, (FARPROC)extglClear},
|
|
{HOOK_IAT_CANDIDATE, "wglCreateContext", NULL, (FARPROC *)&pwglCreateContext, (FARPROC)extwglCreateContext},
|
|
{HOOK_IAT_CANDIDATE, "wglMakeCurrent", NULL, (FARPROC *)&pwglMakeCurrent, (FARPROC)extwglMakeCurrent},
|
|
{HOOK_IAT_CANDIDATE, "wglGetProcAddress", NULL, (FARPROC *)&pwglGetProcAddress, (FARPROC)extwglGetProcAddress},
|
|
{HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
static HookEntry_Type wglHooks[]={
|
|
{HOOK_IAT_CANDIDATE, "glViewport", NULL, (FARPROC *)&pglViewport, (FARPROC)extglViewport},
|
|
{HOOK_IAT_CANDIDATE, "glScissor", NULL, (FARPROC *)&pglScissor, (FARPROC)extglScissor},
|
|
{HOOK_IAT_CANDIDATE, "glGetIntegerv", NULL, (FARPROC *)&pglGetIntegerv, (FARPROC)&extglGetIntegerv},
|
|
{HOOK_IAT_CANDIDATE, "glDrawBuffer", NULL, (FARPROC *)&pglDrawBuffer, (FARPROC)extglDrawBuffer},
|
|
{HOOK_IAT_CANDIDATE, "glPolygonMode", NULL, (FARPROC *)&pglPolygonMode, (FARPROC)extglPolygonMode},
|
|
{HOOK_IAT_CANDIDATE, "glGetFloatv", NULL, (FARPROC *)&pglGetFloatv, (FARPROC)extglGetFloatv},
|
|
{HOOK_IAT_CANDIDATE, "glClear", NULL, (FARPROC *)&pglClear, (FARPROC)extglClear},
|
|
{HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator
|
|
};
|
|
|
|
FARPROC Remap_gl_ProcAddress(LPCSTR proc, HMODULE hModule)
|
|
{
|
|
FARPROC addr;
|
|
if(!(dxw.dwFlags2 & HOOKOPENGL)) return NULL;
|
|
if (addr=RemapLibrary(proc, hModule, Hooks)) return addr;
|
|
// NULL -> keep the original call address
|
|
return NULL;
|
|
}
|
|
|
|
static FARPROC wglRemapLibrary(LPCSTR proc, HookEntry_Type *Hooks)
|
|
{
|
|
int i;
|
|
HookEntry_Type *Hook;
|
|
for(i=0; Hooks[i].APIName; i++){
|
|
Hook=&Hooks[i];
|
|
if (!strcmp(proc,Hook->APIName)){
|
|
if (Hook->StoreAddress) *(Hook->StoreAddress)=(*pwglGetProcAddress)(proc);
|
|
OutTraceDW("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), (Hook->StoreAddress) ? *(Hook->StoreAddress) : 0);
|
|
return Hook->HookerAddress;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
PROC Remap_wgl_ProcAddress(LPCSTR proc)
|
|
{
|
|
FARPROC addr;
|
|
if(addr=wglRemapLibrary(proc, wglHooks)) return addr;
|
|
// NULL -> keep the original call address
|
|
return NULL;
|
|
}
|
|
|
|
void ForceHookOpenGL(HMODULE base) // to do .....
|
|
{
|
|
HMODULE hGlLib;
|
|
static int DoOnce=FALSE;
|
|
|
|
if(DoOnce) return;
|
|
DoOnce = TRUE;
|
|
|
|
hGlLib=(*pLoadLibraryA)("OpenGL32.dll");
|
|
OutTrace("hGlLib=%x\n",hGlLib);
|
|
if(!hGlLib){
|
|
OutTraceE("LoadLibrary(\"OpenGL32.dll\") ERROR: err=%d at %d\n", GetLastError(), __LINE__);
|
|
return;
|
|
}
|
|
|
|
pglViewport=(glViewport_Type)GetProcAddress(hGlLib, "glViewport");
|
|
if(pglViewport) {
|
|
HookAPI(base, "opengl32", pglViewport, "glViewport", extglViewport);
|
|
extglViewport(dxw.iPosX,dxw.iPosY,dxw.iSizX,dxw.iSizY);
|
|
}
|
|
pwglGetProcAddress=(wglGetProcAddress_Type)GetProcAddress(hGlLib, "wglGetProcAddress");
|
|
if(pwglGetProcAddress) {
|
|
HookAPI(base, "opengl32", pwglGetProcAddress, "wglGetProcAddress", extwglGetProcAddress);
|
|
extwglGetProcAddress("wglGetProcAddress");
|
|
}
|
|
pglScissor=(glScissor_Type)GetProcAddress(hGlLib, "glScissor");
|
|
if(pglScissor) {
|
|
HookAPI(base, "opengl32", pglScissor, "glScissor", extglScissor);
|
|
}
|
|
pglGetIntegerv=(glGetIntegerv_Type)GetProcAddress(hGlLib, "glGetIntegerv");
|
|
if(pglGetIntegerv) {
|
|
HookAPI(base, "opengl32", pglGetIntegerv, "glGetIntegerv", extglGetIntegerv);
|
|
}
|
|
pglDrawBuffer=(glDrawBuffer_Type)GetProcAddress(hGlLib, "glDrawBuffer");
|
|
if(pglDrawBuffer) {
|
|
HookAPI(base, "opengl32", pglDrawBuffer, "glDrawBuffer", extglDrawBuffer);
|
|
}
|
|
pglPolygonMode=(glPolygonMode_Type)GetProcAddress(hGlLib, "glPolygonMode");
|
|
if(pglPolygonMode) {
|
|
HookAPI(base, "opengl32", pglPolygonMode, "glPolygonMode", extglPolygonMode);
|
|
}
|
|
pglGetFloatv=(glGetFloatv_Type)GetProcAddress(hGlLib, "glGetFloatv");
|
|
if(pglGetFloatv) {
|
|
HookAPI(base, "opengl32", pglGetFloatv, "glGetFloatv", extglGetFloatv);
|
|
}
|
|
pglClear=(glClear_Type)GetProcAddress(hGlLib, "glClear");
|
|
if(pglClear) {
|
|
HookAPI(base, "opengl32", pglClear, "glClear", extglClear);
|
|
}
|
|
pwglCreateContext=(wglCreateContext_Type)GetProcAddress(hGlLib, "wglCreateContext");
|
|
if(pwglCreateContext) {
|
|
HookAPI(base, "opengl32", pwglCreateContext, "wglCreateContext", extwglCreateContext);
|
|
}
|
|
pwglMakeCurrent=(wglMakeCurrent_Type)GetProcAddress(hGlLib, "wglMakeCurrent");
|
|
if(pwglMakeCurrent) {
|
|
HookAPI(base, "opengl32", pwglMakeCurrent, "wglMakeCurrent", extwglMakeCurrent);
|
|
}
|
|
}
|
|
|
|
void HookOpenGL(HMODULE module, char *customlib)
|
|
{
|
|
void *tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "glViewport", extglViewport);
|
|
if(tmp) pglViewport = (glViewport_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "glScissor", extglScissor);
|
|
if(tmp) pglScissor = (glScissor_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "glGetIntegerv", extglGetIntegerv);
|
|
if(tmp) pglGetIntegerv = (glGetIntegerv_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "glDrawBuffer", extglDrawBuffer);
|
|
if(tmp) pglDrawBuffer = (glDrawBuffer_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "glPolygonMode", extglPolygonMode);
|
|
if(tmp) pglPolygonMode = (glPolygonMode_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "glGetFloatv", extglGetFloatv);
|
|
if(tmp) pglGetFloatv = (glGetFloatv_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "glClear", extglClear);
|
|
if(tmp) pglClear = (glClear_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "wglCreateContext", extwglCreateContext);
|
|
if(tmp) pwglCreateContext = (wglCreateContext_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "wglGetProcAddress", extwglGetProcAddress);
|
|
if(tmp) pwglGetProcAddress = (wglGetProcAddress_Type)tmp;
|
|
tmp = HookAPI(module, customlib, NULL, "wglMakeCurrent", extwglMakeCurrent);
|
|
if(tmp) pwglMakeCurrent = (wglMakeCurrent_Type)tmp;
|
|
}
|
|
|
|
void HookOpenGLLibs(HMODULE module, char *customlib)
|
|
{
|
|
char *DefOpenGLModule="OpenGL32.dll";
|
|
|
|
if (!customlib) customlib=DefOpenGLModule;
|
|
|
|
OutTraceDW("HookOpenGLLibs module=%x lib=\"%s\" forced=%x\n", module, customlib, (dxw.dwFlags3 & FORCEHOOKOPENGL)?1:0);
|
|
if (dxw.dwFlags3 & FORCEHOOKOPENGL)
|
|
ForceHookOpenGL(module);
|
|
else
|
|
HookOpenGL(module, customlib);
|
|
|
|
return;
|
|
}
|
|
|
|
void WINAPI extglViewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
|
{
|
|
RECT client;
|
|
POINT p={0,0};
|
|
HWND hwnd;
|
|
//if (dxw.dwFlags2 & HANDLEFPS) if(dxw.HandleFPS()) return;
|
|
hwnd=dxw.GethWnd();
|
|
(*pGetClientRect)(hwnd, &client);
|
|
OutTraceDW("glViewport: declared pos=(%d,%d) size=(%d,%d)\n", x, y, width, height);
|
|
if(IsDebug) OutTrace("glViewport: DEBUG hwnd=%x win=(%d,%d) screen=(%d,%d)\n",
|
|
hwnd, client.right, client.bottom, dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
|
if(x==CW_USEDEFAULT) x=0;
|
|
if(y==CW_USEDEFAULT) y=0;
|
|
x = (x * (GLint)client.right) / (GLint)dxw.GetScreenWidth();
|
|
y = (y * (GLint)client.bottom) / (GLint)dxw.GetScreenHeight();
|
|
width = (width * (GLint)client.right) / (GLint)dxw.GetScreenWidth();
|
|
height = (height * (GLint)client.bottom) / (GLint)dxw.GetScreenHeight();
|
|
OutTraceDW("glViewport: remapped pos=(%d,%d) size=(%d,%d)\n", x, y, width, height);
|
|
(*pglViewport)(x, y, width, height);
|
|
}
|
|
|
|
void WINAPI extglScissor(GLint x, GLint y, GLsizei width, GLsizei height)
|
|
{
|
|
RECT client;
|
|
POINT p={0,0};
|
|
//if (dxw.dwFlags2 & HANDLEFPS) if(dxw.HandleFPS()) return;
|
|
(*pGetClientRect)(dxw.GethWnd(), &client);
|
|
OutTraceDW("glScissor: declared pos=(%d,%d) size=(%d,%d)\n", x, y, width, height);
|
|
x = (x * (GLint)client.right) / (GLint)dxw.GetScreenWidth();
|
|
y = (y * (GLint)client.bottom) / (GLint)dxw.GetScreenHeight();
|
|
width = (width * (GLint)client.right) / (GLint)dxw.GetScreenWidth();
|
|
height = (height * (GLint)client.bottom) / (GLint)dxw.GetScreenHeight();
|
|
OutTraceDW("glScissor: remapped pos=(%d,%d) size=(%d,%d)\n", x, y, width, height);
|
|
(*pglScissor)(x, y, width, height);
|
|
}
|
|
|
|
void WINAPI extglGetIntegerv(GLenum pname, GLint *params)
|
|
{
|
|
(*pglGetIntegerv)(pname, params);
|
|
OutTraceDW("glGetIntegerv: pname=%d\n", pname);
|
|
}
|
|
|
|
void WINAPI extglDrawBuffer(GLenum mode)
|
|
{
|
|
if (IsDebug) OutTrace("glDrawBuffer: mode=%x\n", mode);
|
|
if(dxw.dwFlags2 & WIREFRAME) (*pglClear)(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) ; // clear screen for wireframe mode....
|
|
// handle FPS only to backbuffer updates (if stereo, on left backbuffer...)
|
|
// using the frontbuffer seems less reliable: Return to Castle Wolfenstein doesn't use it at all!
|
|
if (dxw.dwFlags2 & HANDLEFPS){
|
|
switch (mode){
|
|
//case GL_FRONT_LEFT:
|
|
case GL_BACK_LEFT:
|
|
//case GL_FRONT:
|
|
case GL_BACK:
|
|
case GL_LEFT:
|
|
case GL_FRONT_AND_BACK:
|
|
if(dxw.HandleFPS()) return;
|
|
}
|
|
}
|
|
(*pglDrawBuffer)(mode);
|
|
dxw.ShowOverlay();
|
|
}
|
|
|
|
void WINAPI extglPolygonMode(GLenum face, GLenum mode)
|
|
{
|
|
OutTraceDW("glPolygonMode: face=%x mode=%x\n", face, mode);
|
|
//OutTraceDW("glPolygonMode: extglPolygonMode=%x pglPolygonMode=%x\n", extglPolygonMode, pglPolygonMode);
|
|
if(dxw.dwFlags2 & WIREFRAME) mode = GL_LINE; // trick to set wireframe mode....
|
|
(*pglPolygonMode)(face, mode);
|
|
return;
|
|
}
|
|
|
|
void WINAPI extglGetFloatv(GLenum pname, GLboolean *params)
|
|
{
|
|
OutTraceDW("glGetFloatv: pname=%x\n", pname);
|
|
(*pglGetFloatv)(pname, params);
|
|
return;
|
|
}
|
|
|
|
void WINAPI extglClear(GLbitfield mask)
|
|
{
|
|
(*pglClear)(mask);
|
|
return;
|
|
}
|
|
|
|
//BEWARE: SetPixelFormat must be issued on the same hdc used by OpenGL wglCreateContext, otherwise
|
|
// a failure err=2000 ERROR INVALID PIXEL FORMAT occurs!!
|
|
|
|
HGLRC WINAPI extwglCreateContext(HDC hdc)
|
|
{
|
|
HGLRC ret;
|
|
OutTraceDW("wglCreateContext: hdc=%x\n", hdc);
|
|
// v2.02.31: don't let it use desktop hdc
|
|
if(dxw.IsDesktop(WindowFromDC(hdc))){
|
|
HDC oldhdc = hdc;
|
|
hdc=(*pGDIGetDC)(dxw.GethWnd());
|
|
OutTraceDW("wglCreateContext: remapped desktop hdc=%x->%x hWnd=%x\n", oldhdc, hdc, dxw.GethWnd());
|
|
}
|
|
ret=(*pwglCreateContext)(hdc);
|
|
if(ret){
|
|
HWND hwnd;
|
|
hwnd=WindowFromDC(hdc);
|
|
dxw.SethWnd(hwnd);
|
|
OutTraceDW("wglCreateContext: SET hwnd=%x\n", hwnd);
|
|
}
|
|
else {
|
|
OutTraceDW("wglCreateContext: ERROR err=%d\n", GetLastError());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
PROC WINAPI extwglGetProcAddress(LPCSTR proc)
|
|
{
|
|
PROC procaddr;
|
|
|
|
OutTraceDW("wglGetProcAddress: proc=%s\n", proc);
|
|
procaddr=Remap_wgl_ProcAddress(proc);
|
|
if (!procaddr) procaddr=(*pwglGetProcAddress)(proc);
|
|
return procaddr;
|
|
}
|
|
|
|
BOOL WINAPI extwglMakeCurrent(HDC hdc, HGLRC hglrc)
|
|
{
|
|
BOOL ret;
|
|
|
|
OutTraceDW("wglMakeCurrent: hdc=%x hglrc=%x\n", hdc, hglrc);
|
|
// v2.02.31: don't let it use desktop hdc
|
|
if(dxw.IsDesktop(WindowFromDC(hdc))){
|
|
HDC oldhdc = hdc;
|
|
hdc=(*pGDIGetDC)(dxw.GethWnd());
|
|
OutTraceDW("wglMakeCurrent: remapped desktop hdc=%x->%x\n", oldhdc, hdc);
|
|
}
|
|
ret=(*pwglMakeCurrent)(hdc, hglrc);
|
|
if(ret){
|
|
HWND hWnd;
|
|
hWnd = WindowFromDC(hdc);
|
|
OutTraceDW("wglMakeCurrent: setting hwnd=%x\n", hWnd);
|
|
dxw.SethWnd(hWnd);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// to do:
|
|
// glutSetWindow - save current window handle
|
|
// glutInitWindowPosition, glutInitWindowSize
|
|
// glutInitDisplayMode
|
|
// glutCreateWindow, glutCreateSubWindow
|
|
// glutPositionWindow, glutReshapeWindow
|
|
// glGetFloatv ( GL_SCISSOR_BOX - GL_VIEWPORT )
|
|
|