mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-24 17:49:52 +01:00
First take at real windowed mode, includes a hack for CnC and RA mouse
This commit is contained in:
parent
7bb1168a90
commit
4e57e75652
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
|||||||
all:
|
all:
|
||||||
i586-mingw32msvc-gcc -Wall -Wl,--enable-stdcall-fixup -shared -s -o ddraw.dll main.c palette.c surface.c clipper.c ddraw.def -lgdi32
|
i586-mingw32msvc-gcc -Wall -Wl,--enable-stdcall-fixup -shared -s -o ddraw.dll main.c mouse.c palette.c surface.c clipper.c ddraw.def -lgdi32
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ddraw.dll
|
rm -f ddraw.dll
|
||||||
|
126
main.c
126
main.c
@ -23,6 +23,13 @@
|
|||||||
#include "surface.h"
|
#include "surface.h"
|
||||||
#include "clipper.h"
|
#include "clipper.h"
|
||||||
|
|
||||||
|
/* from mouse.c */
|
||||||
|
void mouse_init(HWND);
|
||||||
|
void mouse_lock();
|
||||||
|
void mouse_unlock();
|
||||||
|
|
||||||
|
IDirectDrawImpl *ddraw = NULL;
|
||||||
|
|
||||||
HRESULT __stdcall ddraw_Compact(IDirectDrawImpl *This)
|
HRESULT __stdcall ddraw_Compact(IDirectDrawImpl *This)
|
||||||
{
|
{
|
||||||
printf("DirectDraw::Compact(This=%p)\n", This);
|
printf("DirectDraw::Compact(This=%p)\n", This);
|
||||||
@ -132,6 +139,92 @@ HRESULT __stdcall ddraw_RestoreDisplayMode(IDirectDrawImpl *This)
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch(uMsg)
|
||||||
|
{
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
if(wParam == VK_CONTROL)
|
||||||
|
{
|
||||||
|
ddraw->key_ctrl = TRUE;
|
||||||
|
}
|
||||||
|
if(wParam == VK_MENU)
|
||||||
|
{
|
||||||
|
ddraw->key_alt = TRUE;
|
||||||
|
}
|
||||||
|
if(ddraw->key_alt && ddraw->key_ctrl)
|
||||||
|
{
|
||||||
|
mouse_unlock();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_KEYUP:
|
||||||
|
if(wParam == VK_CONTROL)
|
||||||
|
{
|
||||||
|
ddraw->key_ctrl = FALSE;
|
||||||
|
}
|
||||||
|
if(wParam == VK_MENU)
|
||||||
|
{
|
||||||
|
ddraw->key_alt = FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
if(!ddraw->locked)
|
||||||
|
{
|
||||||
|
mouse_lock();
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
if(ddraw->locked)
|
||||||
|
{
|
||||||
|
ddraw->cursor.x = LOWORD(lParam);
|
||||||
|
ddraw->cursor.y = HIWORD(lParam);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_SETFOCUS:
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
case WM_KILLFOCUS:
|
||||||
|
mouse_unlock();
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
case WM_PAINT:
|
||||||
|
if(ddraw_primary)
|
||||||
|
{
|
||||||
|
SetEvent(ddraw_primary->flipEvent);
|
||||||
|
}
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
|
||||||
|
case WM_MOVE:
|
||||||
|
ddraw->winpos.x = LOWORD(lParam);
|
||||||
|
ddraw->winpos.y = HIWORD(lParam);
|
||||||
|
if(ddraw->winpos.x < 0)
|
||||||
|
{
|
||||||
|
ddraw->winpos.x = 0;
|
||||||
|
}
|
||||||
|
if(ddraw->winpos.y < 0)
|
||||||
|
{
|
||||||
|
ddraw->winpos.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ddraw_primary)
|
||||||
|
{
|
||||||
|
SetEvent(ddraw_primary->flipEvent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_WINDOWPOSCHANGED:
|
||||||
|
GetClientRect(ddraw->hWnd, &ddraw->cursorclip);
|
||||||
|
|
||||||
|
POINT pt = { ddraw->cursorclip.left, ddraw->cursorclip.top };
|
||||||
|
POINT pt2 = { ddraw->cursorclip.right, ddraw->cursorclip.bottom };
|
||||||
|
ClientToScreen(ddraw->hWnd, &pt);
|
||||||
|
ClientToScreen(ddraw->hWnd, &pt2);
|
||||||
|
SetRect(&ddraw->cursorclip, pt.x, pt.y, pt2.x, pt2.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ddraw->WndProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DWORD dwFlags)
|
HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DWORD dwFlags)
|
||||||
{
|
{
|
||||||
printf("DirectDraw::SetCooperativeLevel(This=%p, hWnd=0x%08X, dwFlags=0x%08X)\n", This, (unsigned int)hWnd, (unsigned int)dwFlags);
|
printf("DirectDraw::SetCooperativeLevel(This=%p, hWnd=0x%08X, dwFlags=0x%08X)\n", This, (unsigned int)hWnd, (unsigned int)dwFlags);
|
||||||
@ -142,8 +235,13 @@ HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DW
|
|||||||
return DDERR_INVALIDPARAMS;
|
return DDERR_INVALIDPARAMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mouse_init(hWnd);
|
||||||
|
|
||||||
This->hWnd = hWnd;
|
This->hWnd = hWnd;
|
||||||
|
|
||||||
|
This->WndProc = (LRESULT CALLBACK (*)(HWND, UINT, WPARAM, LPARAM))GetWindowLong(This->hWnd, GWL_WNDPROC);
|
||||||
|
SetWindowLong(This->hWnd, GWL_WNDPROC, (LONG)WndProc);
|
||||||
|
|
||||||
#ifndef USE_OPENGL
|
#ifndef USE_OPENGL
|
||||||
if(IDirectDraw_SetCooperativeLevel(This->real_ddraw, hWnd, DDSCL_NORMAL) != DD_OK)
|
if(IDirectDraw_SetCooperativeLevel(This->real_ddraw, hWnd, DDSCL_NORMAL) != DD_OK)
|
||||||
{
|
{
|
||||||
@ -159,12 +257,30 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD
|
|||||||
{
|
{
|
||||||
printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
|
printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
|
||||||
|
|
||||||
|
/* currently we only support 8 bit modes */
|
||||||
|
if(bpp != 8)
|
||||||
|
{
|
||||||
|
return DDERR_INVALIDMODE;
|
||||||
|
}
|
||||||
|
|
||||||
This->width = width;
|
This->width = width;
|
||||||
This->height = height;
|
This->height = height;
|
||||||
This->bpp = bpp;
|
This->bpp = bpp;
|
||||||
|
|
||||||
|
SetWindowLong(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) | WS_POPUPWINDOW | WS_CAPTION);
|
||||||
MoveWindow(This->hWnd, 0, 0, This->width, This->height, TRUE);
|
MoveWindow(This->hWnd, 0, 0, This->width, This->height, TRUE);
|
||||||
|
|
||||||
|
RECT rcClient, rcWindow;
|
||||||
|
POINT ptDiff;
|
||||||
|
GetClientRect(This->hWnd, &rcClient);
|
||||||
|
GetWindowRect(This->hWnd, &rcWindow);
|
||||||
|
ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
|
||||||
|
ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
|
||||||
|
|
||||||
|
MoveWindow(This->hWnd, rcWindow.left, rcWindow.top, This->width + ptDiff.x, This->height + ptDiff.y, TRUE);
|
||||||
|
|
||||||
|
mouse_unlock();
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +319,7 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This)
|
|||||||
IDirectDraw_Release(This->real_ddraw);
|
IDirectDraw_Release(This->real_ddraw);
|
||||||
#endif
|
#endif
|
||||||
free(This);
|
free(This);
|
||||||
|
ddraw = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,13 +367,18 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(ddraw)
|
||||||
|
{
|
||||||
|
return DDERR_DIRECTDRAWALREADYCREATED;
|
||||||
|
}
|
||||||
|
|
||||||
printf("DirectDrawCreate(lpGUID=%p, lplpDD=%p, pUnkOuter=%p)\n", lpGUID, lplpDD, pUnkOuter);
|
printf("DirectDrawCreate(lpGUID=%p, lplpDD=%p, pUnkOuter=%p)\n", lpGUID, lplpDD, pUnkOuter);
|
||||||
|
|
||||||
IDirectDrawImpl *This = (IDirectDrawImpl *)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawImpl));
|
IDirectDrawImpl *This = (IDirectDrawImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
|
||||||
This->lpVtbl = &iface;
|
This->lpVtbl = &iface;
|
||||||
This->hWnd = NULL;
|
|
||||||
printf(" This = %p\n", This);
|
printf(" This = %p\n", This);
|
||||||
*lplpDD = (LPDIRECTDRAW)This;
|
*lplpDD = (LPDIRECTDRAW)This;
|
||||||
|
ddraw = This;
|
||||||
|
|
||||||
#ifndef USE_OPENGL
|
#ifndef USE_OPENGL
|
||||||
This->real_dll = LoadLibrary("system32\\ddraw.dll");
|
This->real_dll = LoadLibrary("system32\\ddraw.dll");
|
||||||
|
10
main.h
10
main.h
@ -25,6 +25,8 @@
|
|||||||
struct IDirectDrawImpl;
|
struct IDirectDrawImpl;
|
||||||
struct IDirectDrawImplVtbl;
|
struct IDirectDrawImplVtbl;
|
||||||
|
|
||||||
|
extern struct IDirectDrawImpl *ddraw;
|
||||||
|
|
||||||
typedef struct IDirectDrawImpl
|
typedef struct IDirectDrawImpl
|
||||||
{
|
{
|
||||||
struct IDirectDrawImplVtbl *lpVtbl;
|
struct IDirectDrawImplVtbl *lpVtbl;
|
||||||
@ -36,6 +38,14 @@ typedef struct IDirectDrawImpl
|
|||||||
DWORD bpp;
|
DWORD bpp;
|
||||||
|
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
|
LRESULT CALLBACK (*WndProc)(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
POINT winpos;
|
||||||
|
POINT cursor;
|
||||||
|
RECT cursorclip;
|
||||||
|
BOOL locked;
|
||||||
|
|
||||||
|
BOOL key_ctrl;
|
||||||
|
BOOL key_alt;
|
||||||
|
|
||||||
HMODULE real_dll;
|
HMODULE real_dll;
|
||||||
LPDIRECTDRAW real_ddraw;
|
LPDIRECTDRAW real_ddraw;
|
||||||
|
76
mouse.c
Normal file
76
mouse.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is a special mouse coordinate fix for games that use GetCursorPos and expect to be in fullscreen */
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "main.h"
|
||||||
|
#include "surface.h"
|
||||||
|
|
||||||
|
BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint)
|
||||||
|
{
|
||||||
|
lpPoint->x = ddraw->cursor.x;
|
||||||
|
lpPoint->y = ddraw->cursor.y;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_lock()
|
||||||
|
{
|
||||||
|
if(!ddraw->locked)
|
||||||
|
{
|
||||||
|
ddraw->locked = TRUE;
|
||||||
|
ClipCursor(&ddraw->cursorclip);
|
||||||
|
while(ShowCursor(FALSE) > 0);
|
||||||
|
SetEvent(ddraw_primary->flipEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_unlock()
|
||||||
|
{
|
||||||
|
if(ddraw->locked)
|
||||||
|
{
|
||||||
|
ShowCursor(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ddraw->locked = FALSE;
|
||||||
|
ClipCursor(NULL);
|
||||||
|
ddraw->cursor.x = ddraw->width / 2;
|
||||||
|
ddraw->cursor.y = ddraw->height / 2;
|
||||||
|
|
||||||
|
if(ddraw_primary)
|
||||||
|
{
|
||||||
|
SetEvent(ddraw_primary->flipEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_init(HWND hWnd)
|
||||||
|
{
|
||||||
|
DWORD tmp;
|
||||||
|
HANDLE hProcess;
|
||||||
|
DWORD dwWritten;
|
||||||
|
|
||||||
|
GetWindowThreadProcessId(hWnd, &tmp);
|
||||||
|
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, tmp);
|
||||||
|
|
||||||
|
tmp = (DWORD)fake_GetCursorPos;
|
||||||
|
|
||||||
|
// Command & Conquer
|
||||||
|
//WriteProcessMemory(hProcess, (void *)0x005B0184, &tmp, 4, &dwWritten);
|
||||||
|
|
||||||
|
// Red Alert
|
||||||
|
//WriteProcessMemory(hProcess, (void *)0x005E6848, &tmp, 4, &dwWritten);
|
||||||
|
}
|
10
surface.c
10
surface.c
@ -25,6 +25,8 @@ DWORD WINAPI dd_Thread(IDirectDrawSurfaceImpl *This);
|
|||||||
void dump_ddsd(DWORD);
|
void dump_ddsd(DWORD);
|
||||||
void dump_ddscaps(DWORD);
|
void dump_ddscaps(DWORD);
|
||||||
|
|
||||||
|
IDirectDrawSurfaceImpl *ddraw_primary = NULL;
|
||||||
|
|
||||||
HRESULT __stdcall ddraw_surface_QueryInterface(IDirectDrawSurfaceImpl *This, REFIID riid, void **obj)
|
HRESULT __stdcall ddraw_surface_QueryInterface(IDirectDrawSurfaceImpl *This, REFIID riid, void **obj)
|
||||||
{
|
{
|
||||||
printf("DirectDrawSurface::QueryInterface(This=%p, riid=%08X, obj=%p)\n", This, (unsigned int)riid, obj);
|
printf("DirectDrawSurface::QueryInterface(This=%p, riid=%08X, obj=%p)\n", This, (unsigned int)riid, obj);
|
||||||
@ -422,6 +424,8 @@ HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC lpD
|
|||||||
{
|
{
|
||||||
if(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
|
if(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
|
||||||
{
|
{
|
||||||
|
ddraw_primary = Surface;
|
||||||
|
|
||||||
Surface->width = This->width;
|
Surface->width = This->width;
|
||||||
Surface->height = This->height;
|
Surface->height = This->height;
|
||||||
Surface->hWnd = This->hWnd;
|
Surface->hWnd = This->hWnd;
|
||||||
@ -532,7 +536,6 @@ DWORD WINAPI dd_Thread(IDirectDrawSurfaceImpl *This)
|
|||||||
LPDIRECTDRAWSURFACE primary;
|
LPDIRECTDRAWSURFACE primary;
|
||||||
LPDIRECTDRAWCLIPPER clipper;
|
LPDIRECTDRAWCLIPPER clipper;
|
||||||
DWORD width;
|
DWORD width;
|
||||||
POINT pt;
|
|
||||||
|
|
||||||
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||||
@ -560,9 +563,6 @@ DWORD WINAPI dd_Thread(IDirectDrawSurfaceImpl *This)
|
|||||||
if(!This->dRun)
|
if(!This->dRun)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pt.x = pt.y = 0;
|
|
||||||
//ClientToScreen(This->hWnd, &pt);
|
|
||||||
|
|
||||||
if(IDirectDrawSurface_Lock(primary, NULL, &ddsd, DDLOCK_WRITEONLY|DDLOCK_WAIT, NULL) != DD_OK)
|
if(IDirectDrawSurface_Lock(primary, NULL, &ddsd, DDLOCK_WRITEONLY|DDLOCK_WAIT, NULL) != DD_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -571,7 +571,7 @@ DWORD WINAPI dd_Thread(IDirectDrawSurfaceImpl *This)
|
|||||||
{
|
{
|
||||||
for(j=0; j<This->width; j++)
|
for(j=0; j<This->width; j++)
|
||||||
{
|
{
|
||||||
((int *)ddsd.lpSurface)[(i+pt.y)*width+(j+pt.x)] = This->palette->data[((unsigned char *)This->surface)[i*This->lPitch + j*This->lXPitch]];
|
((int *)ddsd.lpSurface)[(i+This->parent->winpos.y)*width+(j+This->parent->winpos.x)] = This->palette->data[((unsigned char *)This->surface)[i*This->lPitch + j*This->lXPitch]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC DDS
|
|||||||
struct IDirectDrawSurfaceImpl;
|
struct IDirectDrawSurfaceImpl;
|
||||||
struct IDirectDrawSurfaceImplVtbl;
|
struct IDirectDrawSurfaceImplVtbl;
|
||||||
|
|
||||||
|
extern struct IDirectDrawSurfaceImpl *ddraw_primary;
|
||||||
|
|
||||||
typedef struct IDirectDrawSurfaceImpl
|
typedef struct IDirectDrawSurfaceImpl
|
||||||
{
|
{
|
||||||
struct IDirectDrawSurfaceImplVtbl *lpVtbl;
|
struct IDirectDrawSurfaceImplVtbl *lpVtbl;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user