mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-18 17:14:13 +02:00
Added ddraw dll and sdl2.
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
#pragma comment(linker, "/EXPORT:DirectDrawCreate=_DirectDrawCreate@12")
|
||||
|
||||
#include "DirectDrawWrapper.h"
|
||||
#include "resource.h"
|
||||
//#include "detours.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
// Main thread ddrawwrapper object
|
||||
IDirectDrawWrapper *lpDD = NULL;
|
||||
// Original setcursorpos function pointer
|
||||
static BOOL (WINAPI *TrueSetCursorPos)(int,int) = SetCursorPos;
|
||||
static HMODULE (WINAPI *TrueLoadLibraryA)(LPCSTR) = GetModuleHandleA;
|
||||
|
||||
// Are we in the settings menu
|
||||
BOOL inMenu;
|
||||
// Dll start time
|
||||
DWORD start_time;
|
||||
// The level of debug to display
|
||||
int debugLevel;
|
||||
//debug display mode (-1 = none, 0 = console, 1 = file)
|
||||
int debugDisplay;
|
||||
//the debug file handle
|
||||
FILE *debugFile;
|
||||
|
||||
// Dll hmodule
|
||||
HMODULE hMod;
|
||||
|
||||
/* Helper function for throwing debug/error messages
|
||||
*
|
||||
* int level - Debug level
|
||||
* char *location - Message location
|
||||
* char *message - Message
|
||||
*/
|
||||
void debugMessage(int level, char *location, char *message)
|
||||
{
|
||||
// If above the current level then skip totally
|
||||
if(level > debugLevel) return;
|
||||
|
||||
// Calculate HMS
|
||||
DWORD cur_time = GetTickCount() - start_time;
|
||||
long hours = (long)floor((double)cur_time / (double)3600000.0);
|
||||
cur_time -= (hours * 3600000);
|
||||
int minutes = (int)floor((double)cur_time / (double)60000.0);
|
||||
cur_time -= (minutes * 60000);
|
||||
double seconds = (double)cur_time / (double)1000.0;
|
||||
|
||||
// Build error message
|
||||
char text[4096] = "\0";
|
||||
if(level == 0)
|
||||
{
|
||||
sprintf_s(text, 4096, "%d:%d:%#.1f ERR %s %s\n", hours, minutes, seconds, location, message);
|
||||
}
|
||||
else if(level == 1)
|
||||
{
|
||||
sprintf_s(text, 4096, "%d:%d:%#.1f WRN %s %s\n", hours, minutes, seconds, location, message);
|
||||
}
|
||||
else if(level == 2)
|
||||
{
|
||||
sprintf_s(text, 4096, "%d:%d:%#.1f INF %s %s\n", hours, minutes, seconds, location, message);
|
||||
}
|
||||
// Output and flush
|
||||
printf_s(text);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// Override function for cursor position
|
||||
BOOL WINAPI OverrideSetCursorPos(int X, int Y)
|
||||
{
|
||||
// If ddraw object exists and windowed mode
|
||||
if(lpDD != NULL && lpDD->isWindowed)
|
||||
{
|
||||
// X,Y are relative to client area within the code
|
||||
// Get client area location
|
||||
POINT cpos;
|
||||
cpos.x = 0;
|
||||
cpos.y = 0;
|
||||
ClientToScreen(lpDD->hWnd, &cpos);
|
||||
|
||||
// Calculate correct cursor offset and move
|
||||
BOOL res = TrueSetCursorPos(cpos.x + X, cpos.y + Y);
|
||||
return res;
|
||||
}
|
||||
return TrueSetCursorPos(X, Y);
|
||||
}
|
||||
|
||||
// Override function for load library
|
||||
/*HMODULE WINAPI OverrideLoadLibraryA(LPCSTR lpModuleName)
|
||||
{
|
||||
printf_s("%s\n", lpModuleName);
|
||||
return TrueLoadLibraryA(lpModuleName);
|
||||
}*/
|
||||
|
||||
// Pretty standard winproc
|
||||
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
// On syskey down
|
||||
case WM_SYSKEYDOWN:
|
||||
// ALT+ENTER trap keydown
|
||||
if (wParam == VK_RETURN)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
// On syskey up
|
||||
case WM_SYSKEYUP:
|
||||
// ALT+ENTER trap keyup
|
||||
if (wParam == VK_RETURN)
|
||||
{
|
||||
// If DDW exists
|
||||
if(lpDD != NULL)
|
||||
{
|
||||
lpDD->ToggleFullscreen();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
// On keydown
|
||||
case WM_KEYDOWN:
|
||||
// Overload printscreen(save a snapshot of the current screen
|
||||
if(wParam == VK_SNAPSHOT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// Always pass ~ to menu
|
||||
if(wParam == VK_OEM_3)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// Everything gets passed if we are in the menu
|
||||
if(inMenu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
// On keyup
|
||||
case WM_KEYUP:
|
||||
// Overload printscreen(save a snapshot of the current screen)
|
||||
if(!inMenu && wParam == VK_SNAPSHOT)
|
||||
{
|
||||
lpDD->DoSnapshot();
|
||||
return 0;
|
||||
}
|
||||
// Always pass ~ to menu
|
||||
if(wParam == VK_OEM_3)
|
||||
{
|
||||
// Pass to menu and set inMenu to result
|
||||
inMenu = lpDD->MenuKey(VK_OEM_3);
|
||||
return 0;
|
||||
}
|
||||
// Everything gets passed if we are in the menu
|
||||
if(inMenu)
|
||||
{
|
||||
// Pass to menu and set inMenu to result
|
||||
inMenu = lpDD->MenuKey(wParam);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
// On destroy window
|
||||
case WM_DESTROY:
|
||||
// Restore the orignal window proc if we have it
|
||||
if(lpDD->lpPrevWndFunc != NULL)
|
||||
{
|
||||
SetWindowLong(hwnd, GWL_WNDPROC, (LONG)lpDD->lpPrevWndFunc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Call original windiow proc by default
|
||||
return CallWindowProc(lpDD->lpPrevWndFunc, hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
// Main dll entry
|
||||
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
LONG error;
|
||||
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
// Initial process attach
|
||||
case DLL_PROCESS_ATTACH:
|
||||
// Store module handle
|
||||
hMod = hModule;
|
||||
|
||||
// Set default variables
|
||||
debugLevel = 0;
|
||||
debugDisplay = -1;
|
||||
|
||||
// Set time start
|
||||
start_time = GetTickCount();
|
||||
|
||||
// Not in menu to start
|
||||
inMenu = false;
|
||||
|
||||
// Retrieve command line arguments
|
||||
LPWSTR *szArgList;
|
||||
int argCount;
|
||||
szArgList = CommandLineToArgvW(GetCommandLine(), &argCount);
|
||||
|
||||
// If arguments
|
||||
if(szArgList != NULL)
|
||||
{
|
||||
for(int i = 0; i < argCount; i++)
|
||||
{
|
||||
// If debug
|
||||
if(wcscmp(szArgList[i], L"/ddrawdebug") == 0) {
|
||||
debugDisplay = 0;
|
||||
debugLevel = 2;
|
||||
// Create the debug console
|
||||
AllocConsole();
|
||||
// Redirect stdout to console
|
||||
freopen( "CONOUT$", "wb", stdout);
|
||||
break;
|
||||
}
|
||||
// If ddrawlog
|
||||
else if(wcscmp(szArgList[i], L"/ddrawlog") == 0) {
|
||||
debugDisplay = 1;
|
||||
debugLevel = 2;
|
||||
// Redireect stdout to file
|
||||
char curPath[MAX_PATH];
|
||||
char filename[MAX_PATH];
|
||||
GetCurrentDirectoryA(MAX_PATH, curPath);
|
||||
sprintf_s(filename, MAX_PATH, "%s\\ddraw_debug.log", curPath);
|
||||
freopen_s(&debugFile, filename, "wb", stdout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalFree(szArgList);
|
||||
|
||||
// Hook setcursorpos
|
||||
//DetourRestoreAfterWith();
|
||||
//DetourTransactionBegin();
|
||||
//DetourUpdateThread(GetCurrentThread());
|
||||
//DetourAttach(&(PVOID&)TrueSetCursorPos, OverrideSetCursorPos);
|
||||
////DetourAttach(&(PVOID&)TrueLoadLibraryA, OverrideLoadLibraryA);
|
||||
//error = DetourTransactionCommit();
|
||||
//if (error == NO_ERROR) {
|
||||
// debugMessage(2, "DllMain(DLL_PROCESS_ATTACH)", "Successfully detoured SetCursorPos");
|
||||
//}
|
||||
//else {
|
||||
// debugMessage(1, "DllMain(DLL_PROCESS_ATTACH)", "Failed to detour SetCursorPos");
|
||||
//}
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
// Do nothing on thread attach
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
// Do nothing on thread detach
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
// Delete DirectDrawWrapper object
|
||||
delete lpDD;
|
||||
|
||||
// Detach function hook
|
||||
//DetourTransactionBegin();
|
||||
//DetourUpdateThread(GetCurrentThread());
|
||||
//DetourDetach(&(PVOID&)TrueSetCursorPos, OverrideSetCursorPos);
|
||||
//error = DetourTransactionCommit();
|
||||
|
||||
|
||||
//cleanup debug console or file if exists
|
||||
if(debugDisplay == 0)
|
||||
{
|
||||
FreeConsole();
|
||||
}
|
||||
else if(debugDisplay == 1)
|
||||
{
|
||||
fclose(debugFile);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Emulated direct draw create
|
||||
extern HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter)
|
||||
{
|
||||
// Create directdraw object
|
||||
lpDD = new IDirectDrawWrapper();
|
||||
if(lpDD == NULL)
|
||||
{
|
||||
debugMessage(0, "DirectDrawCreate", "Failed to create IDirectDrawWrapper.");
|
||||
return DDERR_OUTOFMEMORY; // Simulate OOM error
|
||||
}
|
||||
|
||||
// Initialize the ddraw object with new wndproc
|
||||
HRESULT hr = lpDD->WrapperInitialize(&WndProc, hMod);
|
||||
// If error then return error(message will have been taken care of already)
|
||||
if(hr != DD_OK) return hr;
|
||||
|
||||
// Set return pointer to the newly created DirectDrawWrapper interface
|
||||
*lplpDD = (LPDIRECTDRAW)lpDD;
|
||||
|
||||
// Return success
|
||||
return DD_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user