diff --git a/Makefile b/Makefile
index 92071d1..5805122 100644
--- a/Makefile
+++ b/Makefile
@@ -6,20 +6,28 @@ CFLAGS = -std=c99
LIBS = -lgdi32 -lwinmm
FILES = src/debug.c \
- src/main.c \
- src/mouse.c \
- src/palette.c \
- src/surface.c \
- src/clipper.c \
- src/render.c \
- src/render_soft.c \
+ src/dd.c \
+ src/ddpalette.c \
+ src/ddsurface.c \
+ src/ddclipper.c \
+ src/IDirectDraw/IDirectDraw.c \
+ src/IDirectDraw/IDirectDrawPalette.c \
+ src/IDirectDraw/IDirectDrawClipper.c \
+ src/IDirectDraw/IDirectDrawSurface.c \
+ src/render_ogl.c \
+ src/render_gdi.c \
src/render_d3d9.c \
+ src/mouse.c \
+ src/winapi_hooks.c \
src/screenshot.c \
- src/settings.c \
+ src/config.c \
src/lodepng.c \
- src/dinput.c \
+ src/directinput.c \
src/hook.c \
- src/opengl.c
+ src/dllmain.c \
+ src/wndproc.c \
+ src/utils.c \
+ src/opengl_utils.c
all:
$(WINDRES) -J rc ddraw.rc ddraw.rc.o
diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj
index 3781845..ebdd647 100644
--- a/cnc-ddraw.vcxproj
+++ b/cnc-ddraw.vcxproj
@@ -11,7 +11,7 @@
-
+
@@ -26,37 +26,58 @@
true
-
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
-
+
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
+
-
+
+
+
+
+
diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters
index 24513d4..8f64818 100644
--- a/cnc-ddraw.vcxproj.filters
+++ b/cnc-ddraw.vcxproj.filters
@@ -16,53 +16,26 @@
{af194dd7-3316-4887-93d6-9f2af2135f94}
+
+ {37ee5b88-e57f-4c55-a43e-e475cf4e8920}
+
-
- Source Files
-
Source Files
-
- Source Files
-
Source Files
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
Source Files
-
- Source Files
-
-
- Source Files
-
Source Files
-
- Source Files
-
Source Files
-
- Source Files
-
-
- Source Files
-
Source Files\detours
@@ -96,35 +69,71 @@
Source Files\detours
+
+ Source Files
+
+
+ Source Files\IDirectDraw
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files\IDirectDraw
+
+
+ Source Files
+
+
+ Source Files\IDirectDraw
+
+
+ Source Files
+
+
+ Source Files\IDirectDraw
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
-
- Header Files
-
Header Files
Header Files
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
-
- Header Files
-
Header Files
@@ -146,6 +155,63 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
diff --git a/ddraw.def b/ddraw.def
index 855453b..c537348 100644
--- a/ddraw.def
+++ b/ddraw.def
@@ -1,10 +1,10 @@
LIBRARY ddraw.dll
EXPORTS
- DirectDrawCreate @1
- DirectDrawEnumerateA @2
- DirectDrawCreateClipper @10
- GameHandlesClose DATA
- NvOptimusEnablement DATA
- AmdPowerXpressRequestHighPerformance DATA
- pvBmpBits DATA
+ DirectDrawCreate @8
+ DirectDrawCreateClipper @9
+ DirectDrawEnumerateA @11
+ GameHandlesClose DATA
+ NvOptimusEnablement DATA
+ AmdPowerXpressRequestHighPerformance DATA
+ pvBmpBits = g_fake_primary_surface_export DATA
diff --git a/ddraw.rc b/ddraw.rc
index e2913cc..b34cb4a 100644
--- a/ddraw.rc
+++ b/ddraw.rc
@@ -4,7 +4,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_BUILD 7
-#define VERSION_REVISION 1
+#define VERSION_REVISION 2
#define VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION
#define VERSION_STRING ver_str(VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION)
diff --git a/inc/IDirectDraw.h b/inc/IDirectDraw.h
new file mode 100644
index 0000000..b9d7550
--- /dev/null
+++ b/inc/IDirectDraw.h
@@ -0,0 +1,71 @@
+#ifndef IDIRECTDRAW_H
+#define IDIRECTDRAW_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "ddraw.h"
+
+
+DEFINE_GUID(IID_IDirectDraw4, 0x9c59509a, 0x39bd, 0x11d1, 0x8c, 0x4a, 0x00, 0xc0, 0x4f, 0xd9, 0x30, 0xc5);
+DEFINE_GUID(IID_IDirectDraw7, 0x15e65ec0, 0x3b9c, 0x11d2, 0xb9, 0x2f, 0x00, 0x60, 0x97, 0x97, 0xea, 0x5b);
+
+extern struct IDirectDrawImplVtbl g_dd_vtbl1;
+extern struct IDirectDrawImplVtbl g_dd_vtblx;
+
+struct IDirectDrawImpl;
+struct IDirectDrawImplVtbl;
+
+typedef struct IDirectDrawImpl
+{
+ struct IDirectDrawImplVtbl* lpVtbl;
+
+ ULONG ref;
+
+} IDirectDrawImpl;
+
+typedef struct IDirectDrawImplVtbl IDirectDrawImplVtbl;
+
+struct IDirectDrawImplVtbl
+{
+ HRESULT(__stdcall* QueryInterface) (IDirectDrawImpl*, const IID* const riid, LPVOID* ppvObj);
+ ULONG(__stdcall* AddRef) (IDirectDrawImpl*);
+ ULONG(__stdcall* Release) (IDirectDrawImpl*);
+
+ HRESULT(__stdcall* Compact)(IDirectDrawImpl*);
+ HRESULT(__stdcall* CreateClipper)(IDirectDrawImpl*, DWORD, LPDIRECTDRAWCLIPPER*, IUnknown*);
+ HRESULT(__stdcall* CreatePalette)(IDirectDrawImpl*, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE*, IUnknown*);
+ HRESULT(__stdcall* CreateSurface)(IDirectDrawImpl*, LPDDSURFACEDESC, LPDIRECTDRAWSURFACE*, IUnknown*);
+ HRESULT(__stdcall* DuplicateSurface)(IDirectDrawImpl*, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE*);
+ HRESULT(__stdcall* EnumDisplayModes)(IDirectDrawImpl*, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK);
+ HRESULT(__stdcall* EnumSurfaces)(IDirectDrawImpl*, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMSURFACESCALLBACK);
+ HRESULT(__stdcall* FlipToGDISurface)(IDirectDrawImpl*);
+ HRESULT(__stdcall* GetCaps)(IDirectDrawImpl*, LPDDCAPS, LPDDCAPS);
+ HRESULT(__stdcall* GetDisplayMode)(IDirectDrawImpl*, LPDDSURFACEDESC);
+ HRESULT(__stdcall* GetFourCCCodes)(IDirectDrawImpl*, LPDWORD, LPDWORD);
+ HRESULT(__stdcall* GetGDISurface)(IDirectDrawImpl*, LPDIRECTDRAWSURFACE*);
+ HRESULT(__stdcall* GetMonitorFrequency)(IDirectDrawImpl*, LPDWORD);
+ HRESULT(__stdcall* GetScanLine)(IDirectDrawImpl*, LPDWORD);
+ HRESULT(__stdcall* GetVerticalBlankStatus)(IDirectDrawImpl*, LPBOOL);
+ HRESULT(__stdcall* Initialize)(IDirectDrawImpl*, GUID*);
+ HRESULT(__stdcall* RestoreDisplayMode)(IDirectDrawImpl*);
+ HRESULT(__stdcall* SetCooperativeLevel)(IDirectDrawImpl*, HWND, DWORD);
+ union
+ {
+ LPVOID d;
+ HRESULT(__stdcall* SetDisplayMode)(IDirectDrawImpl*, DWORD, DWORD, DWORD);
+ HRESULT(__stdcall* SetDisplayModeX)(IDirectDrawImpl*, DWORD, DWORD, DWORD, DWORD, DWORD);
+ };
+ HRESULT(__stdcall* WaitForVerticalBlank)(IDirectDrawImpl*, DWORD, HANDLE);
+ // v2
+ HRESULT(__stdcall* GetAvailableVidMem)(IDirectDrawImpl*, void*, LPDWORD, LPDWORD);
+ // v4
+ HRESULT(__stdcall* GetSurfaceFromDC)(IDirectDrawImpl*, HDC, void*);
+ HRESULT(__stdcall* RestoreAllSurfaces)(IDirectDrawImpl*);
+ HRESULT(__stdcall* TestCooperativeLevel)(IDirectDrawImpl*);
+ HRESULT(__stdcall* GetDeviceIdentifier)(IDirectDrawImpl*, void*, DWORD);
+ // v7
+ HRESULT(__stdcall* StartModeTest)(IDirectDrawImpl*, LPSIZE, DWORD, DWORD);
+ HRESULT(__stdcall* EvaluateMode)(IDirectDrawImpl*, DWORD, DWORD*);
+};
+
+#endif
diff --git a/inc/IDirectDrawClipper.h b/inc/IDirectDrawClipper.h
new file mode 100644
index 0000000..186695a
--- /dev/null
+++ b/inc/IDirectDrawClipper.h
@@ -0,0 +1,40 @@
+#ifndef IDIRECTDRAWCLIPPER_H
+#define IDIRECTDRAWCLIPPER_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "ddraw.h"
+
+
+struct IDirectDrawClipperImpl;
+struct IDirectDrawClipperImplVtbl;
+
+typedef struct IDirectDrawClipperImpl
+{
+ struct IDirectDrawClipperImplVtbl *lpVtbl;
+
+ ULONG ref;
+
+} IDirectDrawClipperImpl;
+
+typedef struct IDirectDrawClipperImplVtbl IDirectDrawClipperImplVtbl;
+
+struct IDirectDrawClipperImplVtbl
+{
+ /* IUnknown */
+ HRESULT (__stdcall *QueryInterface)(IDirectDrawClipperImpl *, REFIID, void **);
+ ULONG (__stdcall *AddRef)(IDirectDrawClipperImpl *);
+ ULONG (__stdcall *Release)(IDirectDrawClipperImpl *);
+
+ /* IDirectDrawClipper */
+ HRESULT (__stdcall *GetClipList)(IDirectDrawClipperImpl *, LPRECT, LPRGNDATA, LPDWORD);
+ HRESULT (__stdcall *GetHWnd)(IDirectDrawClipperImpl *, HWND FAR *);
+ HRESULT (__stdcall *Initialize)(IDirectDrawClipperImpl *, LPDIRECTDRAW, DWORD);
+ HRESULT (__stdcall *IsClipListChanged)(IDirectDrawClipperImpl *, BOOL FAR *);
+ HRESULT (__stdcall *SetClipList)(IDirectDrawClipperImpl *, LPRGNDATA,DWORD);
+ HRESULT (__stdcall *SetHWnd)(IDirectDrawClipperImpl *, DWORD, HWND );
+};
+
+extern struct IDirectDrawClipperImplVtbl g_ddc_vtbl;
+
+#endif
diff --git a/inc/IDirectDrawPalette.h b/inc/IDirectDrawPalette.h
new file mode 100644
index 0000000..3762897
--- /dev/null
+++ b/inc/IDirectDrawPalette.h
@@ -0,0 +1,42 @@
+#ifndef IDIRECTDRAWPALETTE_H
+#define IDIRECTDRAWPALETTE_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "ddraw.h"
+
+
+struct IDirectDrawPaletteImpl;
+struct IDirectDrawPaletteImplVtbl;
+
+typedef struct IDirectDrawPaletteImpl
+{
+ struct IDirectDrawPaletteImplVtbl* lpVtbl;
+
+ ULONG ref;
+
+ int data_bgr[256];
+ RGBQUAD* data_rgb;
+
+} IDirectDrawPaletteImpl;
+
+typedef struct IDirectDrawPaletteImplVtbl IDirectDrawPaletteImplVtbl;
+
+struct IDirectDrawPaletteImplVtbl
+{
+ /* IUnknown */
+ HRESULT(__stdcall* QueryInterface)(IDirectDrawPaletteImpl*, REFIID, void**);
+ ULONG(__stdcall* AddRef)(IDirectDrawPaletteImpl*);
+ ULONG(__stdcall* Release)(IDirectDrawPaletteImpl*);
+
+ /* IDirectDrawPalette */
+ HRESULT(__stdcall* GetCaps)(IDirectDrawPaletteImpl*, LPDWORD);
+ HRESULT(__stdcall* GetEntries)(IDirectDrawPaletteImpl*, DWORD, DWORD, DWORD, LPPALETTEENTRY);
+ HRESULT(__stdcall* Initialize)(IDirectDrawPaletteImpl*, LPDIRECTDRAW, DWORD, LPPALETTEENTRY);
+ HRESULT(__stdcall* SetEntries)(IDirectDrawPaletteImpl*, DWORD, DWORD, DWORD, LPPALETTEENTRY);
+
+};
+
+extern struct IDirectDrawPaletteImplVtbl g_ddp_vtbl;
+
+#endif
diff --git a/inc/surface.h b/inc/IDirectDrawSurface.h
similarity index 74%
rename from inc/surface.h
rename to inc/IDirectDrawSurface.h
index 45631c1..b015fea 100644
--- a/inc/surface.h
+++ b/inc/IDirectDrawSurface.h
@@ -1,38 +1,20 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
-
-#ifndef SURFACE_H
-#define SURFACE_H
+#ifndef IDIRECTDRAWSURFACE_H
+#define IDIRECTDRAWSURFACE_H
+#define WIN32_LEAN_AND_MEAN
#include
+#include "IDirectDrawPalette.h"
#include "ddraw.h"
-#include "palette.h"
-HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC DDSurfaceDesc, LPDIRECTDRAWSURFACE FAR *DDSurface, IUnknown FAR * unkOuter);
struct IDirectDrawSurfaceImpl;
struct IDirectDrawSurfaceImplVtbl;
-extern struct IDirectDrawSurfaceImpl *ddraw_primary;
-
typedef struct IDirectDrawSurfaceImpl
{
struct IDirectDrawSurfaceImplVtbl *lpVtbl;
- ULONG Ref;
+ ULONG ref;
DWORD width;
DWORD height;
@@ -43,18 +25,20 @@ typedef struct IDirectDrawSurfaceImpl
IDirectDrawPaletteImpl *palette;
void *surface;
- DWORD lPitch;
- DWORD lXPitch;
+ DWORD l_pitch;
+ DWORD lx_pitch;
PBITMAPINFO bmi;
HBITMAP bitmap;
- HDC hDC;
- DDCOLORKEY colorKey;
- DWORD lastFlipTick;
- DWORD lastBltTick;
+ HDC hdc;
+ DDCOLORKEY color_key;
+ DWORD last_flip_tick;
+ DWORD last_blt_tick;
} IDirectDrawSurfaceImpl;
+typedef struct IDirectDrawSurfaceImplVtbl IDirectDrawSurfaceImplVtbl;
+
struct IDirectDrawSurfaceImplVtbl
{
/* IUnknown */
@@ -96,7 +80,8 @@ struct IDirectDrawSurfaceImplVtbl
HRESULT (__stdcall *UpdateOverlay)(IDirectDrawSurfaceImpl*, LPRECT, LPDIRECTDRAWSURFACE,LPRECT,DWORD, LPDDOVERLAYFX);
HRESULT (__stdcall *UpdateOverlayDisplay)(IDirectDrawSurfaceImpl*, DWORD);
HRESULT (__stdcall *UpdateOverlayZOrder)(IDirectDrawSurfaceImpl*, DWORD, LPDIRECTDRAWSURFACE);
-} IDirectDrawSurfaceImplVtbl;
+};
+extern struct IDirectDrawSurfaceImplVtbl g_dds_vtbl;
#endif
diff --git a/inc/clipper.h b/inc/clipper.h
deleted file mode 100644
index f716dcb..0000000
--- a/inc/clipper.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
-
-#ifndef CLIPPER_H
-#define CLIPPER_H
-
-#include
-#include "ddraw.h"
-#include "main.h"
-
-HRESULT __stdcall ddraw_CreateClipper(IDirectDrawImpl *This, DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, IUnknown FAR *pUnkOuter );
-
-struct IDirectDrawClipperImpl;
-struct IDirectDrawClipperImplVtbl;
-
-typedef struct IDirectDrawClipperImpl
-{
- struct IDirectDrawClipperImplVtbl *lpVtbl;
-
- ULONG Ref;
-
-} IDirectDrawClipperImpl;
-
-struct IDirectDrawClipperImplVtbl
-{
- /* IUnknown */
- HRESULT (__stdcall *QueryInterface)(IDirectDrawClipperImpl *, REFIID, void **);
- ULONG (__stdcall *AddRef)(IDirectDrawClipperImpl *);
- ULONG (__stdcall *Release)(IDirectDrawClipperImpl *);
-
- /* IDirectDrawClipper */
- HRESULT (__stdcall *GetClipList)(IDirectDrawClipperImpl *, LPRECT, LPRGNDATA, LPDWORD);
- HRESULT (__stdcall *GetHWnd)(IDirectDrawClipperImpl *, HWND FAR *);
- HRESULT (__stdcall *Initialize)(IDirectDrawClipperImpl *, LPDIRECTDRAW, DWORD);
- HRESULT (__stdcall *IsClipListChanged)(IDirectDrawClipperImpl *, BOOL FAR *);
- HRESULT (__stdcall *SetClipList)(IDirectDrawClipperImpl *, LPRGNDATA,DWORD);
- HRESULT (__stdcall *SetHWnd)(IDirectDrawClipperImpl *, DWORD, HWND );
-} IDirectDrawClipperImplVtbl;
-
-#endif
diff --git a/inc/config.h b/inc/config.h
new file mode 100644
index 0000000..a63dc4f
--- /dev/null
+++ b/inc/config.h
@@ -0,0 +1,23 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+
+typedef struct cnc_ddraw_config
+{
+ RECT window_rect;
+ int window_state;
+ char ini_path[MAX_PATH];
+ char process_file_name[96];
+ int save_settings;
+
+} cnc_ddraw_config;
+
+extern cnc_ddraw_config g_config;
+
+void cfg_load();
+void cfg_save();
+
+#endif
diff --git a/inc/d3d9shader.h b/inc/d3d9shader.h
index f2bad6b..6d32268 100644
--- a/inc/d3d9shader.h
+++ b/inc/d3d9shader.h
@@ -1,3 +1,6 @@
+#ifndef D3D9SHADER_H
+#define D3D9SHADER_H
+
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 10.1
@@ -42,7 +45,7 @@ float4 main(float2 texCoords : TEXCOORD) : COLOR
*/
#endif
-const BYTE PalettePixelShaderSrc[] =
+const BYTE D3D9_PALETTE_SHADER[] =
{
0, 2, 255, 255, 254, 255,
44, 0, 67, 84, 65, 66,
@@ -99,3 +102,5 @@ const BYTE PalettePixelShaderSrc[] =
0, 8, 15, 128, 0, 0,
228, 128, 255, 255, 0, 0
};
+
+#endif
\ No newline at end of file
diff --git a/inc/dd.h b/inc/dd.h
new file mode 100644
index 0000000..f33a288
--- /dev/null
+++ b/inc/dd.h
@@ -0,0 +1,118 @@
+#ifndef DD_H
+#define DD_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "ddraw.h"
+
+
+ULONG dd_AddRef();
+ULONG dd_Release();
+HRESULT dd_EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback);
+HRESULT dd_WaitForVerticalBlank(DWORD dwFlags, HANDLE h);
+HRESULT dd_SetDisplayMode(DWORD width, DWORD height, DWORD bpp);
+HRESULT dd_SetCooperativeLevel(HWND hwnd, DWORD dwFlags);
+HRESULT dd_RestoreDisplayMode();
+HRESULT dd_GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDEmulCaps);
+HRESULT dd_GetAvailableVidMem(void* lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree);
+HRESULT dd_GetVerticalBlankStatus(LPBOOL lpbIsInVB);
+
+typedef struct speed_limiter
+{
+ DWORD tick_length;
+ LONGLONG tick_length_ns;
+ HANDLE htimer;
+ LARGE_INTEGER due_time;
+ BOOL use_blt_or_flip;
+} speed_limiter;
+
+struct IDirectDrawSurfaceImpl;
+
+extern struct cnc_ddraw *g_ddraw;
+
+typedef struct cnc_ddraw
+{
+ ULONG ref;
+
+ DWORD width;
+ DWORD height;
+ DWORD bpp;
+ BOOL windowed;
+ BOOL border;
+ BOOL boxing;
+ DEVMODE mode;
+ struct IDirectDrawSurfaceImpl *primary;
+ char title[128];
+ HMODULE real_dll;
+
+ /* real export from system32\ddraw.dll */
+ HRESULT (WINAPI *DirectDrawCreate)(GUID FAR*, LPDIRECTDRAW FAR*, IUnknown FAR*);
+ CRITICAL_SECTION cs;
+
+ struct
+ {
+ int maxfps;
+ BOOL forcefps;
+ int width;
+ int height;
+ int bpp;
+
+ HDC hdc;
+ int *tex;
+
+ HANDLE thread;
+ BOOL run;
+ HANDLE sem;
+ DEVMODE mode;
+ struct { int width; int height; int x; int y; } viewport;
+
+ LONG palette_updated;
+ LONG surface_updated;
+
+ float scale_w;
+ float scale_h;
+ float unscale_w;
+ float unscale_h;
+ } render;
+
+ HWND hwnd;
+ LRESULT (CALLBACK *wndproc)(HWND, UINT, WPARAM, LPARAM);
+ struct { float x; float y; } cursor;
+ BOOL locked;
+ BOOL adjmouse;
+ BOOL devmode;
+ BOOL vsync;
+ BOOL vhack;
+ BOOL isredalert;
+ BOOL iscnc1;
+ LONG incutscene;
+ DWORD (WINAPI *renderer)(void);
+ BOOL fullscreen;
+ BOOL maintas;
+ BOOL noactivateapp;
+ BOOL handlemouse;
+ char shader[MAX_PATH];
+ BOOL wine;
+ BOOL altenter;
+ BOOL hidecursor;
+ BOOL accurate_timers;
+ BOOL resizable;
+ BOOL sierrahack;
+ BOOL nonexclusive;
+ BOOL bnet_active;
+ BOOL bnet_was_fullscreen;
+ BOOL bnet_was_upscaled;
+ RECT bnet_win_rect;
+ POINT bnet_pos;
+ int mouse_y_adjust;
+ void* last_freed_palette; // Dungeon Keeper hack
+ BOOL child_window_exists;
+ DWORD last_set_window_pos_tick; // WINE hack
+ BOOL show_driver_warning;
+ speed_limiter ticks_limiter;
+ speed_limiter flip_limiter;
+ speed_limiter fps_limiter;
+
+} cnc_ddraw;
+
+#endif
diff --git a/inc/ddclipper.h b/inc/ddclipper.h
new file mode 100644
index 0000000..499b818
--- /dev/null
+++ b/inc/ddclipper.h
@@ -0,0 +1,11 @@
+#ifndef DDCLIPPER_H
+#define DDCLIPPER_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "ddraw.h"
+
+
+HRESULT dd_CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter);
+
+#endif
diff --git a/inc/ddpalette.h b/inc/ddpalette.h
new file mode 100644
index 0000000..7bf3c92
--- /dev/null
+++ b/inc/ddpalette.h
@@ -0,0 +1,14 @@
+#ifndef DDPALETTE_H
+#define DDPALETTE_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "ddraw.h"
+#include "IDirectDrawPalette.h"
+#include "dd.h"
+
+HRESULT ddp_GetEntries(IDirectDrawPaletteImpl* This, DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries);
+HRESULT ddp_SetEntries(IDirectDrawPaletteImpl* This, DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries);
+HRESULT dd_CreatePalette(DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR* lpDDPalette, IUnknown FAR* unkOuter);
+
+#endif
diff --git a/inc/ddraw.h b/inc/ddraw.h
index 7923059..893a292 100644
--- a/inc/ddraw.h
+++ b/inc/ddraw.h
@@ -422,7 +422,7 @@ typedef DDBLTBATCH FAR * LPDDBLTBATCH;
/*
* callbacks
*/
-typedef DWORD (FAR PASCAL *LPCLIPPERCALLBACK)(LPDIRECTDRAWCLIPPER lpDDClipper, HWND hWnd, DWORD code, LPVOID lpContext );
+typedef DWORD (FAR PASCAL *LPCLIPPERCALLBACK)(LPDIRECTDRAWCLIPPER lpDDClipper, HWND hwnd, DWORD code, LPVOID lpContext );
#ifdef STREAMING
typedef DWORD (FAR PASCAL *LPSURFACESTREAMINGCALLBACK)(DWORD);
#endif
diff --git a/inc/ddsurface.h b/inc/ddsurface.h
new file mode 100644
index 0000000..5f9f388
--- /dev/null
+++ b/inc/ddsurface.h
@@ -0,0 +1,32 @@
+#ifndef DDSURFACE_H
+#define DDSURFACE_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "ddraw.h"
+#include "IDirectDrawSurface.h"
+
+// enables redraw via blt/unlock if there wasn't any flip for X ms
+#define FLIP_REDRAW_TIMEOUT 1000 / 10
+
+HRESULT dds_AddAttachedSurface(IDirectDrawSurfaceImpl* This, LPDIRECTDRAWSURFACE lpDDSurface);
+HRESULT dds_Blt(IDirectDrawSurfaceImpl* This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx);
+HRESULT dds_BltFast(IDirectDrawSurfaceImpl* This, DWORD dst_x, DWORD dst_y, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD flags);
+HRESULT dds_DeleteAttachedSurface(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSurface);
+HRESULT dds_GetSurfaceDesc(IDirectDrawSurfaceImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc);
+HRESULT dds_EnumAttachedSurfaces(IDirectDrawSurfaceImpl* This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback);
+HRESULT dds_Flip(IDirectDrawSurfaceImpl* This, LPDIRECTDRAWSURFACE surface, DWORD flags);
+HRESULT dds_GetAttachedSurface(IDirectDrawSurfaceImpl* This, LPDDSCAPS lpDdsCaps, LPDIRECTDRAWSURFACE FAR* surface);
+HRESULT dds_GetCaps(IDirectDrawSurfaceImpl* This, LPDDSCAPS lpDDSCaps);
+HRESULT dds_GetColorKey(IDirectDrawSurfaceImpl* This, DWORD flags, LPDDCOLORKEY colorKey);
+HRESULT dds_GetDC(IDirectDrawSurfaceImpl* This, HDC FAR* a);
+HRESULT dds_GetPalette(IDirectDrawSurfaceImpl* This, LPDIRECTDRAWPALETTE FAR* lplpDDPalette);
+HRESULT dds_GetPixelFormat(IDirectDrawSurfaceImpl* This, LPDDPIXELFORMAT ddpfPixelFormat);
+HRESULT dds_Lock(IDirectDrawSurfaceImpl* This, LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent);
+HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl* This, DWORD flags, LPDDCOLORKEY colorKey);
+HRESULT dds_SetPalette(IDirectDrawSurfaceImpl* This, LPDIRECTDRAWPALETTE lpDDPalette);
+HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPVOID lpRect);
+HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR* lpDDSurface, IUnknown FAR* unkOuter);
+
+
+#endif
diff --git a/inc/debug.h b/inc/debug.h
index 19d9907..1e9165c 100644
--- a/inc/debug.h
+++ b/inc/debug.h
@@ -1,17 +1,25 @@
-#pragma once
+#ifndef DEBUG_H
+#define DEBUG_H
+
#define WIN32_LEAN_AND_MEAN
#include
-#include
-void CounterStart();
-double CounterStop();
-void DebugPrint(const char *format, ...);
-void DrawFrameInfoStart();
-void DrawFrameInfoEnd();
-int dprintf(const char *fmt, ...);
-extern double DebugFrameTime;
-extern DWORD DebugFrameCount;
+void dbg_counter_start();
+double dbg_counter_stop();
+void dbg_debug_string(const char *format, ...);
+void dbg_draw_frame_info_start();
+void dbg_draw_frame_info_end();
+int dbg_printf(const char *fmt, ...);
+void dbg_init();
+void dbg_dump_dds_blt_flags(DWORD flags);
+void dbg_dump_dds_caps(DWORD caps);
+void dbg_dump_dds_flags(DWORD flags);
+void dbg_dump_dds_blt_fast_flags(DWORD flags);
+void dbg_dump_dds_lock_flags(DWORD flags);
+
+extern double g_dbg_frame_time;
+extern DWORD g_dbg_frame_count;
//#define _DEBUG 1
@@ -21,14 +29,35 @@ extern DWORD DebugFrameCount;
//log everything (slow)
//#define _DEBUG_X 1
+
+
#ifdef _DEBUG
#ifdef _DEBUG_S
-#define printf(format, ...) DebugPrint("xDBG " format, ##__VA_ARGS__)
+
+#define dprintf(format, ...) dbg_debug_string("xDBG " format, ##__VA_ARGS__)
+
+#ifdef _DEBUG_X
+#define dprintfex(format, ...) dbg_debug_string("xDBG " format, ##__VA_ARGS__)
#else
-#define printf(format, ...) dprintf(format, ##__VA_ARGS__)
+#define dprintfex(format, ...)
+#endif
+
+#else
+
+#define dprintf(format, ...) dbg_printf(format, ##__VA_ARGS__)
+
+#ifdef _DEBUG_X
+#define dprintfex(format, ...) dbg_printf(format, ##__VA_ARGS__)
+#else
+#define dprintfex(format, ...)
+#endif
+
#endif
#else
-#define printf(format, ...)
-#endif
+#define dprintf(format, ...)
+#define dprintfex(format, ...)
+#endif
+
+#endif
diff --git a/inc/directinput.h b/inc/directinput.h
new file mode 100644
index 0000000..50f251d
--- /dev/null
+++ b/inc/directinput.h
@@ -0,0 +1,7 @@
+#ifndef DINPUTINPUT_H
+#define DINPUTINPUT_H
+
+void dinput_hook();
+void dinput_unhook();
+
+#endif
diff --git a/inc/dllmain.h b/inc/dllmain.h
new file mode 100644
index 0000000..78a2ff6
--- /dev/null
+++ b/inc/dllmain.h
@@ -0,0 +1,16 @@
+#ifndef DLLMAIN_H
+#define DLLMAIN_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+extern BOOL GameHandlesClose;
+extern HMODULE g_ddraw_module;
+
+typedef enum PROCESS_DPI_AWARENESS {
+ PROCESS_DPI_UNAWARE = 0,
+ PROCESS_SYSTEM_DPI_AWARE = 1,
+ PROCESS_PER_MONITOR_DPI_AWARE = 2
+} PROCESS_DPI_AWARENESS;
+
+#endif
diff --git a/inc/hook.h b/inc/hook.h
index 71c5714..8721f89 100644
--- a/inc/hook.h
+++ b/inc/hook.h
@@ -1,8 +1,10 @@
#ifndef HOOK_H
#define HOOK_H
+#define WIN32_LEAN_AND_MEAN
#include
+
typedef BOOL (WINAPI* GETCURSORPOSPROC)(LPPOINT);
typedef BOOL(WINAPI* CLIPCURSORPROC)(const RECT*);
typedef int (WINAPI* SHOWCURSORPROC)(BOOL);
@@ -55,13 +57,13 @@ extern LOADLIBRARYWPROC real_LoadLibraryW;
extern LOADLIBRARYEXAPROC real_LoadLibraryExA;
extern LOADLIBRARYEXWPROC real_LoadLibraryExW;
-extern int HookingMethod;
-extern BOOL Hook_Active;
+extern int g_hook_method;
+extern BOOL g_hook_active;
-void Hook_Init();
-void Hook_Exit();
-void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction);
-void Hook_Create(char *moduleName, char *functionName, PROC newFunction, PROC *function);
-void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *function);
+void hook_init();
+void hook_exit();
+void hook_patch_iat(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction);
+void hook_create(char *moduleName, char *functionName, PROC newFunction, PROC *function);
+void hook_revert(char *moduleName, char *functionName, PROC newFunction, PROC *function);
#endif
diff --git a/inc/main.h b/inc/main.h
deleted file mode 100644
index 9e12e5e..0000000
--- a/inc/main.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
-
-#ifndef MAIN_H
-#define MAIN_H
-
-#include
-#include "ddraw.h"
-#include "debug.h"
-
-#define CUTSCENE_WIDTH 640
-#define CUTSCENE_HEIGHT 400
-
-#define WM_AUTORENDERER WM_USER+111
-#define WM_WINEFULLSCREEN WM_USER+112
-#define WM_D3D9DEVICELOST WM_USER+113
-
-#define IDT_TIMER_LEAVE_BNET 541287654
-
-DEFINE_GUID(IID_IMediaStream, 0xb502d1bd, 0x9a57, 0x11d0, 0x8f, 0xde, 0x00, 0xc0, 0x4f, 0xd9, 0x18, 0x9d);
-DEFINE_GUID(IID_IAMMediaStream, 0xbebe595d, 0x9a6f, 0x11d0, 0x8f, 0xde, 0x00, 0xc0, 0x4f, 0xd9, 0x18, 0x9d);
-
-extern BOOL ShowDriverWarning;
-extern RECT WindowRect;
-extern int WindowState;
-extern BOOL ChildWindowExists;
-extern HMODULE DDrawModule;
-
-BOOL detect_cutscene();
-void LimitGameTicks();
-void ToggleFullscreen();
-void SetWindowRect(int x, int y, int width, int height, UINT flags);
-DWORD WINAPI render_main(void);
-DWORD WINAPI render_soft_main(void);
-BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam);
-
-struct IDirectDrawImpl;
-struct IDirectDrawImplVtbl;
-struct IDirectDrawSurfaceImpl;
-
-extern struct IDirectDrawImpl *ddraw;
-
-typedef struct SpeedLimiter
-{
- DWORD ticklength;
- LONGLONG tickLengthNs;
- HANDLE hTimer;
- LARGE_INTEGER dueTime;
- BOOL useBltOrFlip;
-} SpeedLimiter;
-
-typedef struct IDirectDrawImpl
-{
- struct IDirectDrawImplVtbl *lpVtbl;
-
- ULONG Ref;
-
- DWORD width;
- DWORD height;
- DWORD bpp;
- BOOL windowed;
- BOOL border;
- BOOL boxing;
- DEVMODE mode;
- struct IDirectDrawSurfaceImpl *primary;
- char title[128];
- HMODULE real_dll;
-
- /* real export from system32\ddraw.dll */
- HRESULT (WINAPI *DirectDrawCreate)(GUID FAR*, LPDIRECTDRAW FAR*, IUnknown FAR*);
- CRITICAL_SECTION cs;
-
- struct
- {
- int maxfps;
- BOOL forcefps;
- int width;
- int height;
- int bpp;
-
- HDC hDC;
- int *tex;
-
- HANDLE thread;
- BOOL run;
- HANDLE sem;
- DEVMODE mode;
- struct { int width; int height; int x; int y; } viewport;
-
- LONG paletteUpdated;
- LONG surfaceUpdated;
-
- float scaleW;
- float scaleH;
- float unScaleW;
- float unScaleH;
- } render;
-
- HWND hWnd;
- LRESULT (CALLBACK *WndProc)(HWND, UINT, WPARAM, LPARAM);
- struct { float x; float y; } cursor;
- BOOL locked;
- BOOL adjmouse;
- BOOL devmode;
- BOOL vsync;
- BOOL vhack;
- BOOL isredalert;
- BOOL iscnc1;
- LONG incutscene;
- DWORD (WINAPI *renderer)(void);
- BOOL fullscreen;
- BOOL maintas;
- BOOL noactivateapp;
- BOOL handlemouse;
- char shader[MAX_PATH];
- BOOL wine;
- BOOL altenter;
- BOOL hidecursor;
- BOOL accurateTimers;
- BOOL resizable;
- BOOL tm2hack;
- BOOL sierrahack;
- BOOL nonexclusive;
- BOOL bnetActive;
- BOOL bnetWasFullscreen;
- BOOL bnetWasUpscaled;
- RECT bnetWinRect;
- POINT bnetPos;
- SpeedLimiter ticksLimiter;
- SpeedLimiter flipLimiter;
- SpeedLimiter fpsLimiter;
-
-} IDirectDrawImpl;
-
-typedef struct IDirectDrawImplVtbl IDirectDrawImplVtbl;
-
-struct IDirectDrawImplVtbl
-{
- HRESULT(__stdcall *QueryInterface) (IDirectDrawImpl *, const IID* const riid, LPVOID * ppvObj);
- ULONG(__stdcall *AddRef) (IDirectDrawImpl *);
- ULONG(__stdcall *Release) (IDirectDrawImpl *);
-
- HRESULT(__stdcall *Compact)(IDirectDrawImpl *);
- HRESULT(__stdcall *CreateClipper)(IDirectDrawImpl *, DWORD, LPDIRECTDRAWCLIPPER *, IUnknown *);
- HRESULT(__stdcall *CreatePalette)(IDirectDrawImpl *, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *, IUnknown *);
- HRESULT(__stdcall *CreateSurface)(IDirectDrawImpl *, LPDDSURFACEDESC, LPDIRECTDRAWSURFACE *, IUnknown *);
- HRESULT(__stdcall *DuplicateSurface)( IDirectDrawImpl *, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE *);
- HRESULT(__stdcall *EnumDisplayModes)( IDirectDrawImpl *, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK);
- HRESULT(__stdcall *EnumSurfaces)(IDirectDrawImpl *, DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK);
- HRESULT(__stdcall *FlipToGDISurface)(IDirectDrawImpl *);
- HRESULT(__stdcall *GetCaps)(IDirectDrawImpl *, LPDDCAPS, LPDDCAPS);
- HRESULT(__stdcall *GetDisplayMode)(IDirectDrawImpl *, LPDDSURFACEDESC);
- HRESULT(__stdcall *GetFourCCCodes)(IDirectDrawImpl *, LPDWORD, LPDWORD);
- HRESULT(__stdcall *GetGDISurface)(IDirectDrawImpl *, LPDIRECTDRAWSURFACE *);
- HRESULT(__stdcall *GetMonitorFrequency)(IDirectDrawImpl *, LPDWORD);
- HRESULT(__stdcall *GetScanLine)(IDirectDrawImpl *, LPDWORD);
- HRESULT(__stdcall *GetVerticalBlankStatus)(IDirectDrawImpl *, LPBOOL);
- HRESULT(__stdcall *Initialize)(IDirectDrawImpl *, GUID *);
- HRESULT(__stdcall *RestoreDisplayMode)(IDirectDrawImpl *);
- HRESULT(__stdcall *SetCooperativeLevel)(IDirectDrawImpl *, HWND, DWORD);
- union
- {
- HRESULT(__stdcall *SetDisplayMode1)(IDirectDrawImpl *, DWORD, DWORD, DWORD);
- HRESULT(__stdcall *SetDisplayMode2)(IDirectDrawImpl *, DWORD, DWORD, DWORD, DWORD, DWORD);
- };
-
- HRESULT(__stdcall *WaitForVerticalBlank)(IDirectDrawImpl *, DWORD, HANDLE);
- HRESULT(__stdcall *GetAvailableVidMem)(IDirectDrawImpl *, LPDDSCAPS, LPDWORD, LPDWORD);
-};
-
-typedef enum PROCESS_DPI_AWARENESS {
- PROCESS_DPI_UNAWARE = 0,
- PROCESS_SYSTEM_DPI_AWARE = 1,
- PROCESS_PER_MONITOR_DPI_AWARE = 2
-} PROCESS_DPI_AWARENESS;
-
-#endif
diff --git a/inc/mouse.h b/inc/mouse.h
index 549bb39..b3c6460 100644
--- a/inc/mouse.h
+++ b/inc/mouse.h
@@ -1,37 +1,8 @@
#ifndef MOUSE_H
#define MOUSE_H
-#include
-
void mouse_lock();
void mouse_unlock();
-BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint);
-BOOL WINAPI fake_ClipCursor(const RECT *lpRect);
-int WINAPI fake_ShowCursor(BOOL bShow);
-HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor);
-BOOL WINAPI fake_GetWindowRect(HWND hWnd, LPRECT lpRect);
-BOOL WINAPI fake_GetClientRect(HWND hWnd, LPRECT lpRect);
-BOOL WINAPI fake_ClientToScreen(HWND hWnd, LPPOINT lpPoint);
-BOOL WINAPI fake_ScreenToClient(HWND hWnd, LPPOINT lpPoint);
-BOOL WINAPI fake_SetCursorPos(int X, int Y);
-HWND WINAPI fake_WindowFromPoint(POINT Point);
-BOOL WINAPI fake_GetClipCursor(LPRECT lpRect);
-BOOL WINAPI fake_GetCursorInfo(PCURSORINFO pci);
-int WINAPI fake_GetSystemMetrics(int nIndex);
-BOOL WINAPI fake_SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
-BOOL WINAPI fake_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);
-LRESULT WINAPI fake_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
-LONG WINAPI fake_SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong);
-BOOL WINAPI fake_EnableWindow(HWND hWnd, BOOL bEnable);
-BOOL WINAPI fake_DestroyWindow(HWND hWnd);
-int WINAPI fake_GetDeviceCaps(HDC hdc, int index);
-HMODULE WINAPI fake_LoadLibraryA(LPCSTR lpLibFileName);
-HMODULE WINAPI fake_LoadLibraryW(LPCWSTR lpLibFileName);
-HMODULE WINAPI fake_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
-HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
-HWND WINAPI fake_CreateWindowExA(
- DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y,
- int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
#endif
diff --git a/inc/opengl.h b/inc/opengl_utils.h
similarity index 91%
rename from inc/opengl.h
rename to inc/opengl_utils.h
index ce46f55..a8046f4 100644
--- a/inc/opengl.h
+++ b/inc/opengl_utils.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef OPENGL_UTILS_H
+#define OPENGL_UTILS_H
#include "glcorearb.h"
// wgl
@@ -32,11 +33,11 @@ extern PFNGLVERTEX2FPROC glVertex2f;
// <--- compat profile only
-BOOL OpenGL_LoadDll();
-void OpenGL_Init();
-BOOL OpenGL_ExtExists(char *ext, HDC hdc);
-GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource);
-GLuint OpenGL_BuildProgramFromFile(const char *filePath);
+BOOL oglu_load_dll();
+void oglu_init();
+BOOL oglu_ext_exists(char *ext, HDC hdc);
+GLuint oglu_build_program(const GLchar *vertSource, const GLchar *fragSource);
+GLuint oglu_build_program_from_file(const char *filePath);
extern PFNGLVIEWPORTPROC glViewport;
extern PFNGLBINDTEXTUREPROC glBindTexture;
@@ -52,7 +53,6 @@ extern PFNGLGETTEXIMAGEPROC glGetTexImage;
extern PFNGLPIXELSTOREIPROC glPixelStorei;
extern PFNGLENABLEPROC glEnable;
extern PFNGLCLEARPROC glClear;
-
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
extern PFNGLUSEPROGRAMPROC glUseProgram;
@@ -84,13 +84,11 @@ extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
-
extern PFNGLCREATESHADERPROC glCreateShader;
extern PFNGLDELETESHADERPROC glDeleteShader;
extern PFNGLSHADERSOURCEPROC glShaderSource;
extern PFNGLCOMPILESHADERPROC glCompileShader;
extern PFNGLGETSHADERIVPROC glGetShaderiv;
-
extern PFNGLGENBUFFERSPROC glGenBuffers;
extern PFNGLBINDBUFFERPROC glBindBuffer;
extern PFNGLBUFFERDATAPROC glBufferData;
@@ -102,21 +100,18 @@ extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
-
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
-
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
-
extern PFNGLTEXBUFFERPROC glTexBuffer;
-extern HMODULE OpenGL_hModule;
+extern HMODULE g_oglu_hmodule;
+extern BOOL g_oglu_got_version2;
+extern BOOL g_oglu_got_version3;
+extern char g_oglu_version[];
-extern BOOL OpenGL_GotVersion2;
-extern BOOL OpenGL_GotVersion3;
-
-extern char OpenGL_Version[];
+#endif
diff --git a/inc/openglshader.h b/inc/openglshader.h
index 3edd3a6..5e08d6d 100644
--- a/inc/openglshader.h
+++ b/inc/openglshader.h
@@ -1,6 +1,9 @@
+#ifndef OPENGLSHADER_H
+#define OPENGLSHADER_H
+
// old
-const char PassthroughVertShader110Src[] =
+const char PASSTHROUGH_VERT_SHADER_110[] =
"#version 110\n"
"varying vec2 TEX0; \n"
"\n"
@@ -10,7 +13,7 @@ const char PassthroughVertShader110Src[] =
" TEX0 = gl_MultiTexCoord0.xy; \n"
"}\n";
-const char PaletteFragShader110Src[] =
+const char PALETTE_FRAG_SHADER_110[] =
"#version 110\n"
"uniform sampler2D SurfaceTex; \n"
"uniform sampler2D PaletteTex; \n"
@@ -23,7 +26,7 @@ const char PaletteFragShader110Src[] =
"}\n";
-const char PassthroughFragShader110Src[] =
+const char PASSTHROUGH_FRAG_SHADER_110[] =
"#version 110\n"
"uniform sampler2D SurfaceTex; \n"
"varying vec2 TEX0; \n"
@@ -36,7 +39,7 @@ const char PassthroughFragShader110Src[] =
// new
-const char PassthroughVertShaderSrc[] =
+const char PASSTHROUGH_VERT_SHADER[] =
"#version 130\n"
"in vec4 VertexCoord;\n"
"in vec4 COLOR;\n"
@@ -53,7 +56,7 @@ const char PassthroughVertShaderSrc[] =
"}\n";
-const char PaletteFragShaderSrc[] =
+const char PALETTE_FRAG_SHADER[] =
"#version 130\n"
"out vec4 FragColor;\n"
"uniform sampler2D SurfaceTex;\n"
@@ -67,7 +70,7 @@ const char PaletteFragShaderSrc[] =
"}\n";
-const char PassthroughFragShaderSrc[] =
+const char PASSTHROUGH_FRAG_SHADER[] =
"#version 130\n"
"out vec4 FragColor;\n"
"uniform sampler2D SurfaceTex;\n"
@@ -78,3 +81,5 @@ const char PassthroughFragShaderSrc[] =
" vec4 texel = texture(SurfaceTex, TEX0.xy);\n"
" FragColor = texel;\n"
"}\n";
+
+#endif
diff --git a/inc/palette.h b/inc/palette.h
deleted file mode 100644
index 5132ee7..0000000
--- a/inc/palette.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
-
-#ifndef PALETTE_H
-#define PALETTE_H
-
-#include
-#include "ddraw.h"
-#include "main.h"
-
-struct IDirectDrawPaletteImpl;
-struct IDirectDrawPaletteImplVtbl;
-
-typedef struct IDirectDrawPaletteImpl
-{
- struct IDirectDrawPaletteImplVtbl *lpVtbl;
-
- ULONG Ref;
-
- int data_bgr[256];
- RGBQUAD *data_rgb;
-
-} IDirectDrawPaletteImpl;
-
-struct IDirectDrawPaletteImplVtbl
-{
- /* IUnknown */
- HRESULT (__stdcall *QueryInterface)(IDirectDrawPaletteImpl*, REFIID, void**);
- ULONG (__stdcall *AddRef)(IDirectDrawPaletteImpl*);
- ULONG (__stdcall *Release)(IDirectDrawPaletteImpl*);
-
- /* IDirectDrawPalette */
- HRESULT (__stdcall *GetCaps)(IDirectDrawPaletteImpl*, LPDWORD);
- HRESULT (__stdcall *GetEntries)(IDirectDrawPaletteImpl*, DWORD, DWORD, DWORD, LPPALETTEENTRY);
- HRESULT (__stdcall *Initialize)(IDirectDrawPaletteImpl*, LPDIRECTDRAW, DWORD, LPPALETTEENTRY);
- HRESULT (__stdcall *SetEntries)(IDirectDrawPaletteImpl*, DWORD, DWORD, DWORD, LPPALETTEENTRY);
-
-} IDirectDrawPaletteImplVtbl;
-
-HRESULT __stdcall ddraw_CreatePalette(IDirectDrawImpl *This, DWORD dwFlags, LPPALETTEENTRY DDColorArray, LPDIRECTDRAWPALETTE FAR * DDPalette, IUnknown FAR * unkOuter);
-extern IDirectDrawPaletteImpl *LastFreedPalette;
-
-#endif
diff --git a/inc/render_d3d9.h b/inc/render_d3d9.h
index f2054bd..472a774 100644
--- a/inc/render_d3d9.h
+++ b/inc/render_d3d9.h
@@ -1,11 +1,35 @@
-#pragma once
+#ifndef RENDER_D3D9_H
+#define RENDER_D3D9_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include
+
+#define D3D9_TEXTURE_COUNT 2
typedef struct CUSTOMVERTEX { float x, y, z, rhw, u, v; } CUSTOMVERTEX;
-DWORD WINAPI render_d3d9_main(void);
-BOOL Direct3D9_Create();
-BOOL Direct3D9_Reset();
-BOOL Direct3D9_Release();
-BOOL Direct3D9_OnDeviceLost();
+typedef struct d3d9_renderer
+{
+ HMODULE hmodule;
+ D3DPRESENT_PARAMETERS params;
+ LPDIRECT3D9 instance;
+ LPDIRECT3DDEVICE9 device;
+ LPDIRECT3DVERTEXBUFFER9 vertex_buf;
+ IDirect3DTexture9* surface_tex[D3D9_TEXTURE_COUNT];
+ IDirect3DTexture9* palette_tex[D3D9_TEXTURE_COUNT];
+ IDirect3DPixelShader9* pixel_shader;
+ float scale_w;
+ float scale_h;
+ int bits_per_pixel;
+} d3d9_renderer;
-extern HMODULE Direct3D9_hModule;
+BOOL d3d9_is_available();
+DWORD WINAPI d3d9_render_main(void);
+BOOL d3d9_create();
+BOOL d3d9_reset();
+BOOL d3d9_release();
+BOOL d3d9_on_device_lost();
+
+
+#endif
diff --git a/inc/render_gdi.h b/inc/render_gdi.h
new file mode 100644
index 0000000..caf9dab
--- /dev/null
+++ b/inc/render_gdi.h
@@ -0,0 +1,10 @@
+#ifndef RENDER_GDI_H
+#define RENDER_GDI_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+
+DWORD WINAPI gdi_render_main(void);
+
+#endif
diff --git a/inc/render_ogl.h b/inc/render_ogl.h
new file mode 100644
index 0000000..4fb46dc
--- /dev/null
+++ b/inc/render_ogl.h
@@ -0,0 +1,40 @@
+#ifndef RENDER_OGL_H
+#define RENDER_OGL_H
+
+#include
+#include "opengl_utils.h"
+
+#define TEXTURE_COUNT 4
+
+typedef struct ogl_renderer
+{
+ HGLRC context;
+ GLuint main_program;
+ GLuint scale_program;
+ BOOL got_error;
+ int surface_tex_width;
+ int surface_tex_height;
+ int* surface_tex;
+ GLenum surface_format;
+ GLenum surface_type;
+ GLuint surface_tex_ids[TEXTURE_COUNT];
+ GLuint palette_tex_ids[TEXTURE_COUNT];
+ float scale_w;
+ float scale_h;
+ GLint main_tex_coord_attr_loc;
+ GLint main_vertex_coord_attr_loc;
+ GLuint main_vbos[3];
+ GLuint main_vao;
+ GLint frame_count_uni_loc;
+ GLuint frame_buffer_id;
+ GLuint frame_buffer_tex_id;
+ GLuint scale_vbos[3];
+ GLuint scale_vao;
+ BOOL use_opengl;
+ BOOL adjust_alignment;
+ BOOL filter_bilinear;
+} ogl_renderer;
+
+DWORD WINAPI ogl_render_main(void);
+
+#endif
diff --git a/inc/screenshot.h b/inc/screenshot.h
new file mode 100644
index 0000000..f3289ea
--- /dev/null
+++ b/inc/screenshot.h
@@ -0,0 +1,10 @@
+#ifndef SCREENSHOT_H
+#define SCREENSHOT_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "ddsurface.h"
+
+BOOL ss_take_screenshot(struct IDirectDrawSurfaceImpl* src);
+
+#endif
diff --git a/inc/utils.h b/inc/utils.h
new file mode 100644
index 0000000..293a565
--- /dev/null
+++ b/inc/utils.h
@@ -0,0 +1,20 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+#define CUTSCENE_WIDTH 640
+#define CUTSCENE_HEIGHT 400
+
+
+void util_limit_game_ticks();
+void util_update_bnet_pos(int newX, int newY);
+BOOL util_get_lowest_resolution(float ratio, SIZE* outRes, DWORD minWidth, DWORD minHeight, DWORD maxWidth, DWORD maxHeight);
+void util_toggle_fullscreen();
+BOOL util_unadjust_window_rect(LPRECT prc, DWORD dwStyle, BOOL fMenu, DWORD dwExStyle);
+void util_set_window_rect(int x, int y, int width, int height, UINT flags);
+BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lParam);
+BOOL util_detect_cutscene();
+
+#endif
diff --git a/inc/winapi_hooks.h b/inc/winapi_hooks.h
new file mode 100644
index 0000000..ecff33f
--- /dev/null
+++ b/inc/winapi_hooks.h
@@ -0,0 +1,36 @@
+#ifndef WINAPI_HOOKS_H
+#define WINAPI_HOOKS_H
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+
+BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint);
+BOOL WINAPI fake_ClipCursor(const RECT *lpRect);
+int WINAPI fake_ShowCursor(BOOL bShow);
+HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor);
+BOOL WINAPI fake_GetWindowRect(HWND hWnd, LPRECT lpRect);
+BOOL WINAPI fake_GetClientRect(HWND hWnd, LPRECT lpRect);
+BOOL WINAPI fake_ClientToScreen(HWND hWnd, LPPOINT lpPoint);
+BOOL WINAPI fake_ScreenToClient(HWND hWnd, LPPOINT lpPoint);
+BOOL WINAPI fake_SetCursorPos(int X, int Y);
+HWND WINAPI fake_WindowFromPoint(POINT Point);
+BOOL WINAPI fake_GetClipCursor(LPRECT lpRect);
+BOOL WINAPI fake_GetCursorInfo(PCURSORINFO pci);
+int WINAPI fake_GetSystemMetrics(int nIndex);
+BOOL WINAPI fake_SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
+BOOL WINAPI fake_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);
+LRESULT WINAPI fake_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
+LONG WINAPI fake_SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong);
+BOOL WINAPI fake_EnableWindow(HWND hWnd, BOOL bEnable);
+BOOL WINAPI fake_DestroyWindow(HWND hWnd);
+int WINAPI fake_GetDeviceCaps(HDC hdc, int index);
+HMODULE WINAPI fake_LoadLibraryA(LPCSTR lpLibFileName);
+HMODULE WINAPI fake_LoadLibraryW(LPCWSTR lpLibFileName);
+HMODULE WINAPI fake_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
+HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
+HWND WINAPI fake_CreateWindowExA(
+ DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y,
+ int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
+
+#endif
diff --git a/inc/wndproc.h b/inc/wndproc.h
new file mode 100644
index 0000000..14cce2a
--- /dev/null
+++ b/inc/wndproc.h
@@ -0,0 +1,12 @@
+#ifndef WNDPROC_H
+#define WNDPROC_H
+
+#define WM_AUTORENDERER WM_USER+111
+#define WM_WINEFULLSCREEN WM_USER+112
+#define WM_D3D9DEVICELOST WM_USER+113
+
+#define IDT_TIMER_LEAVE_BNET 541287654
+
+LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+#endif
diff --git a/src/IDirectDraw/IDirectDraw.c b/src/IDirectDraw/IDirectDraw.c
new file mode 100644
index 0000000..bf3a4d4
--- /dev/null
+++ b/src/IDirectDraw/IDirectDraw.c
@@ -0,0 +1,369 @@
+#include
+#include "IDirectDraw.h"
+#include "dd.h"
+#include "ddclipper.h"
+#include "ddpalette.h"
+#include "ddsurface.h"
+#include "debug.h"
+
+
+HRESULT __stdcall IDirectDraw__QueryInterface(IDirectDrawImpl* This, REFIID riid, void** obj)
+{
+ dprintf("-> %s(This=%p, riid=%08X, obj=%p)\n", __FUNCTION__, This, (unsigned int)riid, obj);
+ HRESULT ret = DDERR_UNSUPPORTED;
+
+ if (riid)
+ {
+ if (IsEqualGUID(&IID_IDirectDraw2, riid) ||
+ IsEqualGUID(&IID_IDirectDraw4, riid) ||
+ IsEqualGUID(&IID_IDirectDraw7, riid))
+ {
+ dprintf(" GUID = %08X (IID_IDirectDrawX)\n", ((GUID*)riid)->Data1);
+
+ IDirectDrawImpl* dd = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
+ dd->lpVtbl = &g_dd_vtblx;
+
+ *obj = dd;
+ IDirectDraw_AddRef(dd);
+ ret = S_OK;
+ }
+ else
+ {
+ dprintf(" GUID = %08X\n", ((GUID*)riid)->Data1);
+ }
+
+ ret = S_OK;
+ }
+
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+ULONG __stdcall IDirectDraw__AddRef(IDirectDrawImpl* This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+ ULONG ret = ++This->ref;
+ ULONG glob_ref = dd_AddRef();
+ dprintf("<- %s(This ref=%u, global ref=%u)\n", __FUNCTION__, ret, glob_ref);
+ return ret;
+}
+
+ULONG __stdcall IDirectDraw__Release(IDirectDrawImpl* This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+
+ ULONG ret = --This->ref;
+
+ if (This->ref == 0)
+ {
+ dprintf(" Released (%p)\n", This);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ ULONG glob_ref = dd_Release();
+
+ dprintf("<- %s(This ref=%u, global ref=%u)\n", __FUNCTION__, ret, glob_ref);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__Compact(IDirectDrawImpl* This)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__CreateClipper(IDirectDrawImpl* This, DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter)
+{
+ dprintf("-> %s(This=%p, dwFlags=%08X, DDClipper=%p, unkOuter=%p)\n", __FUNCTION__, This, (int)dwFlags, lplpDDClipper, pUnkOuter);
+ HRESULT ret = dd_CreateClipper(dwFlags, lplpDDClipper, pUnkOuter);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__CreatePalette(IDirectDrawImpl* This, DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR* lpDDPalette, IUnknown FAR* unkOuter)
+{
+ dprintf("-> %s(This=%p, dwFlags=%08X, DDColorArray=%p, DDPalette=%p, unkOuter=%p)\n", __FUNCTION__, This, (int)dwFlags, lpDDColorArray, lpDDPalette, unkOuter);
+ HRESULT ret = dd_CreatePalette(dwFlags, lpDDColorArray, lpDDPalette, unkOuter);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__CreateSurface(IDirectDrawImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR* lpDDSurface, IUnknown FAR* unkOuter)
+{
+ dprintf("-> %s(This=%p, lpDDSurfaceDesc=%p, lpDDSurface=%p, unkOuter=%p)\n", __FUNCTION__, This, lpDDSurfaceDesc, lpDDSurface, unkOuter);
+ HRESULT ret = dd_CreateSurface(lpDDSurfaceDesc, lpDDSurface, unkOuter);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__DuplicateSurface(IDirectDrawImpl* This, LPDIRECTDRAWSURFACE src, LPDIRECTDRAWSURFACE* dest)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__EnumDisplayModes(IDirectDrawImpl* This, DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback)
+{
+ dprintf("-> %s(This=%p, dwFlags=%08X, lpDDSurfaceDesc=%p, lpContext=%p, lpEnumModesCallback=%p)\n", __FUNCTION__, This, (unsigned int)dwFlags, lpDDSurfaceDesc, lpContext, lpEnumModesCallback);
+ HRESULT ret = dd_EnumDisplayModes(dwFlags, lpDDSurfaceDesc, lpContext, lpEnumModesCallback);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__EnumSurfaces(IDirectDrawImpl* This, DWORD a, LPDDSURFACEDESC b, LPVOID c, LPDDENUMSURFACESCALLBACK d)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__FlipToGDISurface(IDirectDrawImpl* This)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetCaps(IDirectDrawImpl* This, LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDEmulCaps)
+{
+ dprintf("-> %s(This=%p, lpDDDriverCaps=%p, lpDDEmulCaps=%p)\n", __FUNCTION__, This, lpDDDriverCaps, lpDDEmulCaps);
+ HRESULT ret = dd_GetCaps(lpDDDriverCaps, lpDDEmulCaps);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetDisplayMode(IDirectDrawImpl* This, LPDDSURFACEDESC a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DDERR_UNSUPPORTEDMODE;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetFourCCCodes(IDirectDrawImpl* This, LPDWORD a, LPDWORD b)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetGDISurface(IDirectDrawImpl* This, LPDIRECTDRAWSURFACE* a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetMonitorFrequency(IDirectDrawImpl* This, LPDWORD a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetScanLine(IDirectDrawImpl* This, LPDWORD a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetVerticalBlankStatus(IDirectDrawImpl* This, LPBOOL lpbIsInVB)
+{
+ dprintf("-> %s(This=%p, lpbIsInVB=%p)\n", __FUNCTION__, This, lpbIsInVB);
+ HRESULT ret = dd_GetVerticalBlankStatus(lpbIsInVB);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__Initialize(IDirectDrawImpl* This, GUID* a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__RestoreDisplayMode(IDirectDrawImpl* This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = dd_RestoreDisplayMode();
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__SetCooperativeLevel(IDirectDrawImpl* This, HWND hwnd, DWORD dwFlags)
+{
+ dprintf("-> %s(This=%p, hwnd=0x%08X, dwFlags=0x%08X)\n", __FUNCTION__, This, (unsigned int)hwnd, (unsigned int)dwFlags);
+ HRESULT ret = dd_SetCooperativeLevel(hwnd, dwFlags);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__SetDisplayMode(IDirectDrawImpl* This, DWORD width, DWORD height, DWORD bpp)
+{
+ dprintf("-> %s(This=%p, width=%d, height=%d, bpp=%d)\n", __FUNCTION__, This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
+ HRESULT ret = dd_SetDisplayMode(width, height, bpp);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__SetDisplayModeX(IDirectDrawImpl* This, DWORD width, DWORD height, DWORD bpp, DWORD refreshRate, DWORD flags)
+{
+ dprintf("-> %s(This=%p, width=%d, height=%d, bpp=%d, refreshRate=%d, flags=%d)\n", __FUNCTION__, This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp, (unsigned int)refreshRate, (unsigned int)flags);
+ HRESULT ret = dd_SetDisplayMode(width, height, bpp);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__WaitForVerticalBlank(IDirectDrawImpl* This, DWORD dwFlags, HANDLE h)
+{
+ dprintfex("-> %s(This=%p, flags=%08X, handle=%p)\n", __FUNCTION__, This, dwFlags, h);
+ HRESULT ret = dd_WaitForVerticalBlank(dwFlags, h);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetAvailableVidMem(IDirectDrawImpl* This, void* lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
+{
+ dprintf("-> %s(This=%p, lpDDCaps=%p, lpdwTotal=%p, lpdwFree=%p)\n", __FUNCTION__, This, lpDDCaps, lpdwTotal, lpdwFree);
+ HRESULT ret = dd_GetAvailableVidMem(lpDDCaps, lpdwTotal, lpdwFree);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetSurfaceFromDC(IDirectDrawImpl* This, HDC hdc, void* lplpDDSurface)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DDERR_GENERIC;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__RestoreAllSurfaces(IDirectDrawImpl* This)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DDERR_INVALIDOBJECT;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__TestCooperativeLevel(IDirectDrawImpl* This)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DDERR_INVALIDOBJECT;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__GetDeviceIdentifier(IDirectDrawImpl* This, void* pDDDI, DWORD dwFlags)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DDERR_INVALIDPARAMS;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__StartModeTest(IDirectDrawImpl* This, LPSIZE pModes, DWORD dwNumModes, DWORD dwFlags)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DDERR_CURRENTLYNOTAVAIL;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDraw__EvaluateMode(IDirectDrawImpl* This, DWORD dwFlags, DWORD* pTimeout)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DDERR_INVALIDOBJECT;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+struct IDirectDrawImplVtbl g_dd_vtbl1 =
+{
+ /* IUnknown */
+ IDirectDraw__QueryInterface,
+ IDirectDraw__AddRef,
+ IDirectDraw__Release,
+ /* IDirectDrawImpl */
+ IDirectDraw__Compact,
+ IDirectDraw__CreateClipper,
+ IDirectDraw__CreatePalette,
+ IDirectDraw__CreateSurface,
+ IDirectDraw__DuplicateSurface,
+ IDirectDraw__EnumDisplayModes,
+ IDirectDraw__EnumSurfaces,
+ IDirectDraw__FlipToGDISurface,
+ IDirectDraw__GetCaps,
+ IDirectDraw__GetDisplayMode,
+ IDirectDraw__GetFourCCCodes,
+ IDirectDraw__GetGDISurface,
+ IDirectDraw__GetMonitorFrequency,
+ IDirectDraw__GetScanLine,
+ IDirectDraw__GetVerticalBlankStatus,
+ IDirectDraw__Initialize,
+ IDirectDraw__RestoreDisplayMode,
+ IDirectDraw__SetCooperativeLevel,
+ {IDirectDraw__SetDisplayMode},
+ IDirectDraw__WaitForVerticalBlank,
+ // v2
+ IDirectDraw__GetAvailableVidMem,
+ // v4
+ IDirectDraw__GetSurfaceFromDC,
+ IDirectDraw__RestoreAllSurfaces,
+ IDirectDraw__TestCooperativeLevel,
+ IDirectDraw__GetDeviceIdentifier,
+ // v7
+ IDirectDraw__StartModeTest,
+ IDirectDraw__EvaluateMode,
+};
+
+struct IDirectDrawImplVtbl g_dd_vtblx =
+{
+ /* IUnknown */
+ IDirectDraw__QueryInterface,
+ IDirectDraw__AddRef,
+ IDirectDraw__Release,
+ /* IDirectDrawImpl */
+ IDirectDraw__Compact,
+ IDirectDraw__CreateClipper,
+ IDirectDraw__CreatePalette,
+ IDirectDraw__CreateSurface,
+ IDirectDraw__DuplicateSurface,
+ IDirectDraw__EnumDisplayModes,
+ IDirectDraw__EnumSurfaces,
+ IDirectDraw__FlipToGDISurface,
+ IDirectDraw__GetCaps,
+ IDirectDraw__GetDisplayMode,
+ IDirectDraw__GetFourCCCodes,
+ IDirectDraw__GetGDISurface,
+ IDirectDraw__GetMonitorFrequency,
+ IDirectDraw__GetScanLine,
+ IDirectDraw__GetVerticalBlankStatus,
+ IDirectDraw__Initialize,
+ IDirectDraw__RestoreDisplayMode,
+ IDirectDraw__SetCooperativeLevel,
+ {IDirectDraw__SetDisplayModeX},
+ IDirectDraw__WaitForVerticalBlank,
+ // v2
+ IDirectDraw__GetAvailableVidMem,
+ // v4
+ IDirectDraw__GetSurfaceFromDC,
+ IDirectDraw__RestoreAllSurfaces,
+ IDirectDraw__TestCooperativeLevel,
+ IDirectDraw__GetDeviceIdentifier,
+ // v7
+ IDirectDraw__StartModeTest,
+ IDirectDraw__EvaluateMode,
+};
diff --git a/src/IDirectDraw/IDirectDrawClipper.c b/src/IDirectDraw/IDirectDrawClipper.c
new file mode 100644
index 0000000..06c8c3c
--- /dev/null
+++ b/src/IDirectDraw/IDirectDrawClipper.c
@@ -0,0 +1,99 @@
+#include "IDirectDrawClipper.h"
+#include "ddclipper.h"
+#include "debug.h"
+
+HRESULT __stdcall IDirectDrawClipper__QueryInterface(IDirectDrawClipperImpl *This, REFIID riid, void **obj)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p, riid=%08X, obj=%p)\n", __FUNCTION__, This, (unsigned int)riid, obj);
+ HRESULT ret = S_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+ULONG __stdcall IDirectDrawClipper__AddRef(IDirectDrawClipperImpl *This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+ ULONG ret = ++This->ref;
+ dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+ return ret;
+}
+
+ULONG __stdcall IDirectDrawClipper__Release(IDirectDrawClipperImpl *This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+
+ ULONG ret = --This->ref;
+
+ if (This->ref == 0)
+ {
+ dprintf(" Released (%p)\n", This);
+
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawClipper__GetClipList(IDirectDrawClipperImpl *This, LPRECT a, LPRGNDATA b, LPDWORD c)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawClipper__GetHWnd(IDirectDrawClipperImpl *This, HWND FAR *a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawClipper__Initialize(IDirectDrawClipperImpl *This, LPDIRECTDRAW a, DWORD b)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawClipper__IsClipListChanged(IDirectDrawClipperImpl *This, BOOL FAR *a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawClipper__SetClipList(IDirectDrawClipperImpl *This, LPRGNDATA a, DWORD b)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawClipper__SetHWnd(IDirectDrawClipperImpl *This, DWORD a, HWND b)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+struct IDirectDrawClipperImplVtbl g_ddc_vtbl =
+{
+ /* IUnknown */
+ IDirectDrawClipper__QueryInterface,
+ IDirectDrawClipper__AddRef,
+ IDirectDrawClipper__Release,
+ /* IDirectDrawClipper */
+ IDirectDrawClipper__GetClipList,
+ IDirectDrawClipper__GetHWnd,
+ IDirectDrawClipper__Initialize,
+ IDirectDrawClipper__IsClipListChanged,
+ IDirectDrawClipper__SetClipList,
+ IDirectDrawClipper__SetHWnd
+};
diff --git a/src/IDirectDraw/IDirectDrawPalette.c b/src/IDirectDraw/IDirectDrawPalette.c
new file mode 100644
index 0000000..74dcc19
--- /dev/null
+++ b/src/IDirectDraw/IDirectDrawPalette.c
@@ -0,0 +1,84 @@
+#include "IDirectDrawPalette.h"
+#include "ddpalette.h"
+#include "ddsurface.h"
+#include "debug.h"
+
+
+HRESULT __stdcall IDirectDrawPalette__QueryInterface(IDirectDrawPaletteImpl* This, REFIID riid, void** obj)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p, riid=%08X, obj=%p)\n", __FUNCTION__, This, (unsigned int)riid, obj);
+ HRESULT ret = S_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+ULONG __stdcall IDirectDrawPalette__AddRef(IDirectDrawPaletteImpl* This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+ ULONG ret = ++This->ref;
+ dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+ return ret;
+}
+
+ULONG __stdcall IDirectDrawPalette__Release(IDirectDrawPaletteImpl* This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+
+ ULONG ret = --This->ref;
+
+ if (This->ref == 0)
+ {
+ dprintf(" Released (%p)\n", This);
+ if (g_ddraw)
+ g_ddraw->last_freed_palette = This;
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawPalette__GetCaps(IDirectDrawPaletteImpl* This, LPDWORD caps)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p, caps=%p)\n", __FUNCTION__, This, caps);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawPalette__GetEntries(IDirectDrawPaletteImpl *This, DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries)
+{
+ dprintf("-> %s(This=%p, dwFlags=%08X, dwBase=%d, dwNumEntries=%d, lpEntries=%p)\n", __FUNCTION__, This, (int)dwFlags, (int)dwBase, (int)dwNumEntries, lpEntries);
+ HRESULT ret = ddp_GetEntries(This, dwFlags, dwBase, dwNumEntries, lpEntries);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawPalette__Initialize(IDirectDrawPaletteImpl* This, LPDIRECTDRAW lpDD, DWORD dw, LPPALETTEENTRY paent)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawPalette__SetEntries(IDirectDrawPaletteImpl *This, DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries)
+{
+ dprintfex("-> %s(This=%p, dwFlags=%08X, dwStartingEntry=%d, dwCount=%d, lpEntries=%p)\n", __FUNCTION__, This, (int)dwFlags, (int)dwStartingEntry, (int)dwCount, lpEntries);
+ HRESULT ret = ddp_SetEntries(This, dwFlags, dwStartingEntry, dwCount, lpEntries);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+struct IDirectDrawPaletteImplVtbl g_ddp_vtbl =
+{
+ /* IUnknown */
+ IDirectDrawPalette__QueryInterface,
+ IDirectDrawPalette__AddRef,
+ IDirectDrawPalette__Release,
+ /* IDirectDrawPalette */
+ IDirectDrawPalette__GetCaps,
+ IDirectDrawPalette__GetEntries,
+ IDirectDrawPalette__Initialize,
+ IDirectDrawPalette__SetEntries
+};
diff --git a/src/IDirectDraw/IDirectDrawSurface.c b/src/IDirectDraw/IDirectDrawSurface.c
new file mode 100644
index 0000000..8b22601
--- /dev/null
+++ b/src/IDirectDraw/IDirectDrawSurface.c
@@ -0,0 +1,377 @@
+#include "IDirectDrawSurface.h"
+#include "ddsurface.h"
+#include "dd.h"
+#include "debug.h"
+
+
+HRESULT __stdcall IDirectDrawSurface__QueryInterface(IDirectDrawSurfaceImpl *This, REFIID riid, void **obj)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p, riid=%08X, obj=%p)\n", __FUNCTION__, This, (unsigned int)riid, obj);
+ HRESULT ret = S_OK;
+
+ if (riid && !IsEqualGUID(&IID_IDirectDrawSurface, riid))
+ {
+ dprintf(" GUID = %08X\n", ((GUID *)riid)->Data1);
+
+ IDirectDrawSurface_AddRef(This);
+ }
+
+ *obj = This;
+
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+ULONG __stdcall IDirectDrawSurface__AddRef(IDirectDrawSurfaceImpl *This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+ ULONG ret = ++This->ref;
+ dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+ return ret;
+}
+
+ULONG __stdcall IDirectDrawSurface__Release(IDirectDrawSurfaceImpl *This)
+{
+ dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+
+ ULONG ret = --This->ref;
+
+ if(This->ref == 0)
+ {
+ dprintf(" Released (%p)\n", This);
+
+ if ((This->caps & DDSCAPS_PRIMARYSURFACE))
+ {
+ EnterCriticalSection(&g_ddraw->cs);
+ g_ddraw->primary = NULL;
+ LeaveCriticalSection(&g_ddraw->cs);
+ }
+
+ if (This->bitmap)
+ DeleteObject(This->bitmap);
+ else if (This->surface)
+ HeapFree(GetProcessHeap(), 0, This->surface);
+
+ if (This->hdc)
+ DeleteDC(This->hdc);
+
+ if (This->bmi)
+ HeapFree(GetProcessHeap(), 0, This->bmi);
+
+ if(This->palette && (!g_ddraw || (void*)This->palette != g_ddraw->last_freed_palette))
+ {
+ IDirectDrawPalette_Release(This->palette);
+ }
+
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__AddAttachedSurface(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE lpDDSurface)
+{
+ dprintf("-> %s(This=%p, lpDDSurface=%p)\n", __FUNCTION__, This, lpDDSurface);
+ HRESULT ret = dds_AddAttachedSurface(This, lpDDSurface);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__AddOverlayDirtyRect(IDirectDrawSurfaceImpl *This, LPRECT a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
+{
+ dprintfex("-> %s(This=%p, lpDestRect=%p, lpDDSrcSurface=%p, lpSrcRect=%p, dwFlags=%08X, lpDDBltFx=%p)\n", __FUNCTION__, This, lpDestRect, lpDDSrcSurface, lpSrcRect, (int)dwFlags, lpDDBltFx);
+ HRESULT ret = dds_Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__BltBatch(IDirectDrawSurfaceImpl *This, LPDDBLTBATCH a, DWORD b, DWORD c)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD flags)
+{
+ dprintfex("-> %s(This=%p, x=%d, y=%d, lpDDSrcSurface=%p, lpSrcRect=%p, flags=%08X)\n", __FUNCTION__, This, dst_x, dst_y, lpDDSrcSurface, lpSrcRect, flags);
+ HRESULT ret = dds_BltFast(This, dst_x, dst_y, lpDDSrcSurface, lpSrcRect, flags);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__DeleteAttachedSurface(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSurface)
+{
+ dprintf("-> %s(This=%p, dwFlags=%08X, lpDDSurface=%p)\n", __FUNCTION__, This, (int)dwFlags, lpDDSurface);
+ HRESULT ret = dds_DeleteAttachedSurface(This, dwFlags, lpDDSurface);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetSurfaceDesc(IDirectDrawSurfaceImpl *This, LPDDSURFACEDESC lpDDSurfaceDesc)
+{
+ dprintfex("-> %s(This=%p, lpDDSurfaceDesc=%p)\n", __FUNCTION__, This, lpDDSurfaceDesc);
+ HRESULT ret = dds_GetSurfaceDesc(This, lpDDSurfaceDesc);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__EnumAttachedSurfaces(IDirectDrawSurfaceImpl *This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
+{
+ dprintf("-> %s(This=%p, lpContext=%p, lpEnumSurfacesCallback=%p)\n", __FUNCTION__, This, lpContext, lpEnumSurfacesCallback);
+ HRESULT ret = dds_EnumAttachedSurfaces(This, lpContext, lpEnumSurfacesCallback);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__EnumOverlayZOrders(IDirectDrawSurfaceImpl *This, DWORD a, LPVOID b, LPDDENUMSURFACESCALLBACK c)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE surface, DWORD flags)
+{
+ dprintfex("-> %s(This=%p, surface=%p, flags=%08X)\n", __FUNCTION__, This, surface, flags);
+ HRESULT ret = dds_Flip(This, surface, flags);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetAttachedSurface(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDdsCaps, LPDIRECTDRAWSURFACE FAR *surface)
+{
+ dprintf("-> %s(This=%p, dwCaps=%08X, surface=%p)\n", __FUNCTION__, This, lpDdsCaps->dwCaps, surface);
+ HRESULT ret = dds_GetAttachedSurface(This, lpDdsCaps, surface);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetBltStatus(IDirectDrawSurfaceImpl *This, DWORD a)
+{
+ dprintfex("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintfex("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetCaps(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDDSCaps)
+{
+ dprintf("-> %s(This=%p, lpDDSCaps=%p)\n", __FUNCTION__, This, lpDDSCaps);
+ HRESULT ret = dds_GetCaps(This, lpDDSCaps);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetClipper(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWCLIPPER FAR *a)
+{
+ dprintfex("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintfex("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY colorKey)
+{
+ dprintfex("-> %s(This=%p, flags=0x%08X, color_key=%p)\n", __FUNCTION__, This, flags, colorKey);
+ HRESULT ret = dds_GetColorKey(This, flags, colorKey);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetDC(IDirectDrawSurfaceImpl *This, HDC FAR *a)
+{
+ dprintfex("-> %s(This=%p, ...)\n", __FUNCTION__, This);
+ HRESULT ret = dds_GetDC(This, a);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetFlipStatus(IDirectDrawSurfaceImpl *This, DWORD a)
+{
+ dprintfex("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintfex("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetOverlayPosition(IDirectDrawSurfaceImpl *This, LPLONG a, LPLONG b)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE FAR *lplpDDPalette)
+{
+ dprintf("-> %s(This=%p, lplpDDPalette=%p)\n", __FUNCTION__, This, lplpDDPalette);
+ HRESULT ret = dds_GetPalette(This, lplpDDPalette);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__GetPixelFormat(IDirectDrawSurfaceImpl *This, LPDDPIXELFORMAT ddpfPixelFormat)
+{
+ dprintf("-> %s(This=%p, ...)\n", __FUNCTION__, This);
+ HRESULT ret = dds_GetPixelFormat(This, ddpfPixelFormat);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__Initialize(IDirectDrawSurfaceImpl *This, LPDIRECTDRAW a, LPDDSURFACEDESC b)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__IsLost(IDirectDrawSurfaceImpl *This)
+{
+ dprintfex("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintfex("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__Lock(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
+{
+ dprintfex("-> %s(This=%p, lpDestRect=%p, lpDDSurfaceDesc=%p, dwFlags=%08X, hEvent=%p)\n", __FUNCTION__, This, lpDestRect, lpDDSurfaceDesc, (int)dwFlags, hEvent);
+ HRESULT ret = dds_Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__ReleaseDC(IDirectDrawSurfaceImpl *This, HDC a)
+{
+ dprintfex("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintfex("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__Restore(IDirectDrawSurfaceImpl *This)
+{
+ dprintfex("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintfex("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__SetClipper(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWCLIPPER a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__SetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY colorKey)
+{
+ dprintfex("-> %s(This=%p, flags=0x%08X, color_key=%p)\n", __FUNCTION__, This, flags, colorKey);
+ HRESULT ret = dds_SetColorKey(This, flags, colorKey);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__SetOverlayPosition(IDirectDrawSurfaceImpl *This, LONG a, LONG b)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__SetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE lpDDPalette)
+{
+ dprintf("-> %s(This=%p, lpDDPalette=%p)\n", __FUNCTION__, This, lpDDPalette);
+ HRESULT ret = dds_SetPalette(This, lpDDPalette);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
+{
+ dprintfex("-> %s(This=%p, lpRect=%p)\n", __FUNCTION__, This, lpRect);
+ HRESULT ret = dds_Unlock(This, lpRect);
+ dprintfex("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__UpdateOverlay(IDirectDrawSurfaceImpl *This, LPRECT a, LPDIRECTDRAWSURFACE b, LPRECT c, DWORD d, LPDDOVERLAYFX e)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__UpdateOverlayDisplay(IDirectDrawSurfaceImpl *This, DWORD a)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT __stdcall IDirectDrawSurface__UpdateOverlayZOrder(IDirectDrawSurfaceImpl *This, DWORD a, LPDIRECTDRAWSURFACE b)
+{
+ dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+ HRESULT ret = DD_OK;
+ dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+ return ret;
+}
+
+struct IDirectDrawSurfaceImplVtbl g_dds_vtbl =
+{
+ /* IUnknown */
+ IDirectDrawSurface__QueryInterface,
+ IDirectDrawSurface__AddRef,
+ IDirectDrawSurface__Release,
+ /* IDirectDrawSurface */
+ IDirectDrawSurface__AddAttachedSurface,
+ IDirectDrawSurface__AddOverlayDirtyRect,
+ IDirectDrawSurface__Blt,
+ IDirectDrawSurface__BltBatch,
+ IDirectDrawSurface__BltFast,
+ IDirectDrawSurface__DeleteAttachedSurface,
+ IDirectDrawSurface__EnumAttachedSurfaces,
+ IDirectDrawSurface__EnumOverlayZOrders,
+ IDirectDrawSurface__Flip,
+ IDirectDrawSurface__GetAttachedSurface,
+ IDirectDrawSurface__GetBltStatus,
+ IDirectDrawSurface__GetCaps,
+ IDirectDrawSurface__GetClipper,
+ IDirectDrawSurface__GetColorKey,
+ IDirectDrawSurface__GetDC,
+ IDirectDrawSurface__GetFlipStatus,
+ IDirectDrawSurface__GetOverlayPosition,
+ IDirectDrawSurface__GetPalette,
+ IDirectDrawSurface__GetPixelFormat,
+ IDirectDrawSurface__GetSurfaceDesc,
+ IDirectDrawSurface__Initialize,
+ IDirectDrawSurface__IsLost,
+ IDirectDrawSurface__Lock,
+ IDirectDrawSurface__ReleaseDC,
+ IDirectDrawSurface__Restore,
+ IDirectDrawSurface__SetClipper,
+ IDirectDrawSurface__SetColorKey,
+ IDirectDrawSurface__SetOverlayPosition,
+ IDirectDrawSurface__SetPalette,
+ IDirectDrawSurface__Unlock,
+ IDirectDrawSurface__UpdateOverlay,
+ IDirectDrawSurface__UpdateOverlayDisplay,
+ IDirectDrawSurface__UpdateOverlayZOrder
+};
diff --git a/src/clipper.c b/src/clipper.c
deleted file mode 100644
index fd70511..0000000
--- a/src/clipper.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
-
-#include
-#include
-#include "clipper.h"
-
-HRESULT __stdcall ddraw_clipper_QueryInterface(IDirectDrawClipperImpl *This, REFIID riid, void **obj)
-{
- printf("??? DirectDrawClipper::QueryInterface(This=%p, riid=%08X, obj=%p)\n", This, (unsigned int)riid, obj);
- return S_OK;
-}
-
-ULONG __stdcall ddraw_clipper_AddRef(IDirectDrawClipperImpl *This)
-{
- printf("DirectDrawClipper::AddRef(This=%p)\n", This);
-
- This->Ref++;
-
- return This->Ref;
-}
-
-ULONG __stdcall ddraw_clipper_Release(IDirectDrawClipperImpl *This)
-{
- printf("DirectDrawClipper::Release(This=%p)\n", This);
-
- This->Ref--;
-
- if(This->Ref == 0)
- {
- printf(" Released (%p)\n", This);
-
- HeapFree(GetProcessHeap(), 0, This);
- return 0;
- }
-
- return This->Ref;
-}
-
-HRESULT __stdcall ddraw_clipper_GetClipList(IDirectDrawClipperImpl *This, LPRECT a, LPRGNDATA b, LPDWORD c)
-{
- printf("??? IDirectDrawClipper::GetClipList(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_clipper_GetHWnd(IDirectDrawClipperImpl *This, HWND FAR *a)
-{
- printf("??? IDirectDrawClipper::GetHWnd(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_clipper_Initialize(IDirectDrawClipperImpl *This, LPDIRECTDRAW a, DWORD b)
-{
- printf("??? IDirectDrawClipper::Initialize(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_clipper_IsClipListChanged(IDirectDrawClipperImpl *This, BOOL FAR *a)
-{
- printf("??? IDirectDrawClipper::IsClipListChanged(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_clipper_SetClipList(IDirectDrawClipperImpl *This, LPRGNDATA a, DWORD b)
-{
- printf("??? IDirectDrawClipper::SetClipList(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_clipper_SetHWnd(IDirectDrawClipperImpl *This, DWORD a, HWND b)
-{
- printf("??? IDirectDrawClipper::SetHWnd(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-struct IDirectDrawClipperImplVtbl ciface =
-{
- /* IUnknown */
- ddraw_clipper_QueryInterface,
- ddraw_clipper_AddRef,
- ddraw_clipper_Release,
- /* IDirectDrawClipper */
- ddraw_clipper_GetClipList,
- ddraw_clipper_GetHWnd,
- ddraw_clipper_Initialize,
- ddraw_clipper_IsClipListChanged,
- ddraw_clipper_SetClipList,
- ddraw_clipper_SetHWnd
-};
-
-HRESULT __stdcall ddraw_CreateClipper(IDirectDrawImpl *This, DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, IUnknown FAR *pUnkOuter )
-{
- printf("DirectDraw::CreateClipper(This=%p, dwFlags=%08X, DDClipper=%p, unkOuter=%p)\n", This, (int)dwFlags, lplpDDClipper, pUnkOuter);
-
- if (!lplpDDClipper)
- return DDERR_INVALIDPARAMS;
-
- IDirectDrawClipperImpl *Clipper = (IDirectDrawClipperImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawClipperImpl));
- Clipper->lpVtbl = &ciface;
- printf(" Clipper = %p\n", Clipper);
- *lplpDDClipper = (LPDIRECTDRAWCLIPPER)Clipper;
-
- ddraw_clipper_AddRef(Clipper);
-
- return DD_OK;
-}
diff --git a/src/settings.c b/src/config.c
similarity index 67%
rename from src/settings.c
rename to src/config.c
index b923bda..b059801 100644
--- a/src/settings.c
+++ b/src/config.c
@@ -2,214 +2,205 @@
#include
#include
#include
-#include "main.h"
-#include "opengl.h"
+#include "config.h"
+#include "dd.h"
#include "render_d3d9.h"
+#include "render_gdi.h"
+#include "render_ogl.h"
#include "hook.h"
+#include "debug.h"
-static char SettingsIniPath[MAX_PATH];
-static char ProcessFileName[96];
-static int SaveSettings;
-static BOOL GetBool(LPCSTR key, BOOL defaultValue);
-static int GetInt(LPCSTR key, int defaultValue);
-static DWORD GetString(LPCSTR key, LPCSTR defaultValue, LPSTR outString, DWORD outSize);
-static void CreateSettingsIni();
+static BOOL cfg_get_bool(LPCSTR key, BOOL defaultValue);
+static int cfg_get_int(LPCSTR key, int defaultValue);
+static DWORD cfg_get_string(LPCSTR key, LPCSTR defaultValue, LPSTR outString, DWORD outSize);
+static void cfg_create_ini();
-void Settings_Load()
+cnc_ddraw_config g_config =
+ { .window_rect = { .left = -32000, .top = -32000, .right = 0, .bottom = 0 }, .window_state = -1 };
+
+void cfg_load()
{
//set up settings ini
char cwd[MAX_PATH];
char tmp[256];
GetCurrentDirectoryA(sizeof(cwd), cwd);
- _snprintf(SettingsIniPath, sizeof(SettingsIniPath), "%s\\ddraw.ini", cwd);
+ _snprintf(g_config.ini_path, sizeof(g_config.ini_path), "%s\\ddraw.ini", cwd);
- if (GetFileAttributes(SettingsIniPath) == INVALID_FILE_ATTRIBUTES)
- CreateSettingsIni();
+ if (GetFileAttributes(g_config.ini_path) == INVALID_FILE_ATTRIBUTES)
+ cfg_create_ini();
//get process filename
- char ProcessFilePath[MAX_PATH] = { 0 };
- GetModuleFileNameA(NULL, ProcessFilePath, MAX_PATH);
- _splitpath(ProcessFilePath, NULL, NULL, ProcessFileName, NULL);
+ char process_file_path[MAX_PATH] = { 0 };
+ GetModuleFileNameA(NULL, process_file_path, MAX_PATH);
+ _splitpath(process_file_path, NULL, NULL, g_config.process_file_name, NULL);
//load settings from ini
- ddraw->windowed = GetBool("windowed", FALSE);
- ddraw->border = GetBool("border", TRUE);
- ddraw->boxing = GetBool("boxing", FALSE);
- ddraw->maintas = GetBool("maintas", FALSE);
- ddraw->adjmouse = GetBool("adjmouse", FALSE);
- ddraw->devmode = GetBool("devmode", FALSE);
- ddraw->vsync = GetBool("vsync", FALSE);
- ddraw->noactivateapp = GetBool("noactivateapp", FALSE);
- ddraw->vhack = GetBool("vhack", FALSE);
- ddraw->accurateTimers = GetBool("accuratetimers", FALSE);
- ddraw->resizable = GetBool("resizable", TRUE);
- ddraw->nonexclusive = GetBool("nonexclusive", FALSE);
- ddraw->tm2hack = GetBool("tm2hack", FALSE); // Twisted Metal 2 hack
- ddraw->sierrahack = GetBool("sierrahack", FALSE); // Sierra Caesar III, Pharaoh, and Zeus hack
+ g_ddraw->windowed = cfg_get_bool("windowed", FALSE);
+ g_ddraw->border = cfg_get_bool("border", TRUE);
+ g_ddraw->boxing = cfg_get_bool("boxing", FALSE);
+ g_ddraw->maintas = cfg_get_bool("maintas", FALSE);
+ g_ddraw->adjmouse = cfg_get_bool("adjmouse", FALSE);
+ g_ddraw->devmode = cfg_get_bool("devmode", FALSE);
+ g_ddraw->vsync = cfg_get_bool("vsync", FALSE);
+ g_ddraw->noactivateapp = cfg_get_bool("noactivateapp", FALSE);
+ g_ddraw->vhack = cfg_get_bool("vhack", FALSE);
+ g_ddraw->accurate_timers = cfg_get_bool("accuratetimers", FALSE);
+ g_ddraw->resizable = cfg_get_bool("resizable", TRUE);
+ g_ddraw->nonexclusive = cfg_get_bool("nonexclusive", FALSE);
+ g_ddraw->sierrahack = cfg_get_bool("sierrahack", FALSE); // Sierra Caesar III, Pharaoh, and Zeus hack
- WindowRect.right = GetInt("width", 0);
- WindowRect.bottom = GetInt("height", 0);
- WindowRect.left = GetInt("posX", -32000);
- WindowRect.top = GetInt("posY", -32000);
+ g_config.window_rect.right = cfg_get_int("width", 0);
+ g_config.window_rect.bottom = cfg_get_int("height", 0);
+ g_config.window_rect.left = cfg_get_int("posX", -32000);
+ g_config.window_rect.top = cfg_get_int("posY", -32000);
- SaveSettings = GetInt("savesettings", 2);
+ g_config.save_settings = cfg_get_int("savesettings", 2);
#ifdef _MSC_VER
- HookingMethod = GetInt("hook", 4);
+ g_hook_method = cfg_get_int("hook", 4);
#endif
- ddraw->render.maxfps = GetInt("maxfps", 60);
+ g_ddraw->render.maxfps = cfg_get_int("maxfps", 60);
- if (ddraw->render.maxfps)
- ddraw->render.forcefps = GetBool("forcefps", FALSE);
+ if (g_ddraw->render.maxfps)
+ g_ddraw->render.forcefps = cfg_get_bool("forcefps", FALSE);
- if (ddraw->accurateTimers || ddraw->vsync)
- ddraw->fpsLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
- //can't fully set it up here due to missing ddraw->mode.dmDisplayFrequency
+ if (g_ddraw->accurate_timers || g_ddraw->vsync)
+ g_ddraw->fps_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL);
+ //can't fully set it up here due to missing g_ddraw->mode.dmDisplayFrequency
- int maxTicks = GetInt("maxgameticks", 0);
- if (maxTicks > 0 && maxTicks <= 1000)
+ int max_ticks = cfg_get_int("maxgameticks", 0);
+ if (max_ticks > 0 && max_ticks <= 1000)
{
- if (ddraw->accurateTimers)
- ddraw->ticksLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
+ if (g_ddraw->accurate_timers)
+ g_ddraw->ticks_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL);
- float len = 1000.0f / maxTicks;
- ddraw->ticksLimiter.tickLengthNs = len * 10000;
- ddraw->ticksLimiter.ticklength = len + 0.5f;
+ float len = 1000.0f / max_ticks;
+ g_ddraw->ticks_limiter.tick_length_ns = len * 10000;
+ g_ddraw->ticks_limiter.tick_length = len + 0.5f;
}
- if (maxTicks >= 0)
+ if (max_ticks >= 0)
{
//always using 60 fps for flip...
- if (ddraw->accurateTimers)
- ddraw->flipLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
+ if (g_ddraw->accurate_timers)
+ g_ddraw->flip_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL);
- float flipLen = 1000.0f / 60;
- ddraw->flipLimiter.tickLengthNs = flipLen * 10000;
- ddraw->flipLimiter.ticklength = flipLen + 0.5f;
+ float flip_len = 1000.0f / 60;
+ g_ddraw->flip_limiter.tick_length_ns = flip_len * 10000;
+ g_ddraw->flip_limiter.tick_length = flip_len + 0.5f;
}
- if ((ddraw->fullscreen = GetBool("fullscreen", FALSE)))
- WindowRect.left = WindowRect.top = -32000;
+ if ((g_ddraw->fullscreen = cfg_get_bool("fullscreen", FALSE)))
+ g_config.window_rect.left = g_config.window_rect.top = -32000;
- if (!(ddraw->handlemouse = GetBool("handlemouse", TRUE)))
- ddraw->adjmouse = TRUE;
+ if (!(g_ddraw->handlemouse = cfg_get_bool("handlemouse", TRUE)))
+ g_ddraw->adjmouse = TRUE;
- if (GetBool("singlecpu", TRUE))
+ if (cfg_get_bool("singlecpu", TRUE))
{
SetProcessAffinityMask(GetCurrentProcess(), 1);
}
else
{
- DWORD systemAffinity;
- DWORD procAffinity;
+ DWORD system_affinity;
+ DWORD proc_affinity;
HANDLE proc = GetCurrentProcess();
- if (GetProcessAffinityMask(proc, &procAffinity, &systemAffinity))
- SetProcessAffinityMask(proc, systemAffinity);
+ if (GetProcessAffinityMask(proc, &proc_affinity, &system_affinity))
+ SetProcessAffinityMask(proc, system_affinity);
}
- ddraw->render.bpp = GetInt("bpp", 0);
- if (ddraw->render.bpp != 16 && ddraw->render.bpp != 24 && ddraw->render.bpp != 32)
- ddraw->render.bpp = 0;
+ g_ddraw->render.bpp = cfg_get_int("bpp", 0);
+
+ if (g_ddraw->render.bpp != 16 && g_ddraw->render.bpp != 24 && g_ddraw->render.bpp != 32)
+ g_ddraw->render.bpp = 0;
// to do: read .glslp config file instead of the shader and apply the correct settings
- GetString("shader", "", ddraw->shader, sizeof(ddraw->shader));
+ cfg_get_string("shader", "", g_ddraw->shader, sizeof(g_ddraw->shader));
- GetString("renderer", "auto", tmp, sizeof(tmp));
- printf("Using %s renderer\n", tmp);
+ cfg_get_string("renderer", "auto", tmp, sizeof(tmp));
+ dprintf(" Using %s renderer\n", tmp);
if (tolower(tmp[0]) == 's' || tolower(tmp[0]) == 'g') //gdi
{
- ddraw->renderer = render_soft_main;
+ g_ddraw->renderer = gdi_render_main;
}
else if (tolower(tmp[0]) == 'd') //direct3d9
{
- ddraw->renderer = render_d3d9_main;
+ g_ddraw->renderer = d3d9_render_main;
}
else if (tolower(tmp[0]) == 'o') //opengl
{
- if (OpenGL_LoadDll())
+ if (oglu_load_dll())
{
- ddraw->renderer = render_main;
+ g_ddraw->renderer = ogl_render_main;
}
else
{
- ShowDriverWarning = TRUE;
- ddraw->renderer = render_soft_main;
+ g_ddraw->show_driver_warning = TRUE;
+ g_ddraw->renderer = gdi_render_main;
}
}
else //auto
{
- LPDIRECT3D9 d3d = NULL;
-
- // Windows = Direct3D 9, Wine = OpenGL
- if (!ddraw->wine && (Direct3D9_hModule = LoadLibrary("d3d9.dll")))
+ if (!g_ddraw->wine && d3d9_is_available())
{
- IDirect3D9 *(WINAPI *D3DCreate9)(UINT) =
- (IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(Direct3D9_hModule, "Direct3DCreate9");
-
- if (D3DCreate9 && (d3d = D3DCreate9(D3D_SDK_VERSION)))
- IDirect3D9_Release(d3d);
+ g_ddraw->renderer = d3d9_render_main;
}
-
- if (d3d)
+ else if (oglu_load_dll())
{
- ddraw->renderer = render_d3d9_main;
- }
- else if (OpenGL_LoadDll())
- {
- ddraw->renderer = render_main;
+ g_ddraw->renderer = ogl_render_main;
}
else
{
- ShowDriverWarning = TRUE;
- ddraw->renderer = render_soft_main;
+ g_ddraw->show_driver_warning = TRUE;
+ g_ddraw->renderer = gdi_render_main;
}
}
}
-void Settings_Save(RECT *lpRect, int windowState)
+void cfg_save()
{
- if (!SaveSettings)
+ if (!g_config.save_settings)
return;
char buf[16];
- char *section = SaveSettings == 1 ? "ddraw" : ProcessFileName;
+ char *section = g_config.save_settings == 1 ? "ddraw" : g_config.process_file_name;
- if (lpRect->right)
+ if (g_config.window_rect.right)
{
- sprintf(buf, "%ld", lpRect->right);
- WritePrivateProfileString(section, "width", buf, SettingsIniPath);
+ sprintf(buf, "%ld", g_config.window_rect.right);
+ WritePrivateProfileString(section, "width", buf, g_config.ini_path);
}
- if (lpRect->bottom)
+ if (g_config.window_rect.bottom)
{
- sprintf(buf, "%ld", lpRect->bottom);
- WritePrivateProfileString(section, "height", buf, SettingsIniPath);
+ sprintf(buf, "%ld", g_config.window_rect.bottom);
+ WritePrivateProfileString(section, "height", buf, g_config.ini_path);
}
- if (lpRect->left != -32000)
+ if (g_config.window_rect.left != -32000)
{
- sprintf(buf, "%ld", lpRect->left);
- WritePrivateProfileString(section, "posX", buf, SettingsIniPath);
+ sprintf(buf, "%ld", g_config.window_rect.left);
+ WritePrivateProfileString(section, "posX", buf, g_config.ini_path);
}
- if (lpRect->top != -32000)
+ if (g_config.window_rect.top != -32000)
{
- sprintf(buf, "%ld", lpRect->top);
- WritePrivateProfileString(section, "posY", buf, SettingsIniPath);
+ sprintf(buf, "%ld", g_config.window_rect.top);
+ WritePrivateProfileString(section, "posY", buf, g_config.ini_path);
}
- if (windowState != -1)
+ if (g_config.window_state != -1)
{
- WritePrivateProfileString(section, "windowed", windowState ? "true" : "false", SettingsIniPath);
+ WritePrivateProfileString(section, "windowed", g_config.window_state ? "true" : "false", g_config.ini_path);
}
}
-static void CreateSettingsIni()
+static void cfg_create_ini()
{
- FILE *fh = fopen(SettingsIniPath, "w");
+ FILE *fh = fopen(g_config.ini_path, "w");
if (fh)
{
fputs(
@@ -483,7 +474,6 @@ static void CreateSettingsIni()
"nonexclusive=true\n"
"maxgameticks=60\n"
"handlemouse=false\n"
- "tm2hack=true\n"
"\n"
"; Caesar III\n"
"[c3]\n"
@@ -508,14 +498,17 @@ static void CreateSettingsIni()
}
}
-static DWORD GetString(LPCSTR key, LPCSTR defaultValue, LPSTR outString, DWORD outSize)
+static DWORD cfg_get_string(LPCSTR key, LPCSTR defaultValue, LPSTR outString, DWORD outSize)
{
- DWORD s = GetPrivateProfileStringA(ProcessFileName, key, "", outString, outSize, SettingsIniPath);
+ DWORD s = GetPrivateProfileStringA(
+ g_config.process_file_name, key, "", outString, outSize, g_config.ini_path);
+
if (s > 0)
{
char buf[MAX_PATH] = { 0 };
- if (GetPrivateProfileStringA(ProcessFileName, "checkfile", "", buf, sizeof(buf), SettingsIniPath) > 0)
+ if (GetPrivateProfileStringA(
+ g_config.process_file_name, "checkfile", "", buf, sizeof(buf), g_config.ini_path) > 0)
{
if (GetFileAttributes(buf) != INVALID_FILE_ATTRIBUTES)
return s;
@@ -524,24 +517,24 @@ static DWORD GetString(LPCSTR key, LPCSTR defaultValue, LPSTR outString, DWORD o
return s;
}
- return GetPrivateProfileStringA("ddraw", key, defaultValue, outString, outSize, SettingsIniPath);
+ return GetPrivateProfileStringA("ddraw", key, defaultValue, outString, outSize, g_config.ini_path);
}
-static BOOL GetBool(LPCSTR key, BOOL defaultValue)
+static BOOL cfg_get_bool(LPCSTR key, BOOL defaultValue)
{
char value[8];
- GetString(key, defaultValue ? "Yes" : "No", value, sizeof(value));
+ cfg_get_string(key, defaultValue ? "Yes" : "No", value, sizeof(value));
return (_stricmp(value, "yes") == 0 || _stricmp(value, "true") == 0 || _stricmp(value, "1") == 0);
}
-static int GetInt(LPCSTR key, int defaultValue)
+static int cfg_get_int(LPCSTR key, int defaultValue)
{
- char defvalue[16];
- _snprintf(defvalue, sizeof(defvalue), "%d", defaultValue);
+ char def_value[16];
+ _snprintf(def_value, sizeof(def_value), "%d", defaultValue);
char value[16];
- GetString(key, defvalue, value, sizeof(value));
+ cfg_get_string(key, def_value, value, sizeof(value));
return atoi(value);
}
diff --git a/src/dd.c b/src/dd.c
new file mode 100644
index 0000000..ed67f60
--- /dev/null
+++ b/src/dd.c
@@ -0,0 +1,776 @@
+#include
+#include "ddraw.h"
+#include "dd.h"
+#include "hook.h"
+#include "config.h"
+#include "mouse.h"
+#include "wndproc.h"
+#include "render_d3d9.h"
+#include "render_gdi.h"
+#include "render_ogl.h"
+#include "debug.h"
+#include "utils.h"
+
+
+cnc_ddraw *g_ddraw = NULL;
+
+HRESULT dd_EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback)
+{
+ DWORD i = 0;
+ DDSURFACEDESC s;
+
+ // Some games crash when you feed them with too many resolutions...
+
+ if (g_ddraw->bpp)
+ {
+ dprintf(" g_ddraw->bpp=%u\n", g_ddraw->bpp);
+
+ //set up some filters to keep the list short
+ DWORD refresh_rate = 0;
+ DWORD bpp = 0;
+ DWORD flags = 99998;
+ DWORD fixed_output = 99998;
+ DEVMODE m;
+ memset(&m, 0, sizeof(DEVMODE));
+ m.dmSize = sizeof(DEVMODE);
+
+ while (EnumDisplaySettings(NULL, i, &m))
+ {
+ if (refresh_rate != 60 && m.dmDisplayFrequency >= 50)
+ refresh_rate = m.dmDisplayFrequency;
+
+ if (bpp != 32 && m.dmBitsPerPel >= 16)
+ bpp = m.dmBitsPerPel;
+
+ if (flags != 0)
+ flags = m.dmDisplayFlags;
+
+ if (fixed_output != DMDFO_DEFAULT)
+ fixed_output = m.dmDisplayFixedOutput;
+
+ memset(&m, 0, sizeof(DEVMODE));
+ m.dmSize = sizeof(DEVMODE);
+ i++;
+ }
+
+ memset(&m, 0, sizeof(DEVMODE));
+ m.dmSize = sizeof(DEVMODE);
+ i = 0;
+ while (EnumDisplaySettings(NULL, i, &m))
+ {
+ if (refresh_rate == m.dmDisplayFrequency &&
+ bpp == m.dmBitsPerPel &&
+ flags == m.dmDisplayFlags &&
+ fixed_output == m.dmDisplayFixedOutput)
+ {
+ dprintfex(" %d: %dx%d@%d %d bpp\n", (int)i, (int)m.dmPelsWidth, (int)m.dmPelsHeight, (int)m.dmDisplayFrequency, (int)m.dmBitsPerPel);
+
+ memset(&s, 0, sizeof(DDSURFACEDESC));
+ s.dwSize = sizeof(DDSURFACEDESC);
+ s.dwFlags = DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_PIXELFORMAT;
+ s.dwHeight = m.dmPelsHeight;
+ s.dwWidth = m.dmPelsWidth;
+ s.dwRefreshRate = 60;
+ s.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+
+ s.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
+ s.ddpfPixelFormat.dwRGBBitCount = 8;
+
+ if (g_ddraw->bpp == 16)
+ {
+ s.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ s.ddpfPixelFormat.dwRGBBitCount = 16;
+ s.ddpfPixelFormat.dwRBitMask = 0xF800;
+ s.ddpfPixelFormat.dwGBitMask = 0x07E0;
+ s.ddpfPixelFormat.dwBBitMask = 0x001F;
+ }
+
+ if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
+ {
+ dprintf(" DDENUMRET_CANCEL returned, stopping\n");
+ break;
+ }
+ }
+ memset(&m, 0, sizeof(DEVMODE));
+ m.dmSize = sizeof(DEVMODE);
+ i++;
+ }
+ }
+ else
+ {
+ SIZE resolutions[] =
+ {
+ { 320, 200 },
+ { 320, 240 },
+ { 640, 400 },
+ { 640, 480 },
+ { 800, 600 },
+ { 1024, 768 },
+ { 1280, 1024 },
+ { 1280, 720 },
+ { 1920, 1080 },
+ };
+
+ for (i = 0; i < sizeof(resolutions) / sizeof(resolutions[0]); i++)
+ {
+ memset(&s, 0, sizeof(DDSURFACEDESC));
+ s.dwSize = sizeof(DDSURFACEDESC);
+ s.dwFlags = DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_PIXELFORMAT;
+ s.dwHeight = resolutions[i].cy;
+ s.dwWidth = resolutions[i].cx;
+ s.dwRefreshRate = 60;
+ s.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+ s.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
+ s.ddpfPixelFormat.dwRGBBitCount = 8;
+
+ if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
+ {
+ dprintf(" DDENUMRET_CANCEL returned, stopping\n");
+ break;
+ }
+
+ s.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ s.ddpfPixelFormat.dwRGBBitCount = 16;
+ s.ddpfPixelFormat.dwRBitMask = 0xF800;
+ s.ddpfPixelFormat.dwGBitMask = 0x07E0;
+ s.ddpfPixelFormat.dwBBitMask = 0x001F;
+
+ if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
+ {
+ dprintf(" DDENUMRET_CANCEL returned, stopping\n");
+ break;
+ }
+ }
+ }
+
+ return DD_OK;
+}
+
+HRESULT dd_GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDEmulCaps)
+{
+ if(lpDDDriverCaps)
+ {
+ lpDDDriverCaps->dwSize = sizeof(DDCAPS);
+ lpDDDriverCaps->dwCaps = DDCAPS_BLT | DDCAPS_PALETTE | DDCAPS_BLTCOLORFILL | DDCAPS_BLTSTRETCH | DDCAPS_CANCLIP;
+ lpDDDriverCaps->dwCKeyCaps = 0;
+ lpDDDriverCaps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE;
+ lpDDDriverCaps->dwVidMemTotal = 16777216;
+ lpDDDriverCaps->dwVidMemFree = 16777216;
+ lpDDDriverCaps->dwMaxVisibleOverlays = 0;
+ lpDDDriverCaps->dwCurrVisibleOverlays = 0;
+ lpDDDriverCaps->dwNumFourCCCodes = 0;
+ lpDDDriverCaps->dwAlignBoundarySrc = 0;
+ lpDDDriverCaps->dwAlignSizeSrc = 0;
+ lpDDDriverCaps->dwAlignBoundaryDest = 0;
+ lpDDDriverCaps->dwAlignSizeDest = 0;
+ lpDDDriverCaps->ddsCaps.dwCaps = DDSCAPS_FLIP;
+ }
+
+ if(lpDDEmulCaps)
+ {
+ lpDDEmulCaps->dwSize = 0;
+ }
+
+ return DD_OK;
+}
+
+HRESULT dd_RestoreDisplayMode()
+{
+ if(!g_ddraw->render.run)
+ {
+ return DD_OK;
+ }
+
+ /* only stop drawing in GL mode when minimized */
+ if (g_ddraw->renderer != gdi_render_main)
+ {
+ EnterCriticalSection(&g_ddraw->cs);
+ g_ddraw->render.run = FALSE;
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ LeaveCriticalSection(&g_ddraw->cs);
+
+ if (g_ddraw->render.thread)
+ {
+ WaitForSingleObject(g_ddraw->render.thread, INFINITE);
+ g_ddraw->render.thread = NULL;
+ }
+
+ if (g_ddraw->renderer == d3d9_render_main)
+ d3d9_release();
+ }
+
+ if(!g_ddraw->windowed)
+ {
+ if (g_ddraw->renderer != d3d9_render_main)
+ ChangeDisplaySettings(NULL, 0);
+ }
+
+ return DD_OK;
+}
+
+HRESULT dd_SetDisplayMode(DWORD width, DWORD height, DWORD bpp)
+{
+ if (bpp != 8 && bpp != 16)
+ return DDERR_INVALIDMODE;
+
+ if (g_ddraw->render.thread)
+ {
+ EnterCriticalSection(&g_ddraw->cs);
+ g_ddraw->render.run = FALSE;
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ LeaveCriticalSection(&g_ddraw->cs);
+
+ WaitForSingleObject(g_ddraw->render.thread, INFINITE);
+ g_ddraw->render.thread = NULL;
+ }
+
+ if (!g_ddraw->mode.dmPelsWidth)
+ {
+ g_ddraw->mode.dmSize = sizeof(DEVMODE);
+ g_ddraw->mode.dmDriverExtra = 0;
+
+ if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &g_ddraw->mode) == FALSE)
+ {
+ g_ddraw->mode.dmSize = sizeof(DEVMODE);
+ g_ddraw->mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
+ g_ddraw->mode.dmPelsWidth = real_GetSystemMetrics(SM_CXSCREEN);
+ g_ddraw->mode.dmPelsHeight = real_GetSystemMetrics(SM_CYSCREEN);
+ g_ddraw->mode.dmDisplayFrequency = 60;
+ g_ddraw->mode.dmBitsPerPel = 32;
+
+ if (!g_ddraw->mode.dmPelsWidth || !g_ddraw->mode.dmPelsHeight)
+ {
+ g_ddraw->fullscreen = FALSE;
+ }
+ }
+
+ const int IDR_MYMENU = 93;
+
+ const HANDLE hbicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, real_GetSystemMetrics(SM_CXICON), real_GetSystemMetrics(SM_CYICON), 0);
+ if (hbicon)
+ real_SendMessageA(g_ddraw->hwnd, WM_SETICON, ICON_BIG, (LPARAM)hbicon);
+
+ const HANDLE hsicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, real_GetSystemMetrics(SM_CXSMICON), real_GetSystemMetrics(SM_CYSMICON), 0);
+ if (hsicon)
+ real_SendMessageA(g_ddraw->hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hsicon);
+ }
+
+ if (g_ddraw->altenter)
+ {
+ g_ddraw->altenter = FALSE;
+
+ memset(&g_ddraw->render.mode, 0, sizeof(DEVMODE));
+ g_ddraw->render.mode.dmSize = sizeof(DEVMODE);
+ g_ddraw->render.mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
+ g_ddraw->render.mode.dmPelsWidth = g_ddraw->render.width;
+ g_ddraw->render.mode.dmPelsHeight = g_ddraw->render.height;
+ if (g_ddraw->render.bpp)
+ {
+ g_ddraw->render.mode.dmFields |= DM_BITSPERPEL;
+ g_ddraw->render.mode.dmBitsPerPel = g_ddraw->render.bpp;
+ }
+
+ if (ChangeDisplaySettings(&g_ddraw->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
+ {
+ g_ddraw->render.width = g_ddraw->width;
+ g_ddraw->render.height = g_ddraw->height;
+ }
+ }
+ else
+ {
+ g_ddraw->render.width = g_config.window_rect.right;
+ g_ddraw->render.height = g_config.window_rect.bottom;
+ }
+
+ //temporary fix: center window for games that keep changing their resolution
+ if (g_ddraw->width &&
+ (g_ddraw->width != width || g_ddraw->height != height) &&
+ (width > g_config.window_rect.right || height > g_config.window_rect.bottom))
+ {
+ g_config.window_rect.left = -32000;
+ g_config.window_rect.top = -32000;
+ }
+
+ g_ddraw->width = width;
+ g_ddraw->height = height;
+ g_ddraw->bpp = bpp;
+
+ g_ddraw->cursor.x = width / 2;
+ g_ddraw->cursor.y = height / 2;
+
+ BOOL border = g_ddraw->border;
+
+ if(g_ddraw->fullscreen)
+ {
+ g_ddraw->render.width = g_ddraw->mode.dmPelsWidth;
+ g_ddraw->render.height = g_ddraw->mode.dmPelsHeight;
+
+ if (g_ddraw->windowed) //windowed-fullscreen aka borderless
+ {
+ border = FALSE;
+ g_config.window_rect.left = -32000;
+ g_config.window_rect.top = -32000;
+
+ // prevent OpenGL from going automatically into fullscreen exclusive mode
+ if (g_ddraw->renderer == ogl_render_main)
+ g_ddraw->render.height++;
+
+ }
+ }
+
+ if(g_ddraw->render.width < g_ddraw->width)
+ {
+ g_ddraw->render.width = g_ddraw->width;
+ }
+ if(g_ddraw->render.height < g_ddraw->height)
+ {
+ g_ddraw->render.height = g_ddraw->height;
+ }
+
+ g_ddraw->render.run = TRUE;
+
+ BOOL lock_mouse = g_ddraw->locked || g_ddraw->fullscreen;
+ mouse_unlock();
+
+ memset(&g_ddraw->render.mode, 0, sizeof(DEVMODE));
+ g_ddraw->render.mode.dmSize = sizeof(DEVMODE);
+ g_ddraw->render.mode.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT;
+ g_ddraw->render.mode.dmPelsWidth = g_ddraw->render.width;
+ g_ddraw->render.mode.dmPelsHeight = g_ddraw->render.height;
+ if(g_ddraw->render.bpp)
+ {
+ g_ddraw->render.mode.dmFields |= DM_BITSPERPEL;
+ g_ddraw->render.mode.dmBitsPerPel = g_ddraw->render.bpp;
+ }
+
+ BOOL maintas = g_ddraw->maintas;
+
+ if (!g_ddraw->windowed)
+ {
+ // Making sure the chosen resolution is valid
+ int old_width = g_ddraw->render.width;
+ int old_height = g_ddraw->render.height;
+
+ if (ChangeDisplaySettings(&g_ddraw->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
+ {
+ // fail... compare resolutions
+ if (g_ddraw->render.width > g_ddraw->mode.dmPelsWidth || g_ddraw->render.height > g_ddraw->mode.dmPelsHeight)
+ {
+ // chosen game resolution higher than current resolution, use windowed mode for this case
+ g_ddraw->windowed = TRUE;
+ }
+ else
+ {
+ // Try 2x scaling
+ g_ddraw->render.width *= 2;
+ g_ddraw->render.height *= 2;
+
+ g_ddraw->render.mode.dmPelsWidth = g_ddraw->render.width;
+ g_ddraw->render.mode.dmPelsHeight = g_ddraw->render.height;
+
+ if ((g_ddraw->render.width > g_ddraw->mode.dmPelsWidth || g_ddraw->render.height > g_ddraw->mode.dmPelsHeight) ||
+ ChangeDisplaySettings(&g_ddraw->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
+ {
+ SIZE res = {0};
+
+ //try to get a resolution with the same aspect ratio as the requested resolution
+ BOOL found_res = util_get_lowest_resolution(
+ (float)old_width / old_height,
+ &res,
+ old_width + 1, //don't return the original resolution since we tested that one already
+ old_height + 1,
+ g_ddraw->mode.dmPelsWidth,
+ g_ddraw->mode.dmPelsHeight);
+
+ if (!found_res)
+ {
+ //try to get a resolution with the same aspect ratio as the current display mode
+ found_res = util_get_lowest_resolution(
+ (float)g_ddraw->mode.dmPelsWidth / g_ddraw->mode.dmPelsHeight,
+ &res,
+ old_width,
+ old_height,
+ g_ddraw->mode.dmPelsWidth,
+ g_ddraw->mode.dmPelsHeight);
+
+ if (found_res)
+ maintas = TRUE;
+ }
+
+ g_ddraw->render.width = res.cx;
+ g_ddraw->render.height = res.cy;
+
+ g_ddraw->render.mode.dmPelsWidth = g_ddraw->render.width;
+ g_ddraw->render.mode.dmPelsHeight = g_ddraw->render.height;
+
+ if (!found_res || ChangeDisplaySettings(&g_ddraw->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
+ {
+ // try current display settings
+ g_ddraw->render.width = g_ddraw->mode.dmPelsWidth;
+ g_ddraw->render.height = g_ddraw->mode.dmPelsHeight;
+
+ g_ddraw->render.mode.dmPelsWidth = g_ddraw->render.width;
+ g_ddraw->render.mode.dmPelsHeight = g_ddraw->render.height;
+
+ if (ChangeDisplaySettings(&g_ddraw->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
+ {
+ // everything failed, use windowed mode instead
+ g_ddraw->render.width = old_width;
+ g_ddraw->render.height = old_height;
+
+ g_ddraw->render.mode.dmPelsWidth = g_ddraw->render.width;
+ g_ddraw->render.mode.dmPelsHeight = g_ddraw->render.height;
+
+ g_ddraw->windowed = TRUE;
+ }
+ else
+ maintas = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ if (g_ddraw->nonexclusive && !g_ddraw->windowed && g_ddraw->renderer == ogl_render_main)
+ g_ddraw->render.height++;
+
+ if (!g_ddraw->handlemouse)
+ g_ddraw->boxing = maintas = FALSE;
+
+ g_ddraw->render.viewport.width = g_ddraw->render.width;
+ g_ddraw->render.viewport.height = g_ddraw->render.height;
+ g_ddraw->render.viewport.x = 0;
+ g_ddraw->render.viewport.y = 0;
+
+ if (g_ddraw->boxing)
+ {
+ g_ddraw->render.viewport.width = g_ddraw->width;
+ g_ddraw->render.viewport.height = g_ddraw->height;
+
+ int i;
+ for (i = 20; i-- > 1;)
+ {
+ if (g_ddraw->width * i <= g_ddraw->render.width && g_ddraw->height * i <= g_ddraw->render.height)
+ {
+ g_ddraw->render.viewport.width *= i;
+ g_ddraw->render.viewport.height *= i;
+ break;
+ }
+ }
+
+ g_ddraw->render.viewport.y = g_ddraw->render.height / 2 - g_ddraw->render.viewport.height / 2;
+ g_ddraw->render.viewport.x = g_ddraw->render.width / 2 - g_ddraw->render.viewport.width / 2;
+ }
+ else if (maintas)
+ {
+ g_ddraw->render.viewport.width = g_ddraw->render.width;
+ g_ddraw->render.viewport.height = ((float)g_ddraw->height / g_ddraw->width) * g_ddraw->render.viewport.width;
+
+ if (g_ddraw->render.viewport.height > g_ddraw->render.height)
+ {
+ g_ddraw->render.viewport.width =
+ ((float)g_ddraw->render.viewport.width / g_ddraw->render.viewport.height) * g_ddraw->render.height;
+
+ g_ddraw->render.viewport.height = g_ddraw->render.height;
+ }
+
+ g_ddraw->render.viewport.y = g_ddraw->render.height / 2 - g_ddraw->render.viewport.height / 2;
+ g_ddraw->render.viewport.x = g_ddraw->render.width / 2 - g_ddraw->render.viewport.width / 2;
+ }
+
+ g_ddraw->render.scale_w = ((float)g_ddraw->render.viewport.width / g_ddraw->width);
+ g_ddraw->render.scale_h = ((float)g_ddraw->render.viewport.height / g_ddraw->height);
+ g_ddraw->render.unscale_w = ((float)g_ddraw->width / g_ddraw->render.viewport.width);
+ g_ddraw->render.unscale_h = ((float)g_ddraw->height / g_ddraw->render.viewport.height);
+
+ if (g_ddraw->windowed)
+ {
+ MSG msg; // workaround for "Not Responding" window problem in cnc games
+ PeekMessage(&msg, g_ddraw->hwnd, 0, 0, PM_NOREMOVE);
+
+ if (!border)
+ {
+ real_SetWindowLongA(g_ddraw->hwnd, GWL_STYLE, GetWindowLong(g_ddraw->hwnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
+ }
+ else
+ {
+ real_SetWindowLongA(g_ddraw->hwnd, GWL_STYLE, (GetWindowLong(g_ddraw->hwnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW) & ~WS_MAXIMIZEBOX);
+ }
+
+ if (g_ddraw->wine)
+ real_SetWindowLongA(g_ddraw->hwnd, GWL_STYLE, (GetWindowLong(g_ddraw->hwnd, GWL_STYLE) | WS_MINIMIZEBOX) & ~(WS_MAXIMIZEBOX | WS_THICKFRAME));
+
+ /* center the window with correct dimensions */
+ int cy = g_ddraw->mode.dmPelsWidth ? g_ddraw->mode.dmPelsWidth : g_ddraw->render.width;
+ int cx = g_ddraw->mode.dmPelsHeight ? g_ddraw->mode.dmPelsHeight : g_ddraw->render.height;
+ int x = (g_config.window_rect.left != -32000) ? g_config.window_rect.left : (cy / 2) - (g_ddraw->render.width / 2);
+ int y = (g_config.window_rect.top != -32000) ? g_config.window_rect.top : (cx / 2) - (g_ddraw->render.height / 2);
+ RECT dst = { x, y, g_ddraw->render.width + x, g_ddraw->render.height + y };
+ AdjustWindowRect(&dst, GetWindowLong(g_ddraw->hwnd, GWL_STYLE), FALSE);
+ real_SetWindowPos(g_ddraw->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ real_MoveWindow(g_ddraw->hwnd, dst.left, dst.top, (dst.right - dst.left), (dst.bottom - dst.top), TRUE);
+
+ BOOL d3d9_active = FALSE;
+ if (g_ddraw->renderer == d3d9_render_main)
+ {
+ d3d9_active = d3d9_create();
+ if (!d3d9_active)
+ {
+ d3d9_release();
+ g_ddraw->show_driver_warning = TRUE;
+ g_ddraw->renderer = gdi_render_main;
+ }
+ }
+
+ if (lock_mouse)
+ mouse_lock();
+ }
+ else
+ {
+ LONG style = GetWindowLong(g_ddraw->hwnd, GWL_STYLE);
+
+ if ((style & WS_CAPTION))
+ {
+ real_SetWindowLongA(g_ddraw->hwnd, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
+ }
+
+ BOOL d3d9_active = FALSE;
+ if (g_ddraw->renderer == d3d9_render_main)
+ {
+ d3d9_active = d3d9_create();
+ if (!d3d9_active)
+ {
+ d3d9_release();
+ g_ddraw->show_driver_warning = TRUE;
+ g_ddraw->renderer = gdi_render_main;
+ }
+ }
+
+ if (!d3d9_active && ChangeDisplaySettings(&g_ddraw->render.mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
+ {
+ g_ddraw->render.run = FALSE;
+ g_ddraw->windowed = TRUE;
+ return dd_SetDisplayMode(width, height, bpp);
+ }
+
+ if (g_ddraw->wine)
+ real_SetWindowLongA(g_ddraw->hwnd, GWL_STYLE, GetWindowLong(g_ddraw->hwnd, GWL_STYLE) | WS_MINIMIZEBOX);
+
+ real_SetWindowPos(g_ddraw->hwnd, HWND_TOPMOST, 0, 0, g_ddraw->render.width, g_ddraw->render.height, SWP_SHOWWINDOW);
+ g_ddraw->last_set_window_pos_tick = timeGetTime();
+
+ mouse_lock();
+ }
+
+ if(g_ddraw->render.viewport.x != 0 || g_ddraw->render.viewport.y != 0)
+ {
+ RedrawWindow(g_ddraw->hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
+ }
+
+ if(g_ddraw->render.thread == NULL)
+ {
+ InterlockedExchange(&g_ddraw->render.palette_updated, TRUE);
+ InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+
+ g_ddraw->render.thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)g_ddraw->renderer, NULL, 0, NULL);
+ }
+
+ if (g_ddraw->sierrahack)
+ {
+ PostMessageA(g_ddraw->hwnd, WM_MOVE, 0, MAKELPARAM(-32000, -32000));
+ PostMessageA(g_ddraw->hwnd, WM_DISPLAYCHANGE, g_ddraw->bpp, MAKELPARAM(g_ddraw->width, g_ddraw->height));
+ }
+
+ return DD_OK;
+}
+
+HRESULT dd_SetCooperativeLevel(HWND hwnd, DWORD dwFlags)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+
+ /* Red Alert for some weird reason does this on Windows XP */
+ if(hwnd == NULL)
+ {
+ return DD_OK;
+ }
+
+ if (g_ddraw->hwnd == NULL)
+ {
+ g_ddraw->hwnd = hwnd;
+ }
+
+ if (!g_ddraw->wndproc)
+ {
+ hook_init();
+
+ g_ddraw->wndproc = (LRESULT(CALLBACK *)(HWND, UINT, WPARAM, LPARAM))GetWindowLong(hwnd, GWL_WNDPROC);
+
+ real_SetWindowLongA(g_ddraw->hwnd, GWL_WNDPROC, (LONG)fake_WndProc);
+
+ if (!g_ddraw->render.hdc)
+ {
+ g_ddraw->render.hdc = GetDC(g_ddraw->hwnd);
+
+ memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | (g_ddraw->renderer == ogl_render_main ? PFD_SUPPORT_OPENGL : 0);
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = g_ddraw->render.bpp ? g_ddraw->render.bpp : g_ddraw->mode.dmBitsPerPel;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+ SetPixelFormat(g_ddraw->render.hdc, ChoosePixelFormat(g_ddraw->render.hdc, &pfd), &pfd);
+ }
+
+ if (g_ddraw->handlemouse && g_ddraw->windowed)
+ {
+ while (real_ShowCursor(FALSE) > 0); //workaround for direct input games
+ while (real_ShowCursor(TRUE) < 0);
+ }
+
+ real_SetCursor(LoadCursor(NULL, IDC_ARROW));
+
+ GetWindowText(g_ddraw->hwnd, (LPTSTR)&g_ddraw->title, sizeof(g_ddraw->title));
+
+ g_ddraw->isredalert = strcmp(g_ddraw->title, "Red Alert") == 0;
+ g_ddraw->iscnc1 = strcmp(g_ddraw->title, "Command & Conquer") == 0;
+
+ if (g_ddraw->vhack && !g_ddraw->isredalert && !g_ddraw->iscnc1)
+ g_ddraw->vhack = 0;
+ }
+
+ return DD_OK;
+}
+
+HRESULT dd_WaitForVerticalBlank(DWORD dwFlags, HANDLE h)
+{
+ if (!g_ddraw->flip_limiter.tick_length)
+ return DD_OK;
+
+ if (g_ddraw->flip_limiter.htimer)
+ {
+ FILETIME last_flip_ft = { 0 };
+ GetSystemTimeAsFileTime(&last_flip_ft);
+
+ if (!g_ddraw->flip_limiter.due_time.QuadPart)
+ {
+ memcpy(&g_ddraw->flip_limiter.due_time, &last_flip_ft, sizeof(LARGE_INTEGER));
+ }
+ else
+ {
+ while (CompareFileTime((FILETIME*)&g_ddraw->flip_limiter.due_time, &last_flip_ft) == -1)
+ g_ddraw->flip_limiter.due_time.QuadPart += g_ddraw->flip_limiter.tick_length_ns;
+
+ SetWaitableTimer(g_ddraw->flip_limiter.htimer, &g_ddraw->flip_limiter.due_time, 0, NULL, NULL, FALSE);
+ WaitForSingleObject(g_ddraw->flip_limiter.htimer, g_ddraw->flip_limiter.tick_length * 2);
+ }
+ }
+ else
+ {
+ static DWORD next_game_tick;
+ if (!next_game_tick)
+ {
+ next_game_tick = timeGetTime();
+ return DD_OK;
+ }
+ next_game_tick += g_ddraw->flip_limiter.tick_length;
+ DWORD tick_count = timeGetTime();
+
+ int sleep_time = next_game_tick - tick_count;
+ if (sleep_time <= 0 || sleep_time > g_ddraw->flip_limiter.tick_length)
+ next_game_tick = tick_count;
+ else
+ Sleep(sleep_time);
+ }
+
+ return DD_OK;
+}
+
+ULONG dd_AddRef()
+{
+ return ++g_ddraw->ref;
+}
+
+ULONG dd_Release()
+{
+ g_ddraw->ref--;
+
+ if (g_ddraw->ref == 0)
+ {
+ if (g_ddraw->bpp)
+ cfg_save();
+
+ if(g_ddraw->render.run)
+ {
+ EnterCriticalSection(&g_ddraw->cs);
+ g_ddraw->render.run = FALSE;
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ LeaveCriticalSection(&g_ddraw->cs);
+
+ if (g_ddraw->render.thread)
+ {
+ WaitForSingleObject(g_ddraw->render.thread, INFINITE);
+ g_ddraw->render.thread = NULL;
+ }
+
+ if (g_ddraw->renderer == d3d9_render_main)
+ {
+ d3d9_release();
+ }
+ else if (!g_ddraw->windowed)
+ {
+ ChangeDisplaySettings(NULL, 0);
+ }
+ }
+
+ if(g_ddraw->render.hdc)
+ {
+ ReleaseDC(g_ddraw->hwnd, g_ddraw->render.hdc);
+ g_ddraw->render.hdc = NULL;
+ }
+
+ if (g_ddraw->ticks_limiter.htimer)
+ {
+ CancelWaitableTimer(g_ddraw->ticks_limiter.htimer);
+ CloseHandle(g_ddraw->ticks_limiter.htimer);
+ g_ddraw->ticks_limiter.htimer = NULL;
+ }
+
+ if (g_ddraw->flip_limiter.htimer)
+ {
+ CancelWaitableTimer(g_ddraw->flip_limiter.htimer);
+ CloseHandle(g_ddraw->flip_limiter.htimer);
+ g_ddraw->flip_limiter.htimer = NULL;
+ }
+
+ if (g_ddraw->fps_limiter.htimer)
+ {
+ CancelWaitableTimer(g_ddraw->fps_limiter.htimer);
+ CloseHandle(g_ddraw->fps_limiter.htimer);
+ g_ddraw->fps_limiter.htimer = NULL;
+ }
+
+ DeleteCriticalSection(&g_ddraw->cs);
+
+ /* restore old wndproc, subsequent ddraw creation will otherwise fail */
+ real_SetWindowLongA(g_ddraw->hwnd, GWL_WNDPROC, (LONG)g_ddraw->wndproc);
+ HeapFree(GetProcessHeap(), 0, g_ddraw);
+ g_ddraw = NULL;
+ return 0;
+ }
+
+ return g_ddraw->ref;
+}
+
+HRESULT dd_GetAvailableVidMem(void* lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
+{
+ *lpdwTotal = 16777216;
+ *lpdwFree = 16777216;
+ return DD_OK;
+}
+
+HRESULT dd_GetVerticalBlankStatus(LPBOOL lpbIsInVB)
+{
+ *lpbIsInVB = TRUE;
+ return DD_OK;
+}
diff --git a/src/ddclipper.c b/src/ddclipper.c
new file mode 100644
index 0000000..81847f6
--- /dev/null
+++ b/src/ddclipper.c
@@ -0,0 +1,21 @@
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "IDirectDrawClipper.h"
+#include "ddclipper.h"
+#include "debug.h"
+
+
+HRESULT dd_CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, IUnknown FAR *pUnkOuter )
+{
+ if (!lplpDDClipper)
+ return DDERR_INVALIDPARAMS;
+
+ IDirectDrawClipperImpl *c = (IDirectDrawClipperImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawClipperImpl));
+ c->lpVtbl = &g_ddc_vtbl;
+ dprintf(" Clipper = %p\n", c);
+ *lplpDDClipper = (LPDIRECTDRAWCLIPPER)c;
+
+ IDirectDrawClipper_AddRef(c);
+
+ return DD_OK;
+}
diff --git a/src/ddpalette.c b/src/ddpalette.c
new file mode 100644
index 0000000..892ad91
--- /dev/null
+++ b/src/ddpalette.c
@@ -0,0 +1,65 @@
+#define WIN32_LEAN_AND_MEAN
+#include
+#include "dd.h"
+#include "ddpalette.h"
+#include "ddsurface.h"
+#include "IDirectDrawPalette.h"
+#include "debug.h"
+
+
+HRESULT ddp_GetEntries(IDirectDrawPaletteImpl *This, DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries)
+{
+ int i, x;
+
+ for (i = dwBase, x = 0; i < dwBase + dwNumEntries; i++, x++)
+ {
+ if (This->data_rgb)
+ {
+ lpEntries[x].peRed = This->data_rgb[i].rgbRed;
+ lpEntries[x].peGreen = This->data_rgb[i].rgbGreen;
+ lpEntries[x].peBlue = This->data_rgb[i].rgbBlue;
+ }
+ }
+
+ return DD_OK;
+}
+
+HRESULT ddp_SetEntries(IDirectDrawPaletteImpl *This, DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries)
+{
+ int i, x;
+
+ for (i = dwStartingEntry, x = 0; i < dwStartingEntry + dwCount; i++, x++)
+ {
+ This->data_bgr[i] = (lpEntries[x].peBlue << 16) | (lpEntries[x].peGreen << 8) | lpEntries[x].peRed;
+
+ if (This->data_rgb)
+ {
+ This->data_rgb[i].rgbRed = lpEntries[x].peRed;
+ This->data_rgb[i].rgbGreen = lpEntries[x].peGreen;
+ This->data_rgb[i].rgbBlue = lpEntries[x].peBlue;
+ This->data_rgb[i].rgbReserved = 0;
+ }
+ }
+
+ if (g_ddraw->primary && g_ddraw->primary->palette == This && g_ddraw->render.run)
+ {
+ InterlockedExchange(&g_ddraw->render.palette_updated, TRUE);
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ }
+
+ return DD_OK;
+}
+
+HRESULT dd_CreatePalette(DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR * lpDDPalette, IUnknown FAR * unkOuter)
+{
+ IDirectDrawPaletteImpl *p = (IDirectDrawPaletteImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawPaletteImpl));
+ p->lpVtbl = &g_ddp_vtbl;
+ dprintf(" Palette = %p\n", p);
+ *lpDDPalette = (LPDIRECTDRAWPALETTE)p;
+
+ ddp_SetEntries(p, dwFlags, 0, 256, lpDDColorArray);
+
+ IDirectDrawPalette_AddRef(p);
+
+ return DD_OK;
+}
diff --git a/src/ddsurface.c b/src/ddsurface.c
new file mode 100644
index 0000000..2e3311b
--- /dev/null
+++ b/src/ddsurface.c
@@ -0,0 +1,887 @@
+#include
+#include
+#include "dd.h"
+#include "hook.h"
+#include "ddsurface.h"
+#include "mouse.h"
+#include "scale_pattern.h"
+#include "IDirectDrawSurface.h"
+#include "winapi_hooks.h"
+#include "debug.h"
+#include "utils.h"
+
+
+void *g_fake_primary_surface_export; // hack for some warcraft II tools
+
+HRESULT dds_AddAttachedSurface(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE lpDDSurface)
+{
+ IDirectDrawSurface_AddRef(lpDDSurface);
+ return DD_OK;
+}
+
+HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
+{
+ IDirectDrawSurfaceImpl *src_surface = (IDirectDrawSurfaceImpl *)lpDDSrcSurface;
+
+ dbg_dump_dds_blt_flags(dwFlags);
+
+ RECT src_rect = { 0, 0, src_surface ? src_surface->width : 0, src_surface ? src_surface->height : 0 };
+ RECT dst_rect = { 0, 0, This->width, This->height };
+
+ if (lpSrcRect && src_surface)
+ memcpy(&src_rect, lpSrcRect, sizeof(src_rect));
+
+ if (lpDestRect)
+ memcpy(&dst_rect, lpDestRect, sizeof(dst_rect));
+
+ // stretch or clip?
+ BOOL is_stretch_blt =
+ ((src_rect.right - src_rect.left) != (dst_rect.right - dst_rect.left)) ||
+ ((src_rect.bottom - src_rect.top) != (dst_rect.bottom - dst_rect.top));
+
+ if (src_surface)
+ {
+ if (src_rect.right > src_surface->width)
+ src_rect.right = src_surface->width;
+
+ if (src_rect.bottom > src_surface->height)
+ src_rect.bottom = src_surface->height;
+ }
+
+ if (dst_rect.right > This->width)
+ dst_rect.right = This->width;
+
+ if (dst_rect.bottom > This->height)
+ dst_rect.bottom = This->height;
+
+ int src_w = src_rect.right - src_rect.left;
+ int src_h = src_rect.bottom - src_rect.top;
+ int src_x = src_rect.left;
+ int src_y = src_rect.top;
+
+ int dst_w = dst_rect.right - dst_rect.left;
+ int dst_h = dst_rect.bottom - dst_rect.top;
+ int dst_x = dst_rect.left;
+ int dst_y = dst_rect.top;
+
+
+ if (This->surface && (dwFlags & DDBLT_COLORFILL))
+ {
+ unsigned char *dst = (unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
+ unsigned char *first_row = dst;
+ unsigned int dst_pitch = dst_w * This->lx_pitch;
+ int x, i;
+
+ if (This->bpp == 8)
+ {
+ unsigned char color = (unsigned char)lpDDBltFx->dwFillColor;
+
+ for (i = 0; i < dst_h; i++)
+ {
+ memset(dst, color, dst_pitch);
+ dst += This->l_pitch;
+ }
+ }
+ else if (This->bpp == 16)
+ {
+ unsigned short *row1 = (unsigned short *)dst;
+ unsigned short color = (unsigned short)lpDDBltFx->dwFillColor;
+
+ if ((color & 0xFF) == (color >> 8))
+ {
+ unsigned char c8 = (unsigned char)(color & 0xFF);
+
+ for (i = 0; i < dst_h; i++)
+ {
+ memset(dst, c8, dst_pitch);
+ dst += This->l_pitch;
+ }
+ }
+ else
+ {
+ for (x = 0; x < dst_w; x++)
+ row1[x] = color;
+
+ for (i = 1; i < dst_h; i++)
+ {
+ dst += This->l_pitch;
+ memcpy(dst, first_row, dst_pitch);
+ }
+ }
+ }
+ }
+
+ if (src_surface)
+ {
+ if ((dwFlags & DDBLT_KEYSRC) || (dwFlags & DDBLT_KEYSRCOVERRIDE))
+ {
+ DDCOLORKEY color_key;
+
+ color_key.dwColorSpaceLowValue =
+ (dwFlags & DDBLT_KEYSRCOVERRIDE) ?
+ lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue : src_surface->color_key.dwColorSpaceLowValue;
+
+ color_key.dwColorSpaceHighValue =
+ (dwFlags & DDBLT_KEYSRCOVERRIDE) ?
+ lpDDBltFx->ddckSrcColorkey.dwColorSpaceHighValue : src_surface->color_key.dwColorSpaceHighValue;
+
+ if (!is_stretch_blt)
+ {
+ int width = dst_w > src_w ? src_w : dst_w;
+ int height = dst_h > src_h ? src_h : dst_h;
+
+ if (This->bpp == 8)
+ {
+ int y1, x1;
+ for (y1 = 0; y1 < height; y1++)
+ {
+ int ydst = This->width * (y1 + dst_y);
+ int ysrc = src_surface->width * (y1 + src_y);
+
+ for (x1 = 0; x1 < width; x1++)
+ {
+ unsigned char c = ((unsigned char *)src_surface->surface)[x1 + src_x + ysrc];
+
+ if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
+ {
+ ((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
+ }
+ }
+ }
+ }
+ else if (This->bpp == 16)
+ {
+ int y1, x1;
+ for (y1 = 0; y1 < height; y1++)
+ {
+ int ydst = This->width * (y1 + dst_y);
+ int ysrc = src_surface->width * (y1 + src_y);
+
+ for (x1 = 0; x1 < width; x1++)
+ {
+ unsigned short c = ((unsigned short *)src_surface->surface)[x1 + src_x + ysrc];
+
+ if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
+ {
+ ((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ dprintf(" DDBLT_KEYSRC / DDBLT_KEYSRCOVERRIDE does not support stretching\n");
+ }
+ }
+ else
+ {
+ if (!is_stretch_blt)
+ {
+ int width = dst_w > src_w ? src_w : dst_w;
+ int height = dst_h > src_h ? src_h : dst_h;
+
+ unsigned char *src =
+ (unsigned char *)src_surface->surface + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
+
+ unsigned char *dst =
+ (unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
+
+ unsigned int dst_pitch = width * This->lx_pitch;
+
+ int i;
+ for (i = 0; i < height; i++)
+ {
+ memcpy(dst, src, dst_pitch);
+
+ src += src_surface->l_pitch;
+ dst += This->l_pitch;
+ }
+ }
+ else
+ {
+ /* Linear scaling using integer math
+ * Since the scaling pattern for x will aways be the same, the pattern itself gets pre-calculated
+ * and stored in an array.
+ * Y scaling pattern gets calculated during the blit loop
+ */
+ unsigned int x_ratio = (unsigned int)((src_w << 16) / dst_w) + 1;
+ unsigned int y_ratio = (unsigned int)((src_h << 16) / dst_h) + 1;
+
+ unsigned int s_src_x, s_src_y;
+ unsigned int dest_base, source_base;
+
+ scale_pattern *pattern = malloc((dst_w + 1) * (sizeof(scale_pattern)));
+ int pattern_idx = 0;
+ unsigned int last_src_x = 0;
+
+ if (pattern != NULL)
+ {
+ pattern[pattern_idx] = (scale_pattern) { ONCE, 0, 0, 1 };
+
+ /* Build the pattern! */
+ int x;
+ for (x = 1; x < dst_w; x++) {
+ s_src_x = (x * x_ratio) >> 16;
+ if (s_src_x == last_src_x)
+ {
+ if (pattern[pattern_idx].type == REPEAT || pattern[pattern_idx].type == ONCE)
+ {
+ pattern[pattern_idx].type = REPEAT;
+ pattern[pattern_idx].count++;
+ }
+ else if (pattern[pattern_idx].type == SEQUENCE)
+ {
+ pattern_idx++;
+ pattern[pattern_idx] = (scale_pattern) { REPEAT, x, s_src_x, 1 };
+ }
+ }
+ else if (s_src_x == last_src_x + 1)
+ {
+ if (pattern[pattern_idx].type == SEQUENCE || pattern[pattern_idx].type == ONCE)
+ {
+ pattern[pattern_idx].type = SEQUENCE;
+ pattern[pattern_idx].count++;
+ }
+ else if (pattern[pattern_idx].type == REPEAT)
+ {
+ pattern_idx++;
+ pattern[pattern_idx] = (scale_pattern) { ONCE, x, s_src_x, 1 };
+ }
+ }
+ else
+ {
+ pattern_idx++;
+ pattern[pattern_idx] = (scale_pattern) { ONCE, x, s_src_x, 1 };
+ }
+ last_src_x = s_src_x;
+ }
+ pattern[pattern_idx + 1] = (scale_pattern) { END, 0, 0, 0 };
+
+
+ /* Do the actual blitting */
+ int count = 0;
+ int y;
+
+ for (y = 0; y < dst_h; y++) {
+
+ dest_base = dst_x + This->width * (y + dst_y);
+
+ s_src_y = (y * y_ratio) >> 16;
+
+ source_base = src_x + src_surface->width * (s_src_y + src_y);
+
+ pattern_idx = 0;
+ scale_pattern *current = &pattern[pattern_idx];
+
+ if (This->bpp == 8)
+ {
+ unsigned char *d, *s, v;
+ unsigned char *src = (unsigned char *)src_surface->surface;
+ unsigned char *dst = (unsigned char *)This->surface;
+
+ do {
+ switch (current->type)
+ {
+ case ONCE:
+ dst[dest_base + current->dst_index] =
+ src[source_base + current->src_index];
+ break;
+
+ case REPEAT:
+ d = (dst + dest_base + current->dst_index);
+ v = src[source_base + current->src_index];
+
+ count = current->count;
+ while (count-- > 0)
+ *d++ = v;
+
+ break;
+
+ case SEQUENCE:
+ d = dst + dest_base + current->dst_index;
+ s = src + source_base + current->src_index;
+
+ memcpy((void *)d, (void *)s, current->count * This->lx_pitch);
+ break;
+
+ case END:
+ default:
+ break;
+ }
+
+ current = &pattern[++pattern_idx];
+ } while (current->type != END);
+ }
+ else if (This->bpp == 16)
+ {
+ unsigned short *d, *s, v;
+ unsigned short *src = (unsigned short *)src_surface->surface;
+ unsigned short *dst = (unsigned short *)This->surface;
+
+ do {
+ switch (current->type)
+ {
+ case ONCE:
+ dst[dest_base + current->dst_index] =
+ src[source_base + current->src_index];
+ break;
+
+ case REPEAT:
+ d = (dst + dest_base + current->dst_index);
+ v = src[source_base + current->src_index];
+
+ count = current->count;
+ while (count-- > 0)
+ *d++ = v;
+
+ break;
+
+ case SEQUENCE:
+ d = dst + dest_base + current->dst_index;
+ s = src + source_base + current->src_index;
+
+ memcpy((void *)d, (void *)s, current->count * This->lx_pitch);
+ break;
+
+ case END:
+ default:
+ break;
+ }
+
+ current = &pattern[++pattern_idx];
+ } while (current->type != END);
+ }
+ }
+ free(pattern);
+ }
+ }
+
+ }
+ }
+
+ if((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw->render.run)
+ {
+ InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
+
+ if (!(This->flags & DDSD_BACKBUFFERCOUNT) || This->last_flip_tick + FLIP_REDRAW_TIMEOUT < timeGetTime())
+ {
+ This->last_blt_tick = timeGetTime();
+
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ SwitchToThread();
+
+ if (g_ddraw->ticks_limiter.tick_length > 0)
+ {
+ g_ddraw->ticks_limiter.use_blt_or_flip = TRUE;
+ util_limit_game_ticks();
+ }
+ }
+ }
+
+ return DD_OK;
+}
+
+HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD flags)
+{
+ IDirectDrawSurfaceImpl *src_surface = (IDirectDrawSurfaceImpl *)lpDDSrcSurface;
+
+ dbg_dump_dds_blt_fast_flags(flags);
+
+ RECT src_rect = { 0, 0, src_surface ? src_surface->width : 0, src_surface ? src_surface->height : 0 };
+
+ if (lpSrcRect && src_surface)
+ {
+ memcpy(&src_rect, lpSrcRect, sizeof(src_rect));
+
+ if (src_rect.right > src_surface->width)
+ src_rect.right = src_surface->width;
+
+ if (src_rect.bottom > src_surface->height)
+ src_rect.bottom = src_surface->height;
+ }
+
+ int src_x = src_rect.left;
+ int src_y = src_rect.top;
+
+ RECT dst_rect = { dst_x, dst_y, (src_rect.right - src_rect.left) + dst_x, (src_rect.bottom - src_rect.top) + dst_y };
+
+ if (dst_rect.right > This->width)
+ dst_rect.right = This->width;
+
+ if (dst_rect.bottom > This->height)
+ dst_rect.bottom = This->height;
+
+ int dst_w = dst_rect.right - dst_rect.left;
+ int dst_h = dst_rect.bottom - dst_rect.top;
+
+ if (src_surface)
+ {
+ if (flags & DDBLTFAST_SRCCOLORKEY)
+ {
+ if (This->bpp == 8)
+ {
+ int y1, x1;
+ for (y1 = 0; y1 < dst_h; y1++)
+ {
+ int ydst = This->width * (y1 + dst_y);
+ int ysrc = src_surface->width * (y1 + src_y);
+
+ for (x1 = 0; x1 < dst_w; x1++)
+ {
+ unsigned char c = ((unsigned char *)src_surface->surface)[x1 + src_x + ysrc];
+
+ if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
+ {
+ ((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
+ }
+ }
+ }
+ }
+ else if (This->bpp == 16)
+ {
+ int y1, x1;
+ for (y1 = 0; y1 < dst_h; y1++)
+ {
+ int ydst = This->width * (y1 + dst_y);
+ int ysrc = src_surface->width * (y1 + src_y);
+
+ for (x1 = 0; x1 < dst_w; x1++)
+ {
+ unsigned short c = ((unsigned short *)src_surface->surface)[x1 + src_x + ysrc];
+
+ if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
+ {
+ ((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ unsigned char *src =
+ (unsigned char *)src_surface->surface + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
+
+ unsigned char *dst =
+ (unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
+
+ unsigned int dst_pitch = dst_w * This->lx_pitch;
+
+ int i;
+ for (i = 0; i < dst_h; i++)
+ {
+ memcpy(dst, src, dst_pitch);
+
+ src += src_surface->l_pitch;
+ dst += This->l_pitch;
+ }
+ }
+ }
+
+ if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw->render.run)
+ {
+ InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
+
+ DWORD time = timeGetTime();
+
+ if (!(This->flags & DDSD_BACKBUFFERCOUNT) ||
+ (This->last_flip_tick + FLIP_REDRAW_TIMEOUT < time && This->last_blt_tick + FLIP_REDRAW_TIMEOUT < time))
+ {
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ }
+ }
+
+ return DD_OK;
+}
+
+HRESULT dds_DeleteAttachedSurface(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSurface)
+{
+ IDirectDrawSurface_Release(lpDDSurface);
+ return DD_OK;
+}
+
+HRESULT dds_GetSurfaceDesc(IDirectDrawSurfaceImpl *This, LPDDSURFACEDESC lpDDSurfaceDesc)
+{
+ lpDDSurfaceDesc->dwSize = sizeof(DDSURFACEDESC);
+ lpDDSurfaceDesc->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_LPSURFACE;
+ lpDDSurfaceDesc->dwWidth = This->width;
+ lpDDSurfaceDesc->dwHeight = This->height;
+ lpDDSurfaceDesc->lPitch = This->l_pitch;
+ lpDDSurfaceDesc->lpSurface = This->surface;
+ lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+ lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB;
+ lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = This->bpp;
+ lpDDSurfaceDesc->ddsCaps.dwCaps = This->caps | DDSCAPS_VIDEOMEMORY;
+
+ if (This->bpp == 8)
+ {
+ lpDDSurfaceDesc->ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
+ }
+ else if (This->bpp == 16)
+ {
+ lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0xF800;
+ lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x07E0;
+ lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x001F;
+ }
+
+ return DD_OK;
+}
+
+HRESULT dds_EnumAttachedSurfaces(IDirectDrawSurfaceImpl *This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
+{
+ /* this is not actually complete, but Carmageddon seems to call EnumAttachedSurfaces instead of GetSurfaceDesc to get the main surface description */
+ static DDSURFACEDESC dd_surface_desc;
+ memset(&dd_surface_desc, 0, sizeof(DDSURFACEDESC));
+
+ dds_GetSurfaceDesc(This, &dd_surface_desc);
+ This->caps |= DDSCAPS_BACKBUFFER; // Nox hack
+ lpEnumSurfacesCallback((LPDIRECTDRAWSURFACE)This, &dd_surface_desc, lpContext);
+
+ if ((This->caps & DDSCAPS_PRIMARYSURFACE) && (This->caps & DDSCAPS_FLIP) && !(This->caps & DDSCAPS_BACKBUFFER))
+ IDirectDrawSurface_AddRef(This);
+
+ This->caps &= ~DDSCAPS_BACKBUFFER;
+
+ return DD_OK;
+}
+
+HRESULT dds_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE surface, DWORD flags)
+{
+ if(This->caps & DDSCAPS_PRIMARYSURFACE && g_ddraw->render.run)
+ {
+ This->last_flip_tick = timeGetTime();
+
+ InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ SwitchToThread();
+
+ if (flags & DDFLIP_WAIT)
+ {
+ dd_WaitForVerticalBlank(DDWAITVB_BLOCKEND, NULL);
+ }
+
+ if (g_ddraw->ticks_limiter.tick_length > 0)
+ {
+ g_ddraw->ticks_limiter.use_blt_or_flip = TRUE;
+ util_limit_game_ticks();
+ }
+ }
+
+ return DD_OK;
+}
+
+HRESULT dds_GetAttachedSurface(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDdsCaps, LPDIRECTDRAWSURFACE FAR *surface)
+{
+ if ((This->caps & DDSCAPS_PRIMARYSURFACE) && (This->caps & DDSCAPS_FLIP) && (lpDdsCaps->dwCaps & DDSCAPS_BACKBUFFER))
+ {
+ IDirectDrawSurface_AddRef(This);
+ *surface = (LPDIRECTDRAWSURFACE)This;
+ }
+
+ return DD_OK;
+}
+
+HRESULT dds_GetCaps(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDDSCaps)
+{
+ lpDDSCaps->dwCaps = This->caps;
+ return DD_OK;
+}
+
+HRESULT dds_GetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY colorKey)
+{
+ if (colorKey)
+ {
+ colorKey->dwColorSpaceHighValue = This->color_key.dwColorSpaceHighValue;
+ colorKey->dwColorSpaceLowValue = This->color_key.dwColorSpaceLowValue;
+ }
+
+ return DD_OK;
+}
+
+HRESULT dds_GetDC(IDirectDrawSurfaceImpl *This, HDC FAR *a)
+{
+ if ((This->width % 4))
+ {
+ dprintf(" GetDC: width=%d height=%d\n", This->width, This->height);
+ }
+
+ RGBQUAD *data =
+ This->palette && This->palette->data_rgb ? This->palette->data_rgb :
+ g_ddraw->primary && g_ddraw->primary->palette ? g_ddraw->primary->palette->data_rgb :
+ NULL;
+
+ if (data)
+ SetDIBColorTable(This->hdc, 0, 256, data);
+
+ *a = This->hdc;
+ return DD_OK;
+}
+
+HRESULT dds_GetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE FAR *lplpDDPalette)
+{
+ *lplpDDPalette = (LPDIRECTDRAWPALETTE)This->palette;
+
+ if (This->palette)
+ {
+ return DD_OK;
+ }
+ else
+ {
+ return DDERR_NOPALETTEATTACHED;
+ }
+}
+
+HRESULT dds_GetPixelFormat(IDirectDrawSurfaceImpl *This, LPDDPIXELFORMAT ddpfPixelFormat)
+{
+ DWORD size = ddpfPixelFormat->dwSize;
+
+ if (size == sizeof(DDPIXELFORMAT))
+ {
+ memset(ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT));
+
+ ddpfPixelFormat->dwSize = size;
+ ddpfPixelFormat->dwFlags = DDPF_RGB;
+ ddpfPixelFormat->dwRGBBitCount = This->bpp;
+
+ if (This->bpp == 8)
+ {
+ ddpfPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;
+ }
+ else if (This->bpp == 16)
+ {
+ ddpfPixelFormat->dwRBitMask = 0xF800;
+ ddpfPixelFormat->dwGBitMask = 0x07E0;
+ ddpfPixelFormat->dwBBitMask = 0x001F;
+ }
+
+ return DD_OK;
+ }
+
+ return DDERR_INVALIDPARAMS;
+}
+
+HRESULT dds_Lock(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
+{
+ dbg_dump_dds_lock_flags(dwFlags);
+
+ return dds_GetSurfaceDesc(This, lpDDSurfaceDesc);
+}
+
+HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY colorKey)
+{
+ if (colorKey)
+ {
+ dprintfex(" dwColorSpaceHighValue=%d\n", colorKey->dwColorSpaceHighValue);
+ dprintfex(" dwColorSpaceLowValue=%d\n", colorKey->dwColorSpaceLowValue);
+
+ This->color_key.dwColorSpaceHighValue = colorKey->dwColorSpaceHighValue;
+ This->color_key.dwColorSpaceLowValue = colorKey->dwColorSpaceLowValue;
+ }
+
+ return DD_OK;
+}
+
+HRESULT dds_SetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE lpDDPalette)
+{
+ IDirectDrawPalette_AddRef(lpDDPalette);
+
+ if (This->palette)
+ {
+ IDirectDrawPalette_Release(This->palette);
+ }
+
+ EnterCriticalSection(&g_ddraw->cs);
+
+ This->palette = (IDirectDrawPaletteImpl *)lpDDPalette;
+ This->palette->data_rgb = &This->bmi->bmiColors[0];
+
+ int i;
+ for (i = 0; i < 256; i++)
+ {
+ This->palette->data_rgb[i].rgbRed = This->palette->data_bgr[i] & 0xFF;
+ This->palette->data_rgb[i].rgbGreen = (This->palette->data_bgr[i] >> 8) & 0xFF;
+ This->palette->data_rgb[i].rgbBlue = (This->palette->data_bgr[i] >> 16) & 0xFF;
+ This->palette->data_rgb[i].rgbReserved = 0;
+ }
+
+ LeaveCriticalSection(&g_ddraw->cs);
+
+ return DD_OK;
+}
+
+HRESULT dds_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
+{
+ HWND hwnd = g_ddraw->bnet_active ? FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL) : NULL;
+ if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
+ {
+ if (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)
+ SetDIBColorTable(g_ddraw->primary->hdc, 0, 256, g_ddraw->primary->palette->data_rgb);
+
+ //GdiTransparentBlt idea taken from Aqrit's war2 ddraw
+
+ RGBQUAD quad;
+ GetDIBColorTable(g_ddraw->primary->hdc, 0xFE, 1, &quad);
+ COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
+ BOOL erase = FALSE;
+
+ do
+ {
+ RECT rc;
+ if (fake_GetWindowRect(hwnd, &rc))
+ {
+ if (rc.bottom - rc.top == 479)
+ erase = TRUE;
+
+ HDC hdc = GetDCEx(hwnd, NULL, DCX_PARENTCLIP | DCX_CACHE);
+
+ GdiTransparentBlt(
+ hdc,
+ 0,
+ 0,
+ rc.right - rc.left,
+ rc.bottom - rc.top,
+ g_ddraw->primary->hdc,
+ rc.left,
+ rc.top,
+ rc.right - rc.left,
+ rc.bottom - rc.top,
+ color
+ );
+
+ ReleaseDC(hwnd, hdc);
+ }
+
+ } while ((hwnd = FindWindowEx(HWND_DESKTOP, hwnd, "SDlgDialog", NULL)));
+
+ if (erase)
+ {
+ BOOL x = g_ddraw->ticks_limiter.use_blt_or_flip;
+
+ DDBLTFX fx = { .dwFillColor = 0xFE };
+ IDirectDrawSurface_Blt(This, NULL, NULL, NULL, DDBLT_COLORFILL, &fx);
+
+ g_ddraw->ticks_limiter.use_blt_or_flip = x;
+ }
+ }
+
+ if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw->render.run)
+ {
+ InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
+
+ DWORD time = timeGetTime();
+
+ if (!(This->flags & DDSD_BACKBUFFERCOUNT) ||
+ (This->last_flip_tick + FLIP_REDRAW_TIMEOUT < time && This->last_blt_tick + FLIP_REDRAW_TIMEOUT < time))
+ {
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+
+ if (g_ddraw->ticks_limiter.tick_length > 0 && !g_ddraw->ticks_limiter.use_blt_or_flip)
+ util_limit_game_ticks();
+ }
+ }
+
+ return DD_OK;
+}
+
+HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR *lpDDSurface, IUnknown FAR * unkOuter)
+{
+ dbg_dump_dds_flags(lpDDSurfaceDesc->dwFlags);
+
+ IDirectDrawSurfaceImpl *dst_surface = (IDirectDrawSurfaceImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
+
+ dst_surface->lpVtbl = &g_dds_vtbl;
+
+ lpDDSurfaceDesc->dwFlags |= DDSD_CAPS;
+
+ /* private stuff */
+ dst_surface->bpp = g_ddraw->bpp;
+ dst_surface->flags = lpDDSurfaceDesc->dwFlags;
+
+ if(lpDDSurfaceDesc->dwFlags & DDSD_CAPS)
+ {
+ if(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+ {
+ g_ddraw->primary = dst_surface;
+
+ dst_surface->width = g_ddraw->width;
+ dst_surface->height = g_ddraw->height;
+ }
+
+ dbg_dump_dds_caps(lpDDSurfaceDesc->ddsCaps.dwCaps);
+ dst_surface->caps = lpDDSurfaceDesc->ddsCaps.dwCaps;
+ }
+
+ if( !(lpDDSurfaceDesc->dwFlags & DDSD_CAPS) || !(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) )
+ {
+ dst_surface->width = lpDDSurfaceDesc->dwWidth;
+ dst_surface->height = lpDDSurfaceDesc->dwHeight;
+ }
+
+ if(dst_surface->width && dst_surface->height)
+ {
+ if (dst_surface->width == 622 && dst_surface->height == 51) dst_surface->width = 624; //AoE2
+ if (dst_surface->width == 71 && dst_surface->height == 24) dst_surface->width = 72; //Commandos
+
+ dst_surface->bmi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
+ dst_surface->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dst_surface->bmi->bmiHeader.biWidth = dst_surface->width;
+ dst_surface->bmi->bmiHeader.biHeight = -(dst_surface->height + 200);
+ dst_surface->bmi->bmiHeader.biPlanes = 1;
+ dst_surface->bmi->bmiHeader.biBitCount = dst_surface->bpp;
+ dst_surface->bmi->bmiHeader.biCompression = dst_surface->bpp == 16 ? BI_BITFIELDS : BI_RGB;
+
+ WORD c_clr_bits = (WORD)(dst_surface->bmi->bmiHeader.biPlanes * dst_surface->bmi->bmiHeader.biBitCount);
+ if (c_clr_bits < 24)
+ dst_surface->bmi->bmiHeader.biClrUsed = (1 << c_clr_bits);
+
+ dst_surface->bmi->bmiHeader.biSizeImage = ((dst_surface->width * c_clr_bits + 31) & ~31) / 8 * dst_surface->height;
+
+ if (dst_surface->bpp == 8)
+ {
+ int i;
+ for (i = 0; i < 256; i++)
+ {
+ dst_surface->bmi->bmiColors[i].rgbRed = i;
+ dst_surface->bmi->bmiColors[i].rgbGreen = i;
+ dst_surface->bmi->bmiColors[i].rgbBlue = i;
+ dst_surface->bmi->bmiColors[i].rgbReserved = 0;
+ }
+ }
+ else if (dst_surface->bpp == 16)
+ {
+ ((DWORD *)dst_surface->bmi->bmiColors)[0] = 0xF800;
+ ((DWORD *)dst_surface->bmi->bmiColors)[1] = 0x07E0;
+ ((DWORD *)dst_surface->bmi->bmiColors)[2] = 0x001F;
+ }
+
+ dst_surface->lx_pitch = dst_surface->bpp / 8;
+ dst_surface->l_pitch = dst_surface->width * dst_surface->lx_pitch;
+
+ dst_surface->hdc = CreateCompatibleDC(g_ddraw->render.hdc);
+ dst_surface->bitmap = CreateDIBSection(dst_surface->hdc, dst_surface->bmi, DIB_RGB_COLORS, (void **)&dst_surface->surface, NULL, 0);
+ dst_surface->bmi->bmiHeader.biHeight = -dst_surface->height;
+
+ if (!dst_surface->bitmap)
+ dst_surface->surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dst_surface->l_pitch * (dst_surface->height + 200) * dst_surface->lx_pitch);
+
+ if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+ g_fake_primary_surface_export = dst_surface->surface;
+
+ SelectObject(dst_surface->hdc, dst_surface->bitmap);
+ }
+
+ if (lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
+ {
+ dprintf(" dwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount);
+ }
+
+ dprintf(" dst_surface = %p (%dx%d@%d)\n", dst_surface, (int)dst_surface->width, (int)dst_surface->height, (int)dst_surface->bpp);
+
+ *lpDDSurface = (LPDIRECTDRAWSURFACE)dst_surface;
+
+ dst_surface->ref = 0;
+ IDirectDrawSurface_AddRef(dst_surface);
+
+ return DD_OK;
+}
diff --git a/src/debug.c b/src/debug.c
index b9e08f2..085f4d6 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -1,41 +1,72 @@
-
#include
#include
-#include "main.h"
-#include "surface.h"
+#include "dd.h"
+#include "ddraw.h"
+#include "ddsurface.h"
+#include "debug.h"
-double DebugFrameTime = 0;
-DWORD DebugFrameCount = 0;
-static LONGLONG CounterStartTime = 0;
-static double CounterFreq = 0.0;
+double g_dbg_frame_time = 0;
+DWORD g_dbg_frame_count = 0;
-void CounterStart()
+static LONGLONG g_dbg_counter_start_time = 0;
+static double g_dbg_counter_freq = 0.0;
+
+void dbg_init()
+{
+ static int stdout_open = 0;
+
+ if (!stdout_open)
+ {
+ freopen("cnc-ddraw.log", "w", stdout);
+ setvbuf(stdout, NULL, _IOLBF, 1024);
+ stdout_open = 1;
+
+ HKEY hkey;
+ LONG status =
+ RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0L, KEY_READ, &hkey);
+
+ if (status == ERROR_SUCCESS)
+ {
+ char name[256] = { 0 };
+ DWORD name_size = sizeof(name);
+ RegQueryValueExA(hkey, "ProductName", NULL, NULL, (PVOID)&name, &name_size);
+
+ char build[256] = { 0 };
+ DWORD build_size = sizeof(build);
+ RegQueryValueExA(hkey, "BuildLab", NULL, NULL, (PVOID)&build, &build_size);
+
+ dbg_printf("%s (%s)\n", name, build);
+ }
+ }
+}
+
+void dbg_counter_start()
{
LARGE_INTEGER li;
QueryPerformanceFrequency(&li);
- CounterFreq = (double)(li.QuadPart) / 1000.0;
+ g_dbg_counter_freq = (double)(li.QuadPart) / 1000.0;
QueryPerformanceCounter(&li);
- CounterStartTime = li.QuadPart;
+ g_dbg_counter_start_time = li.QuadPart;
}
-double CounterStop()
+double dbg_counter_stop()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
- return (double)(li.QuadPart - CounterStartTime) / CounterFreq;
+ return (double)(li.QuadPart - g_dbg_counter_start_time) / g_dbg_counter_freq;
}
-void DebugPrint(const char *format, ...)
+void dbg_debug_string(const char *format, ...)
{
va_list args;
va_start(args, format);
- char buffer[512];
+ char buffer[512] = { 0 };
_vsnprintf(buffer, sizeof(buffer), format, args);
OutputDebugStringA(buffer);
}
-int dprintf(const char *fmt, ...)
+int dbg_printf(const char *fmt, ...)
{
static CRITICAL_SECTION cs;
static BOOL initialized;
@@ -65,42 +96,292 @@ int dprintf(const char *fmt, ...)
return ret;
}
-void DrawFrameInfoStart()
+void dbg_draw_frame_info_start()
{
static DWORD tick_fps = 0;
- static char debugText[512] = { 0 };
+ static char debug_text[512] = { 0 };
- RECT debugrc = { 0, 0, ddraw->width, ddraw->height };
+ RECT debugrc = { 0, 0, g_ddraw->width, g_ddraw->height };
- if (ddraw->primary)
+ if (g_ddraw->primary)
{
- if (ddraw->primary->palette && ddraw->primary->palette->data_rgb)
- SetDIBColorTable(ddraw->primary->hDC, 0, 256, ddraw->primary->palette->data_rgb);
+ if (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)
+ SetDIBColorTable(g_ddraw->primary->hdc, 0, 256, g_ddraw->primary->palette->data_rgb);
- DrawText(ddraw->primary->hDC, debugText, -1, &debugrc, DT_NOCLIP);
+ DrawText(g_ddraw->primary->hdc, debug_text, -1, &debugrc, DT_NOCLIP);
}
DWORD tick_start = timeGetTime();
if (tick_start >= tick_fps)
{
_snprintf(
- debugText,
- sizeof(debugText),
+ debug_text,
+ sizeof(debug_text)-1,
"FPS: %lu | Time: %2.2f ms ",
- DebugFrameCount,
- DebugFrameTime);
+ g_dbg_frame_count,
+ g_dbg_frame_time);
- DebugFrameCount = 0;
+ g_dbg_frame_count = 0;
tick_fps = tick_start + 1000;
- CounterStart();
+ dbg_counter_start();
}
- DebugFrameCount++;
+ g_dbg_frame_count++;
}
-void DrawFrameInfoEnd()
+void dbg_draw_frame_info_end()
{
- if (DebugFrameCount == 1)
- DebugFrameTime = CounterStop();
+ if (g_dbg_frame_count == 1)
+ g_dbg_frame_time = dbg_counter_stop();
+}
+
+void dbg_dump_dds_blt_flags(DWORD flags)
+{
+#ifdef _DEBUG_X
+ if (flags & DDBLT_ALPHADEST) {
+ dprintf(" DDBLT_ALPHADEST\n");
+ }
+ if (flags & DDBLT_ALPHADESTCONSTOVERRIDE) {
+ dprintf(" DDBLT_ALPHADESTCONSTOVERRIDE\n");
+ }
+ if (flags & DDBLT_ALPHADESTNEG) {
+ dprintf(" DDBLT_ALPHADESTNEG\n");
+ }
+ if (flags & DDBLT_ALPHADESTSURFACEOVERRIDE) {
+ dprintf(" DDBLT_ALPHADESTSURFACEOVERRIDE\n");
+ }
+ if (flags & DDBLT_ALPHAEDGEBLEND) {
+ dprintf(" DDBLT_ALPHAEDGEBLEND\n");
+ }
+ if (flags & DDBLT_ALPHASRC) {
+ dprintf(" DDBLT_ALPHASRC\n");
+ }
+ if (flags & DDBLT_ALPHASRCCONSTOVERRIDE) {
+ dprintf(" DDBLT_ALPHASRCCONSTOVERRIDE\n");
+ }
+ if (flags & DDBLT_ALPHASRCNEG) {
+ dprintf(" DDBLT_ALPHASRCNEG\n");
+ }
+ if (flags & DDBLT_ALPHASRCSURFACEOVERRIDE) {
+ dprintf(" DDBLT_ALPHASRCSURFACEOVERRIDE\n");
+ }
+ if (flags & DDBLT_ASYNC) {
+ dprintf(" DDBLT_ASYNC\n");
+ }
+ if (flags & DDBLT_COLORFILL) {
+ dprintf(" DDBLT_COLORFILL\n");
+ }
+ if (flags & DDBLT_DDFX) {
+ dprintf(" DDBLT_DDFX\n");
+ }
+ if (flags & DDBLT_DDROPS) {
+ dprintf(" DDBLT_DDROPS\n");
+ }
+ if (flags & DDBLT_KEYDEST) {
+ dprintf(" DDBLT_KEYDEST\n");
+ }
+ if (flags & DDBLT_KEYDESTOVERRIDE) {
+ dprintf(" DDBLT_KEYDESTOVERRIDE\n");
+ }
+ if (flags & DDBLT_KEYSRC) {
+ dprintf(" DDBLT_KEYSRC\n");
+ }
+ if (flags & DDBLT_KEYSRCOVERRIDE) {
+ dprintf(" DDBLT_KEYSRCOVERRIDE\n");
+ }
+ if (flags & DDBLT_ROP) {
+ dprintf(" DDBLT_ROP\n");
+ }
+ if (flags & DDBLT_ROTATIONANGLE) {
+ dprintf(" DDBLT_ROTATIONANGLE\n");
+ }
+ if (flags & DDBLT_ZBUFFER) {
+ dprintf(" DDBLT_ZBUFFER\n");
+ }
+ if (flags & DDBLT_ZBUFFERDESTCONSTOVERRIDE) {
+ dprintf(" DDBLT_ZBUFFERDESTCONSTOVERRIDE\n");
+ }
+ if (flags & DDBLT_ZBUFFERDESTOVERRIDE) {
+ dprintf(" DDBLT_ZBUFFERDESTOVERRIDE\n");
+ }
+ if (flags & DDBLT_ZBUFFERSRCCONSTOVERRIDE) {
+ dprintf(" DDBLT_ZBUFFERSRCCONSTOVERRIDE\n");
+ }
+ if (flags & DDBLT_ZBUFFERSRCOVERRIDE) {
+ dprintf(" DDBLT_ZBUFFERSRCOVERRIDE\n");
+ }
+ if (flags & DDBLT_WAIT) {
+ dprintf(" DDBLT_WAIT\n");
+ }
+ if (flags & DDBLT_DEPTHFILL) {
+ dprintf(" DDBLT_DEPTHFILL\n");
+ }
+#endif
+}
+
+void dbg_dump_dds_caps(DWORD caps)
+{
+#ifdef _DEBUG_X
+ if (caps & DDSCAPS_ALPHA)
+ {
+ dprintf(" DDSCAPS_ALPHA\n");
+ }
+ if (caps & DDSCAPS_BACKBUFFER)
+ {
+ dprintf(" DDSCAPS_BACKBUFFER\n");
+ }
+ if (caps & DDSCAPS_FLIP)
+ {
+ dprintf(" DDSCAPS_FLIP\n");
+ }
+ if (caps & DDSCAPS_FRONTBUFFER)
+ {
+ dprintf(" DDSCAPS_FRONTBUFFER\n");
+ }
+ if (caps & DDSCAPS_PALETTE)
+ {
+ dprintf(" DDSCAPS_PALETTE\n");
+ }
+ if (caps & DDSCAPS_TEXTURE)
+ {
+ dprintf(" DDSCAPS_TEXTURE\n");
+ }
+ if (caps & DDSCAPS_PRIMARYSURFACE)
+ {
+ dprintf(" DDSCAPS_PRIMARYSURFACE\n");
+ }
+ if (caps & DDSCAPS_OFFSCREENPLAIN)
+ {
+ dprintf(" DDSCAPS_OFFSCREENPLAIN\n");
+ }
+ if (caps & DDSCAPS_VIDEOMEMORY)
+ {
+ dprintf(" DDSCAPS_VIDEOMEMORY\n");
+ }
+ if (caps & DDSCAPS_LOCALVIDMEM)
+ {
+ dprintf(" DDSCAPS_LOCALVIDMEM\n");
+ }
+#endif
+}
+
+void dbg_dump_dds_flags(DWORD flags)
+{
+#ifdef _DEBUG_X
+ if (flags & DDSD_CAPS)
+ {
+ dprintf(" DDSD_CAPS\n");
+ }
+ if (flags & DDSD_HEIGHT)
+ {
+ dprintf(" DDSD_HEIGHT\n");
+ }
+ if (flags & DDSD_WIDTH)
+ {
+ dprintf(" DDSD_WIDTH\n");
+ }
+ if (flags & DDSD_PITCH)
+ {
+ dprintf(" DDSD_PITCH\n");
+ }
+ if (flags & DDSD_BACKBUFFERCOUNT)
+ {
+ dprintf(" DDSD_BACKBUFFERCOUNT\n");
+ }
+ if (flags & DDSD_ZBUFFERBITDEPTH)
+ {
+ dprintf(" DDSD_ZBUFFERBITDEPTH\n");
+ }
+ if (flags & DDSD_ALPHABITDEPTH)
+ {
+ dprintf(" DDSD_ALPHABITDEPTH\n");
+ }
+ if (flags & DDSD_LPSURFACE)
+ {
+ dprintf(" DDSD_LPSURFACE\n");
+ }
+ if (flags & DDSD_PIXELFORMAT)
+ {
+ dprintf(" DDSD_PIXELFORMAT\n");
+ }
+ if (flags & DDSD_CKDESTOVERLAY)
+ {
+ dprintf(" DDSD_CKDESTOVERLAY\n");
+ }
+ if (flags & DDSD_CKDESTBLT)
+ {
+ dprintf(" DDSD_CKDESTBLT\n");
+ }
+ if (flags & DDSD_CKSRCOVERLAY)
+ {
+ dprintf(" DDSD_CKSRCOVERLAY\n");
+ }
+ if (flags & DDSD_CKSRCBLT)
+ {
+ dprintf(" DDSD_CKSRCBLT\n");
+ }
+ if (flags & DDSD_MIPMAPCOUNT)
+ {
+ dprintf(" DDSD_MIPMAPCOUNT\n");
+ }
+ if (flags & DDSD_REFRESHRATE)
+ {
+ dprintf(" DDSD_REFRESHRATE\n");
+ }
+ if (flags & DDSD_LINEARSIZE)
+ {
+ dprintf(" DDSD_LINEARSIZE\n");
+ }
+ if (flags & DDSD_ALL)
+ {
+ dprintf(" DDSD_ALL\n");
+ }
+#endif
+}
+
+void dbg_dump_dds_blt_fast_flags(DWORD flags)
+{
+#ifdef _DEBUG_X
+ if (flags & DDBLTFAST_NOCOLORKEY)
+ {
+ dprintf(" DDBLTFAST_NOCOLORKEY\n");
+ }
+
+ if (flags & DDBLTFAST_SRCCOLORKEY)
+ {
+ dprintf(" DDBLTFAST_SRCCOLORKEY\n");
+ }
+
+ if (flags & DDBLTFAST_DESTCOLORKEY)
+ {
+ dprintf(" DDBLTFAST_DESTCOLORKEY\n");
+ }
+#endif
+}
+
+void dbg_dump_dds_lock_flags(DWORD flags)
+{
+#ifdef _DEBUG_X
+ if (flags & DDLOCK_SURFACEMEMORYPTR)
+ {
+ dprintf(" dwFlags: DDLOCK_SURFACEMEMORYPTR\n");
+ }
+ if (flags & DDLOCK_WAIT)
+ {
+ dprintf(" dwFlags: DDLOCK_WAIT\n");
+ }
+ if (flags & DDLOCK_EVENT)
+ {
+ dprintf(" dwFlags: DDLOCK_EVENT\n");
+ }
+ if (flags & DDLOCK_READONLY)
+ {
+ dprintf(" dwFlags: DDLOCK_READONLY\n");
+ }
+ if (flags & DDLOCK_WRITEONLY)
+ {
+ dprintf(" dwFlags: DDLOCK_WRITEONLY\n");
+ }
+#endif
}
diff --git a/src/dinput.c b/src/dinput.c
deleted file mode 100644
index 55f97ba..0000000
--- a/src/dinput.c
+++ /dev/null
@@ -1,99 +0,0 @@
-#include
-#include
-#include "hook.h"
-#include "main.h"
-
-typedef HRESULT (WINAPI *DIRECTINPUTCREATEAPROC)(HINSTANCE, DWORD, LPDIRECTINPUTA*, LPUNKNOWN);
-typedef HRESULT (WINAPI *DICREATEDEVICEPROC)(IDirectInputA*, REFGUID, LPDIRECTINPUTDEVICEA *, LPUNKNOWN);
-typedef HRESULT (WINAPI *DIDSETCOOPERATIVELEVELPROC)(IDirectInputDeviceA *, HWND, DWORD);
-typedef HRESULT (WINAPI *DIDGETDEVICEDATAPROC)(IDirectInputDeviceA*, DWORD, LPDIDEVICEOBJECTDATA, LPDWORD, DWORD);
-
-static DIRECTINPUTCREATEAPROC DInputCreateA;
-static DICREATEDEVICEPROC DICreateDevice;
-static DIDSETCOOPERATIVELEVELPROC DIDSetCooperativeLevel;
-static DIDGETDEVICEDATAPROC DIDGetDeviceData;
-
-static PROC HookFunc(PROC *orgFunc, PROC newFunc)
-{
- PROC org = *orgFunc;
- DWORD oldProtect;
-
- if (VirtualProtect(orgFunc, sizeof(PROC), PAGE_EXECUTE_READWRITE, &oldProtect))
- {
- *orgFunc = newFunc;
- VirtualProtect(orgFunc, sizeof(PROC), oldProtect, &oldProtect);
- return org;
- }
-
- return 0;
-}
-
-static HRESULT WINAPI fake_DIDSetCooperativeLevel(IDirectInputDeviceA *This, HWND hwnd, DWORD dwFlags)
-{
- return DIDSetCooperativeLevel(This, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
-}
-
-static HRESULT WINAPI fake_DIDGetDeviceData(IDirectInputDeviceA *This, DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags)
-{
- HRESULT result = DIDGetDeviceData(This, cbObjectData, rgdod, pdwInOut, dwFlags);
-
- if (SUCCEEDED(result) && ddraw && !ddraw->locked)
- {
- *pdwInOut = 0;
- }
-
- return result;
-}
-
-static HRESULT WINAPI fake_DICreateDevice(IDirectInputA *This, REFGUID rguid, LPDIRECTINPUTDEVICEA * lplpDIDevice, LPUNKNOWN pUnkOuter)
-{
- HRESULT result = DICreateDevice(This, rguid, lplpDIDevice, pUnkOuter);
-
- if (SUCCEEDED(result) && !DIDSetCooperativeLevel)
- {
- DIDSetCooperativeLevel =
- (DIDSETCOOPERATIVELEVELPROC)HookFunc(
- (PROC *)&(*lplpDIDevice)->lpVtbl->SetCooperativeLevel, (PROC)fake_DIDSetCooperativeLevel);
-
- DIDGetDeviceData =
- (DIDGETDEVICEDATAPROC)HookFunc(
- (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceData, (PROC)fake_DIDGetDeviceData);
- }
-
- return result;
-}
-
-static HRESULT WINAPI fake_DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA* lplpDirectInput, LPUNKNOWN punkOuter)
-{
- printf("??? DirectInputCreateA\n");
-
- DInputCreateA =
- (DIRECTINPUTCREATEAPROC)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA");
-
- if (!DInputCreateA)
- return DIERR_GENERIC;
-
- HRESULT result = DInputCreateA(hinst, dwVersion, lplpDirectInput, punkOuter);
-
- if (SUCCEEDED(result) && !DICreateDevice)
- {
- DICreateDevice =
- (DICREATEDEVICEPROC)HookFunc((PROC *)&(*lplpDirectInput)->lpVtbl->CreateDevice, (PROC)fake_DICreateDevice);
- }
-
- return result;
-}
-
-void DInput_Hook()
-{
- Hook_PatchIAT(GetModuleHandle(NULL), "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA);
-}
-
-void DInput_UnHook()
-{
- Hook_PatchIAT(
- GetModuleHandle(NULL),
- "dinput.dll",
- "DirectInputCreateA",
- (PROC)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA"));
-}
diff --git a/src/directinput.c b/src/directinput.c
new file mode 100644
index 0000000..b6a5c51
--- /dev/null
+++ b/src/directinput.c
@@ -0,0 +1,101 @@
+
+#include
+#include
+#include "debug.h"
+#include "hook.h"
+#include "dd.h"
+
+typedef HRESULT (WINAPI *DIRECTINPUTCREATEAPROC)(HINSTANCE, DWORD, LPDIRECTINPUTA*, LPUNKNOWN);
+typedef HRESULT (WINAPI *DICREATEDEVICEPROC)(IDirectInputA*, REFGUID, LPDIRECTINPUTDEVICEA *, LPUNKNOWN);
+typedef HRESULT (WINAPI *DIDSETCOOPERATIVELEVELPROC)(IDirectInputDeviceA *, HWND, DWORD);
+typedef HRESULT (WINAPI *DIDGETDEVICEDATAPROC)(IDirectInputDeviceA*, DWORD, LPDIDEVICEOBJECTDATA, LPDWORD, DWORD);
+
+static DIRECTINPUTCREATEAPROC real_DirectInputCreateA;
+static DICREATEDEVICEPROC real_di_CreateDevice;
+static DIDSETCOOPERATIVELEVELPROC real_did_SetCooperativeLevel;
+static DIDGETDEVICEDATAPROC real_did_GetDeviceData;
+
+static PROC hook_func(PROC *org_func, PROC new_func)
+{
+ PROC org = *org_func;
+ DWORD old_protect;
+
+ if (VirtualProtect(org_func, sizeof(PROC), PAGE_EXECUTE_READWRITE, &old_protect))
+ {
+ *org_func = new_func;
+ VirtualProtect(org_func, sizeof(PROC), old_protect, &old_protect);
+ return org;
+ }
+
+ return 0;
+}
+
+static HRESULT WINAPI fake_did_SetCooperativeLevel(IDirectInputDeviceA *This, HWND hwnd, DWORD dwFlags)
+{
+ return real_did_SetCooperativeLevel(This, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
+}
+
+static HRESULT WINAPI fake_did_GetDeviceData(IDirectInputDeviceA *This, DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags)
+{
+ HRESULT result = real_did_GetDeviceData(This, cbObjectData, rgdod, pdwInOut, dwFlags);
+
+ if (SUCCEEDED(result) && g_ddraw && !g_ddraw->locked)
+ {
+ *pdwInOut = 0;
+ }
+
+ return result;
+}
+
+static HRESULT WINAPI fake_di_CreateDevice(IDirectInputA *This, REFGUID rguid, LPDIRECTINPUTDEVICEA * lplpDIDevice, LPUNKNOWN pUnkOuter)
+{
+ HRESULT result = real_di_CreateDevice(This, rguid, lplpDIDevice, pUnkOuter);
+
+ if (SUCCEEDED(result) && !real_did_SetCooperativeLevel)
+ {
+ real_did_SetCooperativeLevel =
+ (DIDSETCOOPERATIVELEVELPROC)hook_func(
+ (PROC *)&(*lplpDIDevice)->lpVtbl->SetCooperativeLevel, (PROC)fake_did_SetCooperativeLevel);
+
+ real_did_GetDeviceData =
+ (DIDGETDEVICEDATAPROC)hook_func(
+ (PROC*)&(*lplpDIDevice)->lpVtbl->GetDeviceData, (PROC)fake_did_GetDeviceData);
+ }
+
+ return result;
+}
+
+static HRESULT WINAPI fake_DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA* lplpDirectInput, LPUNKNOWN punkOuter)
+{
+ dprintf("DirectInputCreateA\n");
+
+ real_DirectInputCreateA =
+ (DIRECTINPUTCREATEAPROC)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA");
+
+ if (!real_DirectInputCreateA)
+ return DIERR_GENERIC;
+
+ HRESULT result = real_DirectInputCreateA(hinst, dwVersion, lplpDirectInput, punkOuter);
+
+ if (SUCCEEDED(result) && !real_di_CreateDevice)
+ {
+ real_di_CreateDevice =
+ (DICREATEDEVICEPROC)hook_func((PROC *)&(*lplpDirectInput)->lpVtbl->CreateDevice, (PROC)fake_di_CreateDevice);
+ }
+
+ return result;
+}
+
+void dinput_hook()
+{
+ hook_patch_iat(GetModuleHandle(NULL), "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA);
+}
+
+void dinput_unhook()
+{
+ hook_patch_iat(
+ GetModuleHandle(NULL),
+ "dinput.dll",
+ "DirectInputCreateA",
+ (PROC)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA"));
+}
diff --git a/src/dllmain.c b/src/dllmain.c
new file mode 100644
index 0000000..1fc519c
--- /dev/null
+++ b/src/dllmain.c
@@ -0,0 +1,181 @@
+#include
+#include
+#include
+#include "dllmain.h"
+#include "dd.h"
+#include "ddclipper.h"
+#include "debug.h"
+#include "config.h"
+#include "directinput.h"
+#include "IDirectDraw.h"
+#include "hook.h"
+
+// exports to force usage of discrete high performance graphics device
+DWORD NvOptimusEnablement = 1;
+DWORD AmdPowerXpressRequestHighPerformance = 1;
+
+// export for cncnet cnc games
+BOOL GameHandlesClose;
+
+
+HMODULE g_ddraw_module;
+
+BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+ switch (dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+#if _DEBUG
+ dbg_init();
+#endif
+ g_ddraw_module = hDll;
+
+ char buf[1024];
+
+ if (GetEnvironmentVariable("__COMPAT_LAYER", buf, sizeof(buf)))
+ {
+ char* s = strtok(buf, " ");
+
+ while (s)
+ {
+ if (_strcmpi(s, "WIN95") == 0 || strcmpi(s, "WIN98") == 0 || strcmpi(s, "NT4SP5") == 0)
+ {
+ char mes[128] = { 0 };
+
+ _snprintf(
+ mes,
+ sizeof(mes),
+ "Please disable the '%s' compatibility mode for all game executables and "
+ "then try to start the game again.",
+ s);
+
+ MessageBoxA(NULL, mes, "Compatibility modes detected - cnc-ddraw", MB_OK);
+
+ break;
+ }
+
+ s = strtok(NULL, " ");
+ }
+ }
+
+ BOOL set_dpi_aware = FALSE;
+ HMODULE hshcore = GetModuleHandle("shcore.dll");
+
+ if (hshcore)
+ {
+ typedef HRESULT(__stdcall* SETPROCESSDPIAWERENESSPROC)(PROCESS_DPI_AWARENESS value);
+
+ SETPROCESSDPIAWERENESSPROC set_awareness =
+ (SETPROCESSDPIAWERENESSPROC)GetProcAddress(hshcore, "SetProcessDpiAwareness");
+
+ if (set_awareness)
+ {
+ HRESULT result = set_awareness(PROCESS_PER_MONITOR_DPI_AWARE);
+
+ set_dpi_aware = result == S_OK || result == E_ACCESSDENIED;
+ }
+ }
+
+ if (!set_dpi_aware)
+ {
+ HMODULE hUser32 = GetModuleHandle("user32.dll");
+
+ if (hUser32)
+ {
+ typedef BOOL(__stdcall* SETPROCESSDPIAWAREPROC)();
+
+ SETPROCESSDPIAWAREPROC set_aware =
+ (SETPROCESSDPIAWAREPROC)GetProcAddress(hUser32, "SetProcessDPIAware");
+
+ if (set_aware)
+ set_aware();
+ }
+ }
+
+ timeBeginPeriod(1);
+ dinput_hook();
+ break;
+ }
+ case DLL_PROCESS_DETACH:
+ {
+ dprintf("cnc-ddraw DLL_PROCESS_DETACH\n");
+
+ cfg_save();
+
+ timeEndPeriod(1);
+ hook_exit();
+ dinput_unhook();
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACK lpCallback, LPVOID lpContext)
+{
+ dprintf("-> %s(lpCallback=%p, lpContext=%p)\n", __FUNCTION__, lpCallback, lpContext);
+
+ if (lpCallback)
+ lpCallback(NULL, "display", "(null)", lpContext);
+
+ dprintf("<- %s\n", __FUNCTION__);
+ return DD_OK;
+}
+
+HRESULT WINAPI DirectDrawCreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter)
+{
+ dprintf("-> %s(dwFlags=%08X, DDClipper=%p, unkOuter=%p)\n", __FUNCTION__, (int)dwFlags, lplpDDClipper, pUnkOuter);
+ HRESULT ret = dd_CreateClipper(dwFlags, lplpDDClipper, pUnkOuter);
+ dprintf("<- %s\n", __FUNCTION__);
+ return ret;
+}
+
+HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter)
+{
+ dprintf("-> %s(lpGUID=%p, lplpDD=%p, pUnkOuter=%p)\n", __FUNCTION__, lpGUID, lplpDD, pUnkOuter);
+
+ if (g_ddraw)
+ {
+ /* FIXME: check the calling module before passing the call! */
+ if (g_ddraw->DirectDrawCreate)
+ {
+ dprintf("<- %s\n", __FUNCTION__);
+ return g_ddraw->DirectDrawCreate(lpGUID, lplpDD, pUnkOuter);
+ }
+
+ dprintf("<- %s\n", __FUNCTION__);
+ return DDERR_DIRECTDRAWALREADYCREATED;
+ }
+
+ g_ddraw = (cnc_ddraw*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(cnc_ddraw));
+
+ IDirectDrawImpl* dst_ddraw = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
+ dst_ddraw->lpVtbl = &g_dd_vtbl1;
+
+ *lplpDD = (LPDIRECTDRAW)dst_ddraw;
+ IDirectDraw_AddRef(dst_ddraw);
+
+ if (!g_ddraw->real_dll)
+ g_ddraw->real_dll = LoadLibrary("system32\\ddraw.dll");
+
+ if (g_ddraw->real_dll && !g_ddraw->DirectDrawCreate)
+ {
+ g_ddraw->DirectDrawCreate =
+ (HRESULT(WINAPI*)(GUID FAR*, LPDIRECTDRAW FAR*, IUnknown FAR*))GetProcAddress(g_ddraw->real_dll, "DirectDrawCreate");
+
+ if (g_ddraw->DirectDrawCreate == DirectDrawCreate)
+ g_ddraw->DirectDrawCreate = NULL;
+ }
+
+ InitializeCriticalSection(&g_ddraw->cs);
+
+ g_ddraw->render.sem = CreateSemaphore(NULL, 0, 1, NULL);
+ g_ddraw->wine = GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0;
+
+ cfg_load();
+
+ dprintf("<- %s\n", __FUNCTION__);
+ return DD_OK;
+}
diff --git a/src/hook.c b/src/hook.c
index 41f6420..fd8037a 100644
--- a/src/hook.c
+++ b/src/hook.c
@@ -1,15 +1,18 @@
+#define WIN32_LEAN_AND_MEAN
#include
#include
-#include "main.h"
-#include "mouse.h"
+#include "dd.h"
+#include "winapi_hooks.h"
#include "hook.h"
+#include "dllmain.h"
#ifdef _MSC_VER
#include "detours.h"
#endif
-BOOL Hook_Active;
-int HookingMethod = 1;
+BOOL g_hook_active;
+int g_hook_method = 1;
+
GETCURSORPOSPROC real_GetCursorPos = GetCursorPos;
CLIPCURSORPROC real_ClipCursor = ClipCursor;
SHOWCURSORPROC real_ShowCursor = ShowCursor;
@@ -37,66 +40,66 @@ LOADLIBRARYEXAPROC real_LoadLibraryExA = LoadLibraryExA;
LOADLIBRARYEXWPROC real_LoadLibraryExW = LoadLibraryExW;
-void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction)
+void hook_patch_iat(HMODULE hmod, char *module_name, char *function_name, PROC new_function)
{
- if (!hMod || hMod == INVALID_HANDLE_VALUE || !newFunction)
+ if (!hmod || hmod == INVALID_HANDLE_VALUE || !new_function)
return;
#ifdef _MSC_VER
__try
{
#endif
- PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMod;
- if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)hmod;
+ if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
return;
- PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew);
- if (pNTHeaders->Signature != IMAGE_NT_SIGNATURE)
+ PIMAGE_NT_HEADERS nt_headers = (PIMAGE_NT_HEADERS)((DWORD)dos_header + (DWORD)dos_header->e_lfanew);
+ if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
return;
- PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDosHeader +
- (DWORD)(pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
+ PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header +
+ (DWORD)(nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
- if (pImportDescriptor == (PIMAGE_IMPORT_DESCRIPTOR)pNTHeaders)
+ if (import_desc == (PIMAGE_IMPORT_DESCRIPTOR)nt_headers)
return;
- while (pImportDescriptor->FirstThunk)
+ while (import_desc->FirstThunk)
{
- char* impModuleName = (char*)((DWORD)pDosHeader + (DWORD)(pImportDescriptor->Name));
+ char* imp_module_name = (char*)((DWORD)dos_header + (DWORD)(import_desc->Name));
- if (_stricmp(impModuleName, moduleName) == 0)
+ if (_stricmp(imp_module_name, module_name) == 0)
{
- PIMAGE_THUNK_DATA pFirstThunk =
- (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + (DWORD)pImportDescriptor->FirstThunk);
+ PIMAGE_THUNK_DATA first_thunk =
+ (PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->FirstThunk);
- PIMAGE_THUNK_DATA pOrigFirstThunk =
- (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + (DWORD)pImportDescriptor->OriginalFirstThunk);
+ PIMAGE_THUNK_DATA original_first_thunk =
+ (PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->OriginalFirstThunk);
- while (pFirstThunk->u1.Function && pOrigFirstThunk->u1.AddressOfData)
+ while (first_thunk->u1.Function && original_first_thunk->u1.AddressOfData)
{
- PIMAGE_IMPORT_BY_NAME pImport =
- (PIMAGE_IMPORT_BY_NAME)((DWORD)pDosHeader + pOrigFirstThunk->u1.AddressOfData);
+ PIMAGE_IMPORT_BY_NAME import =
+ (PIMAGE_IMPORT_BY_NAME)((DWORD)dos_header + original_first_thunk->u1.AddressOfData);
- if ((pOrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0 &&
- _stricmp((const char*)pImport->Name, functionName) == 0)
+ if ((original_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0 &&
+ _stricmp((const char*)import->Name, function_name) == 0)
{
- DWORD oldProtect;
+ DWORD old_protect;
- if (VirtualProtect(&pFirstThunk->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect))
+ if (VirtualProtect(&first_thunk->u1.Function, sizeof(DWORD), PAGE_READWRITE, &old_protect))
{
- pFirstThunk->u1.Function = (DWORD)newFunction;
- VirtualProtect(&pFirstThunk->u1.Function, sizeof(DWORD), oldProtect, &oldProtect);
+ first_thunk->u1.Function = (DWORD)new_function;
+ VirtualProtect(&first_thunk->u1.Function, sizeof(DWORD), old_protect, &old_protect);
}
break;
}
- pFirstThunk++;
- pOrigFirstThunk++;
+ first_thunk++;
+ original_first_thunk++;
}
}
- pImportDescriptor++;
+ import_desc++;
}
#ifdef _MSC_VER
}
@@ -106,42 +109,42 @@ void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newF
#endif
}
-void Hook_Create(char *moduleName, char *functionName, PROC newFunction, PROC *function)
+void hook_create(char *module_name, char *function_name, PROC new_function, PROC *function)
{
#ifdef _MSC_VER
- if (HookingMethod == 2)
+ if (g_hook_method == 2)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
- DetourAttach((PVOID *)function, (PVOID)newFunction);
+ DetourAttach((PVOID *)function, (PVOID)new_function);
DetourTransactionCommit();
}
- if (HookingMethod == 3 || HookingMethod == 4)
+ if (g_hook_method == 3 || g_hook_method == 4)
{
- WCHAR gameExePath[MAX_PATH] = { 0 };
- WCHAR gameDir[MAX_PATH] = { 0 };
+ WCHAR game_exe_path[MAX_PATH] = { 0 };
+ WCHAR game_dir[MAX_PATH] = { 0 };
- if (GetModuleFileNameW(NULL, gameExePath, MAX_PATH))
+ if (GetModuleFileNameW(NULL, game_exe_path, MAX_PATH))
{
- _wsplitpath(gameExePath, NULL, gameDir, NULL, NULL);
+ _wsplitpath(game_exe_path, NULL, game_dir, NULL, NULL);
- WCHAR modPath[MAX_PATH] = { 0 };
- WCHAR modDir[MAX_PATH] = { 0 };
- HMODULE hMod = NULL;
+ WCHAR mod_path[MAX_PATH] = { 0 };
+ WCHAR mod_dir[MAX_PATH] = { 0 };
+ HMODULE hmod = NULL;
- while (hMod = DetourEnumerateModules(hMod))
+ while (hmod = DetourEnumerateModules(hmod))
{
- if (hMod == DDrawModule)
+ if (hmod == g_ddraw_module)
continue;
- if (GetModuleFileNameW(hMod, modPath, MAX_PATH))
+ if (GetModuleFileNameW(hmod, mod_path, MAX_PATH))
{
- _wsplitpath(modPath, NULL, modDir, NULL, NULL);
+ _wsplitpath(mod_path, NULL, mod_dir, NULL, NULL);
- if (_wcsnicmp(gameDir, modDir, wcslen(gameDir)) == 0)
+ if (_wcsnicmp(game_dir, mod_dir, wcslen(game_dir)) == 0)
{
- Hook_PatchIAT(hMod, moduleName, functionName, newFunction);
+ hook_patch_iat(hmod, module_name, function_name, new_function);
}
}
}
@@ -149,53 +152,53 @@ void Hook_Create(char *moduleName, char *functionName, PROC newFunction, PROC *f
}
#endif
- if (HookingMethod == 1)
+ if (g_hook_method == 1)
{
- Hook_PatchIAT(GetModuleHandle(NULL), moduleName, functionName, newFunction);
- Hook_PatchIAT(GetModuleHandle("storm.dll"), moduleName, functionName, newFunction);
+ hook_patch_iat(GetModuleHandle(NULL), module_name, function_name, new_function);
+ hook_patch_iat(GetModuleHandle("storm.dll"), module_name, function_name, new_function);
}
}
-void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *function)
+void hook_revert(char *module_name, char *function_name, PROC new_function, PROC *function)
{
#ifdef _MSC_VER
- if (HookingMethod == 2)
+ if (g_hook_method == 2)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
- DetourDetach((PVOID *)function, (PVOID)newFunction);
+ DetourDetach((PVOID *)function, (PVOID)new_function);
DetourTransactionCommit();
}
- if (HookingMethod == 3 || HookingMethod == 4)
+ if (g_hook_method == 3 || g_hook_method == 4)
{
- WCHAR gameExePath[MAX_PATH] = { 0 };
- WCHAR gameDir[MAX_PATH] = { 0 };
+ WCHAR game_exe_path[MAX_PATH] = { 0 };
+ WCHAR game_dir[MAX_PATH] = { 0 };
- if (GetModuleFileNameW(NULL, gameExePath, MAX_PATH))
+ if (GetModuleFileNameW(NULL, game_exe_path, MAX_PATH))
{
- _wsplitpath(gameExePath, NULL, gameDir, NULL, NULL);
+ _wsplitpath(game_exe_path, NULL, game_dir, NULL, NULL);
- WCHAR modPath[MAX_PATH] = { 0 };
- WCHAR modDir[MAX_PATH] = { 0 };
- HMODULE hMod = NULL;
+ WCHAR mod_path[MAX_PATH] = { 0 };
+ WCHAR mod_dir[MAX_PATH] = { 0 };
+ HMODULE hmod = NULL;
- while (hMod = DetourEnumerateModules(hMod))
+ while (hmod = DetourEnumerateModules(hmod))
{
- if (hMod == DDrawModule)
+ if (hmod == g_ddraw_module)
continue;
- if (GetModuleFileNameW(hMod, modPath, MAX_PATH))
+ if (GetModuleFileNameW(hmod, mod_path, MAX_PATH))
{
- _wsplitpath(modPath, NULL, modDir, NULL, NULL);
+ _wsplitpath(mod_path, NULL, mod_dir, NULL, NULL);
- if (_wcsnicmp(gameDir, modDir, wcslen(gameDir)) == 0)
+ if (_wcsnicmp(game_dir, mod_dir, wcslen(game_dir)) == 0)
{
- Hook_PatchIAT(
- hMod,
- moduleName,
- functionName,
- GetProcAddress(GetModuleHandle(moduleName), functionName));
+ hook_patch_iat(
+ hmod,
+ module_name,
+ function_name,
+ GetProcAddress(GetModuleHandle(module_name), function_name));
}
}
}
@@ -203,28 +206,28 @@ void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *f
}
#endif
- if (HookingMethod == 1)
+ if (g_hook_method == 1)
{
- Hook_PatchIAT(
+ hook_patch_iat(
GetModuleHandle(NULL),
- moduleName,
- functionName,
- GetProcAddress(GetModuleHandle(moduleName), functionName));
+ module_name,
+ function_name,
+ GetProcAddress(GetModuleHandle(module_name), function_name));
- Hook_PatchIAT(
+ hook_patch_iat(
GetModuleHandle("storm.dll"),
- moduleName,
- functionName,
- GetProcAddress(GetModuleHandle(moduleName), functionName));
+ module_name,
+ function_name,
+ GetProcAddress(GetModuleHandle(module_name), function_name));
}
}
-void Hook_Init()
+void hook_init()
{
- if (!Hook_Active || HookingMethod == 3 || HookingMethod == 4)
+ if (!g_hook_active || g_hook_method == 3 || g_hook_method == 4)
{
#ifdef _MSC_VER
- if (!Hook_Active && HookingMethod == 3)
+ if (!g_hook_active && g_hook_method == 3)
{
FARPROC proc = GetProcAddress(GetModuleHandle("kernelbase.dll"), "LoadLibraryExW");
@@ -238,48 +241,48 @@ void Hook_Init()
}
#endif
- Hook_Active = TRUE;
+ g_hook_active = TRUE;
- Hook_Create("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
- Hook_Create("user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor);
- Hook_Create("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor);
- Hook_Create("user32.dll", "SetCursor", (PROC)fake_SetCursor, (PROC *)&real_SetCursor);
- Hook_Create("user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect, (PROC *)&real_GetWindowRect);
- Hook_Create("user32.dll", "GetClientRect", (PROC)fake_GetClientRect, (PROC *)&real_GetClientRect);
- Hook_Create("user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen, (PROC *)&real_ClientToScreen);
- Hook_Create("user32.dll", "ScreenToClient", (PROC)fake_ScreenToClient, (PROC *)&real_ScreenToClient);
- Hook_Create("user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos, (PROC *)&real_SetCursorPos);
- Hook_Create("user32.dll", "GetClipCursor", (PROC)fake_GetClipCursor, (PROC *)&real_GetClipCursor);
- Hook_Create("user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC *)&real_WindowFromPoint);
- Hook_Create("user32.dll", "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC *)&real_GetCursorInfo);
- Hook_Create("user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC *)&real_GetSystemMetrics);
- Hook_Create("user32.dll", "SetWindowPos", (PROC)fake_SetWindowPos, (PROC *)&real_SetWindowPos);
- Hook_Create("user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow);
- Hook_Create("user32.dll", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA);
- Hook_Create("user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA);
- Hook_Create("user32.dll", "EnableWindow", (PROC)fake_EnableWindow, (PROC *)&real_EnableWindow);
- Hook_Create("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
- Hook_Create("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
- Hook_Create("gdi32.dll", "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps);
+ hook_create("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
+ hook_create("user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor);
+ hook_create("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor);
+ hook_create("user32.dll", "SetCursor", (PROC)fake_SetCursor, (PROC *)&real_SetCursor);
+ hook_create("user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect, (PROC *)&real_GetWindowRect);
+ hook_create("user32.dll", "GetClientRect", (PROC)fake_GetClientRect, (PROC *)&real_GetClientRect);
+ hook_create("user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen, (PROC *)&real_ClientToScreen);
+ hook_create("user32.dll", "ScreenToClient", (PROC)fake_ScreenToClient, (PROC *)&real_ScreenToClient);
+ hook_create("user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos, (PROC *)&real_SetCursorPos);
+ hook_create("user32.dll", "GetClipCursor", (PROC)fake_GetClipCursor, (PROC *)&real_GetClipCursor);
+ hook_create("user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC *)&real_WindowFromPoint);
+ hook_create("user32.dll", "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC *)&real_GetCursorInfo);
+ hook_create("user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC *)&real_GetSystemMetrics);
+ hook_create("user32.dll", "SetWindowPos", (PROC)fake_SetWindowPos, (PROC *)&real_SetWindowPos);
+ hook_create("user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow);
+ hook_create("user32.dll", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA);
+ hook_create("user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA);
+ hook_create("user32.dll", "EnableWindow", (PROC)fake_EnableWindow, (PROC *)&real_EnableWindow);
+ hook_create("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
+ hook_create("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
+ hook_create("gdi32.dll", "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps);
- if (HookingMethod == 4)
+ if (g_hook_method == 4)
{
- Hook_Create("kernel32.dll", "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA);
- Hook_Create("kernel32.dll", "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW);
- Hook_Create("kernel32.dll", "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA);
- Hook_Create("kernel32.dll", "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW);
+ hook_create("kernel32.dll", "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA);
+ hook_create("kernel32.dll", "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW);
+ hook_create("kernel32.dll", "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA);
+ hook_create("kernel32.dll", "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW);
}
}
}
-void Hook_Exit()
+void hook_exit()
{
- if (Hook_Active)
+ if (g_hook_active)
{
- Hook_Active = FALSE;
+ g_hook_active = FALSE;
#ifdef _MSC_VER
- if (HookingMethod == 3)
+ if (g_hook_method == 3)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
@@ -288,34 +291,34 @@ void Hook_Exit()
}
#endif
- Hook_Revert("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
- Hook_Revert("user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor);
- Hook_Revert("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor);
- Hook_Revert("user32.dll", "SetCursor", (PROC)fake_SetCursor, (PROC *)&real_SetCursor);
- Hook_Revert("user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect, (PROC *)&real_GetWindowRect);
- Hook_Revert("user32.dll", "GetClientRect", (PROC)fake_GetClientRect, (PROC *)&real_GetClientRect);
- Hook_Revert("user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen, (PROC *)&real_ClientToScreen);
- Hook_Revert("user32.dll", "ScreenToClient", (PROC)fake_ScreenToClient, (PROC *)&real_ScreenToClient);
- Hook_Revert("user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos, (PROC *)&real_SetCursorPos);
- Hook_Revert("user32.dll", "GetClipCursor", (PROC)fake_GetClipCursor, (PROC *)&real_GetClipCursor);
- Hook_Revert("user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC *)&real_WindowFromPoint);
- Hook_Revert("user32.dll", "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC *)&real_GetCursorInfo);
- Hook_Revert("user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC *)&real_GetSystemMetrics);
- Hook_Revert("user32.dll", "SetWindowPos", (PROC)fake_SetWindowPos, (PROC *)&real_SetWindowPos);
- Hook_Revert("user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow);
- Hook_Revert("user32.dll", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA);
- Hook_Revert("user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA);
- Hook_Revert("user32.dll", "EnableWindow", (PROC)fake_EnableWindow, (PROC *)&real_EnableWindow);
- Hook_Revert("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
- Hook_Revert("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
- Hook_Revert("gdi32.dll", "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps);
+ hook_revert("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
+ hook_revert("user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor);
+ hook_revert("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor);
+ hook_revert("user32.dll", "SetCursor", (PROC)fake_SetCursor, (PROC *)&real_SetCursor);
+ hook_revert("user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect, (PROC *)&real_GetWindowRect);
+ hook_revert("user32.dll", "GetClientRect", (PROC)fake_GetClientRect, (PROC *)&real_GetClientRect);
+ hook_revert("user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen, (PROC *)&real_ClientToScreen);
+ hook_revert("user32.dll", "ScreenToClient", (PROC)fake_ScreenToClient, (PROC *)&real_ScreenToClient);
+ hook_revert("user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos, (PROC *)&real_SetCursorPos);
+ hook_revert("user32.dll", "GetClipCursor", (PROC)fake_GetClipCursor, (PROC *)&real_GetClipCursor);
+ hook_revert("user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC *)&real_WindowFromPoint);
+ hook_revert("user32.dll", "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC *)&real_GetCursorInfo);
+ hook_revert("user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC *)&real_GetSystemMetrics);
+ hook_revert("user32.dll", "SetWindowPos", (PROC)fake_SetWindowPos, (PROC *)&real_SetWindowPos);
+ hook_revert("user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow);
+ hook_revert("user32.dll", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA);
+ hook_revert("user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA);
+ hook_revert("user32.dll", "EnableWindow", (PROC)fake_EnableWindow, (PROC *)&real_EnableWindow);
+ hook_revert("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
+ hook_revert("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
+ hook_revert("gdi32.dll", "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps);
- if (HookingMethod == 4)
+ if (g_hook_method == 4)
{
- Hook_Revert("kernel32.dll", "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA);
- Hook_Revert("kernel32.dll", "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW);
- Hook_Revert("kernel32.dll", "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA);
- Hook_Revert("kernel32.dll", "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW);
+ hook_revert("kernel32.dll", "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA);
+ hook_revert("kernel32.dll", "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW);
+ hook_revert("kernel32.dll", "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA);
+ hook_revert("kernel32.dll", "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW);
}
}
}
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index 600eceb..0000000
--- a/src/main.c
+++ /dev/null
@@ -1,2035 +0,0 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "ddraw.h"
-#include "main.h"
-#include "opengl.h"
-#include "palette.h"
-#include "surface.h"
-#include "clipper.h"
-#include "hook.h"
-#include "mouse.h"
-#include "render_d3d9.h"
-
-#define IDR_MYMENU 93
-
-BOOL screenshot(struct IDirectDrawSurfaceImpl *);
-void Settings_Load();
-void Settings_Save(RECT *lpRect, int windowState);
-void DInput_Hook();
-void DInput_UnHook();
-
-IDirectDrawImpl *ddraw = NULL;
-
-RECT WindowRect = { .left = -32000, .top = -32000, .right = 0, .bottom = 0 };
-int WindowState = -1;
-BOOL Direct3D9Active;
-BOOL GameHandlesClose;
-BOOL ChildWindowExists;
-DWORD NvOptimusEnablement = 1;
-DWORD AmdPowerXpressRequestHighPerformance = 1;
-HMODULE DDrawModule;
-
-//BOOL WINAPI DllMainCRTStartup(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
-BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
-{
- switch (dwReason)
- {
- case DLL_PROCESS_ATTACH:
- {
- DDrawModule = hDll;
-
- char buf[1024];
- if (GetEnvironmentVariable("__COMPAT_LAYER", buf, sizeof(buf)))
- {
- char *s = strtok(buf, " ");
- while (s)
- {
- if (strcmpi(s, "WIN95") == 0 || strcmpi(s, "WIN98") == 0 || strcmpi(s, "NT4SP5") == 0)
- {
- char mes[128] = { 0 };
-
- _snprintf(
- mes,
- sizeof(mes),
- "Please disable the '%s' compatibility mode for all game executables and "
- "then try to start the game again.",
- s);
-
- MessageBoxA(NULL, mes, "Compatibility modes detected - cnc-ddraw", MB_OK);
-
- //return FALSE;
- break;
- }
-
- s = strtok(NULL, " ");
- }
- }
-
- printf("cnc-ddraw DLL_PROCESS_ATTACH\n");
-
- //SetProcessPriorityBoost(GetCurrentProcess(), TRUE);
-
- BOOL setDpiAware = FALSE;
- HMODULE hShcore = GetModuleHandle("shcore.dll");
- typedef HRESULT (__stdcall* SetProcessDpiAwareness_)(PROCESS_DPI_AWARENESS value);
- if(hShcore)
- {
- SetProcessDpiAwareness_ setProcessDpiAwareness =
- (SetProcessDpiAwareness_)GetProcAddress(hShcore, "SetProcessDpiAwareness");
-
- if (setProcessDpiAwareness)
- {
- HRESULT result = setProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
- setDpiAware = result == S_OK || result == E_ACCESSDENIED;
- }
- }
- if (!setDpiAware)
- {
- HMODULE hUser32 = GetModuleHandle("user32.dll");
- typedef BOOL (__stdcall* SetProcessDPIAware_)();
- if(hUser32)
- {
- SetProcessDPIAware_ setProcessDPIAware =
- (SetProcessDPIAware_)GetProcAddress(hUser32, "SetProcessDPIAware");
-
- if (setProcessDPIAware)
- setProcessDPIAware();
- }
- }
-
- timeBeginPeriod(1);
- DInput_Hook();
- break;
- }
- case DLL_PROCESS_DETACH:
- {
- printf("cnc-ddraw DLL_PROCESS_DETACH\n");
-
- Settings_Save(&WindowRect, WindowState);
-
- timeEndPeriod(1);
- Hook_Exit();
- DInput_UnHook();
- break;
- }
- }
-
- return TRUE;
-}
-
-BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
-{
- IDirectDrawSurfaceImpl *this = (IDirectDrawSurfaceImpl *)lParam;
-
- RECT size;
- RECT pos;
-
- if (real_GetClientRect(hWnd, &size) && real_GetWindowRect(hWnd, &pos) && size.right > 1 && size.bottom > 1)
- {
- ChildWindowExists = TRUE;
-
- HDC hDC = GetDC(hWnd);
-
- MapWindowPoints(HWND_DESKTOP, ddraw->hWnd, (LPPOINT)&pos, 2);
-
- BitBlt(hDC, 0, 0, size.right, size.bottom, this->hDC, pos.left, pos.top, SRCCOPY);
-
- ReleaseDC(hWnd, hDC);
- }
-
- return FALSE;
-}
-
-static unsigned char getPixel(int x, int y)
-{
- return ((unsigned char *)ddraw->primary->surface)[y*ddraw->primary->lPitch + x*ddraw->primary->lXPitch];
-}
-
-int* InMovie = (int*)0x00665F58;
-int* IsVQA640 = (int*)0x0065D7BC;
-BYTE* ShouldStretch = (BYTE*)0x00607D78;
-
-BOOL detect_cutscene()
-{
- if (ddraw->width <= CUTSCENE_WIDTH || ddraw->height <= CUTSCENE_HEIGHT)
- return FALSE;
-
- if (ddraw->isredalert)
- {
- if ((*InMovie && !*IsVQA640) || *ShouldStretch)
- {
- return TRUE;
- }
- return FALSE;
- }
- else if (ddraw->iscnc1)
- {
- return getPixel(CUTSCENE_WIDTH + 1, 0) == 0 || getPixel(CUTSCENE_WIDTH + 5, 1) == 0 ? TRUE : FALSE;
- }
-
- return FALSE;
-}
-
-void LimitGameTicks()
-{
- if (ddraw->ticksLimiter.hTimer)
- {
- FILETIME ft = { 0 };
- GetSystemTimeAsFileTime(&ft);
-
- if (CompareFileTime((FILETIME *)&ddraw->ticksLimiter.dueTime, &ft) == -1)
- {
- memcpy(&ddraw->ticksLimiter.dueTime, &ft, sizeof(LARGE_INTEGER));
- }
- else
- {
- WaitForSingleObject(ddraw->ticksLimiter.hTimer, ddraw->ticksLimiter.ticklength * 2);
- }
-
- ddraw->ticksLimiter.dueTime.QuadPart += ddraw->ticksLimiter.tickLengthNs;
- SetWaitableTimer(ddraw->ticksLimiter.hTimer, &ddraw->ticksLimiter.dueTime, 0, NULL, NULL, FALSE);
- }
- else
- {
- static DWORD nextGameTick;
- if (!nextGameTick)
- {
- nextGameTick = timeGetTime();
- return;
- }
- nextGameTick += ddraw->ticksLimiter.ticklength;
- DWORD tickCount = timeGetTime();
-
- int sleepTime = nextGameTick - tickCount;
- if (sleepTime <= 0 || sleepTime > ddraw->ticksLimiter.ticklength)
- nextGameTick = tickCount;
- else
- Sleep(sleepTime);
- }
-}
-
-void UpdateBnetPos(int newX, int newY)
-{
- static int oldX = -32000;
- static int oldY = -32000;
-
- if (oldX == -32000 || oldY == -32000 || !ddraw->bnetActive)
- {
- oldX = newX;
- oldY = newY;
- return;
- }
-
- POINT pt = { 0, 0 };
- real_ClientToScreen(ddraw->hWnd, &pt);
-
- RECT mainrc;
- SetRect(&mainrc, pt.x, pt.y, pt.x + ddraw->width, pt.y + ddraw->height);
-
- int adjY = 0;
- int adjX = 0;
-
- HWND hWnd = FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL);
-
- while (hWnd != NULL)
- {
- RECT rc;
- real_GetWindowRect(hWnd, &rc);
-
- OffsetRect(&rc, newX - oldX, newY - oldY);
-
- real_SetWindowPos(
- hWnd,
- 0,
- rc.left,
- rc.top,
- 0,
- 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
-
- if (rc.bottom - rc.top <= ddraw->height)
- {
- if (rc.bottom > mainrc.bottom && abs(mainrc.bottom - rc.bottom) > abs(adjY))
- adjY = mainrc.bottom - rc.bottom;
- else if (rc.top < mainrc.top && abs(mainrc.top - rc.top) > abs(adjY))
- adjY = mainrc.top - rc.top;
- }
-
- if (rc.right - rc.left <= ddraw->width)
- {
- if (rc.right > mainrc.right && abs(mainrc.right - rc.right) > abs(adjX))
- adjX = mainrc.right - rc.right;
- else if (rc.left < mainrc.left && abs(mainrc.left - rc.left) > abs(adjX))
- adjX = mainrc.left - rc.left;
- }
-
- hWnd = FindWindowEx(HWND_DESKTOP, hWnd, "SDlgDialog", NULL);
- }
-
- if (adjX || adjY)
- {
- HWND hWnd = FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL);
-
- while (hWnd != NULL)
- {
- RECT rc;
- real_GetWindowRect(hWnd, &rc);
-
- OffsetRect(&rc, adjX, adjY);
-
- real_SetWindowPos(
- hWnd,
- 0,
- rc.left,
- rc.top,
- 0,
- 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
-
- hWnd = FindWindowEx(HWND_DESKTOP, hWnd, "SDlgDialog", NULL);
- }
- }
-
- oldX = newX;
- oldY = newY;
-}
-
-HRESULT __stdcall ddraw_Compact(IDirectDrawImpl *This)
-{
- printf("??? DirectDraw::Compact(This=%p)\n", This);
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_DuplicateSurface(IDirectDrawImpl *This, LPDIRECTDRAWSURFACE src, LPDIRECTDRAWSURFACE *dest)
-{
- printf("??? DirectDraw::DuplicateSurface(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_EnumDisplayModes(IDirectDrawImpl *This, DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback)
-{
- DWORD i = 0;
- DDSURFACEDESC s;
-
- printf("DirectDraw::EnumDisplayModes(This=%p, dwFlags=%08X, lpDDSurfaceDesc=%p, lpContext=%p, lpEnumModesCallback=%p)\n", This, (unsigned int)dwFlags, lpDDSurfaceDesc, lpContext, lpEnumModesCallback);
-
- if (lpDDSurfaceDesc != NULL)
- {
- //return DDERR_UNSUPPORTED;
- }
-
- // Some games crash when you feed them with too many resolutions...
-
- if (This->bpp)
- {
- printf(" This->bpp=%d\n", This->bpp);
-
- //set up some filters to keep the list short
- DWORD refreshRate = 0;
- DWORD bpp = 0;
- DWORD flags = 99998;
- DWORD fixedOutput = 99998;
- DEVMODE m;
- memset(&m, 0, sizeof(DEVMODE));
- m.dmSize = sizeof(DEVMODE);
-
- while (EnumDisplaySettings(NULL, i, &m))
- {
- if (refreshRate != 60 && m.dmDisplayFrequency >= 50)
- refreshRate = m.dmDisplayFrequency;
-
- if (bpp != 32 && m.dmBitsPerPel >= 16)
- bpp = m.dmBitsPerPel;
-
- if (flags != 0)
- flags = m.dmDisplayFlags;
-
- if (fixedOutput != DMDFO_DEFAULT)
- fixedOutput = m.dmDisplayFixedOutput;
-
- memset(&m, 0, sizeof(DEVMODE));
- m.dmSize = sizeof(DEVMODE);
- i++;
- }
-
- memset(&m, 0, sizeof(DEVMODE));
- m.dmSize = sizeof(DEVMODE);
- i = 0;
- while (EnumDisplaySettings(NULL, i, &m))
- {
- if (refreshRate == m.dmDisplayFrequency &&
- bpp == m.dmBitsPerPel &&
- flags == m.dmDisplayFlags &&
- fixedOutput == m.dmDisplayFixedOutput)
- {
-#if _DEBUG_X
- printf(" %d: %dx%d@%d %d bpp\n", (int)i, (int)m.dmPelsWidth, (int)m.dmPelsHeight, (int)m.dmDisplayFrequency, (int)m.dmBitsPerPel);
-#endif
- memset(&s, 0, sizeof(DDSURFACEDESC));
- s.dwSize = sizeof(DDSURFACEDESC);
- s.dwFlags = DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_PIXELFORMAT;
- s.dwHeight = m.dmPelsHeight;
- s.dwWidth = m.dmPelsWidth;
- s.dwRefreshRate = 60;
- s.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
-
- s.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
- s.ddpfPixelFormat.dwRGBBitCount = 8;
-
- if (This->bpp == 16)
- {
- s.ddpfPixelFormat.dwFlags = DDPF_RGB;
- s.ddpfPixelFormat.dwRGBBitCount = 16;
- s.ddpfPixelFormat.dwRBitMask = 0xF800;
- s.ddpfPixelFormat.dwGBitMask = 0x07E0;
- s.ddpfPixelFormat.dwBBitMask = 0x001F;
- }
-
- if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
- {
- printf(" DDENUMRET_CANCEL returned, stopping\n");
- break;
- }
- }
- memset(&m, 0, sizeof(DEVMODE));
- m.dmSize = sizeof(DEVMODE);
- i++;
- }
- }
- else
- {
- SIZE resolutions[] =
- {
- { 320, 200 },
- { 320, 240 },
- { 640, 400 },
- { 640, 480 },
- { 800, 600 },
- { 1024, 768 },
- { 1280, 1024 },
- { 1280, 720 },
- { 1920, 1080 },
- };
-
- for (i = 0; i < sizeof(resolutions) / sizeof(resolutions[0]); i++)
- {
- memset(&s, 0, sizeof(DDSURFACEDESC));
- s.dwSize = sizeof(DDSURFACEDESC);
- s.dwFlags = DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_PIXELFORMAT;
- s.dwHeight = resolutions[i].cy;
- s.dwWidth = resolutions[i].cx;
- s.dwRefreshRate = 60;
- s.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
- s.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
- s.ddpfPixelFormat.dwRGBBitCount = 8;
-
- if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
- {
- printf(" DDENUMRET_CANCEL returned, stopping\n");
- break;
- }
-
- s.ddpfPixelFormat.dwFlags = DDPF_RGB;
- s.ddpfPixelFormat.dwRGBBitCount = 16;
- s.ddpfPixelFormat.dwRBitMask = 0xF800;
- s.ddpfPixelFormat.dwGBitMask = 0x07E0;
- s.ddpfPixelFormat.dwBBitMask = 0x001F;
-
- if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
- {
- printf(" DDENUMRET_CANCEL returned, stopping\n");
- break;
- }
- }
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_EnumSurfaces(IDirectDrawImpl *This, DWORD a, LPDDSURFACEDESC b, LPVOID c, LPDDENUMSURFACESCALLBACK d)
-{
- printf("??? DirectDraw::EnumSurfaces(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_FlipToGDISurface(IDirectDrawImpl *This)
-{
- printf("??? DirectDraw::FlipToGDISurface(This=%p)\n", This);
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_GetCaps(IDirectDrawImpl *This, LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDEmulCaps)
-{
- printf("DirectDraw::GetCaps(This=%p, lpDDDriverCaps=%p, lpDDEmulCaps=%p)\n", This, lpDDDriverCaps, lpDDEmulCaps);
-
- if(lpDDDriverCaps)
- {
- lpDDDriverCaps->dwSize = sizeof(DDCAPS);
- lpDDDriverCaps->dwCaps = DDCAPS_BLT | DDCAPS_PALETTE | DDCAPS_BLTCOLORFILL | DDCAPS_BLTSTRETCH | DDCAPS_CANCLIP;
- lpDDDriverCaps->dwCKeyCaps = 0;
- lpDDDriverCaps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE;
- lpDDDriverCaps->dwVidMemTotal = 16777216;
- lpDDDriverCaps->dwVidMemFree = 16777216;
- lpDDDriverCaps->dwMaxVisibleOverlays = 0;
- lpDDDriverCaps->dwCurrVisibleOverlays = 0;
- lpDDDriverCaps->dwNumFourCCCodes = 0;
- lpDDDriverCaps->dwAlignBoundarySrc = 0;
- lpDDDriverCaps->dwAlignSizeSrc = 0;
- lpDDDriverCaps->dwAlignBoundaryDest = 0;
- lpDDDriverCaps->dwAlignSizeDest = 0;
- lpDDDriverCaps->ddsCaps.dwCaps = DDSCAPS_FLIP;
- }
-
- if(lpDDEmulCaps)
- {
- lpDDEmulCaps->dwSize = 0;
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_GetDisplayMode(IDirectDrawImpl *This, LPDDSURFACEDESC a)
-{
- printf("??? DirectDraw::GetDisplayMode(This=%p, ...)\n", This);
- return DDERR_UNSUPPORTEDMODE;
-}
-
-HRESULT __stdcall ddraw_GetFourCCCodes(IDirectDrawImpl *This, LPDWORD a, LPDWORD b)
-{
- printf("??? DirectDraw::GetFourCCCodes(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_GetGDISurface(IDirectDrawImpl *This, LPDIRECTDRAWSURFACE *a)
-{
- printf("??? DirectDraw::GetGDISurface(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_GetMonitorFrequency(IDirectDrawImpl *This, LPDWORD a)
-{
- printf("??? DirectDraw::GetMonitorFrequency(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_GetScanLine(IDirectDrawImpl *This, LPDWORD a)
-{
- printf("??? DirectDraw::GetScanLine(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_GetVerticalBlankStatus(IDirectDrawImpl *This, LPBOOL lpbIsInVB)
-{
- printf("??? DirectDraw::GetVerticalBlankStatus(This=%p, ...)\n", This);
- *lpbIsInVB = TRUE;
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_Initialize(IDirectDrawImpl *This, GUID *a)
-{
- printf("??? DirectDraw::Initialize(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_RestoreDisplayMode(IDirectDrawImpl *This)
-{
- printf("DirectDraw::RestoreDisplayMode(This=%p)\n", This);
-
- if(!This->render.run)
- {
- return DD_OK;
- }
-
- /* only stop drawing in GL mode when minimized */
- if (This->renderer != render_soft_main)
- {
- EnterCriticalSection(&This->cs);
- This->render.run = FALSE;
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- LeaveCriticalSection(&This->cs);
-
- if (This->render.thread)
- {
- WaitForSingleObject(This->render.thread, INFINITE);
- This->render.thread = NULL;
- }
-
- if (This->renderer == render_d3d9_main)
- Direct3D9_Release();
- }
-
- if(!ddraw->windowed)
- {
- if (!Direct3D9Active)
- ChangeDisplaySettings(NULL, 0);
- }
-
- return DD_OK;
-}
-
-BOOL GetLowestResolution(float ratio, SIZE *outRes, DWORD minWidth, DWORD minHeight, DWORD maxWidth, DWORD maxHeight)
-{
- BOOL result = FALSE;
- int orgRatio = (int)(ratio * 100);
- SIZE lowest = { .cx = maxWidth + 1, .cy = maxHeight + 1 };
- DWORD i = 0;
- DEVMODE m;
- memset(&m, 0, sizeof(DEVMODE));
- m.dmSize = sizeof(DEVMODE);
-
- while (EnumDisplaySettings(NULL, i, &m))
- {
- if (m.dmPelsWidth >= minWidth &&
- m.dmPelsHeight >= minHeight &&
- m.dmPelsWidth <= maxWidth &&
- m.dmPelsHeight <= maxHeight &&
- m.dmPelsWidth < lowest.cx &&
- m.dmPelsHeight < lowest.cy)
- {
- int resRatio = (int)(((float)m.dmPelsWidth / m.dmPelsHeight) * 100);
-
- if (resRatio == orgRatio)
- {
- result = TRUE;
- outRes->cx = lowest.cx = m.dmPelsWidth;
- outRes->cy = lowest.cy = m.dmPelsHeight;
- }
- }
- memset(&m, 0, sizeof(DEVMODE));
- m.dmSize = sizeof(DEVMODE);
- i++;
- }
-
- return result;
-}
-
-void InitDirect3D9()
-{
- Direct3D9Active = Direct3D9_Create();
- if (!Direct3D9Active)
- {
- Direct3D9_Release();
- ShowDriverWarning = TRUE;
- ddraw->renderer = render_soft_main;
- }
-}
-
-// LastSetWindowPosTick = Workaround for a wine+gnome bug where each SetWindowPos call triggers a WA_INACTIVE message
-DWORD LastSetWindowPosTick;
-
-HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD height, DWORD bpp)
-{
- printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
-
- if (bpp != 8 && bpp != 16)
- return DDERR_INVALIDMODE;
-
- if (This->render.thread)
- {
- EnterCriticalSection(&This->cs);
- This->render.run = FALSE;
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- LeaveCriticalSection(&This->cs);
-
- WaitForSingleObject(This->render.thread, INFINITE);
- This->render.thread = NULL;
- }
-
- if (!This->mode.dmPelsWidth)
- {
- This->mode.dmSize = sizeof(DEVMODE);
- This->mode.dmDriverExtra = 0;
-
- if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &This->mode) == FALSE)
- {
- This->mode.dmSize = sizeof(DEVMODE);
- This->mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
- This->mode.dmPelsWidth = real_GetSystemMetrics(SM_CXSCREEN);
- This->mode.dmPelsHeight = real_GetSystemMetrics(SM_CYSCREEN);
- This->mode.dmDisplayFrequency = 60;
- This->mode.dmBitsPerPel = 32;
-
- if (!This->mode.dmPelsWidth || !This->mode.dmPelsHeight)
- {
- This->fullscreen = FALSE;
- }
- }
-
- const HANDLE hbicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, real_GetSystemMetrics(SM_CXICON), real_GetSystemMetrics(SM_CYICON), 0);
- if (hbicon)
- real_SendMessageA(This->hWnd, WM_SETICON, ICON_BIG, (LPARAM)hbicon);
-
- const HANDLE hsicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, real_GetSystemMetrics(SM_CXSMICON), real_GetSystemMetrics(SM_CYSMICON), 0);
- if (hsicon)
- real_SendMessageA(This->hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hsicon);
- }
-
- if (ddraw->altenter)
- {
- ddraw->altenter = FALSE;
-
- memset(&This->render.mode, 0, sizeof(DEVMODE));
- This->render.mode.dmSize = sizeof(DEVMODE);
- This->render.mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
- This->render.mode.dmPelsWidth = This->render.width;
- This->render.mode.dmPelsHeight = This->render.height;
- if (This->render.bpp)
- {
- This->render.mode.dmFields |= DM_BITSPERPEL;
- This->render.mode.dmBitsPerPel = This->render.bpp;
- }
-
- if (ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
- {
- This->render.width = ddraw->width;
- This->render.height = ddraw->height;
- }
- }
- else
- {
- This->render.width = WindowRect.right;
- This->render.height = WindowRect.bottom;
- }
-
- //temporary fix: center window for games that keep changing their resolution
- if (This->width &&
- (This->width != width || This->height != height) &&
- (width > WindowRect.right || height > WindowRect.bottom))
- {
- WindowRect.left = -32000;
- WindowRect.top = -32000;
- }
-
- This->width = width;
- This->height = height;
- This->bpp = bpp;
-
- ddraw->cursor.x = width / 2;
- ddraw->cursor.y = height / 2;
-
- BOOL border = This->border;
-
- if(This->fullscreen)
- {
- This->render.width = This->mode.dmPelsWidth;
- This->render.height = This->mode.dmPelsHeight;
-
- if (This->windowed) //windowed-fullscreen aka borderless
- {
- border = FALSE;
- WindowRect.left = -32000;
- WindowRect.top = -32000;
-
- // prevent OpenGL from going automatically into fullscreen exclusive mode
- if (This->renderer == render_main)
- This->render.height++;
-
- }
- }
-
- if(This->render.width < This->width)
- {
- This->render.width = This->width;
- }
- if(This->render.height < This->height)
- {
- This->render.height = This->height;
- }
-
- This->render.run = TRUE;
-
- BOOL lockMouse = ddraw->locked || This->fullscreen;
- mouse_unlock();
-
- memset(&This->render.mode, 0, sizeof(DEVMODE));
- This->render.mode.dmSize = sizeof(DEVMODE);
- This->render.mode.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT;
- This->render.mode.dmPelsWidth = This->render.width;
- This->render.mode.dmPelsHeight = This->render.height;
- if(This->render.bpp)
- {
- This->render.mode.dmFields |= DM_BITSPERPEL;
- This->render.mode.dmBitsPerPel = This->render.bpp;
- }
-
- BOOL maintas = ddraw->maintas;
-
- if (!This->windowed)
- {
- // Making sure the chosen resolution is valid
- int oldWidth = This->render.width;
- int oldHeight = This->render.height;
-
- if (ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
- {
- // fail... compare resolutions
- if (This->render.width > This->mode.dmPelsWidth || This->render.height > This->mode.dmPelsHeight)
- {
- // chosen game resolution higher than current resolution, use windowed mode for this case
- This->windowed = TRUE;
- }
- else
- {
- // Try 2x scaling
- This->render.width *= 2;
- This->render.height *= 2;
-
- This->render.mode.dmPelsWidth = This->render.width;
- This->render.mode.dmPelsHeight = This->render.height;
-
- if ((This->render.width > This->mode.dmPelsWidth || This->render.height > This->mode.dmPelsHeight) ||
- ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
- {
- SIZE res = {0};
-
- //try to get a resolution with the same aspect ratio as the requested resolution
- BOOL foundRes = GetLowestResolution(
- (float)oldWidth / oldHeight,
- &res,
- oldWidth + 1, //don't return the original resolution since we tested that one already
- oldHeight + 1,
- This->mode.dmPelsWidth,
- This->mode.dmPelsHeight);
-
- if (!foundRes)
- {
- //try to get a resolution with the same aspect ratio as the current display mode
- foundRes = GetLowestResolution(
- (float)This->mode.dmPelsWidth / This->mode.dmPelsHeight,
- &res,
- oldWidth,
- oldHeight,
- This->mode.dmPelsWidth,
- This->mode.dmPelsHeight);
-
- if (foundRes)
- maintas = TRUE;
- }
-
- This->render.width = res.cx;
- This->render.height = res.cy;
-
- This->render.mode.dmPelsWidth = This->render.width;
- This->render.mode.dmPelsHeight = This->render.height;
-
- if (!foundRes || ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
- {
- // try current display settings
- This->render.width = This->mode.dmPelsWidth;
- This->render.height = This->mode.dmPelsHeight;
-
- This->render.mode.dmPelsWidth = This->render.width;
- This->render.mode.dmPelsHeight = This->render.height;
-
- if (ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
- {
- // everything failed, use windowed mode instead
- This->render.width = oldWidth;
- This->render.height = oldHeight;
-
- This->render.mode.dmPelsWidth = This->render.width;
- This->render.mode.dmPelsHeight = This->render.height;
-
- This->windowed = TRUE;
- }
- else
- maintas = TRUE;
- }
- }
- }
- }
- }
-
- if (ddraw->nonexclusive && !ddraw->windowed && ddraw->renderer == render_main)
- This->render.height++;
-
- if (!ddraw->handlemouse)
- This->boxing = maintas = FALSE;
-
- This->render.viewport.width = This->render.width;
- This->render.viewport.height = This->render.height;
- This->render.viewport.x = 0;
- This->render.viewport.y = 0;
-
- if (This->boxing)
- {
- This->render.viewport.width = This->width;
- This->render.viewport.height = This->height;
-
- int i;
- for (i = 20; i-- > 1;)
- {
- if (This->width * i <= This->render.width && This->height * i <= This->render.height)
- {
- This->render.viewport.width *= i;
- This->render.viewport.height *= i;
- break;
- }
- }
-
- This->render.viewport.y = This->render.height / 2 - This->render.viewport.height / 2;
- This->render.viewport.x = This->render.width / 2 - This->render.viewport.width / 2;
- }
- else if (maintas)
- {
- This->render.viewport.width = This->render.width;
- This->render.viewport.height = ((float)This->height / This->width) * This->render.viewport.width;
-
- if (This->render.viewport.height > This->render.height)
- {
- This->render.viewport.width =
- ((float)This->render.viewport.width / This->render.viewport.height) * This->render.height;
-
- This->render.viewport.height = This->render.height;
- }
-
- This->render.viewport.y = This->render.height / 2 - This->render.viewport.height / 2;
- This->render.viewport.x = This->render.width / 2 - This->render.viewport.width / 2;
- }
-
- This->render.scaleW = ((float)This->render.viewport.width / This->width);
- This->render.scaleH = ((float)This->render.viewport.height / This->height);
- This->render.unScaleW = ((float)This->width / This->render.viewport.width);
- This->render.unScaleH = ((float)This->height / This->render.viewport.height);
-
- if (This->windowed)
- {
- MSG msg; // workaround for "Not Responding" window problem in cnc games
- PeekMessage(&msg, ddraw->hWnd, 0, 0, PM_NOREMOVE);
-
- if (!border)
- {
- real_SetWindowLongA(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
- }
- else
- {
- real_SetWindowLongA(This->hWnd, GWL_STYLE, (GetWindowLong(This->hWnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW) & ~WS_MAXIMIZEBOX);
- }
-
- if (ddraw->wine)
- real_SetWindowLongA(This->hWnd, GWL_STYLE, (GetWindowLong(This->hWnd, GWL_STYLE) | WS_MINIMIZEBOX) & ~(WS_MAXIMIZEBOX | WS_THICKFRAME));
-
- /* center the window with correct dimensions */
- int cy = This->mode.dmPelsWidth ? This->mode.dmPelsWidth : This->render.width;
- int cx = This->mode.dmPelsHeight ? This->mode.dmPelsHeight : This->render.height;
- int x = (WindowRect.left != -32000) ? WindowRect.left : (cy / 2) - (This->render.width / 2);
- int y = (WindowRect.top != -32000) ? WindowRect.top : (cx / 2) - (This->render.height / 2);
- RECT dst = { x, y, This->render.width + x, This->render.height + y };
- AdjustWindowRect(&dst, GetWindowLong(This->hWnd, GWL_STYLE), FALSE);
- real_SetWindowPos(ddraw->hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- real_MoveWindow(This->hWnd, dst.left, dst.top, (dst.right - dst.left), (dst.bottom - dst.top), TRUE);
-
- if (This->renderer == render_d3d9_main)
- InitDirect3D9();
-
- if (lockMouse)
- mouse_lock();
- }
- else
- {
- LONG style = GetWindowLong(This->hWnd, GWL_STYLE);
-
- if ((style & WS_CAPTION))
- {
- real_SetWindowLongA(This->hWnd, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
- }
-
- if (This->renderer == render_d3d9_main)
- InitDirect3D9();
-
- if (!Direct3D9Active && ChangeDisplaySettings(&This->render.mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
- {
- This->render.run = FALSE;
- This->windowed = TRUE;
- return ddraw_SetDisplayMode(This, width, height, bpp);
- }
-
- if (ddraw->wine)
- real_SetWindowLongA(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) | WS_MINIMIZEBOX);
-
- real_SetWindowPos(This->hWnd, HWND_TOPMOST, 0, 0, This->render.width, This->render.height, SWP_SHOWWINDOW);
- LastSetWindowPosTick = timeGetTime();
-
- mouse_lock();
- }
-
- if(This->render.viewport.x != 0 || This->render.viewport.y != 0)
- {
- RedrawWindow(This->hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
- }
-
- if(This->render.thread == NULL)
- {
- InterlockedExchange(&ddraw->render.paletteUpdated, TRUE);
- InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
-
- This->render.thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)This->renderer, NULL, 0, NULL);
- }
-
- if (ddraw->sierrahack)
- {
- PostMessageA(ddraw->hWnd, WM_MOVE, 0, MAKELPARAM(-32000, -32000));
- PostMessageA(ddraw->hWnd, WM_DISPLAYCHANGE, ddraw->bpp, MAKELPARAM(ddraw->width, ddraw->height));
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_SetDisplayMode2(IDirectDrawImpl *This, DWORD width, DWORD height, DWORD bpp, DWORD refreshRate, DWORD flags)
-{
- printf("DirectDraw::SetDisplayMode2(refreshRate=%d, flags=%d)\n", (unsigned int)refreshRate, (unsigned int)flags);
-
- return ddraw_SetDisplayMode(This, width, height, bpp);
-}
-
-void ToggleFullscreen()
-{
- if (ddraw->bnetActive)
- return;
-
- if (ddraw->windowed)
- {
- mouse_unlock();
- WindowState = ddraw->windowed = FALSE;
- real_SetWindowLongA(ddraw->hWnd, GWL_STYLE, GetWindowLong(ddraw->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
- ddraw->altenter = TRUE;
- ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
- UpdateBnetPos(0, 0);
- mouse_lock();
- }
- else
- {
- mouse_unlock();
- WindowState = ddraw->windowed = TRUE;
-
- if (Direct3D9Active)
- Direct3D9_Reset();
- else
- ChangeDisplaySettings(NULL, ddraw->bnetActive ? CDS_FULLSCREEN : 0);
-
- ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
- mouse_lock();
- }
-}
-
-BOOL UnadjustWindowRectEx(LPRECT prc, DWORD dwStyle, BOOL fMenu, DWORD dwExStyle)
-{
- RECT rc;
- SetRectEmpty(&rc);
-
- BOOL fRc = AdjustWindowRectEx(&rc, dwStyle, fMenu, dwExStyle);
- if (fRc)
- {
- prc->left -= rc.left;
- prc->top -= rc.top;
- prc->right -= rc.right;
- prc->bottom -= rc.bottom;
- }
-
- return fRc;
-}
-
-void SetWindowRect(int x, int y, int width, int height, UINT flags)
-{
- if (ddraw->windowed)
- {
- if (ddraw->render.thread)
- {
- EnterCriticalSection(&ddraw->cs);
- ddraw->render.run = FALSE;
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- LeaveCriticalSection(&ddraw->cs);
-
- WaitForSingleObject(ddraw->render.thread, INFINITE);
- ddraw->render.thread = NULL;
- }
-
- if ((flags & SWP_NOMOVE) == 0)
- {
- WindowRect.left = x;
- WindowRect.top = y;
- }
-
- if ((flags & SWP_NOSIZE) == 0)
- {
- WindowRect.bottom = height;
- WindowRect.right = width;
- }
-
- ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
- }
-}
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- RECT rc = { 0, 0, ddraw->render.width, ddraw->render.height };
- static BOOL inSizeMove = FALSE;
- static int redrawCount = 0;
-
- switch(uMsg)
- {
- //case WM_NCACTIVATE:
- case WM_GETMINMAXINFO:
- case WM_MOVING:
- case WM_NCLBUTTONDOWN:
- case WM_NCLBUTTONUP:
- case WM_NCPAINT:
- {
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- }
- case WM_NCHITTEST:
- {
- LRESULT result = DefWindowProc(hWnd, uMsg, wParam, lParam);
-
- if (!ddraw->resizable)
- {
- switch (result)
- {
- case HTBOTTOM:
- case HTBOTTOMLEFT:
- case HTBOTTOMRIGHT:
- case HTLEFT:
- case HTRIGHT:
- case HTTOP:
- case HTTOPLEFT:
- case HTTOPRIGHT:
- return HTBORDER;
- }
- }
-
- return result;
- }
- case WM_SETCURSOR:
- {
- // show resize cursor on window borders
- if ((HWND)wParam == ddraw->hWnd)
- {
- WORD message = HIWORD(lParam);
-
- if (message == WM_MOUSEMOVE)
- {
- WORD htcode = LOWORD(lParam);
-
- switch (htcode)
- {
- case HTCAPTION:
- case HTMINBUTTON:
- case HTMAXBUTTON:
- case HTCLOSE:
- case HTBOTTOM:
- case HTBOTTOMLEFT:
- case HTBOTTOMRIGHT:
- case HTLEFT:
- case HTRIGHT:
- case HTTOP:
- case HTTOPLEFT:
- case HTTOPRIGHT:
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- case HTCLIENT:
- if (!ddraw->locked)
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- default:
- break;
- }
- }
- }
-
- break;
- }
- case WM_D3D9DEVICELOST:
- {
- if (Direct3D9Active && Direct3D9_OnDeviceLost())
- {
- if (!ddraw->windowed)
- mouse_lock();
- }
- return 0;
- }
- case WM_TIMER:
- {
- switch (wParam)
- {
- case IDT_TIMER_LEAVE_BNET:
- {
- KillTimer(ddraw->hWnd, IDT_TIMER_LEAVE_BNET);
-
- if (!ddraw->windowed)
- ddraw->bnetWasFullscreen = FALSE;
-
- if (!ddraw->bnetActive)
- {
- if (ddraw->bnetWasFullscreen)
- {
- int ws = WindowState;
- ToggleFullscreen();
- WindowState = ws;
- ddraw->bnetWasFullscreen = FALSE;
- }
- else if (ddraw->bnetWasUpscaled)
- {
- SetWindowRect(0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- ddraw->bnetWasUpscaled = FALSE;
- }
- }
-
- return 0;
- }
- }
- break;
- }
- case WM_WINDOWPOSCHANGED:
- {
- WINDOWPOS *pos = (WINDOWPOS *)lParam;
-
- if (ddraw->wine && !ddraw->windowed && (pos->x > 0 || pos->y > 0) && LastSetWindowPosTick + 500 < timeGetTime())
- PostMessage(ddraw->hWnd, WM_WINEFULLSCREEN, 0, 0);
-
- break;
- }
- case WM_WINEFULLSCREEN:
- {
- if (!ddraw->windowed)
- {
- LastSetWindowPosTick = timeGetTime();
- real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 1, 1, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW);
- real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW);
- }
- return 0;
- }
- case WM_ENTERSIZEMOVE:
- {
- if (ddraw->windowed)
- {
- inSizeMove = TRUE;
- }
- break;
- }
- case WM_EXITSIZEMOVE:
- {
- if (ddraw->windowed)
- {
- inSizeMove = FALSE;
-
- if (!ddraw->render.thread)
- ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
- }
- break;
- }
- case WM_SIZING:
- {
- RECT *windowrc = (RECT *)lParam;
-
- if (ddraw->windowed)
- {
- if (inSizeMove)
- {
- if (ddraw->render.thread)
- {
- EnterCriticalSection(&ddraw->cs);
- ddraw->render.run = FALSE;
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- LeaveCriticalSection(&ddraw->cs);
-
- WaitForSingleObject(ddraw->render.thread, INFINITE);
- ddraw->render.thread = NULL;
- }
-
- RECT clientrc = { 0 };
-
- // maintain aspect ratio
- if (ddraw->maintas &&
- CopyRect(&clientrc, windowrc) &&
- UnadjustWindowRectEx(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)) &&
- SetRect(&clientrc, 0, 0, clientrc.right - clientrc.left, clientrc.bottom - clientrc.top))
- {
- float scaleH = (float)ddraw->height / ddraw->width;
- float scaleW = (float)ddraw->width / ddraw->height;
-
- switch (wParam)
- {
- case WMSZ_BOTTOMLEFT:
- case WMSZ_BOTTOMRIGHT:
- case WMSZ_LEFT:
- case WMSZ_RIGHT:
- {
- windowrc->bottom += scaleH * clientrc.right - clientrc.bottom;
- break;
- }
- case WMSZ_TOP:
- case WMSZ_BOTTOM:
- {
- windowrc->right += scaleW * clientrc.bottom - clientrc.right;
- break;
- }
- case WMSZ_TOPRIGHT:
- case WMSZ_TOPLEFT:
- {
- windowrc->top -= scaleH * clientrc.right - clientrc.bottom;
- break;
- }
- }
- }
-
- //enforce minimum window size
- if (CopyRect(&clientrc, windowrc) &&
- UnadjustWindowRectEx(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)) &&
- SetRect(&clientrc, 0, 0, clientrc.right - clientrc.left, clientrc.bottom - clientrc.top))
- {
- if (clientrc.right < ddraw->width)
- {
- switch (wParam)
- {
- case WMSZ_TOPRIGHT:
- case WMSZ_BOTTOMRIGHT:
- case WMSZ_RIGHT:
- case WMSZ_BOTTOM:
- case WMSZ_TOP:
- {
- windowrc->right += ddraw->width - clientrc.right;
- break;
- }
- case WMSZ_TOPLEFT:
- case WMSZ_BOTTOMLEFT:
- case WMSZ_LEFT:
- {
- windowrc->left -= ddraw->width - clientrc.right;
- break;
- }
- }
- }
-
- if (clientrc.bottom < ddraw->height)
- {
- switch (wParam)
- {
- case WMSZ_BOTTOMLEFT:
- case WMSZ_BOTTOMRIGHT:
- case WMSZ_BOTTOM:
- case WMSZ_RIGHT:
- case WMSZ_LEFT:
- {
- windowrc->bottom += ddraw->height - clientrc.bottom;
- break;
- }
- case WMSZ_TOPLEFT:
- case WMSZ_TOPRIGHT:
- case WMSZ_TOP:
- {
- windowrc->top -= ddraw->height - clientrc.bottom;
- break;
- }
- }
- }
- }
-
- //save new window position
- if (CopyRect(&clientrc, windowrc) &&
- UnadjustWindowRectEx(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)))
- {
- WindowRect.left = clientrc.left;
- WindowRect.top = clientrc.top;
- WindowRect.right = clientrc.right - clientrc.left;
- WindowRect.bottom = clientrc.bottom - clientrc.top;
- }
-
- return TRUE;
- }
- }
- break;
- }
- case WM_SIZE:
- {
- if (ddraw->windowed)
- {
- if (wParam == SIZE_RESTORED)
- {
- if (inSizeMove && !ddraw->render.thread)
- {
- WindowRect.right = LOWORD(lParam);
- WindowRect.bottom = HIWORD(lParam);
- }
- /*
- else if (ddraw->wine)
- {
- WindowRect.right = LOWORD(lParam);
- WindowRect.bottom = HIWORD(lParam);
- if (WindowRect.right != ddraw->render.width || WindowRect.bottom != ddraw->render.height)
- ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
- }
- */
- }
- }
-
- if (!ddraw->handlemouse)
- {
- redrawCount = 2;
- RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
- }
-
- return DefWindowProc(hWnd, uMsg, wParam, lParam); /* Carmageddon fix */
- }
- case WM_MOVE:
- {
- if (ddraw->windowed)
- {
- int x = (int)(short)LOWORD(lParam);
- int y = (int)(short)HIWORD(lParam);
-
- if (x != -32000 && y != -32000)
- UpdateBnetPos(x, y);
-
- if (inSizeMove || ddraw->wine)
- {
- if (x != -32000)
- WindowRect.left = x; // -32000 = Exit/Minimize
-
- if (y != -32000)
- WindowRect.top = y;
- }
- }
-
- if (!ddraw->handlemouse)
- RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
-
- if (ddraw->sierrahack)
- {
- lParam = 0;
- break;
- }
-
- return DefWindowProc(hWnd, uMsg, wParam, lParam); /* Carmageddon fix */
- }
-
- /* C&C and RA really don't want to close down */
- case WM_SYSCOMMAND:
- if (wParam == SC_CLOSE && !GameHandlesClose)
- {
- exit(0);
- }
-
- if (wParam == SC_KEYMENU)
- return 0;
-
- if (!GameHandlesClose)
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
-
- break;
-
- //workaround for a bug where sometimes a background window steals the focus
- case WM_WINDOWPOSCHANGING:
- {
- if (ddraw->locked)
- {
- WINDOWPOS *pos = (WINDOWPOS *)lParam;
-
- if (pos->flags == SWP_NOMOVE + SWP_NOSIZE)
- {
- mouse_unlock();
-
- if (GetForegroundWindow() == ddraw->hWnd)
- mouse_lock();
- }
- }
- break;
- }
-
- case WM_MOUSELEAVE:
- mouse_unlock();
- return 0;
-
- case WM_ACTIVATE:
- if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE)
- {
- if (!ddraw->windowed)
- {
- if (!Direct3D9Active)
- {
- ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
-
- if (wParam == WA_ACTIVE)
- {
- mouse_lock();
- }
- }
- }
-
- if (!ddraw->handlemouse)
- RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
- }
- else if (wParam == WA_INACTIVE)
- {
- if (!ddraw->windowed && !ddraw->locked && ddraw->noactivateapp && !ddraw->devmode)
- return 0;
-
- mouse_unlock();
-
- if (ddraw->wine && LastSetWindowPosTick + 500 > timeGetTime())
- return 0;
-
- /* minimize our window on defocus when in fullscreen */
- if (!ddraw->windowed)
- {
- if (!Direct3D9Active)
- {
- ShowWindow(ddraw->hWnd, SW_MINIMIZE);
- ChangeDisplaySettings(NULL, ddraw->bnetActive ? CDS_FULLSCREEN : 0);
- }
- }
- }
- return 0;
-
- case WM_ACTIVATEAPP:
- /* C&C and RA stop drawing when they receive this with FALSE wParam, disable in windowed mode */
- if (ddraw->windowed || ddraw->noactivateapp)
- {
- // let it pass through once (tiberian sun)
- static BOOL oneTime;
- if (wParam && !oneTime && !ddraw->handlemouse && ddraw->noactivateapp)
- {
- oneTime = TRUE;
- break;
- }
-
- return 0;
- }
- break;
- case WM_AUTORENDERER:
- {
- mouse_unlock();
- real_SetWindowPos(ddraw->hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- mouse_lock();
- return 0;
- }
- case WM_NCLBUTTONDBLCLK:
- {
- ToggleFullscreen();
- return 0;
- }
- case WM_SYSKEYDOWN:
- {
- BOOL contextCode = (lParam & (1 << 29)) != 0;
- BOOL keyState = (lParam & (1 << 30)) != 0;
-
- if (wParam == VK_RETURN && contextCode && !keyState)
- {
- ToggleFullscreen();
- return 0;
- }
- break;
- }
- case WM_KEYDOWN:
- if(wParam == VK_CONTROL || wParam == VK_TAB)
- {
- if(GetAsyncKeyState(VK_CONTROL) & 0x8000 && GetAsyncKeyState(VK_TAB) & 0x8000)
- {
- mouse_unlock();
- return 0;
- }
- }
- if (wParam == VK_CONTROL || wParam == VK_MENU)
- {
- if ((GetAsyncKeyState(VK_RMENU) & 0x8000) && GetAsyncKeyState(VK_RCONTROL) & 0x8000)
- {
- mouse_unlock();
- return 0;
- }
- }
- break;
-
- case WM_KEYUP:
- if (wParam == VK_SNAPSHOT)
- screenshot(ddraw->primary);
-
- break;
-
-
- /* button up messages reactivate cursor lock */
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- if (!ddraw->devmode && !ddraw->locked)
- {
- int x = GET_X_LPARAM(lParam);
- int y = GET_Y_LPARAM(lParam);
-
- if (x > ddraw->render.viewport.x + ddraw->render.viewport.width ||
- x < ddraw->render.viewport.x ||
- y > ddraw->render.viewport.y + ddraw->render.viewport.height ||
- y < ddraw->render.viewport.y)
- {
- ddraw->cursor.x = ddraw->width / 2;
- ddraw->cursor.y = ddraw->height / 2;
- }
- else
- {
- ddraw->cursor.x = (x - ddraw->render.viewport.x) * ddraw->render.unScaleW;
- ddraw->cursor.y = (y - ddraw->render.viewport.y) * ddraw->render.unScaleH;
- }
-
- mouse_lock();
- return 0;
- }
- /* fall through for lParam */
-
- /* down messages are ignored if we have no cursor lock */
- case WM_XBUTTONDBLCLK:
- case WM_XBUTTONDOWN:
- case WM_XBUTTONUP:
- case WM_MOUSEWHEEL:
- case WM_MOUSEHOVER:
- case WM_LBUTTONDBLCLK:
- case WM_MBUTTONDBLCLK:
- case WM_RBUTTONDBLCLK:
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_MOUSEMOVE:
-
- if (!ddraw->devmode)
- {
- if (!ddraw->locked)
- {
- return 0;
- }
-
- if(ddraw->adjmouse)
- {
- fake_GetCursorPos(NULL); /* update our own cursor */
- lParam = MAKELPARAM(ddraw->cursor.x, ddraw->cursor.y);
- }
- }
-
- if (ddraw->devmode)
- {
- mouse_lock();
- ddraw->cursor.x = GET_X_LPARAM(lParam);
- ddraw->cursor.y = GET_Y_LPARAM(lParam);
- }
- break;
-
- case WM_PARENTNOTIFY:
- {
- if (!ddraw->handlemouse)
- {
- switch (LOWORD(wParam))
- {
- case WM_DESTROY: //Workaround for invisible menu on Load/Save/Delete in Tiberian Sun
- redrawCount = 2;
- break;
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_XBUTTONDOWN:
- {
- if (!ddraw->devmode && !ddraw->locked)
- {
- int x = GET_X_LPARAM(lParam);
- int y = GET_Y_LPARAM(lParam);
-
- ddraw->cursor.x = (x - ddraw->render.viewport.x) * ddraw->render.unScaleW;
- ddraw->cursor.y = (y - ddraw->render.viewport.y) * ddraw->render.unScaleH;
-
- ddraw->hidecursor = FALSE;
- mouse_lock();
- }
- break;
- }
- }
- }
- break;
- }
- case WM_PAINT:
- {
- if (!ddraw->handlemouse && redrawCount > 0)
- {
- redrawCount--;
- RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
- }
-
- EnterCriticalSection(&ddraw->cs);
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- LeaveCriticalSection(&ddraw->cs);
- break;
- }
- case WM_ERASEBKGND:
- {
- EnterCriticalSection(&ddraw->cs);
- FillRect(ddraw->render.hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- LeaveCriticalSection(&ddraw->cs);
- break;
- }
- }
-
- return ddraw->WndProc(hWnd, uMsg, wParam, lParam);
-}
-
-HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DWORD dwFlags)
-{
- PIXELFORMATDESCRIPTOR pfd;
-
- printf("DirectDraw::SetCooperativeLevel(This=%p, hWnd=0x%08X, dwFlags=0x%08X)\n", This, (unsigned int)hWnd, (unsigned int)dwFlags);
-
- /* Red Alert for some weird reason does this on Windows XP */
- if(hWnd == NULL)
- {
- return DD_OK;
- }
-
- if (This->hWnd == NULL)
- {
- This->hWnd = hWnd;
- }
-
- if (!This->WndProc)
- {
- Hook_Init();
-
- This->WndProc = (LRESULT(CALLBACK *)(HWND, UINT, WPARAM, LPARAM))GetWindowLong(hWnd, GWL_WNDPROC);
-
- real_SetWindowLongA(This->hWnd, GWL_WNDPROC, (LONG)WndProc);
-
- if (!This->render.hDC)
- {
- This->render.hDC = GetDC(This->hWnd);
-
- memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
- pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- pfd.nVersion = 1;
- pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | (This->renderer == render_main ? PFD_SUPPORT_OPENGL : 0);
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cColorBits = ddraw->render.bpp ? ddraw->render.bpp : ddraw->mode.dmBitsPerPel;
- pfd.iLayerType = PFD_MAIN_PLANE;
- SetPixelFormat(This->render.hDC, ChoosePixelFormat(This->render.hDC, &pfd), &pfd);
- }
-
- if (ddraw->handlemouse && ddraw->windowed)
- {
- while (real_ShowCursor(FALSE) > 0); //workaround for direct input games
- while (real_ShowCursor(TRUE) < 0);
- }
-
- real_SetCursor(LoadCursor(NULL, IDC_ARROW));
-
- GetWindowText(This->hWnd, (LPTSTR)&This->title, sizeof(This->title));
-
- ddraw->isredalert = strcmp(This->title, "Red Alert") == 0;
- ddraw->iscnc1 = strcmp(This->title, "Command & Conquer") == 0;
-
- if (This->vhack && !ddraw->isredalert && !ddraw->iscnc1)
- This->vhack = 0;
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_WaitForVerticalBlank(IDirectDrawImpl *This, DWORD dwFlags, HANDLE h)
-{
-#if _DEBUG_X
- printf("DirectDraw::WaitForVerticalBlank(This=%p, flags=%08X, handle=%p)\n", This, dwFlags, h);
-#endif
- if (!ddraw->flipLimiter.ticklength)
- return DD_OK;
-
- if (ddraw->flipLimiter.hTimer)
- {
- FILETIME lastFlipFT = { 0 };
- GetSystemTimeAsFileTime(&lastFlipFT);
-
- if (!ddraw->flipLimiter.dueTime.QuadPart)
- {
- memcpy(&ddraw->flipLimiter.dueTime, &lastFlipFT, sizeof(LARGE_INTEGER));
- }
- else
- {
- while (CompareFileTime((FILETIME*)&ddraw->flipLimiter.dueTime, &lastFlipFT) == -1)
- ddraw->flipLimiter.dueTime.QuadPart += ddraw->flipLimiter.tickLengthNs;
-
- SetWaitableTimer(ddraw->flipLimiter.hTimer, &ddraw->flipLimiter.dueTime, 0, NULL, NULL, FALSE);
- WaitForSingleObject(ddraw->flipLimiter.hTimer, ddraw->flipLimiter.ticklength * 2);
- }
- }
- else
- {
- static DWORD nextGameTick;
- if (!nextGameTick)
- {
- nextGameTick = timeGetTime();
- return DD_OK;
- }
- nextGameTick += ddraw->flipLimiter.ticklength;
- DWORD tickCount = timeGetTime();
-
- int sleepTime = nextGameTick - tickCount;
- if (sleepTime <= 0 || sleepTime > ddraw->flipLimiter.ticklength)
- nextGameTick = tickCount;
- else
- Sleep(sleepTime);
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_GetAvailableVidMem(IDirectDrawImpl *This, LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
-{
- printf("??? DirectDraw::GetAvailableVidMem(This=%p)\n", This);
-
- *lpdwTotal = 16777216;
- *lpdwFree = 16777216;
-
- return DD_OK;
-}
-
-ULONG __stdcall ddraw_AddRef(IDirectDrawImpl *This)
-{
- printf("DirectDraw::AddRef(This=%p)\n", This);
-
- This->Ref++;
-
- return This->Ref;
-}
-
-HRESULT __stdcall ddraw_QueryInterface(IDirectDrawImpl *This, REFIID riid, void **obj)
-{
- printf("DirectDraw::QueryInterface(This=%p, riid=%08X, obj=%p)\n", This, (unsigned int)riid, obj);
-
- if (riid && !IsEqualGUID(&IID_IDirectDraw, riid))
- {
- printf(" GUID = %08X\n", ((GUID *)riid)->Data1);
-
- ddraw_AddRef(This);
- *obj = This;
-
- if (!IsEqualGUID(&IID_IMediaStream, riid) && !IsEqualGUID(&IID_IAMMediaStream, riid))
- This->lpVtbl->SetDisplayMode2 = ddraw_SetDisplayMode2;
-
- return S_OK;
- }
-
- *obj = This;
-
- return DDERR_UNSUPPORTED;
-}
-
-ULONG __stdcall ddraw_Release(IDirectDrawImpl *This)
-{
- printf("DirectDraw::Release(This=%p)\n", This);
-
- This->Ref--;
-
- if(This->Ref == 0)
- {
- printf(" Released (%p)\n", This);
-
- if (This->bpp)
- Settings_Save(&WindowRect, WindowState);
-
- if(This->render.run)
- {
- EnterCriticalSection(&This->cs);
- This->render.run = FALSE;
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- LeaveCriticalSection(&This->cs);
-
- if (This->render.thread)
- {
- WaitForSingleObject(This->render.thread, INFINITE);
- This->render.thread = NULL;
- }
-
- if (This->renderer == render_d3d9_main)
- {
- Direct3D9_Release();
- }
- else if (!ddraw->windowed)
- {
- ChangeDisplaySettings(NULL, 0);
- }
- }
-
- if(This->render.hDC)
- {
- ReleaseDC(This->hWnd, This->render.hDC);
- This->render.hDC = NULL;
- }
-
- if (This->ticksLimiter.hTimer)
- {
- CancelWaitableTimer(This->ticksLimiter.hTimer);
- CloseHandle(This->ticksLimiter.hTimer);
- This->ticksLimiter.hTimer = NULL;
- }
-
- if (This->flipLimiter.hTimer)
- {
- CancelWaitableTimer(This->flipLimiter.hTimer);
- CloseHandle(This->flipLimiter.hTimer);
- This->flipLimiter.hTimer = NULL;
- }
-
- if (This->fpsLimiter.hTimer)
- {
- CancelWaitableTimer(This->fpsLimiter.hTimer);
- CloseHandle(This->fpsLimiter.hTimer);
- This->fpsLimiter.hTimer = NULL;
- }
-
- DeleteCriticalSection(&This->cs);
-
- /* restore old wndproc, subsequent ddraw creation will otherwise fail */
- real_SetWindowLongA(This->hWnd, GWL_WNDPROC, (LONG)This->WndProc);
- HeapFree(GetProcessHeap(), 0, This);
- ddraw = NULL;
- return 0;
- }
- else
- {
- // This->lpVtbl->SetDisplayMode1 = ddraw_SetDisplayMode;
- }
-
- if (This->tm2hack)
- return 0;
-
- return This->Ref;
-}
-
-struct IDirectDrawImplVtbl iface =
-{
- /* IUnknown */
- ddraw_QueryInterface,
- ddraw_AddRef,
- ddraw_Release,
- /* IDirectDrawImpl */
- ddraw_Compact,
- ddraw_CreateClipper,
- ddraw_CreatePalette,
- ddraw_CreateSurface,
- ddraw_DuplicateSurface,
- ddraw_EnumDisplayModes,
- ddraw_EnumSurfaces,
- ddraw_FlipToGDISurface,
- ddraw_GetCaps,
- ddraw_GetDisplayMode,
- ddraw_GetFourCCCodes,
- ddraw_GetGDISurface,
- ddraw_GetMonitorFrequency,
- ddraw_GetScanLine,
- ddraw_GetVerticalBlankStatus,
- ddraw_Initialize,
- ddraw_RestoreDisplayMode,
- ddraw_SetCooperativeLevel,
- ddraw_SetDisplayMode,
- ddraw_WaitForVerticalBlank,
- ddraw_GetAvailableVidMem
-};
-
-HRESULT WINAPI DirectDrawCreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, IUnknown FAR *pUnkOuter)
-{
- return ddraw_CreateClipper(NULL, dwFlags, lplpDDClipper, pUnkOuter);
-}
-
-HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACK lpCallback, LPVOID lpContext)
-{
- printf("??? DirectDrawEnumerateA(lpCallback=%p, lpContext=%p)\n", lpCallback, lpContext);
-
- if (lpCallback)
- lpCallback(NULL, "display", "(null)", lpContext);
-
- return DD_OK;
-}
-
-int stdout_open = 0;
-HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter)
-{
-#if _DEBUG
- if(!stdout_open)
- {
- freopen("cnc-ddraw.log", "w", stdout);
- setvbuf(stdout, NULL, _IOLBF, 1024);
- stdout_open = 1;
-
- HKEY hKey;
- LONG status =
- RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0L, KEY_READ, &hKey);
-
- if (status == ERROR_SUCCESS)
- {
- char name[256] = {0};
- DWORD nameSize = sizeof(name);
- RegQueryValueExA(hKey, "ProductName", NULL, NULL, (PVOID)&name, &nameSize);
-
- char build[256] = {0};
- DWORD buildSize = sizeof(build);
- RegQueryValueExA(hKey, "BuildLab", NULL, NULL, (PVOID)&build, &buildSize);
-
- printf("%s (%s)\n", name, build);
- }
- }
-#endif
-
- printf("DirectDrawCreate(lpGUID=%p, lplpDD=%p, pUnkOuter=%p)\n", lpGUID, lplpDD, pUnkOuter);
-
- if(ddraw)
- {
- /* FIXME: check the calling module before passing the call! */
- if (ddraw->DirectDrawCreate)
- return ddraw->DirectDrawCreate(lpGUID, lplpDD, pUnkOuter);
-
- return DDERR_DIRECTDRAWALREADYCREATED;
- }
-
- IDirectDrawImpl *This = (IDirectDrawImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
- This->lpVtbl = &iface;
- printf(" This = %p\n", This);
- *lplpDD = (LPDIRECTDRAW)This;
- This->Ref = 0;
- ddraw_AddRef(This);
-
- ddraw = This;
-
- if (!This->real_dll)
- This->real_dll = LoadLibrary("system32\\ddraw.dll");
-
- if(This->real_dll && !This->DirectDrawCreate)
- {
- This->DirectDrawCreate =
- (HRESULT(WINAPI *)(GUID FAR*, LPDIRECTDRAW FAR*, IUnknown FAR*))GetProcAddress(This->real_dll, "DirectDrawCreate");
-
- if (This->DirectDrawCreate == DirectDrawCreate)
- This->DirectDrawCreate = NULL;
- }
-
- InitializeCriticalSection(&This->cs);
- This->render.sem = CreateSemaphore(NULL, 0, 1, NULL);
-
- This->wine = GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0;
-
- Settings_Load();
-
- return DD_OK;
-}
diff --git a/src/mouse.c b/src/mouse.c
index 7755e12..5e45712 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -1,213 +1,78 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
-
+#define WIN32_LEAN_AND_MEAN
#include
-#include
-#include "main.h"
-#include "surface.h"
+#include "dd.h"
#include "hook.h"
-#include "render_d3d9.h"
-int yAdjust = 0;
-
-BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint)
-{
- POINT pt, realpt;
-
- if (!real_GetCursorPos(&pt) || !ddraw)
- return FALSE;
-
- realpt.x = pt.x;
- realpt.y = pt.y;
-
- if(ddraw->locked && (!ddraw->windowed || real_ScreenToClient(ddraw->hWnd, &pt)))
- {
- //fallback solution for possible ClipCursor failure
- int diffx = 0, diffy = 0;
- int maxWidth = ddraw->adjmouse ? ddraw->render.viewport.width : ddraw->width;
- int maxHeight = ddraw->adjmouse ? ddraw->render.viewport.height : ddraw->height;
-
- if (pt.x < 0)
- {
- diffx = pt.x;
- pt.x = 0;
- }
-
- if (pt.y < 0)
- {
- diffy = pt.y;
- pt.y = 0;
- }
-
- if (pt.x > maxWidth)
- {
- diffx = pt.x - maxWidth;
- pt.x = maxWidth;
- }
-
- if (pt.y > maxHeight)
- {
- diffy = pt.y - maxHeight;
- pt.y = maxHeight;
- }
-
- if (diffx || diffy)
- real_SetCursorPos(realpt.x - diffx, realpt.y - diffy);
-
-
- if(ddraw->adjmouse)
- {
- ddraw->cursor.x = pt.x * ddraw->render.unScaleW;
- ddraw->cursor.y = pt.y * ddraw->render.unScaleH;
- }
- else
- {
- ddraw->cursor.x = pt.x;
- ddraw->cursor.y = pt.y;
- }
-
- if (ddraw->vhack && InterlockedExchangeAdd(&ddraw->incutscene, 0))
- {
- diffx = 0;
- diffy = 0;
-
- if (ddraw->cursor.x > CUTSCENE_WIDTH)
- {
- diffx = ddraw->cursor.x - CUTSCENE_WIDTH;
- ddraw->cursor.x = CUTSCENE_WIDTH;
- }
-
- if (ddraw->cursor.y > CUTSCENE_HEIGHT)
- {
- diffy = ddraw->cursor.y - CUTSCENE_HEIGHT;
- ddraw->cursor.y = CUTSCENE_HEIGHT;
- }
-
- if (diffx || diffy)
- real_SetCursorPos(realpt.x - diffx, realpt.y - diffy);
- }
- }
-
- if (lpPoint)
- {
- lpPoint->x = (int)ddraw->cursor.x;
- lpPoint->y = (int)ddraw->cursor.y;
- }
-
- return TRUE;
-}
-
-BOOL WINAPI fake_ClipCursor(const RECT *lpRect)
-{
- if(lpRect)
- {
- /* hack for 640x480 mode */
- if (lpRect->bottom == 400 && ddraw->height == 480)
- yAdjust = 40;
- }
- return TRUE;
-}
-
-int WINAPI fake_ShowCursor(BOOL bShow)
-{
- static int count;
-
- if (ddraw && !ddraw->handlemouse)
- return real_ShowCursor(bShow);
-
- return bShow ? ++count : --count;
-}
-
-HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor)
-{
- if (ddraw && !ddraw->handlemouse)
- return real_SetCursor(hCursor);
-
- return NULL;
-}
void mouse_lock()
{
RECT rc;
- if (ddraw->bnetActive)
+ if (g_ddraw->bnet_active)
return;
- if (ddraw->devmode)
+ if (g_ddraw->devmode)
{
- if (ddraw->handlemouse)
+ if (g_ddraw->handlemouse)
while(real_ShowCursor(FALSE) > 0);
return;
}
- if (Hook_Active && !ddraw->locked)
+ if (g_hook_active && !g_ddraw->locked)
{
// Get the window client area.
- real_GetClientRect(ddraw->hWnd, &rc);
+ real_GetClientRect(g_ddraw->hwnd, &rc);
- if(ddraw->adjmouse)
+ if(g_ddraw->adjmouse)
{
- rc.right = ddraw->render.viewport.width;
- rc.bottom = ddraw->render.viewport.height;
+ rc.right = g_ddraw->render.viewport.width;
+ rc.bottom = g_ddraw->render.viewport.height;
}
else
{
- rc.right = ddraw->width;
- rc.bottom = ddraw->height;
+ rc.right = g_ddraw->width;
+ rc.bottom = g_ddraw->height;
}
// Convert the client area to screen coordinates.
POINT pt = { rc.left, rc.top };
POINT pt2 = { rc.right, rc.bottom };
- real_ClientToScreen(ddraw->hWnd, &pt);
- real_ClientToScreen(ddraw->hWnd, &pt2);
+ real_ClientToScreen(g_ddraw->hwnd, &pt);
+ real_ClientToScreen(g_ddraw->hwnd, &pt2);
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
- rc.bottom -= (yAdjust * 2) * ddraw->render.scaleH;
+ rc.bottom -= (g_ddraw->mouse_y_adjust * 2) * g_ddraw->render.scale_h;
- if(ddraw->adjmouse)
+ if(g_ddraw->adjmouse)
{
real_SetCursorPos(
- rc.left + (ddraw->cursor.x * ddraw->render.scaleW),
- rc.top + ((ddraw->cursor.y - yAdjust) * ddraw->render.scaleH));
+ rc.left + (g_ddraw->cursor.x * g_ddraw->render.scale_w),
+ rc.top + ((g_ddraw->cursor.y - g_ddraw->mouse_y_adjust) * g_ddraw->render.scale_h));
}
else
{
- real_SetCursorPos(rc.left + ddraw->cursor.x, rc.top + ddraw->cursor.y - yAdjust);
+ real_SetCursorPos(rc.left + g_ddraw->cursor.x, rc.top + g_ddraw->cursor.y - g_ddraw->mouse_y_adjust);
}
- if (ddraw->handlemouse)
+ if (g_ddraw->handlemouse)
{
- SetCapture(ddraw->hWnd);
+ SetCapture(g_ddraw->hwnd);
real_ClipCursor(&rc);
while (real_ShowCursor(FALSE) > 0);
}
else
{
- if (ddraw->hidecursor)
+ if (g_ddraw->hidecursor)
{
- ddraw->hidecursor = FALSE;
+ g_ddraw->hidecursor = FALSE;
real_ShowCursor(FALSE);
}
real_ClipCursor(&rc);
}
- ddraw->locked = TRUE;
+ g_ddraw->locked = TRUE;
}
}
@@ -215,34 +80,34 @@ void mouse_unlock()
{
RECT rc;
- if (ddraw->devmode)
+ if (g_ddraw->devmode)
{
- if (ddraw->handlemouse)
+ if (g_ddraw->handlemouse)
while(real_ShowCursor(TRUE) < 0);
return;
}
- if(!Hook_Active)
+ if(!g_hook_active)
{
return;
}
- if(ddraw->locked)
+ if(g_ddraw->locked)
{
- ddraw->locked = FALSE;
+ g_ddraw->locked = FALSE;
// Get the window client area.
- real_GetClientRect(ddraw->hWnd, &rc);
+ real_GetClientRect(g_ddraw->hwnd, &rc);
// Convert the client area to screen coordinates.
POINT pt = { rc.left, rc.top };
POINT pt2 = { rc.right, rc.bottom };
- real_ClientToScreen(ddraw->hWnd, &pt);
- real_ClientToScreen(ddraw->hWnd, &pt2);
+ real_ClientToScreen(g_ddraw->hwnd, &pt);
+ real_ClientToScreen(g_ddraw->hwnd, &pt2);
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
- if (ddraw->handlemouse)
+ if (g_ddraw->handlemouse)
{
while (real_ShowCursor(TRUE) < 0);
real_SetCursor(LoadCursor(NULL, IDC_ARROW));
@@ -252,7 +117,7 @@ void mouse_unlock()
CURSORINFO ci = { .cbSize = sizeof(CURSORINFO) };
if (real_GetCursorInfo(&ci) && ci.flags == 0)
{
- ddraw->hidecursor = TRUE;
+ g_ddraw->hidecursor = TRUE;
while (real_ShowCursor(TRUE) < 0);
}
}
@@ -261,308 +126,7 @@ void mouse_unlock()
ReleaseCapture();
real_SetCursorPos(
- rc.left + ddraw->render.viewport.x + (ddraw->cursor.x * ddraw->render.scaleW),
- rc.top + ddraw->render.viewport.y + ((ddraw->cursor.y + yAdjust) * ddraw->render.scaleH));
+ rc.left + g_ddraw->render.viewport.x + (g_ddraw->cursor.x * g_ddraw->render.scale_w),
+ rc.top + g_ddraw->render.viewport.y + ((g_ddraw->cursor.y + g_ddraw->mouse_y_adjust) * g_ddraw->render.scale_h));
}
}
-
-BOOL WINAPI fake_GetWindowRect(HWND hWnd, LPRECT lpRect)
-{
- if (lpRect && ddraw)
- {
- if (ddraw->hWnd == hWnd)
- {
- lpRect->bottom = ddraw->height;
- lpRect->left = 0;
- lpRect->right = ddraw->width;
- lpRect->top = 0;
-
- return TRUE;
- }
- else
- {
- if (real_GetWindowRect(hWnd, lpRect))
- {
- MapWindowPoints(HWND_DESKTOP, ddraw->hWnd, (LPPOINT)lpRect, 2);
-
- return TRUE;
- }
-
- return FALSE;
- }
- }
-
- return real_GetWindowRect(hWnd, lpRect);
-}
-
-BOOL WINAPI fake_GetClientRect(HWND hWnd, LPRECT lpRect)
-{
- if (lpRect && ddraw && ddraw->hWnd == hWnd)
- {
- lpRect->bottom = ddraw->height;
- lpRect->left = 0;
- lpRect->right = ddraw->width;
- lpRect->top = 0;
-
- return TRUE;
- }
-
- return real_GetClientRect(hWnd, lpRect);
-}
-
-BOOL WINAPI fake_ClientToScreen(HWND hWnd, LPPOINT lpPoint)
-{
- if (ddraw && ddraw->hWnd != hWnd)
- return real_ClientToScreen(hWnd, lpPoint) && real_ScreenToClient(ddraw->hWnd, lpPoint);
-
- return TRUE;
-}
-
-BOOL WINAPI fake_ScreenToClient(HWND hWnd, LPPOINT lpPoint)
-{
- if (ddraw && ddraw->hWnd != hWnd)
- return real_ClientToScreen(ddraw->hWnd, lpPoint) && real_ScreenToClient(hWnd, lpPoint);
-
- return TRUE;
-}
-
-BOOL WINAPI fake_SetCursorPos(int X, int Y)
-{
- POINT pt = { X, Y };
- return ddraw && real_ClientToScreen(ddraw->hWnd, &pt) && real_SetCursorPos(pt.x, pt.y);
-}
-
-HWND WINAPI fake_WindowFromPoint(POINT Point)
-{
- POINT pt = { Point.x, Point.y };
- return ddraw && real_ClientToScreen(ddraw->hWnd, &pt) ? real_WindowFromPoint(pt) : NULL;
-}
-
-BOOL WINAPI fake_GetClipCursor(LPRECT lpRect)
-{
- if (lpRect && ddraw)
- {
- lpRect->bottom = ddraw->height;
- lpRect->left = 0;
- lpRect->right = ddraw->width;
- lpRect->top = 0;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL WINAPI fake_GetCursorInfo(PCURSORINFO pci)
-{
- return pci && ddraw && real_GetCursorInfo(pci) && real_ScreenToClient(ddraw->hWnd, &pci->ptScreenPos);
-}
-
-int WINAPI fake_GetSystemMetrics(int nIndex)
-{
- if (ddraw)
- {
- if (nIndex == SM_CXSCREEN)
- return ddraw->width;
-
- if (nIndex == SM_CYSCREEN)
- return ddraw->height;
- }
-
- return real_GetSystemMetrics(nIndex);
-}
-
-BOOL WINAPI fake_SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
-{
- UINT reqFlags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER;
-
- if (ddraw && ddraw->hWnd == hWnd && (uFlags & reqFlags) != reqFlags)
- return TRUE;
-
- return real_SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
-}
-
-BOOL WINAPI fake_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint)
-{
- if (ddraw && ddraw->hWnd == hWnd)
- return TRUE;
-
- return real_MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
-}
-
-LRESULT WINAPI fake_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
- LRESULT result = real_SendMessageA(hWnd, Msg, wParam, lParam);
-
- if (result && ddraw && Msg == CB_GETDROPPEDCONTROLRECT)
- {
- RECT *rc = (RECT *)lParam;
- if (rc)
- MapWindowPoints(HWND_DESKTOP, ddraw->hWnd, (LPPOINT)rc, 2);
- }
-
- return result;
-}
-
-LONG WINAPI fake_SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong)
-{
- if (ddraw && ddraw->hWnd == hWnd && nIndex == GWL_STYLE)
- return 0;
-
- return real_SetWindowLongA(hWnd, nIndex, dwNewLong);
-}
-
-BOOL WINAPI fake_EnableWindow(HWND hWnd, BOOL bEnable)
-{
- if (ddraw && ddraw->hWnd == hWnd)
- {
- return FALSE;
- }
-
- return real_EnableWindow(hWnd, bEnable);
-}
-
-int WINAPI fake_GetDeviceCaps(HDC hdc, int index)
-{
- if (ddraw && ddraw->bpp && index == BITSPIXEL)
- {
- return ddraw->bpp;
- }
-
- return real_GetDeviceCaps(hdc, index);
-}
-
-HMODULE WINAPI fake_LoadLibraryA(LPCSTR lpLibFileName)
-{
- HMODULE hMod = real_LoadLibraryA(lpLibFileName);
-
- Hook_Init();
-
- return hMod;
-}
-
-HMODULE WINAPI fake_LoadLibraryW(LPCWSTR lpLibFileName)
-{
- HMODULE hMod = real_LoadLibraryW(lpLibFileName);
-
- Hook_Init();
-
- return hMod;
-}
-
-HMODULE WINAPI fake_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
-{
- HMODULE hMod = real_LoadLibraryExA(lpLibFileName, hFile, dwFlags);
-
- Hook_Init();
-
- return hMod;
-}
-
-HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
-{
- HMODULE hMod = real_LoadLibraryExW(lpLibFileName, hFile, dwFlags);
-
- Hook_Init();
-
- return hMod;
-}
-
-BOOL WINAPI fake_DestroyWindow(HWND hWnd)
-{
- BOOL result = real_DestroyWindow(hWnd);
-
- if (ddraw && ddraw->hWnd != hWnd && ddraw->bnetActive)
- {
- RedrawWindow(NULL, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
-
- if (!FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL))
- {
- ddraw->bnetActive = FALSE;
- SetFocus(ddraw->hWnd);
- mouse_lock();
-
- if (ddraw->windowed)
- {
- ddraw->bnetPos.x = ddraw->bnetPos.y = 0;
- real_ClientToScreen(ddraw->hWnd, &ddraw->bnetPos);
-
- if (!ddraw->bnetWasUpscaled)
- {
- int width = ddraw->bnetWinRect.right - ddraw->bnetWinRect.left;
- int height = ddraw->bnetWinRect.bottom - ddraw->bnetWinRect.top;
- UINT flags = width != ddraw->width || height != ddraw->height ? 0 : SWP_NOMOVE;
-
- SetWindowRect(ddraw->bnetWinRect.left, ddraw->bnetWinRect.top, width, height, flags);
- }
-
- ddraw->fullscreen = ddraw->bnetWasUpscaled;
-
- SetTimer(ddraw->hWnd, IDT_TIMER_LEAVE_BNET, 1000, (TIMERPROC)NULL);
-
- ddraw->resizable = TRUE;
- }
- }
- }
-
- return result;
-}
-
-HWND WINAPI fake_CreateWindowExA(
- DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y,
- int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
-{
- if (lpClassName && _strcmpi(lpClassName, "SDlgDialog") == 0 && ddraw)
- {
- if (!ddraw->bnetActive)
- {
- ddraw->bnetWasUpscaled = ddraw->fullscreen;
- ddraw->fullscreen = FALSE;
-
- if (!ddraw->windowed && !ddraw->bnetWasFullscreen)
- {
- int ws = WindowState;
- ToggleFullscreen();
- WindowState = ws;
- ddraw->bnetWasFullscreen = TRUE;
- }
-
- real_GetClientRect(ddraw->hWnd, &ddraw->bnetWinRect);
- MapWindowPoints(ddraw->hWnd, HWND_DESKTOP, (LPPOINT)&ddraw->bnetWinRect, 2);
-
- int width = ddraw->bnetWinRect.right - ddraw->bnetWinRect.left;
- int height = ddraw->bnetWinRect.bottom - ddraw->bnetWinRect.top;
- int x = ddraw->bnetPos.x || ddraw->bnetPos.y ? ddraw->bnetPos.x : -32000;
- int y = ddraw->bnetPos.x || ddraw->bnetPos.y ? ddraw->bnetPos.y : -32000;
- UINT flags = width != ddraw->width || height != ddraw->height ? 0 : SWP_NOMOVE;
-
- SetWindowRect(x, y, ddraw->width, ddraw->height, flags);
- ddraw->resizable = FALSE;
-
- ddraw->bnetActive = TRUE;
- mouse_unlock();
- }
-
- POINT pt = { 0, 0 };
- real_ClientToScreen(ddraw->hWnd, &pt);
-
- X += pt.x;
- Y += pt.y;
-
- dwStyle |= WS_CLIPCHILDREN;
- }
-
- return real_CreateWindowExA(
- dwExStyle,
- lpClassName,
- lpWindowName,
- dwStyle,
- X,
- Y,
- nWidth,
- nHeight,
- hWndParent,
- hMenu,
- hInstance,
- lpParam);
-}
diff --git a/src/opengl.c b/src/opengl_utils.c
similarity index 70%
rename from src/opengl.c
rename to src/opengl_utils.c
index a13332a..f09788a 100644
--- a/src/opengl.c
+++ b/src/opengl_utils.c
@@ -1,6 +1,6 @@
#include
#include
-#include "opengl.h"
+#include "opengl_utils.h"
PFNWGLCREATECONTEXTPROC xwglCreateContext;
PFNWGLDELETECONTEXTPROC xwglDeleteContext;
@@ -21,13 +21,10 @@ PFNGLGETTEXIMAGEPROC glGetTexImage;
PFNGLPIXELSTOREIPROC glPixelStorei;
PFNGLENABLEPROC glEnable;
PFNGLCLEARPROC glClear;
-
PFNGLBEGINPROC glBegin;
PFNGLENDPROC glEnd;
PFNGLTEXCOORD2FPROC glTexCoord2f;
PFNGLVERTEX2FPROC glVertex2f;
-
-// Program
PFNGLCREATEPROGRAMPROC glCreateProgram;
PFNGLDELETEPROGRAMPROC glDeleteProgram;
PFNGLUSEPROGRAMPROC glUseProgram;
@@ -59,13 +56,11 @@ PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
-
PFNGLCREATESHADERPROC glCreateShader;
PFNGLDELETESHADERPROC glDeleteShader;
PFNGLSHADERSOURCEPROC glShaderSource;
PFNGLCOMPILESHADERPROC glCompileShader;
PFNGLGETSHADERIVPROC glGetShaderiv;
-
PFNGLGENBUFFERSPROC glGenBuffers;
PFNGLBINDBUFFERPROC glBindBuffer;
PFNGLBUFFERDATAPROC glBufferData;
@@ -77,59 +72,53 @@ PFNGLDELETEBUFFERSPROC glDeleteBuffers;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
-
PFNGLACTIVETEXTUREPROC glActiveTexture;
-
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
PFNGLDRAWBUFFERSPROC glDrawBuffers;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
-
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
-
PFNGLTEXBUFFERPROC glTexBuffer;
-HMODULE OpenGL_hModule;
+HMODULE g_oglu_hmodule;
+BOOL g_oglu_got_version2;
+BOOL g_oglu_got_version3;
+char g_oglu_version[128];
-BOOL OpenGL_GotVersion2;
-BOOL OpenGL_GotVersion3;
-
-char OpenGL_Version[128];
-
-BOOL OpenGL_LoadDll()
+BOOL oglu_load_dll()
{
- if (!OpenGL_hModule)
- OpenGL_hModule = LoadLibrary("opengl32.dll");
+ if (!g_oglu_hmodule)
+ g_oglu_hmodule = LoadLibrary("opengl32.dll");
- if (OpenGL_hModule)
+ if (g_oglu_hmodule)
{
- xwglCreateContext = (PFNWGLCREATECONTEXTPROC)GetProcAddress(OpenGL_hModule, "wglCreateContext");
- xwglDeleteContext = (PFNWGLDELETECONTEXTPROC)GetProcAddress(OpenGL_hModule, "wglDeleteContext");
- xwglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress(OpenGL_hModule, "wglGetProcAddress");
- xwglMakeCurrent = (PFNWGLMAKECURRENTPROC)GetProcAddress(OpenGL_hModule, "wglMakeCurrent");
+ xwglCreateContext = (PFNWGLCREATECONTEXTPROC)GetProcAddress(g_oglu_hmodule, "wglCreateContext");
+ xwglDeleteContext = (PFNWGLDELETECONTEXTPROC)GetProcAddress(g_oglu_hmodule, "wglDeleteContext");
+ xwglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress(g_oglu_hmodule, "wglGetProcAddress");
+ xwglMakeCurrent = (PFNWGLMAKECURRENTPROC)GetProcAddress(g_oglu_hmodule, "wglMakeCurrent");
- glViewport = (PFNGLVIEWPORTPROC)GetProcAddress(OpenGL_hModule, "glViewport");
- glBindTexture = (PFNGLBINDTEXTUREPROC)GetProcAddress(OpenGL_hModule, "glBindTexture");
- glGenTextures = (PFNGLGENTEXTURESPROC)GetProcAddress(OpenGL_hModule, "glGenTextures");
- glTexParameteri = (PFNGLTEXPARAMETERIPROC)GetProcAddress(OpenGL_hModule, "glTexParameteri");
- glDeleteTextures = (PFNGLDELETETEXTURESPROC)GetProcAddress(OpenGL_hModule, "glDeleteTextures");
- glTexImage2D = (PFNGLTEXIMAGE2DPROC)GetProcAddress(OpenGL_hModule, "glTexImage2D");
- glDrawElements = (PFNGLDRAWELEMENTSPROC)GetProcAddress(OpenGL_hModule, "glDrawElements");
- glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)GetProcAddress(OpenGL_hModule, "glTexSubImage2D");
- glGetError = (PFNGLGETERRORPROC)GetProcAddress(OpenGL_hModule, "glGetError");
- glGetString = (PFNGLGETSTRINGPROC)GetProcAddress(OpenGL_hModule, "glGetString");
- glGetTexImage = (PFNGLGETTEXIMAGEPROC)GetProcAddress(OpenGL_hModule, "glGetTexImage");
- glPixelStorei = (PFNGLPIXELSTOREIPROC)GetProcAddress(OpenGL_hModule, "glPixelStorei");
- glEnable = (PFNGLENABLEPROC)GetProcAddress(OpenGL_hModule, "glEnable");
- glClear = (PFNGLCLEARPROC)GetProcAddress(OpenGL_hModule, "glClear");
+ glViewport = (PFNGLVIEWPORTPROC)GetProcAddress(g_oglu_hmodule, "glViewport");
+ glBindTexture = (PFNGLBINDTEXTUREPROC)GetProcAddress(g_oglu_hmodule, "glBindTexture");
+ glGenTextures = (PFNGLGENTEXTURESPROC)GetProcAddress(g_oglu_hmodule, "glGenTextures");
+ glTexParameteri = (PFNGLTEXPARAMETERIPROC)GetProcAddress(g_oglu_hmodule, "glTexParameteri");
+ glDeleteTextures = (PFNGLDELETETEXTURESPROC)GetProcAddress(g_oglu_hmodule, "glDeleteTextures");
+ glTexImage2D = (PFNGLTEXIMAGE2DPROC)GetProcAddress(g_oglu_hmodule, "glTexImage2D");
+ glDrawElements = (PFNGLDRAWELEMENTSPROC)GetProcAddress(g_oglu_hmodule, "glDrawElements");
+ glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)GetProcAddress(g_oglu_hmodule, "glTexSubImage2D");
+ glGetError = (PFNGLGETERRORPROC)GetProcAddress(g_oglu_hmodule, "glGetError");
+ glGetString = (PFNGLGETSTRINGPROC)GetProcAddress(g_oglu_hmodule, "glGetString");
+ glGetTexImage = (PFNGLGETTEXIMAGEPROC)GetProcAddress(g_oglu_hmodule, "glGetTexImage");
+ glPixelStorei = (PFNGLPIXELSTOREIPROC)GetProcAddress(g_oglu_hmodule, "glPixelStorei");
+ glEnable = (PFNGLENABLEPROC)GetProcAddress(g_oglu_hmodule, "glEnable");
+ glClear = (PFNGLCLEARPROC)GetProcAddress(g_oglu_hmodule, "glClear");
- glBegin = (PFNGLBEGINPROC)GetProcAddress(OpenGL_hModule, "glBegin");
- glEnd = (PFNGLENDPROC)GetProcAddress(OpenGL_hModule, "glEnd");
- glTexCoord2f = (PFNGLTEXCOORD2FPROC)GetProcAddress(OpenGL_hModule, "glTexCoord2f");
- glVertex2f = (PFNGLVERTEX2FPROC)GetProcAddress(OpenGL_hModule, "glVertex2f");
+ glBegin = (PFNGLBEGINPROC)GetProcAddress(g_oglu_hmodule, "glBegin");
+ glEnd = (PFNGLENDPROC)GetProcAddress(g_oglu_hmodule, "glEnd");
+ glTexCoord2f = (PFNGLTEXCOORD2FPROC)GetProcAddress(g_oglu_hmodule, "glTexCoord2f");
+ glVertex2f = (PFNGLVERTEX2FPROC)GetProcAddress(g_oglu_hmodule, "glVertex2f");
}
return xwglCreateContext && xwglDeleteContext && xwglGetProcAddress && xwglMakeCurrent && glViewport &&
@@ -138,7 +127,7 @@ BOOL OpenGL_LoadDll()
glEnable && glClear && glBegin && glEnd && glTexCoord2f && glVertex2f;
}
-void OpenGL_Init()
+void oglu_init()
{
// Program
glCreateProgram = (PFNGLCREATEPROGRAMPROC)xwglGetProcAddress("glCreateProgram");
@@ -170,13 +159,11 @@ void OpenGL_Init()
glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)xwglGetProcAddress("glVertexAttrib4fv");
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)xwglGetProcAddress("glEnableVertexAttribArray");
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)xwglGetProcAddress("glBindAttribLocation");
-
glCreateShader = (PFNGLCREATESHADERPROC)xwglGetProcAddress("glCreateShader");
glDeleteShader = (PFNGLDELETESHADERPROC)xwglGetProcAddress("glDeleteShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)xwglGetProcAddress("glShaderSource");
glCompileShader = (PFNGLCOMPILESHADERPROC)xwglGetProcAddress("glCompileShader");
glGetShaderiv = (PFNGLGETSHADERIVPROC)xwglGetProcAddress("glGetShaderiv");
-
glGenBuffers = (PFNGLGENBUFFERSPROC)xwglGetProcAddress("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)xwglGetProcAddress("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)xwglGetProcAddress("glBufferData");
@@ -188,9 +175,7 @@ void OpenGL_Init()
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)xwglGetProcAddress("glGenVertexArrays");
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)xwglGetProcAddress("glBindVertexArray");
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)xwglGetProcAddress("glDeleteVertexArrays");
-
glActiveTexture = (PFNGLACTIVETEXTUREPROC)xwglGetProcAddress("glActiveTexture");
-
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)xwglGetProcAddress("glGenFramebuffers");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)xwglGetProcAddress("glBindFramebuffer");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)xwglGetProcAddress("glFramebufferTexture2D");
@@ -206,23 +191,23 @@ void OpenGL_Init()
char *glversion = (char *)glGetString(GL_VERSION);
if (glversion)
{
- strncpy(OpenGL_Version, glversion, sizeof(OpenGL_Version));
+ strncpy(g_oglu_version, glversion, sizeof(g_oglu_version)-1);
const char deli[2] = " ";
- strtok(OpenGL_Version, deli);
+ strtok(g_oglu_version, deli);
}
else
- OpenGL_Version[0] = '0';
+ g_oglu_version[0] = '0';
- OpenGL_GotVersion2 = glGetUniformLocation && glActiveTexture && glUniform1i;
+ g_oglu_got_version2 = glGetUniformLocation && glActiveTexture && glUniform1i;
- OpenGL_GotVersion3 = glGenFramebuffers && glBindFramebuffer && glFramebufferTexture2D && glDrawBuffers &&
+ g_oglu_got_version3 = glGenFramebuffers && glBindFramebuffer && glFramebufferTexture2D && glDrawBuffers &&
glCheckFramebufferStatus && glUniform4f && glActiveTexture && glUniform1i &&
glGetAttribLocation && glGenBuffers && glBindBuffer && glBufferData && glVertexAttribPointer &&
glEnableVertexAttribArray && glUniform2fv && glUniformMatrix4fv && glGenVertexArrays && glBindVertexArray &&
glGetUniformLocation && glversion && glversion[0] != '2';
}
-BOOL OpenGL_ExtExists(char *ext, HDC hdc)
+BOOL oglu_ext_exists(char *ext, HDC hdc)
{
char *glext = (char *)glGetString(GL_EXTENSIONS);
if (glext)
@@ -244,46 +229,46 @@ BOOL OpenGL_ExtExists(char *ext, HDC hdc)
return FALSE;
}
-GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource)
+GLuint oglu_build_program(const GLchar *vertSource, const GLchar *fragSource)
{
if (!glCreateShader || !glShaderSource || !glCompileShader || !glCreateProgram ||
!glAttachShader || !glLinkProgram || !glUseProgram || !glDetachShader)
return 0;
- GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
- GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
+ GLuint vert_shader = glCreateShader(GL_VERTEX_SHADER);
+ GLuint frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
- if (!vertShader || !fragShader)
+ if (!vert_shader || !frag_shader)
return 0;
- glShaderSource(vertShader, 1, &vertSource, NULL);
- glShaderSource(fragShader, 1, &fragSource, NULL);
+ glShaderSource(vert_shader, 1, &vertSource, NULL);
+ glShaderSource(frag_shader, 1, &fragSource, NULL);
- GLint isCompiled = 0;
+ GLint is_compiled = 0;
- glCompileShader(vertShader);
+ glCompileShader(vert_shader);
if (glGetShaderiv)
{
- glGetShaderiv(vertShader, GL_COMPILE_STATUS, &isCompiled);
- if (isCompiled == GL_FALSE)
+ glGetShaderiv(vert_shader, GL_COMPILE_STATUS, &is_compiled);
+ if (is_compiled == GL_FALSE)
{
if (glDeleteShader)
- glDeleteShader(vertShader);
+ glDeleteShader(vert_shader);
return 0;
}
}
- glCompileShader(fragShader);
+ glCompileShader(frag_shader);
if (glGetShaderiv)
{
- glGetShaderiv(fragShader, GL_COMPILE_STATUS, &isCompiled);
- if (isCompiled == GL_FALSE)
+ glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &is_compiled);
+ if (is_compiled == GL_FALSE)
{
if (glDeleteShader)
{
- glDeleteShader(fragShader);
- glDeleteShader(vertShader);
+ glDeleteShader(frag_shader);
+ glDeleteShader(vert_shader);
}
return 0;
@@ -293,21 +278,21 @@ GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource)
GLuint program = glCreateProgram();
if (program)
{
- glAttachShader(program, vertShader);
- glAttachShader(program, fragShader);
+ glAttachShader(program, vert_shader);
+ glAttachShader(program, frag_shader);
glLinkProgram(program);
- glDetachShader(program, vertShader);
- glDetachShader(program, fragShader);
- glDeleteShader(vertShader);
- glDeleteShader(fragShader);
+ glDetachShader(program, vert_shader);
+ glDetachShader(program, frag_shader);
+ glDeleteShader(vert_shader);
+ glDeleteShader(frag_shader);
if (glGetProgramiv)
{
- GLint isLinked = 0;
- glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
- if (isLinked == GL_FALSE)
+ GLint is_linked = 0;
+ glGetProgramiv(program, GL_LINK_STATUS, &is_linked);
+ if (is_linked == GL_FALSE)
{
if (glDeleteProgram)
glDeleteProgram(program);
@@ -320,7 +305,7 @@ GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource)
return program;
}
-GLuint OpenGL_BuildProgramFromFile(const char *filePath)
+GLuint oglu_build_program_from_file(const char *filePath)
{
GLuint program = 0;
@@ -328,47 +313,47 @@ GLuint OpenGL_BuildProgramFromFile(const char *filePath)
if (file)
{
fseek(file, 0, SEEK_END);
- long fileSize = ftell(file);
+ long file_size = ftell(file);
fseek(file, 0, SEEK_SET);
- char *source = fileSize > 0 ? calloc(fileSize + 1, 1) : NULL;
+ char *source = file_size > 0 ? calloc(file_size + 1, 1) : NULL;
if (source)
{
- fread(source, fileSize, 1, file);
+ fread(source, file_size, 1, file);
fclose(file);
- char *vertSource = calloc(fileSize + 50, 1);
- char *fragSource = calloc(fileSize + 50, 1);
+ char *vert_source = calloc(file_size + 50, 1);
+ char *frag_source = calloc(file_size + 50, 1);
- if (fragSource && vertSource)
+ if (frag_source && vert_source)
{
- char *versionStart = strstr(source, "#version");
- if (versionStart)
+ char *version_start = strstr(source, "#version");
+ if (version_start)
{
const char deli[2] = "\n";
- char *version = strtok(versionStart, deli);
+ char *version = strtok(version_start, deli);
- strcpy(vertSource, source);
- strcpy(fragSource, source);
- strcat(vertSource, "\n#define VERTEX\n");
- strcat(fragSource, "\n#define FRAGMENT\n");
- strcat(vertSource, version + strlen(version) + 1);
- strcat(fragSource, version + strlen(version) + 1);
+ strcpy(vert_source, source);
+ strcpy(frag_source, source);
+ strcat(vert_source, "\n#define VERTEX\n");
+ strcat(frag_source, "\n#define FRAGMENT\n");
+ strcat(vert_source, version + strlen(version) + 1);
+ strcat(frag_source, version + strlen(version) + 1);
- program = OpenGL_BuildProgram(vertSource, fragSource);
+ program = oglu_build_program(vert_source, frag_source);
}
else
{
- strcpy(vertSource, "#define VERTEX\n");
- strcpy(fragSource, "#define FRAGMENT\n");
- strcat(vertSource, source);
- strcat(fragSource, source);
+ strcpy(vert_source, "#define VERTEX\n");
+ strcpy(frag_source, "#define FRAGMENT\n");
+ strcat(vert_source, source);
+ strcat(frag_source, source);
- program = OpenGL_BuildProgram(vertSource, fragSource);
+ program = oglu_build_program(vert_source, frag_source);
}
- free(vertSource);
- free(fragSource);
+ free(vert_source);
+ free(frag_source);
}
free(source);
diff --git a/src/palette.c b/src/palette.c
deleted file mode 100644
index be87311..0000000
--- a/src/palette.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
-
-#include
-#include
-#include "palette.h"
-#include "surface.h"
-
-IDirectDrawPaletteImpl *LastFreedPalette; // Dungeon Keeper hack
-
-HRESULT __stdcall ddraw_palette_GetEntries(IDirectDrawPaletteImpl *This, DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries)
-{
- int i, x;
-
- printf("DirectDrawPalette::GetEntries(This=%p, dwFlags=%08X, dwBase=%d, dwNumEntries=%d, lpEntries=%p)\n", This, (int)dwFlags, (int)dwBase, (int)dwNumEntries, lpEntries);
-
- for (i = dwBase, x = 0; i < dwBase + dwNumEntries; i++, x++)
- {
- if (This->data_rgb)
- {
- lpEntries[x].peRed = This->data_rgb[i].rgbRed;
- lpEntries[x].peGreen = This->data_rgb[i].rgbGreen;
- lpEntries[x].peBlue = This->data_rgb[i].rgbBlue;
- }
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_palette_SetEntries(IDirectDrawPaletteImpl *This, DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries)
-{
- int i, x;
-
-#if _DEBUG_X
- printf("DirectDrawPalette::SetEntries(This=%p, dwFlags=%08X, dwStartingEntry=%d, dwCount=%d, lpEntries=%p)\n", This, (int)dwFlags, (int)dwStartingEntry, (int)dwCount, lpEntries);
-#endif
-
- for (i = dwStartingEntry, x = 0; i < dwStartingEntry + dwCount; i++, x++)
- {
- This->data_bgr[i] = (lpEntries[x].peBlue << 16) | (lpEntries[x].peGreen << 8) | lpEntries[x].peRed;
-
- if (This->data_rgb)
- {
- This->data_rgb[i].rgbRed = lpEntries[x].peRed;
- This->data_rgb[i].rgbGreen = lpEntries[x].peGreen;
- This->data_rgb[i].rgbBlue = lpEntries[x].peBlue;
- This->data_rgb[i].rgbReserved = 0;
- }
- }
-
- if (ddraw->primary && ddraw->primary->palette == This && ddraw->render.run)
- {
- InterlockedExchange(&ddraw->render.paletteUpdated, TRUE);
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_palette_QueryInterface(IDirectDrawPaletteImpl *This, REFIID riid, void **obj)
-{
- printf("??? DirectDrawPalette::QueryInterface(This=%p, riid=%08X, obj=%p)\n", This, (unsigned int)riid, obj);
- return S_OK;
-}
-
-ULONG __stdcall ddraw_palette_AddRef(IDirectDrawPaletteImpl *This)
-{
- printf("DirectDrawPalette::AddRef(This=%p)\n", This);
-
- This->Ref++;
-
- return This->Ref;
-}
-
-ULONG __stdcall ddraw_palette_Release(IDirectDrawPaletteImpl *This)
-{
- printf("DirectDrawPalette::Release(This=%p)\n", This);
-
- This->Ref--;
-
- if(This->Ref == 0)
- {
- printf(" Released (%p)\n", This);
-
- LastFreedPalette = This;
- HeapFree(GetProcessHeap(), 0, This);
- return 0;
- }
-
- return This->Ref;
-}
-
-HRESULT __stdcall ddraw_palette_GetCaps(IDirectDrawPaletteImpl *This, LPDWORD caps)
-{
- printf("??? DirectDrawPalette::GetCaps(This=%p, caps=%p)\n", This, caps);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_palette_Initialize(IDirectDrawPaletteImpl *This, LPDIRECTDRAW lpDD, DWORD dw, LPPALETTEENTRY paent)
-{
- printf("??? DirectDrawPalette::Initialize(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-struct IDirectDrawPaletteImplVtbl piface =
-{
- /* IUnknown */
- ddraw_palette_QueryInterface,
- ddraw_palette_AddRef,
- ddraw_palette_Release,
- /* IDirectDrawPalette */
- ddraw_palette_GetCaps,
- ddraw_palette_GetEntries,
- ddraw_palette_Initialize,
- ddraw_palette_SetEntries
-};
-
-HRESULT __stdcall ddraw_CreatePalette(IDirectDrawImpl *This, DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR * lpDDPalette, IUnknown FAR * unkOuter)
-{
- printf("DirectDraw::CreatePalette(This=%p, dwFlags=%08X, DDColorArray=%p, DDPalette=%p, unkOuter=%p)\n", This, (int)dwFlags, lpDDColorArray, lpDDPalette, unkOuter);
-
- IDirectDrawPaletteImpl *Palette = (IDirectDrawPaletteImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawPaletteImpl));
- Palette->lpVtbl = &piface;
- printf(" Palette = %p\n", Palette);
- *lpDDPalette = (LPDIRECTDRAWPALETTE)Palette;
-
- ddraw_palette_SetEntries(Palette, dwFlags, 0, 256, lpDDColorArray);
-
- ddraw_palette_AddRef(Palette);
-
- return DD_OK;
-}
-
diff --git a/src/render.c b/src/render.c
deleted file mode 100644
index f1e64ef..0000000
--- a/src/render.c
+++ /dev/null
@@ -1,1049 +0,0 @@
-/*
-* Copyright (c) 2010 Toni Spets
-*
-* 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.
-*/
-
-
-#include
-#include
-#include "opengl.h"
-#include "main.h"
-#include "surface.h"
-#include "openglshader.h"
-
-#define TEXTURE_COUNT 4
-
-static HGLRC OpenGLContext;
-static GLuint MainProgram;
-static GLuint ScaleProgram;
-static BOOL GotError;
-static int SurfaceTexWidth;
-static int SurfaceTexHeight;
-static int *SurfaceTex;
-static GLenum SurfaceFormat = GL_LUMINANCE;
-static GLenum SurfaceType = GL_UNSIGNED_BYTE;
-static GLuint SurfaceTexIds[TEXTURE_COUNT];
-static GLuint PaletteTexIds[TEXTURE_COUNT];
-static float ScaleW;
-static float ScaleH;
-static GLint MainTexCoordAttrLoc = -1;
-static GLint MainVertexCoordAttrLoc = -1;
-static GLuint MainVBOs[3], MainVAO;
-static GLint FrameCountUniLoc = -1;
-static GLuint FrameBufferId;
-static GLuint FrameBufferTexId;
-static GLuint ScaleVBOs[3], ScaleVAO;
-static BOOL UseOpenGL;
-static BOOL AdjustAlignment;
-static BOOL FilterBilinear;
-
-static HGLRC CreateContext(HDC hdc);
-static void SetMaxFPS();
-static void BuildPrograms();
-static void CreateTextures(int width, int height);
-static void InitMainProgram();
-static void InitScaleProgram();
-static void Render();
-static void DeleteContext(HGLRC context);
-static BOOL TextureUploadTest();
-static BOOL ShaderTest();
-
-DWORD WINAPI render_main(void)
-{
- Sleep(500);
- GotError = UseOpenGL = FALSE;
-
- OpenGLContext = CreateContext(ddraw->render.hDC);
- if (OpenGLContext)
- {
- OpenGL_Init();
- SetMaxFPS();
- BuildPrograms();
- CreateTextures(ddraw->width, ddraw->height);
- InitMainProgram();
- InitScaleProgram();
-
- GotError = GotError || !TextureUploadTest();
- GotError = GotError || !ShaderTest();
- GotError = GotError || glGetError() != GL_NO_ERROR;
- UseOpenGL = (MainProgram || ddraw->bpp == 16) && !GotError;
-
- Render();
-
- DeleteContext(OpenGLContext);
- }
-
- if (!UseOpenGL)
- {
- ShowDriverWarning = TRUE;
- ddraw->renderer = render_soft_main;
- render_soft_main();
- }
-
- return 0;
-}
-
-static HGLRC CreateContext(HDC hdc)
-{
- HGLRC context = xwglCreateContext(hdc);
- BOOL madeCurrent = context && xwglMakeCurrent(hdc, context);
-
- if (!madeCurrent || glGetError() != GL_NO_ERROR)
- {
- if (madeCurrent)
- {
- xwglMakeCurrent(NULL, NULL);
- xwglDeleteContext(context);
- }
-
- context = 0;
- }
-
- return context;
-}
-
-static void SetMaxFPS()
-{
- int maxFPS = ddraw->render.maxfps;
- ddraw->fpsLimiter.tickLengthNs = 0;
- ddraw->fpsLimiter.ticklength = 0;
-
- /*
- if (OpenGL_ExtExists("WGL_EXT_swap_control_tear", ddraw->render.hDC))
- {
- if (wglSwapIntervalEXT)
- {
- if (ddraw->vsync)
- {
- wglSwapIntervalEXT(-1);
- maxFPS = ddraw->mode.dmDisplayFrequency;
- }
- else
- wglSwapIntervalEXT(0);
- }
- }
- else */
- if (OpenGL_ExtExists("WGL_EXT_swap_control", ddraw->render.hDC))
- {
- if (wglSwapIntervalEXT)
- {
- if (ddraw->vsync)
- {
- wglSwapIntervalEXT(1);
- maxFPS = ddraw->mode.dmDisplayFrequency;
- }
- else
- wglSwapIntervalEXT(0);
- }
- }
-
- if (maxFPS < 0)
- maxFPS = ddraw->mode.dmDisplayFrequency;
-
- if (maxFPS > 1000)
- maxFPS = 0;
-
- if (maxFPS > 0)
- {
- float len = 1000.0f / maxFPS;
- ddraw->fpsLimiter.tickLengthNs = len * 10000;
- ddraw->fpsLimiter.ticklength = len;// + 0.5f;
- }
-}
-
-static void BuildPrograms()
-{
- MainProgram = ScaleProgram = 0;
-
- if (OpenGL_GotVersion3)
- {
- if (ddraw->bpp == 8)
- MainProgram = OpenGL_BuildProgram(PassthroughVertShaderSrc, PaletteFragShaderSrc);
- else if (ddraw->bpp == 16)
- MainProgram = OpenGL_BuildProgram(PassthroughVertShaderSrc, PassthroughFragShaderSrc);
-
- if (MainProgram)
- ScaleProgram = OpenGL_BuildProgramFromFile(ddraw->shader);
- else
- OpenGL_GotVersion3 = FALSE;
-
- FilterBilinear = strstr(ddraw->shader, "bilinear.glsl") != 0;
- }
-
- if (OpenGL_GotVersion2 && !MainProgram)
- {
- if (ddraw->bpp == 8)
- MainProgram = OpenGL_BuildProgram(PassthroughVertShader110Src, PaletteFragShader110Src);
- else if (ddraw->bpp == 16)
- MainProgram = OpenGL_BuildProgram(PassthroughVertShader110Src, PassthroughFragShader110Src);
- }
-}
-
-static void CreateTextures(int width, int height)
-{
- SurfaceTexWidth =
- width <= 1024 ? 1024 : width <= 2048 ? 2048 : width <= 4096 ? 4096 : width;
-
- SurfaceTexHeight =
- height <= 512 ? 512 : height <= 1024 ? 1024 : height <= 2048 ? 2048 : height <= 4096 ? 4096 : height;
-
- SurfaceTex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SurfaceTexWidth * SurfaceTexHeight * sizeof(int));
-
- AdjustAlignment = (width % 4) != 0;
-
- ScaleW = (float)width / SurfaceTexWidth;
- ScaleH = (float)height / SurfaceTexHeight;
-
- glGenTextures(TEXTURE_COUNT, SurfaceTexIds);
-
- int i;
- for (i = 0; i < TEXTURE_COUNT; i++)
- {
- glBindTexture(GL_TEXTURE_2D, SurfaceTexIds[i]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- GotError = GotError || glGetError() != GL_NO_ERROR;
-
- while (glGetError() != GL_NO_ERROR);
-
- if (ddraw->bpp == 16)
- {
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_RGB565,
- SurfaceTexWidth,
- SurfaceTexHeight,
- 0,
- SurfaceFormat = GL_RGB,
- SurfaceType = GL_UNSIGNED_SHORT_5_6_5,
- 0);
-
-
- if (glGetError() != GL_NO_ERROR)
- {
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_RGB5,
- SurfaceTexWidth,
- SurfaceTexHeight,
- 0,
- SurfaceFormat = GL_RGB,
- SurfaceType = GL_UNSIGNED_SHORT_5_6_5,
- 0);
- }
- }
- else if (ddraw->bpp == 8)
- {
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE8,
- SurfaceTexWidth,
- SurfaceTexHeight,
- 0,
- SurfaceFormat = GL_LUMINANCE,
- SurfaceType = GL_UNSIGNED_BYTE,
- 0);
-
-
- if (glGetError() != GL_NO_ERROR)
- {
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_R8,
- SurfaceTexWidth,
- SurfaceTexHeight,
- 0,
- SurfaceFormat = GL_RED,
- SurfaceType = GL_UNSIGNED_BYTE,
- 0);
- }
-
- if (glGetError() != GL_NO_ERROR)
- {
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_RED,
- SurfaceTexWidth,
- SurfaceTexHeight,
- 0,
- SurfaceFormat = GL_RED,
- SurfaceType = GL_UNSIGNED_BYTE,
- 0);
- }
- }
- }
-
- if (ddraw->bpp == 8)
- {
- glGenTextures(TEXTURE_COUNT, PaletteTexIds);
-
- for (i = 0; i < TEXTURE_COUNT; i++)
- {
- glBindTexture(GL_TEXTURE_2D, PaletteTexIds[i]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- }
- }
-}
-
-static void InitMainProgram()
-{
- if (!MainProgram)
- return;
-
- glUseProgram(MainProgram);
-
- glUniform1i(glGetUniformLocation(MainProgram, "SurfaceTex"), 0);
-
- if (ddraw->bpp == 8)
- glUniform1i(glGetUniformLocation(MainProgram, "PaletteTex"), 1);
-
- if (OpenGL_GotVersion3)
- {
- MainVertexCoordAttrLoc = glGetAttribLocation(MainProgram, "VertexCoord");
- MainTexCoordAttrLoc = glGetAttribLocation(MainProgram, "TexCoord");
-
- glGenBuffers(3, MainVBOs);
-
- if (ScaleProgram)
- {
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[0]);
- static const GLfloat vertexCoord[] = {
- -1.0f,-1.0f,
- -1.0f, 1.0f,
- 1.0f, 1.0f,
- 1.0f,-1.0f,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
- GLfloat texCoord[] = {
- 0.0f, 0.0f,
- 0.0f, ScaleH,
- ScaleW, ScaleH,
- ScaleW, 0.0f,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
- else
- {
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[0]);
- static const GLfloat vertexCoord[] = {
- -1.0f, 1.0f,
- 1.0f, 1.0f,
- 1.0f,-1.0f,
- -1.0f,-1.0f,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
- GLfloat texCoord[] = {
- 0.0f, 0.0f,
- ScaleW, 0.0f,
- ScaleW, ScaleH,
- 0.0f, ScaleH,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- glGenVertexArrays(1, &MainVAO);
- glBindVertexArray(MainVAO);
-
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[0]);
- glVertexAttribPointer(MainVertexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glEnableVertexAttribArray(MainVertexCoordAttrLoc);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
- glVertexAttribPointer(MainTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glEnableVertexAttribArray(MainTexCoordAttrLoc);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, MainVBOs[2]);
- static const GLushort indices[] =
- {
- 0, 1, 2,
- 0, 2, 3,
- };
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
-
- glBindVertexArray(0);
-
- const float mvpMatrix[16] = {
- 1,0,0,0,
- 0,1,0,0,
- 0,0,1,0,
- 0,0,0,1,
- };
- glUniformMatrix4fv(glGetUniformLocation(MainProgram, "MVPMatrix"), 1, GL_FALSE, mvpMatrix);
-
- }
-}
-
-static void InitScaleProgram()
-{
- if (!ScaleProgram)
- return;
-
- glUseProgram(ScaleProgram);
-
- GLint vertexCoordAttrLoc = glGetAttribLocation(ScaleProgram, "VertexCoord");
- GLint texCoordAttrLoc = glGetAttribLocation(ScaleProgram, "TexCoord");
- FrameCountUniLoc = glGetUniformLocation(ScaleProgram, "FrameCount");
-
- glGenBuffers(3, ScaleVBOs);
-
- glBindBuffer(GL_ARRAY_BUFFER, ScaleVBOs[0]);
- static const GLfloat vertexCoord[] = {
- -1.0f, 1.0f,
- 1.0f, 1.0f,
- 1.0f,-1.0f,
- -1.0f,-1.0f,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glBindBuffer(GL_ARRAY_BUFFER, ScaleVBOs[1]);
- GLfloat texCoord[] = {
- 0.0f, 0.0f,
- ScaleW, 0.0f,
- ScaleW, ScaleH,
- 0.0f, ScaleH,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glGenVertexArrays(1, &ScaleVAO);
- glBindVertexArray(ScaleVAO);
-
- glBindBuffer(GL_ARRAY_BUFFER, ScaleVBOs[0]);
- glVertexAttribPointer(vertexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glEnableVertexAttribArray(vertexCoordAttrLoc);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glBindBuffer(GL_ARRAY_BUFFER, ScaleVBOs[1]);
- glVertexAttribPointer(texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glEnableVertexAttribArray(texCoordAttrLoc);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ScaleVBOs[2]);
- static const GLushort indices[] =
- {
- 0, 1, 2,
- 0, 2, 3,
- };
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
-
- glBindVertexArray(0);
-
- float inputSize[2], outputSize[2], textureSize[2];
-
- inputSize[0] = ddraw->width;
- inputSize[1] = ddraw->height;
- textureSize[0] = SurfaceTexWidth;
- textureSize[1] = SurfaceTexHeight;
- outputSize[0] = ddraw->render.viewport.width;
- outputSize[1] = ddraw->render.viewport.height;
-
- glUniform2fv(glGetUniformLocation(ScaleProgram, "OutputSize"), 1, outputSize);
- glUniform2fv(glGetUniformLocation(ScaleProgram, "TextureSize"), 1, textureSize);
- glUniform2fv(glGetUniformLocation(ScaleProgram, "InputSize"), 1, inputSize);
- glUniform1i(glGetUniformLocation(ScaleProgram, "FrameDirection"), 1);
- glUniform1i(glGetUniformLocation(ScaleProgram, "Texture"), 0);
-
- const float mvpMatrix[16] = {
- 1,0,0,0,
- 0,1,0,0,
- 0,0,1,0,
- 0,0,0,1,
- };
- glUniformMatrix4fv(glGetUniformLocation(ScaleProgram, "MVPMatrix"), 1, GL_FALSE, mvpMatrix);
-
- glGenFramebuffers(1, &FrameBufferId);
- glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferId);
-
- glGenTextures(1, &FrameBufferTexId);
- glBindTexture(GL_TEXTURE_2D, FrameBufferTexId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, FilterBilinear ? GL_LINEAR : GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilterBilinear ? GL_LINEAR : GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SurfaceTexWidth, SurfaceTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FrameBufferTexId, 0);
-
- GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
- glDrawBuffers(1, drawBuffers);
-
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- {
- glDeleteTextures(1, &FrameBufferTexId);
-
- if (glDeleteFramebuffers)
- glDeleteFramebuffers(1, &FrameBufferId);
-
- if (glDeleteProgram)
- glDeleteProgram(ScaleProgram);
-
- ScaleProgram = 0;
-
- if (glDeleteBuffers)
- glDeleteBuffers(3, ScaleVBOs);
-
- if (glDeleteVertexArrays)
- glDeleteVertexArrays(1, &ScaleVAO);
-
- if (MainProgram)
- {
- glBindVertexArray(MainVAO);
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[0]);
- static const GLfloat vertexCoordPal[] = {
- -1.0f, 1.0f,
- 1.0f, 1.0f,
- 1.0f,-1.0f,
- -1.0f,-1.0f,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoordPal), vertexCoordPal, GL_STATIC_DRAW);
- glVertexAttribPointer(MainVertexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glEnableVertexAttribArray(MainVertexCoordAttrLoc);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
-
- glBindVertexArray(MainVAO);
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
- GLfloat texCoordPal[] = {
- 0.0f, 0.0f,
- ScaleW, 0.0f,
- ScaleW, ScaleH,
- 0.0f, ScaleH,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(texCoordPal), texCoordPal, GL_STATIC_DRAW);
- glVertexAttribPointer(MainTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glEnableVertexAttribArray(MainTexCoordAttrLoc);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- }
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-}
-
-static void Render()
-{
- DWORD tickStart = 0;
- DWORD tickEnd = 0;
- BOOL needsUpdate = FALSE;
-
- glViewport(
- ddraw->render.viewport.x, ddraw->render.viewport.y,
- ddraw->render.viewport.width, ddraw->render.viewport.height);
-
- if (MainProgram)
- glUseProgram(MainProgram);
- else if (ddraw->bpp == 16)
- glEnable(GL_TEXTURE_2D);
-
- while (UseOpenGL && ddraw->render.run &&
- (ddraw->render.forcefps || WaitForSingleObject(ddraw->render.sem, 200) != WAIT_FAILED))
- {
-#if _DEBUG
- DrawFrameInfoStart();
-#endif
-
- ScaleW = (float)ddraw->width / SurfaceTexWidth;
- ScaleH = (float)ddraw->height / SurfaceTexHeight;
-
- static int texIndex = 0, palIndex = 0;
-
- BOOL scaleChanged = FALSE;
-
- if (ddraw->fpsLimiter.ticklength > 0)
- tickStart = timeGetTime();
-
- EnterCriticalSection(&ddraw->cs);
-
- if (ddraw->primary && (ddraw->bpp == 16 || ddraw->primary->palette))
- {
- if (ddraw->vhack)
- {
- if (detect_cutscene())
- {
- ScaleW *= (float)CUTSCENE_WIDTH / ddraw->width;
- ScaleH *= (float)CUTSCENE_HEIGHT / ddraw->height;
-
- if (!InterlockedExchange(&ddraw->incutscene, TRUE))
- scaleChanged = TRUE;
- }
- else
- {
- if (InterlockedExchange(&ddraw->incutscene, FALSE))
- scaleChanged = TRUE;
- }
- }
-
- if (ddraw->bpp == 8 && InterlockedExchange(&ddraw->render.paletteUpdated, FALSE))
- {
- if (++palIndex >= TEXTURE_COUNT)
- palIndex = 0;
-
- glBindTexture(GL_TEXTURE_2D, PaletteTexIds[palIndex]);
-
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- 256,
- 1,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- ddraw->primary->palette->data_bgr);
- }
-
- if (InterlockedExchange(&ddraw->render.surfaceUpdated, FALSE))
- {
- if (++texIndex >= TEXTURE_COUNT)
- texIndex = 0;
-
- glBindTexture(GL_TEXTURE_2D, SurfaceTexIds[texIndex]);
-
- if (AdjustAlignment)
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- ddraw->width,
- ddraw->height,
- SurfaceFormat,
- SurfaceType,
- ddraw->primary->surface);
-
- if (AdjustAlignment)
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- }
-
- static int errorCheckCount = 0;
- if (errorCheckCount < 20)
- {
- glClear(GL_COLOR_BUFFER_BIT);
-
- errorCheckCount++;
-
- if (glGetError() != GL_NO_ERROR)
- UseOpenGL = FALSE;
- }
-
- if (!ddraw->handlemouse)
- {
- ChildWindowExists = FALSE;
- EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary);
-
- if (ddraw->render.width != ddraw->width || ddraw->render.height != ddraw->height)
- {
- if (ChildWindowExists)
- {
- glClear(GL_COLOR_BUFFER_BIT);
-
- if (!needsUpdate)
- {
- glViewport(0, ddraw->render.height - ddraw->height, ddraw->width, ddraw->height);
- needsUpdate = TRUE;
- }
- }
- else if (needsUpdate)
- {
- glViewport(
- ddraw->render.viewport.x, ddraw->render.viewport.y,
- ddraw->render.viewport.width, ddraw->render.viewport.height);
-
- needsUpdate = FALSE;
- }
- }
- }
- }
-
- LeaveCriticalSection(&ddraw->cs);
-
- if (scaleChanged)
- {
- if (ScaleProgram && MainProgram)
- {
- glBindVertexArray(MainVAO);
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
- GLfloat texCoord[] = {
- 0.0f, 0.0f,
- 0.0f, ScaleH,
- ScaleW, ScaleH,
- ScaleW, 0.0f,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
- glVertexAttribPointer(MainTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glEnableVertexAttribArray(MainTexCoordAttrLoc);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- }
- else if (OpenGL_GotVersion3 && MainProgram)
- {
- glBindVertexArray(MainVAO);
- glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
- GLfloat texCoord[] = {
- 0.0f, 0.0f,
- ScaleW, 0.0f,
- ScaleW, ScaleH,
- 0.0f, ScaleH,
- };
- glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
- glVertexAttribPointer(MainTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glEnableVertexAttribArray(MainTexCoordAttrLoc);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- }
- }
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, SurfaceTexIds[texIndex]);
-
- if (ddraw->bpp == 8)
- {
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, PaletteTexIds[palIndex]);
-
- glActiveTexture(GL_TEXTURE0);
- }
-
- if (ScaleProgram && MainProgram)
- {
- // draw surface into framebuffer
- glUseProgram(MainProgram);
-
- glViewport(0, 0, ddraw->width, ddraw->height);
-
- glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferId);
-
- glBindVertexArray(MainVAO);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
- glBindVertexArray(0);
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- if (ChildWindowExists)
- glViewport(0, ddraw->render.height - ddraw->height, ddraw->width, ddraw->height);
- else
- glViewport(
- ddraw->render.viewport.x, ddraw->render.viewport.y,
- ddraw->render.viewport.width, ddraw->render.viewport.height);
-
- // apply filter
-
- glUseProgram(ScaleProgram);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, FrameBufferTexId);
-
- static int frames = 1;
- if (FrameCountUniLoc != -1)
- glUniform1i(FrameCountUniLoc, frames++);
-
- glBindVertexArray(ScaleVAO);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
- glBindVertexArray(0);
- }
- else if (OpenGL_GotVersion3 && MainProgram)
- {
- glBindVertexArray(MainVAO);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
- glBindVertexArray(0);
- }
- else
- {
- glBegin(GL_TRIANGLE_FAN);
- glTexCoord2f(0, 0); glVertex2f(-1, 1);
- glTexCoord2f(ScaleW, 0); glVertex2f(1, 1);
- glTexCoord2f(ScaleW, ScaleH); glVertex2f(1, -1);
- glTexCoord2f(0, ScaleH); glVertex2f(-1, -1);
- glEnd();
- }
-
- if (ddraw->bnetActive)
- glClear(GL_COLOR_BUFFER_BIT);
-
- SwapBuffers(ddraw->render.hDC);
-
-#if _DEBUG
- DrawFrameInfoEnd();
-#endif
-
- if (ddraw->fpsLimiter.ticklength > 0)
- {
- if (ddraw->fpsLimiter.hTimer)
- {
- if (ddraw->vsync)
- {
- WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
- LARGE_INTEGER liDueTime = { .QuadPart = -ddraw->fpsLimiter.tickLengthNs };
- SetWaitableTimer(ddraw->fpsLimiter.hTimer, &liDueTime, 0, NULL, NULL, FALSE);
- }
- else
- {
- FILETIME ft = { 0 };
- GetSystemTimeAsFileTime(&ft);
-
- if (CompareFileTime((FILETIME *)&ddraw->fpsLimiter.dueTime, &ft) == -1)
- {
- memcpy(&ddraw->fpsLimiter.dueTime, &ft, sizeof(LARGE_INTEGER));
- }
- else
- {
- WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
- }
-
- ddraw->fpsLimiter.dueTime.QuadPart += ddraw->fpsLimiter.tickLengthNs;
- SetWaitableTimer(ddraw->fpsLimiter.hTimer, &ddraw->fpsLimiter.dueTime, 0, NULL, NULL, FALSE);
- }
- }
- else
- {
- tickEnd = timeGetTime();
-
- if (tickEnd - tickStart < ddraw->fpsLimiter.ticklength)
- Sleep(ddraw->fpsLimiter.ticklength - (tickEnd - tickStart));
- }
- }
- }
-}
-
-static void DeleteContext(HGLRC context)
-{
- HeapFree(GetProcessHeap(), 0, SurfaceTex);
- glDeleteTextures(TEXTURE_COUNT, SurfaceTexIds);
-
- if (ddraw->bpp == 8)
- glDeleteTextures(TEXTURE_COUNT, PaletteTexIds);
-
- if (glUseProgram)
- glUseProgram(0);
-
- if (ScaleProgram)
- {
- glDeleteTextures(1, &FrameBufferTexId);
-
- if (glDeleteBuffers)
- glDeleteBuffers(3, ScaleVBOs);
-
- if (glDeleteFramebuffers)
- glDeleteFramebuffers(1, &FrameBufferId);
-
- if (glDeleteVertexArrays)
- glDeleteVertexArrays(1, &ScaleVAO);
- }
-
- if (glDeleteProgram)
- {
- if (MainProgram)
- glDeleteProgram(MainProgram);
-
- if (ScaleProgram)
- glDeleteProgram(ScaleProgram);
- }
-
- if (OpenGL_GotVersion3)
- {
- if (MainProgram)
- {
- if (glDeleteBuffers)
- glDeleteBuffers(3, MainVBOs);
-
- if (glDeleteVertexArrays)
- glDeleteVertexArrays(1, &MainVAO);
- }
- }
-
- xwglMakeCurrent(NULL, NULL);
- xwglDeleteContext(context);
-}
-
-static BOOL TextureUploadTest()
-{
- static char testData[] = { 0,1,2,0,0,2,3,0,0,4,5,0,0,6,7,0,0,8,9,0 };
-
- int i;
- for (i = 0; i < TEXTURE_COUNT; i++)
- {
- memcpy(SurfaceTex, testData, sizeof(testData));
-
- glBindTexture(GL_TEXTURE_2D, SurfaceTexIds[i]);
-
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- ddraw->width,
- ddraw->height,
- SurfaceFormat,
- SurfaceType,
- SurfaceTex);
-
- memset(SurfaceTex, 0, sizeof(testData));
-
- glGetTexImage(GL_TEXTURE_2D, 0, SurfaceFormat, SurfaceType, SurfaceTex);
-
- if (memcmp(SurfaceTex, testData, sizeof(testData)) != 0)
- return FALSE;
- }
-
- if (ddraw->bpp == 8)
- {
- for (i = 0; i < TEXTURE_COUNT; i++)
- {
- glBindTexture(GL_TEXTURE_2D, PaletteTexIds[i]);
-
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- 256,
- 1,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- SurfaceTex);
-
- memset(SurfaceTex, 0, sizeof(testData));
-
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, SurfaceTex);
-
- if (memcmp(SurfaceTex, testData, sizeof(testData)) != 0)
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static BOOL ShaderTest()
-{
- BOOL result = TRUE;
-
- if (ddraw->bpp != 8)
- return result;
-
- if (OpenGL_GotVersion3 && MainProgram)
- {
- memset(SurfaceTex, 0, SurfaceTexHeight * SurfaceTexWidth * sizeof(int));
-
- GLuint fboId = 0;
- glGenFramebuffers(1, &fboId);
-
- glBindFramebuffer(GL_FRAMEBUFFER, fboId);
-
- GLuint fboTexId = 0;
- glGenTextures(1, &fboTexId);
- glBindTexture(GL_TEXTURE_2D, fboTexId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SurfaceTexWidth, SurfaceTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, SurfaceTex);
-
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTexId, 0);
-
- GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
- glDrawBuffers(1, drawBuffers);
-
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
- {
- static char gray0pal[] = { 128,128,128,128 };
-
- glBindTexture(GL_TEXTURE_2D, PaletteTexIds[0]);
-
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- 1,
- 1,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- gray0pal);
-
- glBindTexture(GL_TEXTURE_2D, SurfaceTexIds[0]);
-
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- SurfaceTexWidth,
- SurfaceTexHeight,
- SurfaceFormat,
- GL_UNSIGNED_BYTE,
- SurfaceTex);
-
- glViewport(0, 0, SurfaceTexWidth, SurfaceTexHeight);
-
- glUseProgram(MainProgram);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, PaletteTexIds[0]);
- glActiveTexture(GL_TEXTURE0);
-
- glBindVertexArray(MainVAO);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
- glBindVertexArray(0);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, 0);
- glActiveTexture(GL_TEXTURE0);
-
- glBindTexture(GL_TEXTURE_2D, fboTexId);
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, SurfaceTex);
-
- int i;
- for (i = 0; i < SurfaceTexHeight * SurfaceTexWidth; i++)
- {
- if (SurfaceTex[i] != 0x80808080)
- {
- result = FALSE;
- break;
- }
- }
- }
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- if (glDeleteFramebuffers)
- glDeleteFramebuffers(1, &fboId);
-
- glDeleteTextures(1, &fboTexId);
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
-
- return result;
-}
diff --git a/src/render_d3d9.c b/src/render_d3d9.c
index afaf35d..d16c147 100644
--- a/src/render_d3d9.c
+++ b/src/render_d3d9.c
@@ -1,58 +1,64 @@
#include
#include
#include
-#include "main.h"
-#include "surface.h"
+#include "dd.h"
+#include "ddsurface.h"
#include "d3d9shader.h"
#include "render_d3d9.h"
+#include "utils.h"
+#include "wndproc.h"
-#define TEXTURE_COUNT 2
-HMODULE Direct3D9_hModule;
+static BOOL d3d9_create_resouces();
+static BOOL d3d9_set_states();
+static BOOL d3d9_update_vertices(BOOL in_cutscene, BOOL stretch);
+static void d3d9_set_max_fps();
-static D3DPRESENT_PARAMETERS D3dpp;
-static LPDIRECT3D9 D3d;
-static LPDIRECT3DDEVICE9 D3dDev;
-static LPDIRECT3DVERTEXBUFFER9 VertexBuf;
-static IDirect3DTexture9 *SurfaceTex[TEXTURE_COUNT];
-static IDirect3DTexture9 *PaletteTex[TEXTURE_COUNT];
-static IDirect3DPixelShader9 *PixelShader;
-static float ScaleW;
-static float ScaleH;
-static int BitsPerPixel;
+static d3d9_renderer g_d3d9;
-static BOOL CreateResources();
-static BOOL SetStates();
-static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch);
-static void SetMaxFPS();
-
-BOOL Direct3D9_Create()
+BOOL d3d9_is_available()
{
- if (!Direct3D9_Release())
+ LPDIRECT3D9 d3d9 = NULL;
+
+ if ((g_d3d9.hmodule = LoadLibrary("d3d9.dll")))
+ {
+ IDirect3D9* (WINAPI * d3d_create9)(UINT) =
+ (IDirect3D9 * (WINAPI*)(UINT))GetProcAddress(g_d3d9.hmodule, "Direct3DCreate9");
+
+ if (d3d_create9 && (d3d9 = d3d_create9(D3D_SDK_VERSION)))
+ IDirect3D9_Release(d3d9);
+ }
+
+ return d3d9 != NULL;
+}
+
+BOOL d3d9_create()
+{
+ if (!d3d9_release())
return FALSE;
- if (!Direct3D9_hModule)
- Direct3D9_hModule = LoadLibrary("d3d9.dll");
+ if (!g_d3d9.hmodule)
+ g_d3d9.hmodule = LoadLibrary("d3d9.dll");
- if (Direct3D9_hModule)
+ if (g_d3d9.hmodule)
{
- IDirect3D9 *(WINAPI *D3DCreate9)(UINT) =
- (IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(Direct3D9_hModule, "Direct3DCreate9");
+ IDirect3D9 *(WINAPI *d3d_create9)(UINT) =
+ (IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(g_d3d9.hmodule, "Direct3DCreate9");
- if (D3DCreate9 && (D3d = D3DCreate9(D3D_SDK_VERSION)))
+ if (d3d_create9 && (g_d3d9.instance = d3d_create9(D3D_SDK_VERSION)))
{
- BitsPerPixel = ddraw->render.bpp ? ddraw->render.bpp : ddraw->mode.dmBitsPerPel;
+ g_d3d9.bits_per_pixel = g_ddraw->render.bpp ? g_ddraw->render.bpp : g_ddraw->mode.dmBitsPerPel;
- D3dpp.Windowed = ddraw->windowed;
- D3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- D3dpp.hDeviceWindow = ddraw->hWnd;
- D3dpp.PresentationInterval = ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
- D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
- D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
- D3dpp.BackBufferFormat = BitsPerPixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
- D3dpp.BackBufferCount = 1;
+ g_d3d9.params.Windowed = g_ddraw->windowed;
+ g_d3d9.params.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ g_d3d9.params.hDeviceWindow = g_ddraw->hwnd;
+ g_d3d9.params.PresentationInterval = g_ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
+ g_d3d9.params.BackBufferWidth = g_d3d9.params.Windowed ? 0 : g_ddraw->render.width;
+ g_d3d9.params.BackBufferHeight = g_d3d9.params.Windowed ? 0 : g_ddraw->render.height;
+ g_d3d9.params.BackBufferFormat = g_d3d9.bits_per_pixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
+ g_d3d9.params.BackBufferCount = 1;
- DWORD behaviorFlags[] = {
+ DWORD behavior_flags[] = {
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
@@ -61,18 +67,18 @@ BOOL Direct3D9_Create()
};
int i;
- for (i = 0; i < sizeof(behaviorFlags) / sizeof(behaviorFlags[0]); i++)
+ for (i = 0; i < sizeof(behavior_flags) / sizeof(behavior_flags[0]); i++)
{
if (SUCCEEDED(
IDirect3D9_CreateDevice(
- D3d,
+ g_d3d9.instance,
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
- ddraw->hWnd,
- D3DCREATE_MULTITHREADED | behaviorFlags[i],
- &D3dpp,
- &D3dDev)))
- return D3dDev && CreateResources() && SetStates();
+ g_ddraw->hwnd,
+ D3DCREATE_MULTITHREADED | behavior_flags[i],
+ &g_d3d9.params,
+ &g_d3d9.device)))
+ return g_d3d9.device && d3d9_create_resouces() && d3d9_set_states();
}
}
}
@@ -80,177 +86,177 @@ BOOL Direct3D9_Create()
return FALSE;
}
-BOOL Direct3D9_OnDeviceLost()
+BOOL d3d9_on_device_lost()
{
- if (D3dDev && IDirect3DDevice9_TestCooperativeLevel(D3dDev) == D3DERR_DEVICENOTRESET)
- return Direct3D9_Reset();
+ if (g_d3d9.device && IDirect3DDevice9_TestCooperativeLevel(g_d3d9.device) == D3DERR_DEVICENOTRESET)
+ return d3d9_reset();
return FALSE;
}
-BOOL Direct3D9_Reset()
+BOOL d3d9_reset()
{
- D3dpp.Windowed = ddraw->windowed;
- D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
- D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
- D3dpp.BackBufferFormat = BitsPerPixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
+ g_d3d9.params.Windowed = g_ddraw->windowed;
+ g_d3d9.params.BackBufferWidth = g_d3d9.params.Windowed ? 0 : g_ddraw->render.width;
+ g_d3d9.params.BackBufferHeight = g_d3d9.params.Windowed ? 0 : g_ddraw->render.height;
+ g_d3d9.params.BackBufferFormat = g_d3d9.bits_per_pixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
- if (D3dDev && SUCCEEDED(IDirect3DDevice9_Reset(D3dDev, &D3dpp)))
- return SetStates();
+ if (g_d3d9.device && SUCCEEDED(IDirect3DDevice9_Reset(g_d3d9.device, &g_d3d9.params)))
+ return d3d9_set_states();
return FALSE;
}
-BOOL Direct3D9_Release()
+BOOL d3d9_release()
{
- if (VertexBuf)
+ if (g_d3d9.vertex_buf)
{
- IDirect3DVertexBuffer9_Release(VertexBuf);
- VertexBuf = NULL;
+ IDirect3DVertexBuffer9_Release(g_d3d9.vertex_buf);
+ g_d3d9.vertex_buf = NULL;
}
int i;
- for (i = 0; i < TEXTURE_COUNT; i++)
+ for (i = 0; i < D3D9_TEXTURE_COUNT; i++)
{
- if (SurfaceTex[i])
+ if (g_d3d9.surface_tex[i])
{
- IDirect3DTexture9_Release(SurfaceTex[i]);
- SurfaceTex[i] = NULL;
+ IDirect3DTexture9_Release(g_d3d9.surface_tex[i]);
+ g_d3d9.surface_tex[i] = NULL;
}
- if (PaletteTex[i])
+ if (g_d3d9.palette_tex[i])
{
- IDirect3DTexture9_Release(PaletteTex[i]);
- PaletteTex[i] = NULL;
+ IDirect3DTexture9_Release(g_d3d9.palette_tex[i]);
+ g_d3d9.palette_tex[i] = NULL;
}
}
- if (PixelShader)
+ if (g_d3d9.pixel_shader)
{
- IDirect3DPixelShader9_Release(PixelShader);
- PixelShader = NULL;
+ IDirect3DPixelShader9_Release(g_d3d9.pixel_shader);
+ g_d3d9.pixel_shader = NULL;
}
- if (D3dDev)
+ if (g_d3d9.device)
{
- IDirect3DDevice9_Release(D3dDev);
- D3dDev = NULL;
+ IDirect3DDevice9_Release(g_d3d9.device);
+ g_d3d9.device = NULL;
}
- if (D3d)
+ if (g_d3d9.instance)
{
- IDirect3D9_Release(D3d);
- D3d = NULL;
+ IDirect3D9_Release(g_d3d9.instance);
+ g_d3d9.instance = NULL;
}
return TRUE;
}
-static BOOL CreateResources()
+static BOOL d3d9_create_resouces()
{
BOOL err = FALSE;
- int width = ddraw->width;
- int height = ddraw->height;
+ int width = g_ddraw->width;
+ int height = g_ddraw->height;
- int texWidth =
+ int tex_width =
width <= 1024 ? 1024 : width <= 2048 ? 2048 : width <= 4096 ? 4096 : width;
- int texHeight =
- height <= texWidth ? texWidth : height <= 2048 ? 2048 : height <= 4096 ? 4096 : height;
+ int tex_height =
+ height <= tex_width ? tex_width : height <= 2048 ? 2048 : height <= 4096 ? 4096 : height;
- texWidth = texWidth > texHeight ? texWidth : texHeight;
+ tex_width = tex_width > tex_height ? tex_width : tex_height;
- ScaleW = (float)width / texWidth;;
- ScaleH = (float)height / texHeight;
+ g_d3d9.scale_w = (float)width / tex_width;;
+ g_d3d9.scale_h = (float)height / tex_height;
err = err || FAILED(
IDirect3DDevice9_CreateVertexBuffer(
- D3dDev, sizeof(CUSTOMVERTEX) * 4, 0, D3DFVF_XYZRHW | D3DFVF_TEX1, D3DPOOL_MANAGED, &VertexBuf, NULL));
+ g_d3d9.device, sizeof(CUSTOMVERTEX) * 4, 0, D3DFVF_XYZRHW | D3DFVF_TEX1, D3DPOOL_MANAGED, &g_d3d9.vertex_buf, NULL));
- err = err || !UpdateVertices(InterlockedExchangeAdd(&ddraw->incutscene, 0), TRUE);
+ err = err || !d3d9_update_vertices(InterlockedExchangeAdd(&g_ddraw->incutscene, 0), TRUE);
int i;
- for (i = 0; i < TEXTURE_COUNT; i++)
+ for (i = 0; i < D3D9_TEXTURE_COUNT; i++)
{
err = err || FAILED(
IDirect3DDevice9_CreateTexture(
- D3dDev,
- texWidth,
- texHeight,
+ g_d3d9.device,
+ tex_width,
+ tex_height,
1,
0,
- ddraw->bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_L8,
+ g_ddraw->bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_L8,
D3DPOOL_MANAGED,
- &SurfaceTex[i],
+ &g_d3d9.surface_tex[i],
0));
- err = err || !SurfaceTex[i];
+ err = err || !g_d3d9.surface_tex[i];
- if (ddraw->bpp == 8)
+ if (g_ddraw->bpp == 8)
{
err = err || FAILED(
IDirect3DDevice9_CreateTexture(
- D3dDev,
+ g_d3d9.device,
256,
256,
1,
0,
D3DFMT_X8R8G8B8,
D3DPOOL_MANAGED,
- &PaletteTex[i],
+ &g_d3d9.palette_tex[i],
0));
- err = err || !PaletteTex[i];
+ err = err || !g_d3d9.palette_tex[i];
}
}
- if (ddraw->bpp == 8)
+ if (g_ddraw->bpp == 8)
{
err = err || FAILED(
- IDirect3DDevice9_CreatePixelShader(D3dDev, (DWORD *)PalettePixelShaderSrc, &PixelShader));
+ IDirect3DDevice9_CreatePixelShader(g_d3d9.device, (DWORD *)D3D9_PALETTE_SHADER, &g_d3d9.pixel_shader));
}
- return VertexBuf && (PixelShader || ddraw->bpp == 16) && !err;
+ return g_d3d9.vertex_buf && (g_d3d9.pixel_shader || g_ddraw->bpp == 16) && !err;
}
-static BOOL SetStates()
+static BOOL d3d9_set_states()
{
BOOL err = FALSE;
- err = err || FAILED(IDirect3DDevice9_SetFVF(D3dDev, D3DFVF_XYZRHW | D3DFVF_TEX1));
- err = err || FAILED(IDirect3DDevice9_SetStreamSource(D3dDev, 0, VertexBuf, 0, sizeof(CUSTOMVERTEX)));
- err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 0, (IDirect3DBaseTexture9 *)SurfaceTex[0]));
+ err = err || FAILED(IDirect3DDevice9_SetFVF(g_d3d9.device, D3DFVF_XYZRHW | D3DFVF_TEX1));
+ err = err || FAILED(IDirect3DDevice9_SetStreamSource(g_d3d9.device, 0, g_d3d9.vertex_buf, 0, sizeof(CUSTOMVERTEX)));
+ err = err || FAILED(IDirect3DDevice9_SetTexture(g_d3d9.device, 0, (IDirect3DBaseTexture9 *)g_d3d9.surface_tex[0]));
- if (ddraw->bpp == 8)
+ if (g_ddraw->bpp == 8)
{
- err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 1, (IDirect3DBaseTexture9 *)PaletteTex[0]));
- err = err || FAILED(IDirect3DDevice9_SetPixelShader(D3dDev, PixelShader));
+ err = err || FAILED(IDirect3DDevice9_SetTexture(g_d3d9.device, 1, (IDirect3DBaseTexture9 *)g_d3d9.palette_tex[0]));
+ err = err || FAILED(IDirect3DDevice9_SetPixelShader(g_d3d9.device, g_d3d9.pixel_shader));
}
- D3DVIEWPORT9 viewData = {
- ddraw->render.viewport.x,
- ddraw->render.viewport.y,
- ddraw->render.viewport.width,
- ddraw->render.viewport.height,
+ D3DVIEWPORT9 view_data = {
+ g_ddraw->render.viewport.x,
+ g_ddraw->render.viewport.y,
+ g_ddraw->render.viewport.width,
+ g_ddraw->render.viewport.height,
0.0f,
1.0f };
- err = err || FAILED(IDirect3DDevice9_SetViewport(D3dDev, &viewData));
+ err = err || FAILED(IDirect3DDevice9_SetViewport(g_d3d9.device, &view_data));
return !err;
}
-static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch)
+static BOOL d3d9_update_vertices(BOOL in_cutscene, BOOL stretch)
{
- float vpX = stretch ? (float)ddraw->render.viewport.x : 0.0f;
- float vpY = stretch ? (float)ddraw->render.viewport.y : 0.0f;
+ float vpX = stretch ? (float)g_ddraw->render.viewport.x : 0.0f;
+ float vpY = stretch ? (float)g_ddraw->render.viewport.y : 0.0f;
- float vpW = stretch ? (float)(ddraw->render.viewport.width + ddraw->render.viewport.x) : (float)ddraw->width;
- float vpH = stretch ? (float)(ddraw->render.viewport.height + ddraw->render.viewport.y) : (float)ddraw->height;
+ float vpW = stretch ? (float)(g_ddraw->render.viewport.width + g_ddraw->render.viewport.x) : (float)g_ddraw->width;
+ float vpH = stretch ? (float)(g_ddraw->render.viewport.height + g_ddraw->render.viewport.y) : (float)g_ddraw->height;
- float sH = inCutscene ? ScaleH * ((float)CUTSCENE_HEIGHT / ddraw->height) : ScaleH;
- float sW = inCutscene ? ScaleW * ((float)CUTSCENE_WIDTH / ddraw->width) : ScaleW;
+ float sH = in_cutscene ? g_d3d9.scale_h * ((float)CUTSCENE_HEIGHT / g_ddraw->height) : g_d3d9.scale_h;
+ float sW = in_cutscene ? g_d3d9.scale_w * ((float)CUTSCENE_WIDTH / g_ddraw->width) : g_d3d9.scale_w;
CUSTOMVERTEX vertices[] =
{
@@ -261,197 +267,198 @@ static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch)
};
void *data;
- if (VertexBuf && SUCCEEDED(IDirect3DVertexBuffer9_Lock(VertexBuf, 0, 0, (void**)&data, 0)))
+ if (g_d3d9.vertex_buf && SUCCEEDED(IDirect3DVertexBuffer9_Lock(g_d3d9.vertex_buf, 0, 0, (void**)&data, 0)))
{
memcpy(data, vertices, sizeof(vertices));
- IDirect3DVertexBuffer9_Unlock(VertexBuf);
+ IDirect3DVertexBuffer9_Unlock(g_d3d9.vertex_buf);
return TRUE;
}
return FALSE;
}
-static void SetMaxFPS()
+static void d3d9_set_max_fps()
{
- int maxFPS = ddraw->render.maxfps;
- ddraw->fpsLimiter.tickLengthNs = 0;
- ddraw->fpsLimiter.ticklength = 0;
+ int max_fps = g_ddraw->render.maxfps;
- if (maxFPS < 0 || ddraw->vsync)
- maxFPS = ddraw->mode.dmDisplayFrequency;
+ g_ddraw->fps_limiter.tick_length_ns = 0;
+ g_ddraw->fps_limiter.tick_length = 0;
- if (maxFPS > 1000)
- maxFPS = 0;
+ if (max_fps < 0 || g_ddraw->vsync)
+ max_fps = g_ddraw->mode.dmDisplayFrequency;
- if (maxFPS > 0)
+ if (max_fps > 1000)
+ max_fps = 0;
+
+ if (max_fps > 0)
{
- float len = 1000.0f / maxFPS;
- ddraw->fpsLimiter.tickLengthNs = len * 10000;
- ddraw->fpsLimiter.ticklength = len;// + 0.5f;
+ float len = 1000.0f / max_fps;
+ g_ddraw->fps_limiter.tick_length_ns = len * 10000;
+ g_ddraw->fps_limiter.tick_length = len;// + 0.5f;
}
}
-DWORD WINAPI render_d3d9_main(void)
+DWORD WINAPI d3d9_render_main(void)
{
Sleep(500);
- SetMaxFPS();
+ d3d9_set_max_fps();
- DWORD tickStart = 0;
- DWORD tickEnd = 0;
- BOOL needsUpdate = FALSE;
+ DWORD tick_start = 0;
+ DWORD tick_end = 0;
+ BOOL needs_update = FALSE;
- while (ddraw->render.run &&
- (ddraw->render.forcefps || WaitForSingleObject(ddraw->render.sem, 200) != WAIT_FAILED))
+ while (g_ddraw->render.run &&
+ (g_ddraw->render.forcefps || WaitForSingleObject(g_ddraw->render.sem, 200) != WAIT_FAILED))
{
#if _DEBUG
DrawFrameInfoStart();
#endif
- static int texIndex = 0, palIndex = 0;
+ static int tex_index = 0, palIndex = 0;
- if (ddraw->fpsLimiter.ticklength > 0)
- tickStart = timeGetTime();
+ if (g_ddraw->fps_limiter.tick_length > 0)
+ tick_start = timeGetTime();
- EnterCriticalSection(&ddraw->cs);
+ EnterCriticalSection(&g_ddraw->cs);
- if (ddraw->primary && (ddraw->bpp == 16 || (ddraw->primary->palette && ddraw->primary->palette->data_rgb)))
+ if (g_ddraw->primary && (g_ddraw->bpp == 16 || (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)))
{
- if (ddraw->vhack)
+ if (g_ddraw->vhack)
{
- if (detect_cutscene())
+ if (util_detect_cutscene())
{
- if (!InterlockedExchange(&ddraw->incutscene, TRUE))
- UpdateVertices(TRUE, TRUE);
+ if (!InterlockedExchange(&g_ddraw->incutscene, TRUE))
+ d3d9_update_vertices(TRUE, TRUE);
}
else
{
- if (InterlockedExchange(&ddraw->incutscene, FALSE))
- UpdateVertices(FALSE, TRUE);
+ if (InterlockedExchange(&g_ddraw->incutscene, FALSE))
+ d3d9_update_vertices(FALSE, TRUE);
}
}
D3DLOCKED_RECT lock_rc;
- if (InterlockedExchange(&ddraw->render.surfaceUpdated, FALSE))
+ if (InterlockedExchange(&g_ddraw->render.surface_updated, FALSE))
{
- if (++texIndex >= TEXTURE_COUNT)
- texIndex = 0;
+ if (++tex_index >= D3D9_TEXTURE_COUNT)
+ tex_index = 0;
- RECT rc = { 0,0,ddraw->width,ddraw->height };
+ RECT rc = { 0, 0, g_ddraw->width, g_ddraw->height };
- if (SUCCEEDED(IDirect3DDevice9_SetTexture(D3dDev, 0, (IDirect3DBaseTexture9 *)SurfaceTex[texIndex])) &&
- SUCCEEDED(IDirect3DTexture9_LockRect(SurfaceTex[texIndex], 0, &lock_rc, &rc, 0)))
+ if (SUCCEEDED(IDirect3DDevice9_SetTexture(g_d3d9.device, 0, (IDirect3DBaseTexture9 *)g_d3d9.surface_tex[tex_index])) &&
+ SUCCEEDED(IDirect3DTexture9_LockRect(g_d3d9.surface_tex[tex_index], 0, &lock_rc, &rc, 0)))
{
- unsigned char *src = (unsigned char *)ddraw->primary->surface;
+ unsigned char *src = (unsigned char *)g_ddraw->primary->surface;
unsigned char *dst = (unsigned char *)lock_rc.pBits;
int i;
- for (i = 0; i < ddraw->height; i++)
+ for (i = 0; i < g_ddraw->height; i++)
{
- memcpy(dst, src, ddraw->primary->lPitch);
+ memcpy(dst, src, g_ddraw->primary->l_pitch);
- src += ddraw->primary->lPitch;
+ src += g_ddraw->primary->l_pitch;
dst += lock_rc.Pitch;
}
- IDirect3DTexture9_UnlockRect(SurfaceTex[texIndex], 0);
+ IDirect3DTexture9_UnlockRect(g_d3d9.surface_tex[tex_index], 0);
}
}
- if (ddraw->bpp == 8 && InterlockedExchange(&ddraw->render.paletteUpdated, FALSE))
+ if (g_ddraw->bpp == 8 && InterlockedExchange(&g_ddraw->render.palette_updated, FALSE))
{
- if (++palIndex >= TEXTURE_COUNT)
+ if (++palIndex >= D3D9_TEXTURE_COUNT)
palIndex = 0;
RECT rc = { 0,0,256,1 };
- if (SUCCEEDED(IDirect3DDevice9_SetTexture(D3dDev, 1, (IDirect3DBaseTexture9 *)PaletteTex[palIndex])) &&
- SUCCEEDED(IDirect3DTexture9_LockRect(PaletteTex[palIndex], 0, &lock_rc, &rc, 0)))
+ if (SUCCEEDED(IDirect3DDevice9_SetTexture(g_d3d9.device, 1, (IDirect3DBaseTexture9 *)g_d3d9.palette_tex[palIndex])) &&
+ SUCCEEDED(IDirect3DTexture9_LockRect(g_d3d9.palette_tex[palIndex], 0, &lock_rc, &rc, 0)))
{
- memcpy(lock_rc.pBits, ddraw->primary->palette->data_rgb, 256 * sizeof(int));
+ memcpy(lock_rc.pBits, g_ddraw->primary->palette->data_rgb, 256 * sizeof(int));
- IDirect3DTexture9_UnlockRect(PaletteTex[palIndex], 0);
+ IDirect3DTexture9_UnlockRect(g_d3d9.palette_tex[palIndex], 0);
}
}
- if (!ddraw->handlemouse)
+ if (!g_ddraw->handlemouse)
{
- ChildWindowExists = FALSE;
- EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary);
+ g_ddraw->child_window_exists = FALSE;
+ EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary);
- if (ddraw->render.width != ddraw->width || ddraw->render.height != ddraw->height)
+ if (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height)
{
- if (ChildWindowExists)
+ if (g_ddraw->child_window_exists)
{
- IDirect3DDevice9_Clear(D3dDev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
+ IDirect3DDevice9_Clear(g_d3d9.device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
- if (!needsUpdate && UpdateVertices(FALSE, FALSE))
- needsUpdate = TRUE;
+ if (!needs_update && d3d9_update_vertices(FALSE, FALSE))
+ needs_update = TRUE;
}
- else if (needsUpdate)
+ else if (needs_update)
{
- if (UpdateVertices(FALSE, TRUE))
- needsUpdate = FALSE;
+ if (d3d9_update_vertices(FALSE, TRUE))
+ needs_update = FALSE;
}
}
}
}
- LeaveCriticalSection(&ddraw->cs);
+ LeaveCriticalSection(&g_ddraw->cs);
- IDirect3DDevice9_BeginScene(D3dDev);
- IDirect3DDevice9_DrawPrimitive(D3dDev, D3DPT_TRIANGLESTRIP, 0, 2);
- IDirect3DDevice9_EndScene(D3dDev);
+ IDirect3DDevice9_BeginScene(g_d3d9.device);
+ IDirect3DDevice9_DrawPrimitive(g_d3d9.device, D3DPT_TRIANGLESTRIP, 0, 2);
+ IDirect3DDevice9_EndScene(g_d3d9.device);
- if (ddraw->bnetActive)
- IDirect3DDevice9_Clear(D3dDev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
+ if (g_ddraw->bnet_active)
+ IDirect3DDevice9_Clear(g_d3d9.device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
- if (FAILED(IDirect3DDevice9_Present(D3dDev, NULL, NULL, NULL, NULL)))
+ if (FAILED(IDirect3DDevice9_Present(g_d3d9.device, NULL, NULL, NULL, NULL)))
{
- DWORD_PTR dwResult;
- SendMessageTimeout(ddraw->hWnd, WM_D3D9DEVICELOST, 0, 0, 0, 1000, &dwResult);
+ DWORD_PTR result;
+ SendMessageTimeout(g_ddraw->hwnd, WM_D3D9DEVICELOST, 0, 0, 0, 1000, &result);
}
#if _DEBUG
DrawFrameInfoEnd();
#endif
- if (ddraw->fpsLimiter.ticklength > 0)
+ if (g_ddraw->fps_limiter.tick_length > 0)
{
- if (ddraw->fpsLimiter.hTimer)
+ if (g_ddraw->fps_limiter.htimer)
{
- if (ddraw->vsync)
+ if (g_ddraw->vsync)
{
- WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
- LARGE_INTEGER liDueTime = { .QuadPart = -ddraw->fpsLimiter.tickLengthNs };
- SetWaitableTimer(ddraw->fpsLimiter.hTimer, &liDueTime, 0, NULL, NULL, FALSE);
+ WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
+ LARGE_INTEGER due_time = { .QuadPart = -g_ddraw->fps_limiter.tick_length_ns };
+ SetWaitableTimer(g_ddraw->fps_limiter.htimer, &due_time, 0, NULL, NULL, FALSE);
}
else
{
FILETIME ft = { 0 };
GetSystemTimeAsFileTime(&ft);
- if (CompareFileTime((FILETIME *)&ddraw->fpsLimiter.dueTime, &ft) == -1)
+ if (CompareFileTime((FILETIME *)&g_ddraw->fps_limiter.due_time, &ft) == -1)
{
- memcpy(&ddraw->fpsLimiter.dueTime, &ft, sizeof(LARGE_INTEGER));
+ memcpy(&g_ddraw->fps_limiter.due_time, &ft, sizeof(LARGE_INTEGER));
}
else
{
- WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
+ WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
}
- ddraw->fpsLimiter.dueTime.QuadPart += ddraw->fpsLimiter.tickLengthNs;
- SetWaitableTimer(ddraw->fpsLimiter.hTimer, &ddraw->fpsLimiter.dueTime, 0, NULL, NULL, FALSE);
+ g_ddraw->fps_limiter.due_time.QuadPart += g_ddraw->fps_limiter.tick_length_ns;
+ SetWaitableTimer(g_ddraw->fps_limiter.htimer, &g_ddraw->fps_limiter.due_time, 0, NULL, NULL, FALSE);
}
}
else
{
- tickEnd = timeGetTime();
+ tick_end = timeGetTime();
- if (tickEnd - tickStart < ddraw->fpsLimiter.ticklength)
- Sleep(ddraw->fpsLimiter.ticklength - (tickEnd - tickStart));
+ if (tick_end - tick_start < g_ddraw->fps_limiter.tick_length)
+ Sleep(g_ddraw->fps_limiter.tick_length - (tick_end - tick_start));
}
}
}
diff --git a/src/render_gdi.c b/src/render_gdi.c
new file mode 100644
index 0000000..44d0850
--- /dev/null
+++ b/src/render_gdi.c
@@ -0,0 +1,181 @@
+#include
+#include
+#include "dd.h"
+#include "ddsurface.h"
+#include "opengl_utils.h"
+#include "utils.h"
+#include "wndproc.h"
+
+
+DWORD WINAPI gdi_render_main(void)
+{
+ DWORD warning_end_tick = timeGetTime() + (15 * 1000);
+ char warning_text[512] = { 0 };
+
+ if (g_ddraw->show_driver_warning)
+ {
+ g_ddraw->show_driver_warning = FALSE;
+
+ if (!g_ddraw->windowed)
+ PostMessage(g_ddraw->hwnd, WM_AUTORENDERER, 0, 0);
+
+ _snprintf(
+ warning_text, sizeof(warning_text),
+ "-WARNING- Using slow software rendering, please update your graphics card driver (%s)",
+ strlen(g_oglu_version) > 10 ? "" : g_oglu_version);
+ }
+
+ Sleep(500);
+
+ DWORD tick_start = 0;
+ DWORD tick_end = 0;
+
+ int max_fps = g_ddraw->render.maxfps;
+
+ g_ddraw->fps_limiter.tick_length_ns = 0;
+ g_ddraw->fps_limiter.tick_length = 0;
+
+ if (max_fps < 0)
+ max_fps = g_ddraw->mode.dmDisplayFrequency;
+
+ if (max_fps > 1000)
+ max_fps = 0;
+
+ if (max_fps > 0)
+ {
+ float len = 1000.0f / max_fps;
+ g_ddraw->fps_limiter.tick_length_ns = len * 10000;
+ g_ddraw->fps_limiter.tick_length = len + (g_ddraw->accurate_timers ? 0.5f : 0.0f);
+ }
+
+ while (g_ddraw->render.run &&
+ (g_ddraw->render.forcefps || WaitForSingleObject(g_ddraw->render.sem, 200) != WAIT_FAILED))
+ {
+#if _DEBUG
+ DrawFrameInfoStart();
+#endif
+
+ if (g_ddraw->fps_limiter.tick_length > 0)
+ tick_start = timeGetTime();
+
+ EnterCriticalSection(&g_ddraw->cs);
+
+ if (g_ddraw->primary && (g_ddraw->bpp == 16 || (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)))
+ {
+ if (warning_text[0])
+ {
+ if (timeGetTime() < warning_end_tick)
+ {
+ RECT rc = { 0, 0, g_ddraw->width, g_ddraw->height };
+ DrawText(g_ddraw->primary->hdc, warning_text, -1, &rc, DT_NOCLIP | DT_CENTER);
+ }
+ else
+ warning_text[0] = 0;
+ }
+
+ BOOL scale_cutscene = g_ddraw->vhack && util_detect_cutscene();
+
+ if (g_ddraw->vhack)
+ InterlockedExchange(&g_ddraw->incutscene, scale_cutscene);
+
+ if (!g_ddraw->handlemouse)
+ {
+ g_ddraw->child_window_exists = FALSE;
+ EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary);
+ }
+
+ if (g_ddraw->bnet_active)
+ {
+ RECT rc = { 0, 0, g_ddraw->render.width, g_ddraw->render.height };
+ FillRect(g_ddraw->render.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
+ }
+ else if (scale_cutscene)
+ {
+ StretchDIBits(
+ g_ddraw->render.hdc,
+ g_ddraw->render.viewport.x,
+ g_ddraw->render.viewport.y,
+ g_ddraw->render.viewport.width,
+ g_ddraw->render.viewport.height,
+ 0,
+ g_ddraw->height - 400,
+ CUTSCENE_WIDTH,
+ CUTSCENE_HEIGHT,
+ g_ddraw->primary->surface,
+ g_ddraw->primary->bmi,
+ DIB_RGB_COLORS,
+ SRCCOPY);
+ }
+ else if (!g_ddraw->child_window_exists &&
+ (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height))
+ {
+ StretchDIBits(
+ g_ddraw->render.hdc,
+ g_ddraw->render.viewport.x,
+ g_ddraw->render.viewport.y,
+ g_ddraw->render.viewport.width,
+ g_ddraw->render.viewport.height,
+ 0,
+ 0,
+ g_ddraw->width,
+ g_ddraw->height,
+ g_ddraw->primary->surface,
+ g_ddraw->primary->bmi,
+ DIB_RGB_COLORS,
+ SRCCOPY);
+ }
+ else
+ {
+ SetDIBitsToDevice(
+ g_ddraw->render.hdc,
+ 0,
+ 0,
+ g_ddraw->width,
+ g_ddraw->height,
+ 0,
+ 0,
+ 0,
+ g_ddraw->height,
+ g_ddraw->primary->surface,
+ g_ddraw->primary->bmi,
+ DIB_RGB_COLORS);
+ }
+ }
+
+ LeaveCriticalSection(&g_ddraw->cs);
+
+#if _DEBUG
+ DrawFrameInfoEnd();
+#endif
+
+ if (g_ddraw->fps_limiter.tick_length > 0)
+ {
+ if (g_ddraw->fps_limiter.htimer)
+ {
+ FILETIME ft = { 0 };
+ GetSystemTimeAsFileTime(&ft);
+
+ if (CompareFileTime((FILETIME*)&g_ddraw->fps_limiter.due_time, &ft) == -1)
+ {
+ memcpy(&g_ddraw->fps_limiter.due_time, &ft, sizeof(LARGE_INTEGER));
+ }
+ else
+ {
+ WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
+ }
+
+ g_ddraw->fps_limiter.due_time.QuadPart += g_ddraw->fps_limiter.tick_length_ns;
+ SetWaitableTimer(g_ddraw->fps_limiter.htimer, &g_ddraw->fps_limiter.due_time, 0, NULL, NULL, FALSE);
+ }
+ else
+ {
+ tick_end = timeGetTime();
+
+ if (tick_end - tick_start < g_ddraw->fps_limiter.tick_length)
+ Sleep(g_ddraw->fps_limiter.tick_length - (tick_end - tick_start));
+ }
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/render_ogl.c b/src/render_ogl.c
new file mode 100644
index 0000000..d09ebe7
--- /dev/null
+++ b/src/render_ogl.c
@@ -0,0 +1,1025 @@
+#include
+#include
+#include "opengl_utils.h"
+#include "dd.h"
+#include "ddsurface.h"
+#include "openglshader.h"
+#include "render_gdi.h"
+#include "render_ogl.h"
+#include "utils.h"
+
+
+static HGLRC ogl_create_context(HDC hdc);
+static void ogl_set_max_fps();
+static void ogl_build_programs();
+static void ogl_create_textures(int width, int height);
+static void ogl_init_main_program();
+static void ogl_init_scale_program();
+static void ogl_render();
+static void ogl_delete_context(HGLRC context);
+static BOOL ogl_texture_upload_test();
+static BOOL ogl_shader_test();
+
+static ogl_renderer g_ogl;
+
+DWORD WINAPI ogl_render_main(void)
+{
+ Sleep(500);
+ g_ogl.got_error = g_ogl.use_opengl = FALSE;
+
+ g_ogl.context = ogl_create_context(g_ddraw->render.hdc);
+ if (g_ogl.context)
+ {
+ oglu_init();
+ ogl_set_max_fps();
+ ogl_build_programs();
+ ogl_create_textures(g_ddraw->width, g_ddraw->height);
+ ogl_init_main_program();
+ ogl_init_scale_program();
+
+ g_ogl.got_error = g_ogl.got_error || !ogl_texture_upload_test();
+ g_ogl.got_error = g_ogl.got_error || !ogl_shader_test();
+ g_ogl.got_error = g_ogl.got_error || glGetError() != GL_NO_ERROR;
+ g_ogl.use_opengl = (g_ogl.main_program || g_ddraw->bpp == 16) && !g_ogl.got_error;
+
+ ogl_render();
+
+ ogl_delete_context(g_ogl.context);
+ }
+
+ if (!g_ogl.use_opengl)
+ {
+ g_ddraw->show_driver_warning = TRUE;
+ g_ddraw->renderer = gdi_render_main;
+ gdi_render_main();
+ }
+
+ return 0;
+}
+
+static HGLRC ogl_create_context(HDC hdc)
+{
+ HGLRC context = xwglCreateContext(hdc);
+ BOOL made_current = context && xwglMakeCurrent(hdc, context);
+
+ if (!made_current || glGetError() != GL_NO_ERROR)
+ {
+ if (made_current)
+ {
+ xwglMakeCurrent(NULL, NULL);
+ xwglDeleteContext(context);
+ }
+
+ context = 0;
+ }
+
+ return context;
+}
+
+static void ogl_set_max_fps()
+{
+ int max_fps = g_ddraw->render.maxfps;
+
+ g_ddraw->fps_limiter.tick_length_ns = 0;
+ g_ddraw->fps_limiter.tick_length = 0;
+
+ /*
+ if (oglu_ext_exists("WGL_EXT_swap_control_tear", g_ddraw->render.hDC))
+ {
+ if (wglSwapIntervalEXT)
+ {
+ if (g_ddraw->vsync)
+ {
+ wglSwapIntervalEXT(-1);
+ max_fps = g_ddraw->mode.dmDisplayFrequency;
+ }
+ else
+ wglSwapIntervalEXT(0);
+ }
+ }
+ else */
+ if (oglu_ext_exists("WGL_EXT_swap_control", g_ddraw->render.hdc))
+ {
+ if (wglSwapIntervalEXT)
+ {
+ if (g_ddraw->vsync)
+ {
+ wglSwapIntervalEXT(1);
+ max_fps = g_ddraw->mode.dmDisplayFrequency;
+ }
+ else
+ wglSwapIntervalEXT(0);
+ }
+ }
+
+ if (max_fps < 0)
+ max_fps = g_ddraw->mode.dmDisplayFrequency;
+
+ if (max_fps > 1000)
+ max_fps = 0;
+
+ if (max_fps > 0)
+ {
+ float len = 1000.0f / max_fps;
+ g_ddraw->fps_limiter.tick_length_ns = len * 10000;
+ g_ddraw->fps_limiter.tick_length = len;// + 0.5f;
+ }
+}
+
+static void ogl_build_programs()
+{
+ g_ogl.main_program = g_ogl.scale_program = 0;
+
+ if (g_oglu_got_version3)
+ {
+ if (g_ddraw->bpp == 8)
+ {
+ g_ogl.main_program = oglu_build_program(PASSTHROUGH_VERT_SHADER, PALETTE_FRAG_SHADER);
+ }
+ else if (g_ddraw->bpp == 16)
+ {
+ g_ogl.main_program = oglu_build_program(PASSTHROUGH_VERT_SHADER, PASSTHROUGH_FRAG_SHADER);
+ }
+
+ if (g_ogl.main_program)
+ {
+ g_ogl.scale_program = oglu_build_program_from_file(g_ddraw->shader);
+ }
+ else
+ {
+ g_oglu_got_version3 = FALSE;
+ }
+
+ g_ogl.filter_bilinear = strstr(g_ddraw->shader, "bilinear.glsl") != 0;
+ }
+
+ if (g_oglu_got_version2 && !g_ogl.main_program)
+ {
+ if (g_ddraw->bpp == 8)
+ {
+ g_ogl.main_program = oglu_build_program(PASSTHROUGH_VERT_SHADER_110, PALETTE_FRAG_SHADER_110);
+ }
+ else if (g_ddraw->bpp == 16)
+ {
+ g_ogl.main_program = oglu_build_program(PASSTHROUGH_VERT_SHADER_110, PASSTHROUGH_FRAG_SHADER_110);
+ }
+ }
+}
+
+static void ogl_create_textures(int width, int height)
+{
+ g_ogl.surface_tex_width =
+ width <= 1024 ? 1024 : width <= 2048 ? 2048 : width <= 4096 ? 4096 : width;
+
+ g_ogl.surface_tex_height =
+ height <= 512 ? 512 : height <= 1024 ? 1024 : height <= 2048 ? 2048 : height <= 4096 ? 4096 : height;
+
+ g_ogl.surface_tex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, g_ogl.surface_tex_width * g_ogl.surface_tex_height * sizeof(int));
+
+ g_ogl.adjust_alignment = (width % 4) != 0;
+
+ g_ogl.scale_w = (float)width / g_ogl.surface_tex_width;
+ g_ogl.scale_h = (float)height / g_ogl.surface_tex_height;
+
+ glGenTextures(TEXTURE_COUNT, g_ogl.surface_tex_ids);
+
+ int i;
+ for (i = 0; i < TEXTURE_COUNT; i++)
+ {
+ glBindTexture(GL_TEXTURE_2D, g_ogl.surface_tex_ids[i]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ g_ogl.got_error = g_ogl.got_error || glGetError() != GL_NO_ERROR;
+
+ while (glGetError() != GL_NO_ERROR);
+
+ if (g_ddraw->bpp == 16)
+ {
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_RGB565,
+ g_ogl.surface_tex_width,
+ g_ogl.surface_tex_height,
+ 0,
+ g_ogl.surface_format = GL_RGB,
+ g_ogl.surface_type = GL_UNSIGNED_SHORT_5_6_5,
+ 0);
+
+
+ if (glGetError() != GL_NO_ERROR)
+ {
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_RGB5,
+ g_ogl.surface_tex_width,
+ g_ogl.surface_tex_height,
+ 0,
+ g_ogl.surface_format = GL_RGB,
+ g_ogl.surface_type = GL_UNSIGNED_SHORT_5_6_5,
+ 0);
+ }
+ }
+ else if (g_ddraw->bpp == 8)
+ {
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_LUMINANCE8,
+ g_ogl.surface_tex_width,
+ g_ogl.surface_tex_height,
+ 0,
+ g_ogl.surface_format = GL_LUMINANCE,
+ g_ogl.surface_type = GL_UNSIGNED_BYTE,
+ 0);
+
+
+ if (glGetError() != GL_NO_ERROR)
+ {
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_R8,
+ g_ogl.surface_tex_width,
+ g_ogl.surface_tex_height,
+ 0,
+ g_ogl.surface_format = GL_RED,
+ g_ogl.surface_type = GL_UNSIGNED_BYTE,
+ 0);
+ }
+
+ if (glGetError() != GL_NO_ERROR)
+ {
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_RED,
+ g_ogl.surface_tex_width,
+ g_ogl.surface_tex_height,
+ 0,
+ g_ogl.surface_format = GL_RED,
+ g_ogl.surface_type = GL_UNSIGNED_BYTE,
+ 0);
+ }
+ }
+ }
+
+ if (g_ddraw->bpp == 8)
+ {
+ glGenTextures(TEXTURE_COUNT, g_ogl.palette_tex_ids);
+
+ for (i = 0; i < TEXTURE_COUNT; i++)
+ {
+ glBindTexture(GL_TEXTURE_2D, g_ogl.palette_tex_ids[i]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ }
+ }
+}
+
+static void ogl_init_main_program()
+{
+ if (!g_ogl.main_program)
+ return;
+
+ glUseProgram(g_ogl.main_program);
+
+ glUniform1i(glGetUniformLocation(g_ogl.main_program, "SurfaceTex"), 0);
+
+ if (g_ddraw->bpp == 8)
+ glUniform1i(glGetUniformLocation(g_ogl.main_program, "PaletteTex"), 1);
+
+ if (g_oglu_got_version3)
+ {
+ g_ogl.main_vertex_coord_attr_loc = glGetAttribLocation(g_ogl.main_program, "VertexCoord");
+ g_ogl.main_tex_coord_attr_loc = glGetAttribLocation(g_ogl.main_program, "TexCoord");
+
+ glGenBuffers(3, g_ogl.main_vbos);
+
+ if (g_ogl.scale_program)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[0]);
+ static const GLfloat vertex_coord[] = {
+ -1.0f,-1.0f,
+ -1.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f,-1.0f,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_coord), vertex_coord, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[1]);
+ GLfloat tex_coord[] = {
+ 0.0f, 0.0f,
+ 0.0f, g_ogl.scale_h,
+ g_ogl.scale_w, g_ogl.scale_h,
+ g_ogl.scale_w, 0.0f,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coord), tex_coord, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ else
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[0]);
+ static const GLfloat vertex_coord[] = {
+ -1.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f,-1.0f,
+ -1.0f,-1.0f,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_coord), vertex_coord, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[1]);
+ GLfloat tex_coord[] = {
+ 0.0f, 0.0f,
+ g_ogl.scale_w, 0.0f,
+ g_ogl.scale_w, g_ogl.scale_h,
+ 0.0f, g_ogl.scale_h,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coord), tex_coord, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+
+ glGenVertexArrays(1, &g_ogl.main_vao);
+ glBindVertexArray(g_ogl.main_vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[0]);
+ glVertexAttribPointer(g_ogl.main_vertex_coord_attr_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glEnableVertexAttribArray(g_ogl.main_vertex_coord_attr_loc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[1]);
+ glVertexAttribPointer(g_ogl.main_tex_coord_attr_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glEnableVertexAttribArray(g_ogl.main_tex_coord_attr_loc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ogl.main_vbos[2]);
+ static const GLushort indices[] =
+ {
+ 0, 1, 2,
+ 0, 2, 3,
+ };
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
+
+ glBindVertexArray(0);
+
+ const float mvp_matrix[16] = {
+ 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0,
+ 0,0,0,1,
+ };
+ glUniformMatrix4fv(glGetUniformLocation(g_ogl.main_program, "MVPMatrix"), 1, GL_FALSE, mvp_matrix);
+
+ }
+}
+
+static void ogl_init_scale_program()
+{
+ if (!g_ogl.scale_program)
+ return;
+
+ glUseProgram(g_ogl.scale_program);
+
+ GLint vertex_coord_attr_loc = glGetAttribLocation(g_ogl.scale_program, "VertexCoord");
+ GLint tex_coord_attr_loc = glGetAttribLocation(g_ogl.scale_program, "TexCoord");
+ g_ogl.frame_count_uni_loc = glGetUniformLocation(g_ogl.scale_program, "FrameCount");
+
+ glGenBuffers(3, g_ogl.scale_vbos);
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.scale_vbos[0]);
+ static const GLfloat vertext_coord[] = {
+ -1.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f,-1.0f,
+ -1.0f,-1.0f,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertext_coord), vertext_coord, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.scale_vbos[1]);
+ GLfloat tex_coord[] = {
+ 0.0f, 0.0f,
+ g_ogl.scale_w, 0.0f,
+ g_ogl.scale_w, g_ogl.scale_h,
+ 0.0f, g_ogl.scale_h,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coord), tex_coord, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glGenVertexArrays(1, &g_ogl.scale_vao);
+ glBindVertexArray(g_ogl.scale_vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.scale_vbos[0]);
+ glVertexAttribPointer(vertex_coord_attr_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glEnableVertexAttribArray(vertex_coord_attr_loc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.scale_vbos[1]);
+ glVertexAttribPointer(tex_coord_attr_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glEnableVertexAttribArray(tex_coord_attr_loc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ogl.scale_vbos[2]);
+ static const GLushort indices[] =
+ {
+ 0, 1, 2,
+ 0, 2, 3,
+ };
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
+
+ glBindVertexArray(0);
+
+ float input_size[2], output_size[2], texture_size[2];
+
+ input_size[0] = g_ddraw->width;
+ input_size[1] = g_ddraw->height;
+ texture_size[0] = g_ogl.surface_tex_width;
+ texture_size[1] = g_ogl.surface_tex_height;
+ output_size[0] = g_ddraw->render.viewport.width;
+ output_size[1] = g_ddraw->render.viewport.height;
+
+ glUniform2fv(glGetUniformLocation(g_ogl.scale_program, "OutputSize"), 1, output_size);
+ glUniform2fv(glGetUniformLocation(g_ogl.scale_program, "TextureSize"), 1, texture_size);
+ glUniform2fv(glGetUniformLocation(g_ogl.scale_program, "InputSize"), 1, input_size);
+ glUniform1i(glGetUniformLocation(g_ogl.scale_program, "FrameDirection"), 1);
+ glUniform1i(glGetUniformLocation(g_ogl.scale_program, "Texture"), 0);
+
+ const float mvp_matrix[16] = {
+ 1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0,
+ 0,0,0,1,
+ };
+ glUniformMatrix4fv(glGetUniformLocation(g_ogl.scale_program, "MVPMatrix"), 1, GL_FALSE, mvp_matrix);
+
+ glGenFramebuffers(1, &g_ogl.frame_buffer_id);
+ glBindFramebuffer(GL_FRAMEBUFFER, g_ogl.frame_buffer_id);
+
+ glGenTextures(1, &g_ogl.frame_buffer_tex_id);
+ glBindTexture(GL_TEXTURE_2D, g_ogl.frame_buffer_tex_id);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, g_ogl.filter_bilinear ? GL_LINEAR : GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, g_ogl.filter_bilinear ? GL_LINEAR : GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, g_ogl.surface_tex_width, g_ogl.surface_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_ogl.frame_buffer_tex_id, 0);
+
+ GLenum draw_buffers[1] = { GL_COLOR_ATTACHMENT0 };
+ glDrawBuffers(1, draw_buffers);
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ {
+ glDeleteTextures(1, &g_ogl.frame_buffer_tex_id);
+
+ if (glDeleteFramebuffers)
+ glDeleteFramebuffers(1, &g_ogl.frame_buffer_id);
+
+ if (glDeleteProgram)
+ glDeleteProgram(g_ogl.scale_program);
+
+ g_ogl.scale_program = 0;
+
+ if (glDeleteBuffers)
+ glDeleteBuffers(3, g_ogl.scale_vbos);
+
+ if (glDeleteVertexArrays)
+ glDeleteVertexArrays(1, &g_ogl.scale_vao);
+
+ if (g_ogl.main_program)
+ {
+ glBindVertexArray(g_ogl.main_vao);
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[0]);
+ static const GLfloat vertex_coord_pal[] = {
+ -1.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f,-1.0f,
+ -1.0f,-1.0f,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_coord_pal), vertex_coord_pal, GL_STATIC_DRAW);
+ glVertexAttribPointer(g_ogl.main_vertex_coord_attr_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glEnableVertexAttribArray(g_ogl.main_vertex_coord_attr_loc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+
+ glBindVertexArray(g_ogl.main_vao);
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[1]);
+ GLfloat tex_coord_pal[] = {
+ 0.0f, 0.0f,
+ g_ogl.scale_w, 0.0f,
+ g_ogl.scale_w, g_ogl.scale_h,
+ 0.0f, g_ogl.scale_h,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coord_pal), tex_coord_pal, GL_STATIC_DRAW);
+ glVertexAttribPointer(g_ogl.main_tex_coord_attr_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glEnableVertexAttribArray(g_ogl.main_tex_coord_attr_loc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+ }
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+static void ogl_render()
+{
+ DWORD tick_start = 0;
+ DWORD tick_end = 0;
+ BOOL needs_update = FALSE;
+
+ glViewport(
+ g_ddraw->render.viewport.x, g_ddraw->render.viewport.y,
+ g_ddraw->render.viewport.width, g_ddraw->render.viewport.height);
+
+ if (g_ogl.main_program)
+ glUseProgram(g_ogl.main_program);
+ else if (g_ddraw->bpp == 16)
+ glEnable(GL_TEXTURE_2D);
+
+ while (g_ogl.use_opengl && g_ddraw->render.run &&
+ (g_ddraw->render.forcefps || WaitForSingleObject(g_ddraw->render.sem, 200) != WAIT_FAILED))
+ {
+#if _DEBUG
+ DrawFrameInfoStart();
+#endif
+
+ g_ogl.scale_w = (float)g_ddraw->width / g_ogl.surface_tex_width;
+ g_ogl.scale_h = (float)g_ddraw->height / g_ogl.surface_tex_height;
+
+ static int tex_index = 0, pal_index = 0;
+
+ BOOL scale_changed = FALSE;
+
+ if (g_ddraw->fps_limiter.tick_length > 0)
+ tick_start = timeGetTime();
+
+ EnterCriticalSection(&g_ddraw->cs);
+
+ if (g_ddraw->primary && (g_ddraw->bpp == 16 || g_ddraw->primary->palette))
+ {
+ if (g_ddraw->vhack)
+ {
+ if (util_detect_cutscene())
+ {
+ g_ogl.scale_w *= (float)CUTSCENE_WIDTH / g_ddraw->width;
+ g_ogl.scale_h *= (float)CUTSCENE_HEIGHT / g_ddraw->height;
+
+ if (!InterlockedExchange(&g_ddraw->incutscene, TRUE))
+ scale_changed = TRUE;
+ }
+ else
+ {
+ if (InterlockedExchange(&g_ddraw->incutscene, FALSE))
+ scale_changed = TRUE;
+ }
+ }
+
+ if (g_ddraw->bpp == 8 && InterlockedExchange(&g_ddraw->render.palette_updated, FALSE))
+ {
+ if (++pal_index >= TEXTURE_COUNT)
+ pal_index = 0;
+
+ glBindTexture(GL_TEXTURE_2D, g_ogl.palette_tex_ids[pal_index]);
+
+ glTexSubImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ 256,
+ 1,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ g_ddraw->primary->palette->data_bgr);
+ }
+
+ if (InterlockedExchange(&g_ddraw->render.surface_updated, FALSE))
+ {
+ if (++tex_index >= TEXTURE_COUNT)
+ tex_index = 0;
+
+ glBindTexture(GL_TEXTURE_2D, g_ogl.surface_tex_ids[tex_index]);
+
+ if (g_ogl.adjust_alignment)
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glTexSubImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ g_ddraw->width,
+ g_ddraw->height,
+ g_ogl.surface_format,
+ g_ogl.surface_type,
+ g_ddraw->primary->surface);
+
+ if (g_ogl.adjust_alignment)
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ }
+
+ static int error_check_count = 0;
+ if (error_check_count < 20)
+ {
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ error_check_count++;
+
+ if (glGetError() != GL_NO_ERROR)
+ g_ogl.use_opengl = FALSE;
+ }
+
+ if (!g_ddraw->handlemouse)
+ {
+ g_ddraw->child_window_exists = FALSE;
+ EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary);
+
+ if (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height)
+ {
+ if (g_ddraw->child_window_exists)
+ {
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ if (!needs_update)
+ {
+ glViewport(0, g_ddraw->render.height - g_ddraw->height, g_ddraw->width, g_ddraw->height);
+ needs_update = TRUE;
+ }
+ }
+ else if (needs_update)
+ {
+ glViewport(
+ g_ddraw->render.viewport.x, g_ddraw->render.viewport.y,
+ g_ddraw->render.viewport.width, g_ddraw->render.viewport.height);
+
+ needs_update = FALSE;
+ }
+ }
+ }
+ }
+
+ LeaveCriticalSection(&g_ddraw->cs);
+
+ if (scale_changed)
+ {
+ if (g_ogl.scale_program && g_ogl.main_program)
+ {
+ glBindVertexArray(g_ogl.main_vao);
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[1]);
+ GLfloat texCoord[] = {
+ 0.0f, 0.0f,
+ 0.0f, g_ogl.scale_h,
+ g_ogl.scale_w, g_ogl.scale_h,
+ g_ogl.scale_w, 0.0f,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
+ glVertexAttribPointer(g_ogl.main_tex_coord_attr_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glEnableVertexAttribArray(g_ogl.main_tex_coord_attr_loc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+ }
+ else if (g_oglu_got_version3 && g_ogl.main_program)
+ {
+ glBindVertexArray(g_ogl.main_vao);
+ glBindBuffer(GL_ARRAY_BUFFER, g_ogl.main_vbos[1]);
+ GLfloat texCoord[] = {
+ 0.0f, 0.0f,
+ g_ogl.scale_w, 0.0f,
+ g_ogl.scale_w, g_ogl.scale_h,
+ 0.0f, g_ogl.scale_h,
+ };
+ glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
+ glVertexAttribPointer(g_ogl.main_tex_coord_attr_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glEnableVertexAttribArray(g_ogl.main_tex_coord_attr_loc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+ }
+ }
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, g_ogl.surface_tex_ids[tex_index]);
+
+ if (g_ddraw->bpp == 8)
+ {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, g_ogl.palette_tex_ids[pal_index]);
+
+ glActiveTexture(GL_TEXTURE0);
+ }
+
+ if (g_ogl.scale_program && g_ogl.main_program)
+ {
+ // draw surface into framebuffer
+ glUseProgram(g_ogl.main_program);
+
+ glViewport(0, 0, g_ddraw->width, g_ddraw->height);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, g_ogl.frame_buffer_id);
+
+ glBindVertexArray(g_ogl.main_vao);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
+ glBindVertexArray(0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ if (g_ddraw->child_window_exists)
+ glViewport(0, g_ddraw->render.height - g_ddraw->height, g_ddraw->width, g_ddraw->height);
+ else
+ glViewport(
+ g_ddraw->render.viewport.x, g_ddraw->render.viewport.y,
+ g_ddraw->render.viewport.width, g_ddraw->render.viewport.height);
+
+ // apply filter
+
+ glUseProgram(g_ogl.scale_program);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, g_ogl.frame_buffer_tex_id);
+
+ static int frames = 1;
+ if (g_ogl.frame_count_uni_loc != -1)
+ glUniform1i(g_ogl.frame_count_uni_loc, frames++);
+
+ glBindVertexArray(g_ogl.scale_vao);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
+ glBindVertexArray(0);
+ }
+ else if (g_oglu_got_version3 && g_ogl.main_program)
+ {
+ glBindVertexArray(g_ogl.main_vao);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
+ glBindVertexArray(0);
+ }
+ else
+ {
+ glBegin(GL_TRIANGLE_FAN);
+ glTexCoord2f(0, 0); glVertex2f(-1, 1);
+ glTexCoord2f(g_ogl.scale_w, 0); glVertex2f(1, 1);
+ glTexCoord2f(g_ogl.scale_w, g_ogl.scale_h); glVertex2f(1, -1);
+ glTexCoord2f(0, g_ogl.scale_h); glVertex2f(-1, -1);
+ glEnd();
+ }
+
+ if (g_ddraw->bnet_active)
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ SwapBuffers(g_ddraw->render.hdc);
+
+#if _DEBUG
+ DrawFrameInfoEnd();
+#endif
+
+ if (g_ddraw->fps_limiter.tick_length > 0)
+ {
+ if (g_ddraw->fps_limiter.htimer)
+ {
+ if (g_ddraw->vsync)
+ {
+ WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
+ LARGE_INTEGER due_time = { .QuadPart = -g_ddraw->fps_limiter.tick_length_ns };
+ SetWaitableTimer(g_ddraw->fps_limiter.htimer, &due_time, 0, NULL, NULL, FALSE);
+ }
+ else
+ {
+ FILETIME ft = { 0 };
+ GetSystemTimeAsFileTime(&ft);
+
+ if (CompareFileTime((FILETIME *)&g_ddraw->fps_limiter.due_time, &ft) == -1)
+ {
+ memcpy(&g_ddraw->fps_limiter.due_time, &ft, sizeof(LARGE_INTEGER));
+ }
+ else
+ {
+ WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
+ }
+
+ g_ddraw->fps_limiter.due_time.QuadPart += g_ddraw->fps_limiter.tick_length_ns;
+ SetWaitableTimer(g_ddraw->fps_limiter.htimer, &g_ddraw->fps_limiter.due_time, 0, NULL, NULL, FALSE);
+ }
+ }
+ else
+ {
+ tick_end = timeGetTime();
+
+ if (tick_end - tick_start < g_ddraw->fps_limiter.tick_length)
+ Sleep(g_ddraw->fps_limiter.tick_length - (tick_end - tick_start));
+ }
+ }
+ }
+}
+
+static void ogl_delete_context(HGLRC context)
+{
+ HeapFree(GetProcessHeap(), 0, g_ogl.surface_tex);
+ glDeleteTextures(TEXTURE_COUNT, g_ogl.surface_tex_ids);
+
+ if (g_ddraw->bpp == 8)
+ glDeleteTextures(TEXTURE_COUNT, g_ogl.palette_tex_ids);
+
+ if (glUseProgram)
+ glUseProgram(0);
+
+ if (g_ogl.scale_program)
+ {
+ glDeleteTextures(1, &g_ogl.frame_buffer_tex_id);
+
+ if (glDeleteBuffers)
+ glDeleteBuffers(3, g_ogl.scale_vbos);
+
+ if (glDeleteFramebuffers)
+ glDeleteFramebuffers(1, &g_ogl.frame_buffer_id);
+
+ if (glDeleteVertexArrays)
+ glDeleteVertexArrays(1, &g_ogl.scale_vao);
+ }
+
+ if (glDeleteProgram)
+ {
+ if (g_ogl.main_program)
+ glDeleteProgram(g_ogl.main_program);
+
+ if (g_ogl.scale_program)
+ glDeleteProgram(g_ogl.scale_program);
+ }
+
+ if (g_oglu_got_version3)
+ {
+ if (g_ogl.main_program)
+ {
+ if (glDeleteBuffers)
+ glDeleteBuffers(3, g_ogl.main_vbos);
+
+ if (glDeleteVertexArrays)
+ glDeleteVertexArrays(1, &g_ogl.main_vao);
+ }
+ }
+
+ xwglMakeCurrent(NULL, NULL);
+ xwglDeleteContext(context);
+}
+
+static BOOL ogl_texture_upload_test()
+{
+ static char test_data[] = { 0,1,2,0,0,2,3,0,0,4,5,0,0,6,7,0,0,8,9,0 };
+
+ int i;
+ for (i = 0; i < TEXTURE_COUNT; i++)
+ {
+ memcpy(g_ogl.surface_tex, test_data, sizeof(test_data));
+
+ glBindTexture(GL_TEXTURE_2D, g_ogl.surface_tex_ids[i]);
+
+ glTexSubImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ g_ddraw->width,
+ g_ddraw->height,
+ g_ogl.surface_format,
+ g_ogl.surface_type,
+ g_ogl.surface_tex);
+
+ memset(g_ogl.surface_tex, 0, sizeof(test_data));
+
+ glGetTexImage(GL_TEXTURE_2D, 0, g_ogl.surface_format, g_ogl.surface_type, g_ogl.surface_tex);
+
+ if (memcmp(g_ogl.surface_tex, test_data, sizeof(test_data)) != 0)
+ return FALSE;
+ }
+
+ if (g_ddraw->bpp == 8)
+ {
+ for (i = 0; i < TEXTURE_COUNT; i++)
+ {
+ glBindTexture(GL_TEXTURE_2D, g_ogl.palette_tex_ids[i]);
+
+ glTexSubImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ 256,
+ 1,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ g_ogl.surface_tex);
+
+ memset(g_ogl.surface_tex, 0, sizeof(test_data));
+
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_ogl.surface_tex);
+
+ if (memcmp(g_ogl.surface_tex, test_data, sizeof(test_data)) != 0)
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static BOOL ogl_shader_test()
+{
+ BOOL result = TRUE;
+
+ if (g_ddraw->bpp != 8)
+ return result;
+
+ if (g_oglu_got_version3 && g_ogl.main_program)
+ {
+ memset(g_ogl.surface_tex, 0, g_ogl.surface_tex_height * g_ogl.surface_tex_width * sizeof(int));
+
+ GLuint fbo_id = 0;
+ glGenFramebuffers(1, &fbo_id);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
+
+ GLuint fbo_tex_id = 0;
+ glGenTextures(1, &fbo_tex_id);
+ glBindTexture(GL_TEXTURE_2D, fbo_tex_id);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, g_ogl.surface_tex_width, g_ogl.surface_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_ogl.surface_tex);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex_id, 0);
+
+ GLenum draw_buffers[1] = { GL_COLOR_ATTACHMENT0 };
+ glDrawBuffers(1, draw_buffers);
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
+ {
+ static char gray0pal[] = { 128,128,128,128 };
+
+ glBindTexture(GL_TEXTURE_2D, g_ogl.palette_tex_ids[0]);
+
+ glTexSubImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ gray0pal);
+
+ glBindTexture(GL_TEXTURE_2D, g_ogl.surface_tex_ids[0]);
+
+ glTexSubImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ g_ogl.surface_tex_width,
+ g_ogl.surface_tex_height,
+ g_ogl.surface_format,
+ GL_UNSIGNED_BYTE,
+ g_ogl.surface_tex);
+
+ glViewport(0, 0, g_ogl.surface_tex_width, g_ogl.surface_tex_height);
+
+ glUseProgram(g_ogl.main_program);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, g_ogl.palette_tex_ids[0]);
+ glActiveTexture(GL_TEXTURE0);
+
+ glBindVertexArray(g_ogl.main_vao);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
+ glBindVertexArray(0);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE0);
+
+ glBindTexture(GL_TEXTURE_2D, fbo_tex_id);
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_ogl.surface_tex);
+
+ int i;
+ for (i = 0; i < g_ogl.surface_tex_height * g_ogl.surface_tex_width; i++)
+ {
+ if (g_ogl.surface_tex[i] != 0x80808080)
+ {
+ result = FALSE;
+ break;
+ }
+ }
+ }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ if (glDeleteFramebuffers)
+ glDeleteFramebuffers(1, &fbo_id);
+
+ glDeleteTextures(1, &fbo_tex_id);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+
+ return result;
+}
diff --git a/src/render_soft.c b/src/render_soft.c
deleted file mode 100644
index 1dd6014..0000000
--- a/src/render_soft.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2011 Toni Spets
- *
- * 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.
- */
-
-#include
-#include
-
-#include "main.h"
-#include "surface.h"
-#include "opengl.h"
-
-BOOL ShowDriverWarning;
-
-DWORD WINAPI render_soft_main(void)
-{
- DWORD warningEndTick = timeGetTime() + (15 * 1000);
- char warningText[512] = { 0 };
- if (ShowDriverWarning)
- {
- ShowDriverWarning = FALSE;
-
- if (!ddraw->windowed)
- PostMessage(ddraw->hWnd, WM_AUTORENDERER, 0, 0);
-
- _snprintf(
- warningText, sizeof(warningText),
- "-WARNING- Using slow software rendering, please update your graphics card driver (%s)",
- strlen(OpenGL_Version) > 10 ? "" : OpenGL_Version);
- }
-
- Sleep(500);
-
- DWORD tickStart = 0;
- DWORD tickEnd = 0;
- int maxFPS = ddraw->render.maxfps;
- ddraw->fpsLimiter.tickLengthNs = 0;
- ddraw->fpsLimiter.ticklength = 0;
-
- if (maxFPS < 0)
- maxFPS = ddraw->mode.dmDisplayFrequency;
-
- if (maxFPS > 1000)
- maxFPS = 0;
-
- if (maxFPS > 0)
- {
- float len = 1000.0f / maxFPS;
- ddraw->fpsLimiter.tickLengthNs = len * 10000;
- ddraw->fpsLimiter.ticklength = len + (ddraw->accurateTimers ? 0.5f : 0.0f);
- }
-
- while (ddraw->render.run &&
- (ddraw->render.forcefps || WaitForSingleObject(ddraw->render.sem, 200) != WAIT_FAILED))
- {
-#if _DEBUG
- DrawFrameInfoStart();
-#endif
-
- if (ddraw->fpsLimiter.ticklength > 0)
- tickStart = timeGetTime();
-
- EnterCriticalSection(&ddraw->cs);
-
- if (ddraw->primary && (ddraw->bpp == 16 || (ddraw->primary->palette && ddraw->primary->palette->data_rgb)))
- {
- if (warningText[0])
- {
- if (timeGetTime() < warningEndTick)
- {
- RECT rc = { 0, 0, ddraw->width, ddraw->height };
- DrawText(ddraw->primary->hDC, warningText, -1, &rc, DT_NOCLIP | DT_CENTER);
- }
- else
- warningText[0] = 0;
- }
-
- BOOL scaleCutscene = ddraw->vhack && detect_cutscene();
-
- if (ddraw->vhack)
- InterlockedExchange(&ddraw->incutscene, scaleCutscene);
-
- if (!ddraw->handlemouse)
- {
- ChildWindowExists = FALSE;
- EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary);
- }
-
- if (ddraw->bnetActive)
- {
- RECT rc = { 0, 0, ddraw->render.width, ddraw->render.height };
- FillRect(ddraw->render.hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
- }
- else if (scaleCutscene)
- {
- StretchDIBits(
- ddraw->render.hDC,
- ddraw->render.viewport.x,
- ddraw->render.viewport.y,
- ddraw->render.viewport.width,
- ddraw->render.viewport.height,
- 0,
- ddraw->height - 400,
- CUTSCENE_WIDTH,
- CUTSCENE_HEIGHT,
- ddraw->primary->surface,
- ddraw->primary->bmi,
- DIB_RGB_COLORS,
- SRCCOPY);
- }
- else if (!ChildWindowExists && (ddraw->render.width != ddraw->width || ddraw->render.height != ddraw->height))
- {
- StretchDIBits(
- ddraw->render.hDC,
- ddraw->render.viewport.x,
- ddraw->render.viewport.y,
- ddraw->render.viewport.width,
- ddraw->render.viewport.height,
- 0,
- 0,
- ddraw->width,
- ddraw->height,
- ddraw->primary->surface,
- ddraw->primary->bmi,
- DIB_RGB_COLORS,
- SRCCOPY);
- }
- else
- {
- SetDIBitsToDevice(
- ddraw->render.hDC,
- 0,
- 0,
- ddraw->width,
- ddraw->height,
- 0,
- 0,
- 0,
- ddraw->height,
- ddraw->primary->surface,
- ddraw->primary->bmi,
- DIB_RGB_COLORS);
- }
- }
-
- LeaveCriticalSection(&ddraw->cs);
-
-#if _DEBUG
- DrawFrameInfoEnd();
-#endif
-
- if (ddraw->fpsLimiter.ticklength > 0)
- {
- if (ddraw->fpsLimiter.hTimer)
- {
- FILETIME ft = { 0 };
- GetSystemTimeAsFileTime(&ft);
-
- if (CompareFileTime((FILETIME*)&ddraw->fpsLimiter.dueTime, &ft) == -1)
- {
- memcpy(&ddraw->fpsLimiter.dueTime, &ft, sizeof(LARGE_INTEGER));
- }
- else
- {
- WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2);
- }
-
- ddraw->fpsLimiter.dueTime.QuadPart += ddraw->fpsLimiter.tickLengthNs;
- SetWaitableTimer(ddraw->fpsLimiter.hTimer, &ddraw->fpsLimiter.dueTime, 0, NULL, NULL, FALSE);
- }
- else
- {
- tickEnd = timeGetTime();
-
- if (tickEnd - tickStart < ddraw->fpsLimiter.ticklength)
- Sleep(ddraw->fpsLimiter.ticklength - (tickEnd - tickStart));
- }
- }
- }
-
- return TRUE;
-}
diff --git a/src/screenshot.c b/src/screenshot.c
index afa77b9..ca9c4a3 100644
--- a/src/screenshot.c
+++ b/src/screenshot.c
@@ -1,28 +1,13 @@
-/*
- * Copyright (c) 2010 Toni Spets
- *
- * 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.
- */
+#define WIN32_LEAN_AND_MEAN
#include
#include
-#include
#include
-#include "ddraw.h"
-#include "palette.h"
-#include "surface.h"
+#include "dd.h"
+#include "ddpalette.h"
+#include "ddsurface.h"
#include "lodepng.h"
-BOOL screenshot(struct IDirectDrawSurfaceImpl *src)
+BOOL ss_take_screenshot(struct IDirectDrawSurfaceImpl *src)
{
if (!src || !src->palette || !src->surface)
return FALSE;
@@ -33,7 +18,7 @@ BOOL screenshot(struct IDirectDrawSurfaceImpl *src)
char str_time[64];
time_t t = time(NULL);
- strncpy(title, ddraw->title, sizeof(ddraw->title));
+ strncpy(title, g_ddraw->title, sizeof(g_ddraw->title));
for (i = 0; i
- *
- * 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.
- */
-
-#include
-#include
-
-#include "main.h"
-#include "hook.h"
-#include "surface.h"
-#include "mouse.h"
-#include "scale_pattern.h"
-
-// enables redraw via blt/unlock if there wasn't any flip for X ms
-#define FLIP_REDRAW_TIMEOUT 1000 / 10
-
-void dump_ddbltflags(DWORD dwFlags);
-void dump_ddscaps(DWORD dwCaps);
-void dump_ddsd(DWORD dwFlags);
-DWORD WINAPI render_soft_main(void);
-void *pvBmpBits;
-
-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);
-
- if (riid && !IsEqualGUID(&IID_IDirectDrawSurface, riid))
- {
- printf(" GUID = %08X\n", ((GUID *)riid)->Data1);
-
- IDirectDrawSurface_AddRef(This);
- }
-
- *obj = This;
-
- return S_OK;
-}
-
-ULONG __stdcall ddraw_surface_AddRef(IDirectDrawSurfaceImpl *This)
-{
- printf("DirectDrawSurface::AddRef(This=%p)\n", This);
- This->Ref++;
- return This->Ref;
-}
-
-ULONG __stdcall ddraw_surface_Release(IDirectDrawSurfaceImpl *This)
-{
- printf("DirectDrawSurface::Release(This=%p)\n", This);
-
- This->Ref--;
-
- if(This->Ref == 0)
- {
- printf(" Released (%p)\n", This);
-
- if(This->caps & DDSCAPS_PRIMARYSURFACE)
- {
- EnterCriticalSection(&ddraw->cs);
- ddraw->primary = NULL;
- LeaveCriticalSection(&ddraw->cs);
- }
-
- if (This->bitmap)
- DeleteObject(This->bitmap);
- else if (This->surface)
- HeapFree(GetProcessHeap(), 0, This->surface);
-
- if (This->hDC)
- DeleteDC(This->hDC);
-
- if (This->bmi)
- HeapFree(GetProcessHeap(), 0, This->bmi);
-
- if(This->palette && This->palette != LastFreedPalette)
- {
- IDirectDrawPalette_Release(This->palette);
- }
- HeapFree(GetProcessHeap(), 0, This);
- return 0;
- }
- return This->Ref;
-}
-
-HRESULT __stdcall ddraw_surface_AddAttachedSurface(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE lpDDSurface)
-{
- printf("??? DirectDrawSurface::AddAttachedSurface(This=%p, lpDDSurface=%p)\n", This, lpDDSurface);
- IDirectDrawSurface_AddRef(lpDDSurface);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_AddOverlayDirtyRect(IDirectDrawSurfaceImpl *This, LPRECT a)
-{
- printf("??? DirectDrawSurface::AddOverlayDirtyRect(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
-{
- IDirectDrawSurfaceImpl *Source = (IDirectDrawSurfaceImpl *)lpDDSrcSurface;
-
-#if _DEBUG_X
- printf("DirectDrawSurface::Blt(This=%p, lpDestRect=%p, lpDDSrcSurface=%p, lpSrcRect=%p, dwFlags=%08X, lpDDBltFx=%p)\n", This, lpDestRect, lpDDSrcSurface, lpSrcRect, (int)dwFlags, lpDDBltFx);
-
- dump_ddbltflags(dwFlags);
-
- if(lpDestRect)
- {
- printf(" dest: l: %d t: %d r: %d b: %d\n", (int)lpDestRect->left, (int)lpDestRect->top, (int)lpDestRect->right, (int)lpDestRect->bottom);
- }
- if(lpSrcRect)
- {
- printf(" src: l: %d t: %d r: %d b: %d\n", (int)lpSrcRect->left, (int)lpSrcRect->top, (int)lpSrcRect->right, (int)lpSrcRect->bottom);
- }
-#endif
-
- RECT srcRect = { 0, 0, Source ? Source->width : 0, Source ? Source->height : 0 };
- RECT dstRect = { 0, 0, This->width, This->height };
-
- if (lpSrcRect && Source)
- memcpy(&srcRect, lpSrcRect, sizeof(srcRect));
-
- if (lpDestRect)
- memcpy(&dstRect, lpDestRect, sizeof(dstRect));
-
- // stretch or clip?
- BOOL isStretchBlt =
- ((srcRect.right - srcRect.left) != (dstRect.right - dstRect.left)) ||
- ((srcRect.bottom - srcRect.top) != (dstRect.bottom - dstRect.top));
-
- if (Source)
- {
- if (srcRect.right > Source->width)
- srcRect.right = Source->width;
-
- if (srcRect.bottom > Source->height)
- srcRect.bottom = Source->height;
- }
-
- if (dstRect.right > This->width)
- dstRect.right = This->width;
-
- if (dstRect.bottom > This->height)
- dstRect.bottom = This->height;
-
- int src_w = srcRect.right - srcRect.left;
- int src_h = srcRect.bottom - srcRect.top;
- int src_x = srcRect.left;
- int src_y = srcRect.top;
-
- int dst_w = dstRect.right - dstRect.left;
- int dst_h = dstRect.bottom - dstRect.top;
- int dst_x = dstRect.left;
- int dst_y = dstRect.top;
-
-
- if (This->surface && (dwFlags & DDBLT_COLORFILL))
- {
- unsigned char *dst = (unsigned char *)This->surface + (dst_x * This->lXPitch) + (This->lPitch * dst_y);
- unsigned char *firstRow = dst;
- unsigned int dst_pitch = dst_w * This->lXPitch;
- int x, i;
-
- if (This->bpp == 8)
- {
- unsigned char color = (unsigned char)lpDDBltFx->dwFillColor;
-
- for (i = 0; i < dst_h; i++)
- {
- memset(dst, color, dst_pitch);
- dst += This->lPitch;
- }
- }
- else if (This->bpp == 16)
- {
- unsigned short *row1 = (unsigned short *)dst;
- unsigned short color = (unsigned short)lpDDBltFx->dwFillColor;
-
- if ((color & 0xFF) == (color >> 8))
- {
- unsigned char c8 = (unsigned char)(color & 0xFF);
-
- for (i = 0; i < dst_h; i++)
- {
- memset(dst, c8, dst_pitch);
- dst += This->lPitch;
- }
- }
- else
- {
- for (x = 0; x < dst_w; x++)
- row1[x] = color;
-
- for (i = 1; i < dst_h; i++)
- {
- dst += This->lPitch;
- memcpy(dst, firstRow, dst_pitch);
- }
- }
- }
- }
-
- if (Source)
- {
- if ((dwFlags & DDBLT_KEYSRC) || (dwFlags & DDBLT_KEYSRCOVERRIDE))
- {
- DDCOLORKEY colorKey;
-
- colorKey.dwColorSpaceLowValue =
- (dwFlags & DDBLT_KEYSRCOVERRIDE) ?
- lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue : Source->colorKey.dwColorSpaceLowValue;
-
- colorKey.dwColorSpaceHighValue =
- (dwFlags & DDBLT_KEYSRCOVERRIDE) ?
- lpDDBltFx->ddckSrcColorkey.dwColorSpaceHighValue : Source->colorKey.dwColorSpaceHighValue;
-
- if (!isStretchBlt)
- {
- int width = dst_w > src_w ? src_w : dst_w;
- int height = dst_h > src_h ? src_h : dst_h;
-
- if (This->bpp == 8)
- {
- int y1, x1;
- for (y1 = 0; y1 < height; y1++)
- {
- int ydst = This->width * (y1 + dst_y);
- int ysrc = Source->width * (y1 + src_y);
-
- for (x1 = 0; x1 < width; x1++)
- {
- unsigned char c = ((unsigned char *)Source->surface)[x1 + src_x + ysrc];
-
- if (c < colorKey.dwColorSpaceLowValue || c > colorKey.dwColorSpaceHighValue)
- {
- ((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
- }
- }
- }
- }
- else if (This->bpp == 16)
- {
- int y1, x1;
- for (y1 = 0; y1 < height; y1++)
- {
- int ydst = This->width * (y1 + dst_y);
- int ysrc = Source->width * (y1 + src_y);
-
- for (x1 = 0; x1 < width; x1++)
- {
- unsigned short c = ((unsigned short *)Source->surface)[x1 + src_x + ysrc];
-
- if (c < colorKey.dwColorSpaceLowValue || c > colorKey.dwColorSpaceHighValue)
- {
- ((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
- }
- }
- }
- }
- }
- else
- {
- printf(" DDBLT_KEYSRC / DDBLT_KEYSRCOVERRIDE does not support stretching\n");
- }
- }
- else
- {
- if (!isStretchBlt)
- {
- int width = dst_w > src_w ? src_w : dst_w;
- int height = dst_h > src_h ? src_h : dst_h;
-
- unsigned char *src =
- (unsigned char *)Source->surface + (src_x * Source->lXPitch) + (Source->lPitch * src_y);
-
- unsigned char *dst =
- (unsigned char *)This->surface + (dst_x * This->lXPitch) + (This->lPitch * dst_y);
-
- unsigned int widthInBytes = width * This->lXPitch;
-
- int i;
- for (i = 0; i < height; i++)
- {
- memcpy(dst, src, widthInBytes);
-
- src += Source->lPitch;
- dst += This->lPitch;
- }
- }
- else
- {
- /* Linear scaling using integer math
- * Since the scaling pattern for x will aways be the same, the pattern itself gets pre-calculated
- * and stored in an array.
- * Y scaling pattern gets calculated during the blit loop
- */
- unsigned int x_ratio = (unsigned int)((src_w << 16) / dst_w) + 1;
- unsigned int y_ratio = (unsigned int)((src_h << 16) / dst_h) + 1;
-
- unsigned int s_src_x, s_src_y;
- unsigned int dest_base, source_base;
-
- scale_pattern *pattern = malloc((dst_w + 1) * (sizeof(scale_pattern)));
- int pattern_idx = 0;
- unsigned int last_src_x = 0;
-
- if (pattern != NULL)
- {
- pattern[pattern_idx] = (scale_pattern) { ONCE, 0, 0, 1 };
-
- /* Build the pattern! */
- int x;
- for (x = 1; x < dst_w; x++) {
- s_src_x = (x * x_ratio) >> 16;
- if (s_src_x == last_src_x)
- {
- if (pattern[pattern_idx].type == REPEAT || pattern[pattern_idx].type == ONCE)
- {
- pattern[pattern_idx].type = REPEAT;
- pattern[pattern_idx].count++;
- }
- else if (pattern[pattern_idx].type == SEQUENCE)
- {
- pattern_idx++;
- pattern[pattern_idx] = (scale_pattern) { REPEAT, x, s_src_x, 1 };
- }
- }
- else if (s_src_x == last_src_x + 1)
- {
- if (pattern[pattern_idx].type == SEQUENCE || pattern[pattern_idx].type == ONCE)
- {
- pattern[pattern_idx].type = SEQUENCE;
- pattern[pattern_idx].count++;
- }
- else if (pattern[pattern_idx].type == REPEAT)
- {
- pattern_idx++;
- pattern[pattern_idx] = (scale_pattern) { ONCE, x, s_src_x, 1 };
- }
- }
- else
- {
- pattern_idx++;
- pattern[pattern_idx] = (scale_pattern) { ONCE, x, s_src_x, 1 };
- }
- last_src_x = s_src_x;
- }
- pattern[pattern_idx + 1] = (scale_pattern) { END, 0, 0, 0 };
-
-
- /* Do the actual blitting */
- int count = 0;
- int y;
-
- for (y = 0; y < dst_h; y++) {
-
- dest_base = dst_x + This->width * (y + dst_y);
-
- s_src_y = (y * y_ratio) >> 16;
-
- source_base = src_x + Source->width * (s_src_y + src_y);
-
- pattern_idx = 0;
- scale_pattern *current = &pattern[pattern_idx];
-
- if (This->bpp == 8)
- {
- unsigned char *d, *s, v;
- unsigned char *src = (unsigned char *)Source->surface;
- unsigned char *dst = (unsigned char *)This->surface;
-
- do {
- switch (current->type)
- {
- case ONCE:
- dst[dest_base + current->dst_index] =
- src[source_base + current->src_index];
- break;
-
- case REPEAT:
- d = (dst + dest_base + current->dst_index);
- v = src[source_base + current->src_index];
-
- count = current->count;
- while (count-- > 0)
- *d++ = v;
-
- break;
-
- case SEQUENCE:
- d = dst + dest_base + current->dst_index;
- s = src + source_base + current->src_index;
-
- memcpy((void *)d, (void *)s, current->count * This->lXPitch);
- break;
-
- case END:
- default:
- break;
- }
-
- current = &pattern[++pattern_idx];
- } while (current->type != END);
- }
- else if (This->bpp == 16)
- {
- unsigned short *d, *s, v;
- unsigned short *src = (unsigned short *)Source->surface;
- unsigned short *dst = (unsigned short *)This->surface;
-
- do {
- switch (current->type)
- {
- case ONCE:
- dst[dest_base + current->dst_index] =
- src[source_base + current->src_index];
- break;
-
- case REPEAT:
- d = (dst + dest_base + current->dst_index);
- v = src[source_base + current->src_index];
-
- count = current->count;
- while (count-- > 0)
- *d++ = v;
-
- break;
-
- case SEQUENCE:
- d = dst + dest_base + current->dst_index;
- s = src + source_base + current->src_index;
-
- memcpy((void *)d, (void *)s, current->count * This->lXPitch);
- break;
-
- case END:
- default:
- break;
- }
-
- current = &pattern[++pattern_idx];
- } while (current->type != END);
- }
- }
- free(pattern);
- }
- }
-
- }
- }
-
- if((This->caps & DDSCAPS_PRIMARYSURFACE) && ddraw->render.run)
- {
- InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
-
- if (!(This->flags & DDSD_BACKBUFFERCOUNT) || This->lastFlipTick + FLIP_REDRAW_TIMEOUT < timeGetTime())
- {
- This->lastBltTick = timeGetTime();
-
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- SwitchToThread();
-
- if (ddraw->ticksLimiter.ticklength > 0)
- {
- ddraw->ticksLimiter.useBltOrFlip = TRUE;
- LimitGameTicks();
- }
- }
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_BltBatch(IDirectDrawSurfaceImpl *This, LPDDBLTBATCH a, DWORD b, DWORD c)
-{
- printf("??? IDirectDrawSurface::BltBatch(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD flags)
-{
- IDirectDrawSurfaceImpl *Source = (IDirectDrawSurfaceImpl *)lpDDSrcSurface;
-
-#if _DEBUG_X
- printf("IDirectDrawSurface::BltFast(This=%p, x=%d, y=%d, lpDDSrcSurface=%p, lpSrcRect=%p, flags=%08X)\n", This, dst_x, dst_y, lpDDSrcSurface, lpSrcRect, flags);
-
- if (flags & DDBLTFAST_NOCOLORKEY)
- {
- printf(" DDBLTFAST_NOCOLORKEY\n");
- }
-
- if (flags & DDBLTFAST_SRCCOLORKEY)
- {
- printf(" DDBLTFAST_SRCCOLORKEY\n");
- }
-
- if (flags & DDBLTFAST_DESTCOLORKEY)
- {
- printf(" DDBLTFAST_DESTCOLORKEY\n");
- }
-#endif
-
- RECT srcRect = { 0, 0, Source ? Source->width : 0, Source ? Source->height : 0 };
-
- if (lpSrcRect && Source)
- {
- memcpy(&srcRect, lpSrcRect, sizeof(srcRect));
-
- if (srcRect.right > Source->width)
- srcRect.right = Source->width;
-
- if (srcRect.bottom > Source->height)
- srcRect.bottom = Source->height;
- }
-
- int src_x = srcRect.left;
- int src_y = srcRect.top;
-
- RECT dstRect = { dst_x, dst_y, (srcRect.right - srcRect.left) + dst_x, (srcRect.bottom - srcRect.top) + dst_y };
-
- if (dstRect.right > This->width)
- dstRect.right = This->width;
-
- if (dstRect.bottom > This->height)
- dstRect.bottom = This->height;
-
- int dst_w = dstRect.right - dstRect.left;
- int dst_h = dstRect.bottom - dstRect.top;
-
- if (Source)
- {
- if (flags & DDBLTFAST_SRCCOLORKEY)
- {
- if (This->bpp == 8)
- {
- int y1, x1;
- for (y1 = 0; y1 < dst_h; y1++)
- {
- int ydst = This->width * (y1 + dst_y);
- int ysrc = Source->width * (y1 + src_y);
-
- for (x1 = 0; x1 < dst_w; x1++)
- {
- unsigned char c = ((unsigned char *)Source->surface)[x1 + src_x + ysrc];
-
- if (c < Source->colorKey.dwColorSpaceLowValue || c > Source->colorKey.dwColorSpaceHighValue)
- {
- ((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
- }
- }
- }
- }
- else if (This->bpp == 16)
- {
- int y1, x1;
- for (y1 = 0; y1 < dst_h; y1++)
- {
- int ydst = This->width * (y1 + dst_y);
- int ysrc = Source->width * (y1 + src_y);
-
- for (x1 = 0; x1 < dst_w; x1++)
- {
- unsigned short c = ((unsigned short *)Source->surface)[x1 + src_x + ysrc];
-
- if (c < Source->colorKey.dwColorSpaceLowValue || c > Source->colorKey.dwColorSpaceHighValue)
- {
- ((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
- }
- }
- }
- }
- }
- else
- {
- unsigned char *src =
- (unsigned char *)Source->surface + (src_x * Source->lXPitch) + (Source->lPitch * src_y);
-
- unsigned char *dst =
- (unsigned char *)This->surface + (dst_x * This->lXPitch) + (This->lPitch * dst_y);
-
- unsigned int widthInBytes = dst_w * This->lXPitch;
-
- int i;
- for (i = 0; i < dst_h; i++)
- {
- memcpy(dst, src, widthInBytes);
-
- src += Source->lPitch;
- dst += This->lPitch;
- }
- }
- }
-
- if ((This->caps & DDSCAPS_PRIMARYSURFACE) && ddraw->render.run)
- {
- InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
-
- DWORD time = timeGetTime();
-
- if (!(This->flags & DDSD_BACKBUFFERCOUNT) ||
- (This->lastFlipTick + FLIP_REDRAW_TIMEOUT < time && This->lastBltTick + FLIP_REDRAW_TIMEOUT < time))
- {
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- }
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_DeleteAttachedSurface(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSurface)
-{
- printf("IDirectDrawSurface::DeleteAttachedSurface(This=%p, dwFlags=%08X, lpDDSurface=%p)\n", This, (int)dwFlags, lpDDSurface);
- IDirectDrawSurface_Release(lpDDSurface);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetSurfaceDesc(IDirectDrawSurfaceImpl *This, LPDDSURFACEDESC lpDDSurfaceDesc)
-{
-#if _DEBUG_X
- printf("IDirectDrawSurface::GetSurfaceDesc(This=%p, lpDDSurfaceDesc=%p)\n", This, lpDDSurfaceDesc);
-#endif
-
- lpDDSurfaceDesc->dwSize = sizeof(DDSURFACEDESC);
- lpDDSurfaceDesc->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_LPSURFACE;
- lpDDSurfaceDesc->dwWidth = This->width;
- lpDDSurfaceDesc->dwHeight = This->height;
- lpDDSurfaceDesc->lPitch = This->lPitch;
- lpDDSurfaceDesc->lpSurface = This->surface;
- lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
- lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB;
- lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = This->bpp;
- lpDDSurfaceDesc->ddsCaps.dwCaps = This->caps | DDSCAPS_VIDEOMEMORY;
-
- if (This->bpp == 8)
- {
- lpDDSurfaceDesc->ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
- }
- else if (This->bpp == 16)
- {
- lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0xF800;
- lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x07E0;
- lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x001F;
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_EnumAttachedSurfaces(IDirectDrawSurfaceImpl *This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
-{
- printf("IDirectDrawSurface::EnumAttachedSurfaces(This=%p, lpContext=%p, lpEnumSurfacesCallback=%p)\n", This, lpContext, lpEnumSurfacesCallback);
-
- /* this is not actually complete, but Carmageddon seems to call EnumAttachedSurfaces instead of GetSurfaceDesc to get the main surface description */
- static DDSURFACEDESC ddSurfaceDesc;
- memset(&ddSurfaceDesc, 0, sizeof(DDSURFACEDESC));
-
- ddraw_surface_GetSurfaceDesc(This, &ddSurfaceDesc);
- This->caps |= DDSCAPS_BACKBUFFER; // Nox hack
- lpEnumSurfacesCallback((LPDIRECTDRAWSURFACE)This, &ddSurfaceDesc, lpContext);
-
- if ((This->caps & DDSCAPS_PRIMARYSURFACE) && (This->caps & DDSCAPS_FLIP) && !(This->caps & DDSCAPS_BACKBUFFER))
- ddraw_surface_AddRef(This);
-
- This->caps &= ~DDSCAPS_BACKBUFFER;
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_EnumOverlayZOrders(IDirectDrawSurfaceImpl *This, DWORD a, LPVOID b, LPDDENUMSURFACESCALLBACK c)
-{
- printf("??? IDirectDrawSurface::EnumOverlayZOrders(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE surface, DWORD flags)
-{
-#if _DEBUG_X
- printf("IDirectDrawSurface::Flip(This=%p, surface=%p, flags=%08X)\n", This, surface, flags);
-#endif
-
- if(This->caps & DDSCAPS_PRIMARYSURFACE && ddraw->render.run)
- {
- This->lastFlipTick = timeGetTime();
-
- InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
- SwitchToThread();
-
- if (flags & DDFLIP_WAIT)
- {
- IDirectDraw_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKEND, NULL);
- }
-
- if (ddraw->ticksLimiter.ticklength > 0)
- {
- ddraw->ticksLimiter.useBltOrFlip = TRUE;
- LimitGameTicks();
- }
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetAttachedSurface(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDdsCaps, LPDIRECTDRAWSURFACE FAR *surface)
-{
- printf("??? IDirectDrawSurface::GetAttachedSurface(This=%p, dwCaps=%08X, surface=%p)\n", This, lpDdsCaps->dwCaps, surface);
-
- if ((This->caps & DDSCAPS_PRIMARYSURFACE) && (This->caps & DDSCAPS_FLIP) && (lpDdsCaps->dwCaps & DDSCAPS_BACKBUFFER))
- {
- ddraw_surface_AddRef(This);
- *surface = (LPDIRECTDRAWSURFACE)This;
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetBltStatus(IDirectDrawSurfaceImpl *This, DWORD a)
-{
-#if _DEBUG_X
- printf("??? IDirectDrawSurface::GetBltStatus(This=%p, ...)\n", This);
-#endif
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetCaps(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDDSCaps)
-{
- printf("DirectDrawSurface::GetCaps(This=%p, lpDDSCaps=%p)\n", This, lpDDSCaps);
- lpDDSCaps->dwCaps = This->caps;
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetClipper(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWCLIPPER FAR *a)
-{
-#if _DEBUG_X
- printf("??? IDirectDrawSurface::GetClipper(This=%p, ...)\n", This);
-#endif
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY colorKey)
-{
-#if _DEBUG_X
- printf("??? DirectDrawSurface::GetColorKey(This=%p, flags=0x%08X, colorKey=%p)\n", This, flags, colorKey);
-#endif
-
- if (colorKey)
- {
- colorKey->dwColorSpaceHighValue = This->colorKey.dwColorSpaceHighValue;
- colorKey->dwColorSpaceLowValue = This->colorKey.dwColorSpaceLowValue;
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetDC(IDirectDrawSurfaceImpl *This, HDC FAR *a)
-{
-#if _DEBUG_X
- printf("IDirectDrawSurface::GetDC(This=%p, ...)\n", This);
-#endif
- if (This->width % 4)
- {
- printf(" GetDC: width=%d height=%d\n", This->width, This->height);
- }
-
- RGBQUAD *data =
- This->palette && This->palette->data_rgb ? This->palette->data_rgb :
- ddraw->primary && ddraw->primary->palette ? ddraw->primary->palette->data_rgb :
- NULL;
-
- if (data)
- SetDIBColorTable(This->hDC, 0, 256, data);
-
- *a = This->hDC;
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetFlipStatus(IDirectDrawSurfaceImpl *This, DWORD a)
-{
-#if _DEBUG_X
- printf("??? IDirectDrawSurface::GetFlipStatus(This=%p, ...)\n", This);
-#endif
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetOverlayPosition(IDirectDrawSurfaceImpl *This, LPLONG a, LPLONG b)
-{
- printf("??? IDirectDrawSurface::GetOverlayPosition(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_GetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE FAR *lplpDDPalette)
-{
- printf("DirectDrawSurface::GetPalette(This=%p, lplpDDPalette=%p)\n", This, lplpDDPalette);
- *lplpDDPalette = (LPDIRECTDRAWPALETTE)This->palette;
-
- if (This->palette)
- {
- return DD_OK;
- }
- else
- {
- return DDERR_NOPALETTEATTACHED;
- }
-}
-
-HRESULT __stdcall ddraw_surface_GetPixelFormat(IDirectDrawSurfaceImpl *This, LPDDPIXELFORMAT ddpfPixelFormat)
-{
- printf("IDirectDrawSurface::GetPixelFormat(This=%p, ...)\n", This);
-
- DWORD size = ddpfPixelFormat->dwSize;
-
- if (size == sizeof(DDPIXELFORMAT))
- {
- memset(ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT));
-
- ddpfPixelFormat->dwSize = size;
- ddpfPixelFormat->dwFlags = DDPF_RGB;
- ddpfPixelFormat->dwRGBBitCount = This->bpp;
-
- if (This->bpp == 8)
- {
- ddpfPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;
- }
- else if (This->bpp == 16)
- {
- ddpfPixelFormat->dwRBitMask = 0xF800;
- ddpfPixelFormat->dwGBitMask = 0x07E0;
- ddpfPixelFormat->dwBBitMask = 0x001F;
- }
-
- return DD_OK;
- }
-
- return DDERR_INVALIDPARAMS;
-}
-
-HRESULT __stdcall ddraw_surface_Initialize(IDirectDrawSurfaceImpl *This, LPDIRECTDRAW a, LPDDSURFACEDESC b)
-{
- printf("??? IDirectDrawSurface::Initialize(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_IsLost(IDirectDrawSurfaceImpl *This)
-{
-#if _DEBUG_X
- printf("IDirectDrawSurface::IsLost(This=%p)\n", This);
-#endif
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_Lock(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
-{
-#if _DEBUG_X
- printf("DirectDrawSurface::Lock(This=%p, lpDestRect=%p, lpDDSurfaceDesc=%p, dwFlags=%08X, hEvent=%p)\n", This, lpDestRect, lpDDSurfaceDesc, (int)dwFlags, hEvent);
-
- if(dwFlags & DDLOCK_SURFACEMEMORYPTR)
- {
- printf(" dwFlags: DDLOCK_SURFACEMEMORYPTR\n");
- }
- if(dwFlags & DDLOCK_WAIT)
- {
- printf(" dwFlags: DDLOCK_WAIT\n");
- }
- if(dwFlags & DDLOCK_EVENT)
- {
- printf(" dwFlags: DDLOCK_EVENT\n");
- }
- if(dwFlags & DDLOCK_READONLY)
- {
- printf(" dwFlags: DDLOCK_READONLY\n");
- }
- if(dwFlags & DDLOCK_WRITEONLY)
- {
- printf(" dwFlags: DDLOCK_WRITEONLY\n");
- }
-#endif
-
- return ddraw_surface_GetSurfaceDesc(This, lpDDSurfaceDesc);
-}
-
-HRESULT __stdcall ddraw_surface_ReleaseDC(IDirectDrawSurfaceImpl *This, HDC a)
-{
-#if _DEBUG_X
- printf("DirectDrawSurface::ReleaseDC(This=%p, ...)\n", This);
-#endif
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_Restore(IDirectDrawSurfaceImpl *This)
-{
-#if _DEBUG_X
- printf("??? DirectDrawSurface::Restore(This=%p)\n", This);
-#endif
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_SetClipper(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWCLIPPER a)
-{
- printf("??? DirectDrawSurface::SetClipper(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_SetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY colorKey)
-{
-#if _DEBUG_X
- printf("??? DirectDrawSurface::SetColorKey(This=%p, flags=0x%08X, colorKey=%p)\n", This, flags, colorKey);
-
- if (colorKey)
- {
- printf(" dwColorSpaceHighValue=%d\n", colorKey->dwColorSpaceHighValue);
- printf(" dwColorSpaceLowValue=%d\n", colorKey->dwColorSpaceLowValue);
- }
-#endif
-
- if (colorKey)
- {
- This->colorKey.dwColorSpaceHighValue = colorKey->dwColorSpaceHighValue;
- This->colorKey.dwColorSpaceLowValue = colorKey->dwColorSpaceLowValue;
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_SetOverlayPosition(IDirectDrawSurfaceImpl *This, LONG a, LONG b)
-{
- printf("??? DirectDrawSurface::SetOverlayPosition(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_SetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE lpDDPalette)
-{
- printf("DirectDrawSurface::SetPalette(This=%p, lpDDPalette=%p)\n", This, lpDDPalette);
-
- IDirectDrawPalette_AddRef(lpDDPalette);
-
- if(This->palette)
- {
- IDirectDrawPalette_Release(This->palette);
- }
-
- EnterCriticalSection(&ddraw->cs);
-
- This->palette = (IDirectDrawPaletteImpl *)lpDDPalette;
- This->palette->data_rgb = &This->bmi->bmiColors[0];
-
- int i;
- for (i = 0; i < 256; i++)
- {
- This->palette->data_rgb[i].rgbRed = This->palette->data_bgr[i] & 0xFF;
- This->palette->data_rgb[i].rgbGreen = (This->palette->data_bgr[i] >> 8) & 0xFF;
- This->palette->data_rgb[i].rgbBlue = (This->palette->data_bgr[i] >> 16) & 0xFF;
- This->palette->data_rgb[i].rgbReserved = 0;
- }
-
- LeaveCriticalSection(&ddraw->cs);
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
-{
-#if _DEBUG_X
- printf("DirectDrawSurface::Unlock(This=%p, lpRect=%p)\n", This, lpRect);
-#endif
-
- HWND hWnd = ddraw->bnetActive ? FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL) : NULL;
- if (hWnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
- {
- if (ddraw->primary->palette && ddraw->primary->palette->data_rgb)
- SetDIBColorTable(ddraw->primary->hDC, 0, 256, ddraw->primary->palette->data_rgb);
-
- //GdiTransparentBlt idea taken from Aqrit's war2 ddraw
-
- RGBQUAD quad;
- GetDIBColorTable(ddraw->primary->hDC, 0xFE, 1, &quad);
- COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
- BOOL erase = FALSE;
-
- do
- {
- RECT rc;
- if (fake_GetWindowRect(hWnd, &rc))
- {
- if (rc.bottom - rc.top == 479)
- erase = TRUE;
-
- HDC hDC = GetDCEx(hWnd, NULL, DCX_PARENTCLIP | DCX_CACHE);
-
- GdiTransparentBlt(
- hDC,
- 0,
- 0,
- rc.right - rc.left,
- rc.bottom - rc.top,
- ddraw->primary->hDC,
- rc.left,
- rc.top,
- rc.right - rc.left,
- rc.bottom - rc.top,
- color
- );
-
- ReleaseDC(hWnd, hDC);
- }
-
- } while ((hWnd = FindWindowEx(HWND_DESKTOP, hWnd, "SDlgDialog", NULL)));
-
- if (erase)
- {
- BOOL x = ddraw->ticksLimiter.useBltOrFlip;
-
- DDBLTFX fx = { .dwFillColor = 0xFE };
- IDirectDrawSurface_Blt(This, NULL, NULL, NULL, DDBLT_COLORFILL, &fx);
-
- ddraw->ticksLimiter.useBltOrFlip = x;
- }
- }
-
- if ((This->caps & DDSCAPS_PRIMARYSURFACE) && ddraw->render.run)
- {
- InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
-
- DWORD time = timeGetTime();
-
- if (!(This->flags & DDSD_BACKBUFFERCOUNT) ||
- (This->lastFlipTick + FLIP_REDRAW_TIMEOUT < time && This->lastBltTick + FLIP_REDRAW_TIMEOUT < time))
- {
- ReleaseSemaphore(ddraw->render.sem, 1, NULL);
-
- if (ddraw->ticksLimiter.ticklength > 0 && !ddraw->ticksLimiter.useBltOrFlip)
- LimitGameTicks();
- }
- }
-
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_UpdateOverlay(IDirectDrawSurfaceImpl *This, LPRECT a, LPDIRECTDRAWSURFACE b, LPRECT c, DWORD d, LPDDOVERLAYFX e)
-{
- printf("??? DirectDrawSurface::UpdateOverlay(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_UpdateOverlayDisplay(IDirectDrawSurfaceImpl *This, DWORD a)
-{
- printf("??? DirectDrawSurface::UpdateOverlayDisplay(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-HRESULT __stdcall ddraw_surface_UpdateOverlayZOrder(IDirectDrawSurfaceImpl *This, DWORD a, LPDIRECTDRAWSURFACE b)
-{
- printf("??? DirectDrawSurface::UpdateOverlayZOrder(This=%p, ...)\n", This);
- return DD_OK;
-}
-
-struct IDirectDrawSurfaceImplVtbl siface =
-{
- /* IUnknown */
- ddraw_surface_QueryInterface,
- ddraw_surface_AddRef,
- ddraw_surface_Release,
- /* IDirectDrawSurface */
- ddraw_surface_AddAttachedSurface,
- ddraw_surface_AddOverlayDirtyRect,
- ddraw_surface_Blt,
- ddraw_surface_BltBatch,
- ddraw_surface_BltFast,
- ddraw_surface_DeleteAttachedSurface,
- ddraw_surface_EnumAttachedSurfaces,
- ddraw_surface_EnumOverlayZOrders,
- ddraw_surface_Flip,
- ddraw_surface_GetAttachedSurface,
- ddraw_surface_GetBltStatus,
- ddraw_surface_GetCaps,
- ddraw_surface_GetClipper,
- ddraw_surface_GetColorKey,
- ddraw_surface_GetDC,
- ddraw_surface_GetFlipStatus,
- ddraw_surface_GetOverlayPosition,
- ddraw_surface_GetPalette,
- ddraw_surface_GetPixelFormat,
- ddraw_surface_GetSurfaceDesc,
- ddraw_surface_Initialize,
- ddraw_surface_IsLost,
- ddraw_surface_Lock,
- ddraw_surface_ReleaseDC,
- ddraw_surface_Restore,
- ddraw_surface_SetClipper,
- ddraw_surface_SetColorKey,
- ddraw_surface_SetOverlayPosition,
- ddraw_surface_SetPalette,
- ddraw_surface_Unlock,
- ddraw_surface_UpdateOverlay,
- ddraw_surface_UpdateOverlayDisplay,
- ddraw_surface_UpdateOverlayZOrder
-};
-
-HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR *lpDDSurface, IUnknown FAR * unkOuter)
-{
- printf("DirectDraw::CreateSurface(This=%p, lpDDSurfaceDesc=%p, lpDDSurface=%p, unkOuter=%p)\n", This, lpDDSurfaceDesc, lpDDSurface, unkOuter);
-
- dump_ddsd(lpDDSurfaceDesc->dwFlags);
-
- IDirectDrawSurfaceImpl *Surface = (IDirectDrawSurfaceImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
-
- Surface->lpVtbl = &siface;
-
- lpDDSurfaceDesc->dwFlags |= DDSD_CAPS;
-
- /* private stuff */
- Surface->bpp = This->bpp;
- Surface->flags = lpDDSurfaceDesc->dwFlags;
-
- if(lpDDSurfaceDesc->dwFlags & DDSD_CAPS)
- {
- if(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- {
- ddraw->primary = Surface;
-
- Surface->width = This->width;
- Surface->height = This->height;
- }
-
- dump_ddscaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
- Surface->caps = lpDDSurfaceDesc->ddsCaps.dwCaps;
- }
-
- if( !(lpDDSurfaceDesc->dwFlags & DDSD_CAPS) || !(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) )
- {
- Surface->width = lpDDSurfaceDesc->dwWidth;
- Surface->height = lpDDSurfaceDesc->dwHeight;
- }
-
- if(Surface->width && Surface->height)
- {
- if (Surface->width == 622 && Surface->height == 51) Surface->width = 624; //AoE2
- if (Surface->width == 71 && Surface->height == 24) Surface->width = 72; //Commandos
-
- Surface->bmi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
- Surface->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- Surface->bmi->bmiHeader.biWidth = Surface->width;
- Surface->bmi->bmiHeader.biHeight = -(Surface->height + 200);
- Surface->bmi->bmiHeader.biPlanes = 1;
- Surface->bmi->bmiHeader.biBitCount = Surface->bpp;
- Surface->bmi->bmiHeader.biCompression = Surface->bpp == 16 ? BI_BITFIELDS : BI_RGB;
-
- WORD cClrBits = (WORD)(Surface->bmi->bmiHeader.biPlanes * Surface->bmi->bmiHeader.biBitCount);
- if (cClrBits < 24)
- Surface->bmi->bmiHeader.biClrUsed = (1 << cClrBits);
-
- Surface->bmi->bmiHeader.biSizeImage = ((Surface->width * cClrBits + 31) & ~31) / 8 * Surface->height;
-
- if (Surface->bpp == 8)
- {
- int i;
- for (i = 0; i < 256; i++)
- {
- Surface->bmi->bmiColors[i].rgbRed = i;
- Surface->bmi->bmiColors[i].rgbGreen = i;
- Surface->bmi->bmiColors[i].rgbBlue = i;
- Surface->bmi->bmiColors[i].rgbReserved = 0;
- }
- }
- else if (Surface->bpp == 16)
- {
- ((DWORD *)Surface->bmi->bmiColors)[0] = 0xF800;
- ((DWORD *)Surface->bmi->bmiColors)[1] = 0x07E0;
- ((DWORD *)Surface->bmi->bmiColors)[2] = 0x001F;
- }
-
- Surface->lXPitch = Surface->bpp / 8;
- Surface->lPitch = Surface->width * Surface->lXPitch;
-
- Surface->hDC = CreateCompatibleDC(ddraw->render.hDC);
- Surface->bitmap = CreateDIBSection(Surface->hDC, Surface->bmi, DIB_RGB_COLORS, (void **)&Surface->surface, NULL, 0);
- Surface->bmi->bmiHeader.biHeight = -Surface->height;
-
- if (!Surface->bitmap)
- Surface->surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Surface->lPitch * (Surface->height + 200) * Surface->lXPitch);
-
- if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- pvBmpBits = Surface->surface;
-
- SelectObject(Surface->hDC, Surface->bitmap);
- }
-
- if (lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
- {
- printf(" dwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount);
- }
-
- printf(" Surface = %p (%dx%d@%d)\n", Surface, (int)Surface->width, (int)Surface->height, (int)Surface->bpp);
-
- *lpDDSurface = (LPDIRECTDRAWSURFACE)Surface;
-
- Surface->Ref = 0;
- ddraw_surface_AddRef(Surface);
-
- return DD_OK;
-}
-
-void dump_ddbltflags(DWORD dwFlags)
-{
- if (dwFlags & DDBLT_ALPHADEST) {
- printf(" DDBLT_ALPHADEST\n");
- }
- if (dwFlags & DDBLT_ALPHADESTCONSTOVERRIDE) {
- printf(" DDBLT_ALPHADESTCONSTOVERRIDE\n");
- }
- if (dwFlags & DDBLT_ALPHADESTNEG) {
- printf(" DDBLT_ALPHADESTNEG\n");
- }
- if (dwFlags & DDBLT_ALPHADESTSURFACEOVERRIDE) {
- printf(" DDBLT_ALPHADESTSURFACEOVERRIDE\n");
- }
- if (dwFlags & DDBLT_ALPHAEDGEBLEND) {
- printf(" DDBLT_ALPHAEDGEBLEND\n");
- }
- if (dwFlags & DDBLT_ALPHASRC) {
- printf(" DDBLT_ALPHASRC\n");
- }
- if (dwFlags & DDBLT_ALPHASRCCONSTOVERRIDE) {
- printf(" DDBLT_ALPHASRCCONSTOVERRIDE\n");
- }
- if (dwFlags & DDBLT_ALPHASRCNEG) {
- printf(" DDBLT_ALPHASRCNEG\n");
- }
- if (dwFlags & DDBLT_ALPHASRCSURFACEOVERRIDE) {
- printf(" DDBLT_ALPHASRCSURFACEOVERRIDE\n");
- }
- if (dwFlags & DDBLT_ASYNC) {
- printf(" DDBLT_ASYNC\n");
- }
- if (dwFlags & DDBLT_COLORFILL) {
- printf(" DDBLT_COLORFILL\n");
- }
- if (dwFlags & DDBLT_DDFX) {
- printf(" DDBLT_DDFX\n");
- }
- if (dwFlags & DDBLT_DDROPS) {
- printf(" DDBLT_DDROPS\n");
- }
- if (dwFlags & DDBLT_KEYDEST) {
- printf(" DDBLT_KEYDEST\n");
- }
- if (dwFlags & DDBLT_KEYDESTOVERRIDE) {
- printf(" DDBLT_KEYDESTOVERRIDE\n");
- }
- if (dwFlags & DDBLT_KEYSRC) {
- printf(" DDBLT_KEYSRC\n");
- }
- if (dwFlags & DDBLT_KEYSRCOVERRIDE) {
- printf(" DDBLT_KEYSRCOVERRIDE\n");
- }
- if (dwFlags & DDBLT_ROP) {
- printf(" DDBLT_ROP\n");
- }
- if (dwFlags & DDBLT_ROTATIONANGLE) {
- printf(" DDBLT_ROTATIONANGLE\n");
- }
- if (dwFlags & DDBLT_ZBUFFER) {
- printf(" DDBLT_ZBUFFER\n");
- }
- if (dwFlags & DDBLT_ZBUFFERDESTCONSTOVERRIDE) {
- printf(" DDBLT_ZBUFFERDESTCONSTOVERRIDE\n");
- }
- if (dwFlags & DDBLT_ZBUFFERDESTOVERRIDE) {
- printf(" DDBLT_ZBUFFERDESTOVERRIDE\n");
- }
- if (dwFlags & DDBLT_ZBUFFERSRCCONSTOVERRIDE) {
- printf(" DDBLT_ZBUFFERSRCCONSTOVERRIDE\n");
- }
- if (dwFlags & DDBLT_ZBUFFERSRCOVERRIDE) {
- printf(" DDBLT_ZBUFFERSRCOVERRIDE\n");
- }
- if (dwFlags & DDBLT_WAIT) {
- printf(" DDBLT_WAIT\n");
- }
- if (dwFlags & DDBLT_DEPTHFILL) {
- printf(" DDBLT_DEPTHFILL\n");
- }
-}
-
-void dump_ddscaps(DWORD dwCaps)
-{
- if (dwCaps & DDSCAPS_ALPHA)
- {
- printf(" DDSCAPS_ALPHA\n");
- }
- if (dwCaps & DDSCAPS_BACKBUFFER)
- {
- printf(" DDSCAPS_BACKBUFFER\n");
- }
- if (dwCaps & DDSCAPS_FLIP)
- {
- printf(" DDSCAPS_FLIP\n");
- }
- if (dwCaps & DDSCAPS_FRONTBUFFER)
- {
- printf(" DDSCAPS_FRONTBUFFER\n");
- }
- if (dwCaps & DDSCAPS_PALETTE)
- {
- printf(" DDSCAPS_PALETTE\n");
- }
- if (dwCaps & DDSCAPS_TEXTURE)
- {
- printf(" DDSCAPS_TEXTURE\n");
- }
- if(dwCaps & DDSCAPS_PRIMARYSURFACE)
- {
- printf(" DDSCAPS_PRIMARYSURFACE\n");
- }
- if(dwCaps & DDSCAPS_OFFSCREENPLAIN)
- {
- printf(" DDSCAPS_OFFSCREENPLAIN\n");
- }
- if(dwCaps & DDSCAPS_VIDEOMEMORY)
- {
- printf(" DDSCAPS_VIDEOMEMORY\n");
- }
- if(dwCaps & DDSCAPS_LOCALVIDMEM)
- {
- printf(" DDSCAPS_LOCALVIDMEM\n");
- }
-}
-
-void dump_ddsd(DWORD dwFlags)
-{
- if(dwFlags & DDSD_CAPS)
- {
- printf(" DDSD_CAPS\n");
- }
- if(dwFlags & DDSD_HEIGHT)
- {
- printf(" DDSD_HEIGHT\n");
- }
- if(dwFlags & DDSD_WIDTH)
- {
- printf(" DDSD_WIDTH\n");
- }
- if(dwFlags & DDSD_PITCH)
- {
- printf(" DDSD_PITCH\n");
- }
- if(dwFlags & DDSD_BACKBUFFERCOUNT)
- {
- printf(" DDSD_BACKBUFFERCOUNT\n");
- }
- if(dwFlags & DDSD_ZBUFFERBITDEPTH)
- {
- printf(" DDSD_ZBUFFERBITDEPTH\n");
- }
- if(dwFlags & DDSD_ALPHABITDEPTH)
- {
- printf(" DDSD_ALPHABITDEPTH\n");
- }
- if(dwFlags & DDSD_LPSURFACE)
- {
- printf(" DDSD_LPSURFACE\n");
- }
- if(dwFlags & DDSD_PIXELFORMAT)
- {
- printf(" DDSD_PIXELFORMAT\n");
- }
- if(dwFlags & DDSD_CKDESTOVERLAY)
- {
- printf(" DDSD_CKDESTOVERLAY\n");
- }
- if(dwFlags & DDSD_CKDESTBLT)
- {
- printf(" DDSD_CKDESTBLT\n");
- }
- if(dwFlags & DDSD_CKSRCOVERLAY)
- {
- printf(" DDSD_CKSRCOVERLAY\n");
- }
- if(dwFlags & DDSD_CKSRCBLT)
- {
- printf(" DDSD_CKSRCBLT\n");
- }
- if(dwFlags & DDSD_MIPMAPCOUNT)
- {
- printf(" DDSD_MIPMAPCOUNT\n");
- }
- if(dwFlags & DDSD_REFRESHRATE)
- {
- printf(" DDSD_REFRESHRATE\n");
- }
- if(dwFlags & DDSD_LINEARSIZE)
- {
- printf(" DDSD_LINEARSIZE\n");
- }
- if(dwFlags & DDSD_ALL)
- {
- printf(" DDSD_ALL\n");
- }
-}
diff --git a/src/utils.c b/src/utils.c
new file mode 100644
index 0000000..8427d81
--- /dev/null
+++ b/src/utils.c
@@ -0,0 +1,301 @@
+#include
+#include "ddraw.h"
+#include "dd.h"
+#include "ddsurface.h"
+#include "hook.h"
+#include "mouse.h"
+#include "render_d3d9.h"
+#include "utils.h"
+#include "config.h"
+
+
+void util_limit_game_ticks()
+{
+ if (g_ddraw->ticks_limiter.htimer)
+ {
+ FILETIME ft = { 0 };
+ GetSystemTimeAsFileTime(&ft);
+
+ if (CompareFileTime((FILETIME *)&g_ddraw->ticks_limiter.due_time, &ft) == -1)
+ {
+ memcpy(&g_ddraw->ticks_limiter.due_time, &ft, sizeof(LARGE_INTEGER));
+ }
+ else
+ {
+ WaitForSingleObject(g_ddraw->ticks_limiter.htimer, g_ddraw->ticks_limiter.tick_length * 2);
+ }
+
+ g_ddraw->ticks_limiter.due_time.QuadPart += g_ddraw->ticks_limiter.tick_length_ns;
+ SetWaitableTimer(g_ddraw->ticks_limiter.htimer, &g_ddraw->ticks_limiter.due_time, 0, NULL, NULL, FALSE);
+ }
+ else
+ {
+ static DWORD next_game_tick;
+ if (!next_game_tick)
+ {
+ next_game_tick = timeGetTime();
+ return;
+ }
+ next_game_tick += g_ddraw->ticks_limiter.tick_length;
+ DWORD tick_count = timeGetTime();
+
+ int sleep_time = next_game_tick - tick_count;
+ if (sleep_time <= 0 || sleep_time > g_ddraw->ticks_limiter.tick_length)
+ next_game_tick = tick_count;
+ else
+ Sleep(sleep_time);
+ }
+}
+
+void util_update_bnet_pos(int new_x, int new_y)
+{
+ static int old_x = -32000;
+ static int old_y = -32000;
+
+ if (old_x == -32000 || old_y == -32000 || !g_ddraw->bnet_active)
+ {
+ old_x = new_x;
+ old_y = new_y;
+ return;
+ }
+
+ POINT pt = { 0, 0 };
+ real_ClientToScreen(g_ddraw->hwnd, &pt);
+
+ RECT mainrc;
+ SetRect(&mainrc, pt.x, pt.y, pt.x + g_ddraw->width, pt.y + g_ddraw->height);
+
+ int adj_y = 0;
+ int adj_x = 0;
+
+ HWND hwnd = FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL);
+
+ while (hwnd != NULL)
+ {
+ RECT rc;
+ real_GetWindowRect(hwnd, &rc);
+
+ OffsetRect(&rc, new_x - old_x, new_y - old_y);
+
+ real_SetWindowPos(
+ hwnd,
+ 0,
+ rc.left,
+ rc.top,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+ if (rc.bottom - rc.top <= g_ddraw->height)
+ {
+ if (rc.bottom > mainrc.bottom && abs(mainrc.bottom - rc.bottom) > abs(adj_y))
+ adj_y = mainrc.bottom - rc.bottom;
+ else if (rc.top < mainrc.top && abs(mainrc.top - rc.top) > abs(adj_y))
+ adj_y = mainrc.top - rc.top;
+ }
+
+ if (rc.right - rc.left <= g_ddraw->width)
+ {
+ if (rc.right > mainrc.right && abs(mainrc.right - rc.right) > abs(adj_x))
+ adj_x = mainrc.right - rc.right;
+ else if (rc.left < mainrc.left && abs(mainrc.left - rc.left) > abs(adj_x))
+ adj_x = mainrc.left - rc.left;
+ }
+
+ hwnd = FindWindowEx(HWND_DESKTOP, hwnd, "SDlgDialog", NULL);
+ }
+
+ if (adj_x || adj_y)
+ {
+ HWND hwnd = FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL);
+
+ while (hwnd != NULL)
+ {
+ RECT rc;
+ real_GetWindowRect(hwnd, &rc);
+
+ OffsetRect(&rc, adj_x, adj_y);
+
+ real_SetWindowPos(
+ hwnd,
+ 0,
+ rc.left,
+ rc.top,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+ hwnd = FindWindowEx(HWND_DESKTOP, hwnd, "SDlgDialog", NULL);
+ }
+ }
+
+ old_x = new_x;
+ old_y = new_y;
+}
+
+BOOL util_get_lowest_resolution(float ratio, SIZE *out_res, DWORD min_width, DWORD min_height, DWORD max_width, DWORD max_height)
+{
+ BOOL result = FALSE;
+ int org_ratio = (int)(ratio * 100);
+ SIZE lowest = { .cx = max_width + 1, .cy = max_height + 1 };
+ DWORD i = 0;
+ DEVMODE m;
+ memset(&m, 0, sizeof(DEVMODE));
+ m.dmSize = sizeof(DEVMODE);
+
+ while (EnumDisplaySettings(NULL, i, &m))
+ {
+ if (m.dmPelsWidth >= min_width &&
+ m.dmPelsHeight >= min_height &&
+ m.dmPelsWidth <= max_width &&
+ m.dmPelsHeight <= max_height &&
+ m.dmPelsWidth < lowest.cx &&
+ m.dmPelsHeight < lowest.cy)
+ {
+ int res_ratio = (int)(((float)m.dmPelsWidth / m.dmPelsHeight) * 100);
+
+ if (res_ratio == org_ratio)
+ {
+ result = TRUE;
+ out_res->cx = lowest.cx = m.dmPelsWidth;
+ out_res->cy = lowest.cy = m.dmPelsHeight;
+ }
+ }
+ memset(&m, 0, sizeof(DEVMODE));
+ m.dmSize = sizeof(DEVMODE);
+ i++;
+ }
+
+ return result;
+}
+
+void util_toggle_fullscreen()
+{
+ if (g_ddraw->bnet_active)
+ return;
+
+ if (g_ddraw->windowed)
+ {
+ mouse_unlock();
+ g_config.window_state = g_ddraw->windowed = FALSE;
+ real_SetWindowLongA(g_ddraw->hwnd, GWL_STYLE, GetWindowLong(g_ddraw->hwnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
+ g_ddraw->altenter = TRUE;
+ dd_SetDisplayMode(g_ddraw->width, g_ddraw->height, g_ddraw->bpp);
+ util_update_bnet_pos(0, 0);
+ mouse_lock();
+ }
+ else
+ {
+ mouse_unlock();
+ g_config.window_state = g_ddraw->windowed = TRUE;
+
+ if (g_ddraw->renderer == d3d9_render_main)
+ d3d9_reset();
+ else
+ ChangeDisplaySettings(NULL, g_ddraw->bnet_active ? CDS_FULLSCREEN : 0);
+
+ dd_SetDisplayMode(g_ddraw->width, g_ddraw->height, g_ddraw->bpp);
+ mouse_lock();
+ }
+}
+
+BOOL util_unadjust_window_rect(LPRECT prc, DWORD dwStyle, BOOL fMenu, DWORD dwExStyle)
+{
+ RECT rc;
+ SetRectEmpty(&rc);
+
+ BOOL fRc = AdjustWindowRectEx(&rc, dwStyle, fMenu, dwExStyle);
+ if (fRc)
+ {
+ prc->left -= rc.left;
+ prc->top -= rc.top;
+ prc->right -= rc.right;
+ prc->bottom -= rc.bottom;
+ }
+
+ return fRc;
+}
+
+void util_set_window_rect(int x, int y, int width, int height, UINT flags)
+{
+ if (g_ddraw->windowed)
+ {
+ if (g_ddraw->render.thread)
+ {
+ EnterCriticalSection(&g_ddraw->cs);
+ g_ddraw->render.run = FALSE;
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ LeaveCriticalSection(&g_ddraw->cs);
+
+ WaitForSingleObject(g_ddraw->render.thread, INFINITE);
+ g_ddraw->render.thread = NULL;
+ }
+
+ if ((flags & SWP_NOMOVE) == 0)
+ {
+ g_config.window_rect.left = x;
+ g_config.window_rect.top = y;
+ }
+
+ if ((flags & SWP_NOSIZE) == 0)
+ {
+ g_config.window_rect.bottom = height;
+ g_config.window_rect.right = width;
+ }
+
+ dd_SetDisplayMode(g_ddraw->width, g_ddraw->height, g_ddraw->bpp);
+ }
+}
+
+BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam)
+{
+ IDirectDrawSurfaceImpl* this = (IDirectDrawSurfaceImpl*)lparam;
+
+ RECT size;
+ RECT pos;
+
+ if (real_GetClientRect(hwnd, &size) && real_GetWindowRect(hwnd, &pos) && size.right > 1 && size.bottom > 1)
+ {
+ g_ddraw->child_window_exists = TRUE;
+
+ HDC hdc = GetDC(hwnd);
+
+ MapWindowPoints(HWND_DESKTOP, g_ddraw->hwnd, (LPPOINT)&pos, 2);
+
+ BitBlt(hdc, 0, 0, size.right, size.bottom, this->hdc, pos.left, pos.top, SRCCOPY);
+
+ ReleaseDC(hwnd, hdc);
+ }
+
+ return FALSE;
+}
+
+static unsigned char util_get_pixel(int x, int y)
+{
+ return ((unsigned char*)g_ddraw->primary->surface)[y * g_ddraw->primary->l_pitch + x * g_ddraw->primary->lx_pitch];
+}
+
+BOOL util_detect_cutscene()
+{
+ static int* in_movie = (int*)0x00665F58;
+ static int* is_vqa_640 = (int*)0x0065D7BC;
+ static BYTE* should_stretch = (BYTE*)0x00607D78;
+
+ if (g_ddraw->width <= CUTSCENE_WIDTH || g_ddraw->height <= CUTSCENE_HEIGHT)
+ return FALSE;
+
+ if (g_ddraw->isredalert)
+ {
+ if ((*in_movie && !*is_vqa_640) || *should_stretch)
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ else if (g_ddraw->iscnc1)
+ {
+ return util_get_pixel(CUTSCENE_WIDTH + 1, 0) == 0 || util_get_pixel(CUTSCENE_WIDTH + 5, 1) == 0 ? TRUE : FALSE;
+ }
+
+ return FALSE;
+}
diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c
new file mode 100644
index 0000000..f33cd0c
--- /dev/null
+++ b/src/winapi_hooks.c
@@ -0,0 +1,425 @@
+#include
+#include "dd.h"
+#include "hook.h"
+#include "config.h"
+#include "utils.h"
+#include "mouse.h"
+#include "wndproc.h"
+
+
+BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint)
+{
+ POINT pt, realpt;
+
+ if (!real_GetCursorPos(&pt) || !g_ddraw)
+ return FALSE;
+
+ realpt.x = pt.x;
+ realpt.y = pt.y;
+
+ if(g_ddraw->locked && (!g_ddraw->windowed || real_ScreenToClient(g_ddraw->hwnd, &pt)))
+ {
+ //fallback solution for possible ClipCursor failure
+ int diffx = 0, diffy = 0;
+ int max_width = g_ddraw->adjmouse ? g_ddraw->render.viewport.width : g_ddraw->width;
+ int max_height = g_ddraw->adjmouse ? g_ddraw->render.viewport.height : g_ddraw->height;
+
+ if (pt.x < 0)
+ {
+ diffx = pt.x;
+ pt.x = 0;
+ }
+
+ if (pt.y < 0)
+ {
+ diffy = pt.y;
+ pt.y = 0;
+ }
+
+ if (pt.x > max_width)
+ {
+ diffx = pt.x - max_width;
+ pt.x = max_width;
+ }
+
+ if (pt.y > max_height)
+ {
+ diffy = pt.y - max_height;
+ pt.y = max_height;
+ }
+
+ if (diffx || diffy)
+ real_SetCursorPos(realpt.x - diffx, realpt.y - diffy);
+
+
+ if(g_ddraw->adjmouse)
+ {
+ g_ddraw->cursor.x = pt.x * g_ddraw->render.unscale_w;
+ g_ddraw->cursor.y = pt.y * g_ddraw->render.unscale_h;
+ }
+ else
+ {
+ g_ddraw->cursor.x = pt.x;
+ g_ddraw->cursor.y = pt.y;
+ }
+
+ if (g_ddraw->vhack && InterlockedExchangeAdd(&g_ddraw->incutscene, 0))
+ {
+ diffx = 0;
+ diffy = 0;
+
+ if (g_ddraw->cursor.x > CUTSCENE_WIDTH)
+ {
+ diffx = g_ddraw->cursor.x - CUTSCENE_WIDTH;
+ g_ddraw->cursor.x = CUTSCENE_WIDTH;
+ }
+
+ if (g_ddraw->cursor.y > CUTSCENE_HEIGHT)
+ {
+ diffy = g_ddraw->cursor.y - CUTSCENE_HEIGHT;
+ g_ddraw->cursor.y = CUTSCENE_HEIGHT;
+ }
+
+ if (diffx || diffy)
+ real_SetCursorPos(realpt.x - diffx, realpt.y - diffy);
+ }
+ }
+
+ if (lpPoint)
+ {
+ lpPoint->x = (int)g_ddraw->cursor.x;
+ lpPoint->y = (int)g_ddraw->cursor.y;
+ }
+
+ return TRUE;
+}
+
+BOOL WINAPI fake_ClipCursor(const RECT *lpRect)
+{
+ if(lpRect)
+ {
+ /* hack for 640x480 mode */
+ if (lpRect->bottom == 400 && g_ddraw && g_ddraw->height == 480)
+ g_ddraw->mouse_y_adjust = 40;
+ }
+ return TRUE;
+}
+
+int WINAPI fake_ShowCursor(BOOL bShow)
+{
+ static int count;
+
+ if (g_ddraw && !g_ddraw->handlemouse)
+ return real_ShowCursor(bShow);
+
+ return bShow ? ++count : --count;
+}
+
+HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor)
+{
+ if (g_ddraw && !g_ddraw->handlemouse)
+ return real_SetCursor(hCursor);
+
+ return NULL;
+}
+
+BOOL WINAPI fake_GetWindowRect(HWND hWnd, LPRECT lpRect)
+{
+ if (lpRect && g_ddraw)
+ {
+ if (g_ddraw->hwnd == hWnd)
+ {
+ lpRect->bottom = g_ddraw->height;
+ lpRect->left = 0;
+ lpRect->right = g_ddraw->width;
+ lpRect->top = 0;
+
+ return TRUE;
+ }
+ else
+ {
+ if (real_GetWindowRect(hWnd, lpRect))
+ {
+ MapWindowPoints(HWND_DESKTOP, g_ddraw->hwnd, (LPPOINT)lpRect, 2);
+
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ }
+
+ return real_GetWindowRect(hWnd, lpRect);
+}
+
+BOOL WINAPI fake_GetClientRect(HWND hWnd, LPRECT lpRect)
+{
+ if (lpRect && g_ddraw && g_ddraw->hwnd == hWnd)
+ {
+ lpRect->bottom = g_ddraw->height;
+ lpRect->left = 0;
+ lpRect->right = g_ddraw->width;
+ lpRect->top = 0;
+
+ return TRUE;
+ }
+
+ return real_GetClientRect(hWnd, lpRect);
+}
+
+BOOL WINAPI fake_ClientToScreen(HWND hWnd, LPPOINT lpPoint)
+{
+ if (g_ddraw && g_ddraw->hwnd != hWnd)
+ return real_ClientToScreen(hWnd, lpPoint) && real_ScreenToClient(g_ddraw->hwnd, lpPoint);
+
+ return TRUE;
+}
+
+BOOL WINAPI fake_ScreenToClient(HWND hWnd, LPPOINT lpPoint)
+{
+ if (g_ddraw && g_ddraw->hwnd != hWnd)
+ return real_ClientToScreen(g_ddraw->hwnd, lpPoint) && real_ScreenToClient(hWnd, lpPoint);
+
+ return TRUE;
+}
+
+BOOL WINAPI fake_SetCursorPos(int X, int Y)
+{
+ POINT pt = { X, Y };
+ return g_ddraw && real_ClientToScreen(g_ddraw->hwnd, &pt) && real_SetCursorPos(pt.x, pt.y);
+}
+
+HWND WINAPI fake_WindowFromPoint(POINT Point)
+{
+ POINT pt = { Point.x, Point.y };
+ return g_ddraw && real_ClientToScreen(g_ddraw->hwnd, &pt) ? real_WindowFromPoint(pt) : NULL;
+}
+
+BOOL WINAPI fake_GetClipCursor(LPRECT lpRect)
+{
+ if (lpRect && g_ddraw)
+ {
+ lpRect->bottom = g_ddraw->height;
+ lpRect->left = 0;
+ lpRect->right = g_ddraw->width;
+ lpRect->top = 0;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL WINAPI fake_GetCursorInfo(PCURSORINFO pci)
+{
+ return pci && g_ddraw && real_GetCursorInfo(pci) && real_ScreenToClient(g_ddraw->hwnd, &pci->ptScreenPos);
+}
+
+int WINAPI fake_GetSystemMetrics(int nIndex)
+{
+ if (g_ddraw)
+ {
+ if (nIndex == SM_CXSCREEN)
+ return g_ddraw->width;
+
+ if (nIndex == SM_CYSCREEN)
+ return g_ddraw->height;
+ }
+
+ return real_GetSystemMetrics(nIndex);
+}
+
+BOOL WINAPI fake_SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
+{
+ UINT reqFlags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER;
+
+ if (g_ddraw && g_ddraw->hwnd == hWnd && (uFlags & reqFlags) != reqFlags)
+ return TRUE;
+
+ return real_SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
+}
+
+BOOL WINAPI fake_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint)
+{
+ if (g_ddraw && g_ddraw->hwnd == hWnd)
+ return TRUE;
+
+ return real_MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
+}
+
+LRESULT WINAPI fake_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT result = real_SendMessageA(hWnd, Msg, wParam, lParam);
+
+ if (result && g_ddraw && Msg == CB_GETDROPPEDCONTROLRECT)
+ {
+ RECT *rc = (RECT *)lParam;
+ if (rc)
+ MapWindowPoints(HWND_DESKTOP, g_ddraw->hwnd, (LPPOINT)rc, 2);
+ }
+
+ return result;
+}
+
+LONG WINAPI fake_SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong)
+{
+ if (g_ddraw && g_ddraw->hwnd == hWnd && nIndex == GWL_STYLE)
+ return 0;
+
+ return real_SetWindowLongA(hWnd, nIndex, dwNewLong);
+}
+
+BOOL WINAPI fake_EnableWindow(HWND hWnd, BOOL bEnable)
+{
+ if (g_ddraw && g_ddraw->hwnd == hWnd)
+ {
+ return FALSE;
+ }
+
+ return real_EnableWindow(hWnd, bEnable);
+}
+
+int WINAPI fake_GetDeviceCaps(HDC hdc, int index)
+{
+ if (g_ddraw && g_ddraw->bpp && index == BITSPIXEL)
+ {
+ return g_ddraw->bpp;
+ }
+
+ return real_GetDeviceCaps(hdc, index);
+}
+
+HMODULE WINAPI fake_LoadLibraryA(LPCSTR lpLibFileName)
+{
+ HMODULE hmod = real_LoadLibraryA(lpLibFileName);
+
+ hook_init();
+
+ return hmod;
+}
+
+HMODULE WINAPI fake_LoadLibraryW(LPCWSTR lpLibFileName)
+{
+ HMODULE hmod = real_LoadLibraryW(lpLibFileName);
+
+ hook_init();
+
+ return hmod;
+}
+
+HMODULE WINAPI fake_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
+{
+ HMODULE hmod = real_LoadLibraryExA(lpLibFileName, hFile, dwFlags);
+
+ hook_init();
+
+ return hmod;
+}
+
+HMODULE WINAPI fake_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
+{
+ HMODULE hmod = real_LoadLibraryExW(lpLibFileName, hFile, dwFlags);
+
+ hook_init();
+
+ return hmod;
+}
+
+BOOL WINAPI fake_DestroyWindow(HWND hWnd)
+{
+ BOOL result = real_DestroyWindow(hWnd);
+
+ if (g_ddraw && g_ddraw->hwnd != hWnd && g_ddraw->bnet_active)
+ {
+ RedrawWindow(NULL, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
+
+ if (!FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL))
+ {
+ g_ddraw->bnet_active = FALSE;
+ SetFocus(g_ddraw->hwnd);
+ mouse_lock();
+
+ if (g_ddraw->windowed)
+ {
+ g_ddraw->bnet_pos.x = g_ddraw->bnet_pos.y = 0;
+ real_ClientToScreen(g_ddraw->hwnd, &g_ddraw->bnet_pos);
+
+ if (!g_ddraw->bnet_was_upscaled)
+ {
+ int width = g_ddraw->bnet_win_rect.right - g_ddraw->bnet_win_rect.left;
+ int height = g_ddraw->bnet_win_rect.bottom - g_ddraw->bnet_win_rect.top;
+ UINT flags = width != g_ddraw->width || height != g_ddraw->height ? 0 : SWP_NOMOVE;
+
+ util_set_window_rect(g_ddraw->bnet_win_rect.left, g_ddraw->bnet_win_rect.top, width, height, flags);
+ }
+
+ g_ddraw->fullscreen = g_ddraw->bnet_was_upscaled;
+
+ SetTimer(g_ddraw->hwnd, IDT_TIMER_LEAVE_BNET, 1000, (TIMERPROC)NULL);
+
+ g_ddraw->resizable = TRUE;
+ }
+ }
+ }
+
+ return result;
+}
+
+HWND WINAPI fake_CreateWindowExA(
+ DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y,
+ int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
+{
+ if (lpClassName && _strcmpi(lpClassName, "SDlgDialog") == 0 && g_ddraw)
+ {
+ if (!g_ddraw->bnet_active)
+ {
+ g_ddraw->bnet_was_upscaled = g_ddraw->fullscreen;
+ g_ddraw->fullscreen = FALSE;
+
+ if (!g_ddraw->windowed && !g_ddraw->bnet_was_fullscreen)
+ {
+ int ws = g_config.window_state;
+ util_toggle_fullscreen();
+ g_config.window_state = ws;
+ g_ddraw->bnet_was_fullscreen = TRUE;
+ }
+
+ real_GetClientRect(g_ddraw->hwnd, &g_ddraw->bnet_win_rect);
+ MapWindowPoints(g_ddraw->hwnd, HWND_DESKTOP, (LPPOINT)&g_ddraw->bnet_win_rect, 2);
+
+ int width = g_ddraw->bnet_win_rect.right - g_ddraw->bnet_win_rect.left;
+ int height = g_ddraw->bnet_win_rect.bottom - g_ddraw->bnet_win_rect.top;
+ int x = g_ddraw->bnet_pos.x || g_ddraw->bnet_pos.y ? g_ddraw->bnet_pos.x : -32000;
+ int y = g_ddraw->bnet_pos.x || g_ddraw->bnet_pos.y ? g_ddraw->bnet_pos.y : -32000;
+ UINT flags = width != g_ddraw->width || height != g_ddraw->height ? 0 : SWP_NOMOVE;
+
+ util_set_window_rect(x, y, g_ddraw->width, g_ddraw->height, flags);
+ g_ddraw->resizable = FALSE;
+
+ g_ddraw->bnet_active = TRUE;
+ mouse_unlock();
+ }
+
+ POINT pt = { 0, 0 };
+ real_ClientToScreen(g_ddraw->hwnd, &pt);
+
+ X += pt.x;
+ Y += pt.y;
+
+ dwStyle |= WS_CLIPCHILDREN;
+ }
+
+ return real_CreateWindowExA(
+ dwExStyle,
+ lpClassName,
+ lpWindowName,
+ dwStyle,
+ X,
+ Y,
+ nWidth,
+ nHeight,
+ hWndParent,
+ hMenu,
+ hInstance,
+ lpParam);
+}
diff --git a/src/wndproc.c b/src/wndproc.c
new file mode 100644
index 0000000..7cba714
--- /dev/null
+++ b/src/wndproc.c
@@ -0,0 +1,620 @@
+#include
+#include
+#include "dllmain.h"
+#include "dd.h"
+#include "hook.h"
+#include "mouse.h"
+#include "render_d3d9.h"
+#include "config.h"
+#include "screenshot.h"
+#include "winapi_hooks.h"
+#include "wndproc.h"
+#include "utils.h"
+
+
+LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ RECT rc = { 0, 0, g_ddraw->render.width, g_ddraw->render.height };
+
+ static BOOL in_size_move = FALSE;
+ static int redraw_count = 0;
+
+ switch(uMsg)
+ {
+ //case WM_NCACTIVATE:
+ case WM_GETMINMAXINFO:
+ case WM_MOVING:
+ case WM_NCLBUTTONDOWN:
+ case WM_NCLBUTTONUP:
+ case WM_NCPAINT:
+ {
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+ case WM_NCHITTEST:
+ {
+ LRESULT result = DefWindowProc(hWnd, uMsg, wParam, lParam);
+
+ if (!g_ddraw->resizable)
+ {
+ switch (result)
+ {
+ case HTBOTTOM:
+ case HTBOTTOMLEFT:
+ case HTBOTTOMRIGHT:
+ case HTLEFT:
+ case HTRIGHT:
+ case HTTOP:
+ case HTTOPLEFT:
+ case HTTOPRIGHT:
+ return HTBORDER;
+ }
+ }
+
+ return result;
+ }
+ case WM_SETCURSOR:
+ {
+ // show resize cursor on window borders
+ if ((HWND)wParam == g_ddraw->hwnd)
+ {
+ WORD message = HIWORD(lParam);
+
+ if (message == WM_MOUSEMOVE)
+ {
+ WORD htcode = LOWORD(lParam);
+
+ switch (htcode)
+ {
+ case HTCAPTION:
+ case HTMINBUTTON:
+ case HTMAXBUTTON:
+ case HTCLOSE:
+ case HTBOTTOM:
+ case HTBOTTOMLEFT:
+ case HTBOTTOMRIGHT:
+ case HTLEFT:
+ case HTRIGHT:
+ case HTTOP:
+ case HTTOPLEFT:
+ case HTTOPRIGHT:
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ case HTCLIENT:
+ if (!g_ddraw->locked)
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ default:
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ case WM_D3D9DEVICELOST:
+ {
+ if (g_ddraw->renderer == d3d9_render_main && d3d9_on_device_lost())
+ {
+ if (!g_ddraw->windowed)
+ mouse_lock();
+ }
+ return 0;
+ }
+ case WM_TIMER:
+ {
+ switch (wParam)
+ {
+ case IDT_TIMER_LEAVE_BNET:
+ {
+ KillTimer(g_ddraw->hwnd, IDT_TIMER_LEAVE_BNET);
+
+ if (!g_ddraw->windowed)
+ g_ddraw->bnet_was_fullscreen = FALSE;
+
+ if (!g_ddraw->bnet_active)
+ {
+ if (g_ddraw->bnet_was_fullscreen)
+ {
+ int ws = g_config.window_state;
+ util_toggle_fullscreen();
+ g_config.window_state = ws;
+ g_ddraw->bnet_was_fullscreen = FALSE;
+ }
+ else if (g_ddraw->bnet_was_upscaled)
+ {
+ util_set_window_rect(0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ g_ddraw->bnet_was_upscaled = FALSE;
+ }
+ }
+
+ return 0;
+ }
+ }
+ break;
+ }
+ case WM_WINDOWPOSCHANGED:
+ {
+ WINDOWPOS *pos = (WINDOWPOS *)lParam;
+
+ if (g_ddraw->wine && !g_ddraw->windowed && (pos->x > 0 || pos->y > 0) && g_ddraw->last_set_window_pos_tick + 500 < timeGetTime())
+ PostMessage(g_ddraw->hwnd, WM_WINEFULLSCREEN, 0, 0);
+
+ break;
+ }
+ case WM_WINEFULLSCREEN:
+ {
+ if (!g_ddraw->windowed)
+ {
+ g_ddraw->last_set_window_pos_tick = timeGetTime();
+ real_SetWindowPos(g_ddraw->hwnd, HWND_TOPMOST, 1, 1, g_ddraw->render.width, g_ddraw->render.height, SWP_SHOWWINDOW);
+ real_SetWindowPos(g_ddraw->hwnd, HWND_TOPMOST, 0, 0, g_ddraw->render.width, g_ddraw->render.height, SWP_SHOWWINDOW);
+ }
+ return 0;
+ }
+ case WM_ENTERSIZEMOVE:
+ {
+ if (g_ddraw->windowed)
+ {
+ in_size_move = TRUE;
+ }
+ break;
+ }
+ case WM_EXITSIZEMOVE:
+ {
+ if (g_ddraw->windowed)
+ {
+ in_size_move = FALSE;
+
+ if (!g_ddraw->render.thread)
+ dd_SetDisplayMode(g_ddraw->width, g_ddraw->height, g_ddraw->bpp);
+ }
+ break;
+ }
+ case WM_SIZING:
+ {
+ RECT *windowrc = (RECT *)lParam;
+
+ if (g_ddraw->windowed)
+ {
+ if (in_size_move)
+ {
+ if (g_ddraw->render.thread)
+ {
+ EnterCriticalSection(&g_ddraw->cs);
+ g_ddraw->render.run = FALSE;
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ LeaveCriticalSection(&g_ddraw->cs);
+
+ WaitForSingleObject(g_ddraw->render.thread, INFINITE);
+ g_ddraw->render.thread = NULL;
+ }
+
+ RECT clientrc = { 0 };
+
+ // maintain aspect ratio
+ if (g_ddraw->maintas &&
+ CopyRect(&clientrc, windowrc) &&
+ util_unadjust_window_rect(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)) &&
+ SetRect(&clientrc, 0, 0, clientrc.right - clientrc.left, clientrc.bottom - clientrc.top))
+ {
+ float scaleH = (float)g_ddraw->height / g_ddraw->width;
+ float scaleW = (float)g_ddraw->width / g_ddraw->height;
+
+ switch (wParam)
+ {
+ case WMSZ_BOTTOMLEFT:
+ case WMSZ_BOTTOMRIGHT:
+ case WMSZ_LEFT:
+ case WMSZ_RIGHT:
+ {
+ windowrc->bottom += scaleH * clientrc.right - clientrc.bottom;
+ break;
+ }
+ case WMSZ_TOP:
+ case WMSZ_BOTTOM:
+ {
+ windowrc->right += scaleW * clientrc.bottom - clientrc.right;
+ break;
+ }
+ case WMSZ_TOPRIGHT:
+ case WMSZ_TOPLEFT:
+ {
+ windowrc->top -= scaleH * clientrc.right - clientrc.bottom;
+ break;
+ }
+ }
+ }
+
+ //enforce minimum window size
+ if (CopyRect(&clientrc, windowrc) &&
+ util_unadjust_window_rect(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)) &&
+ SetRect(&clientrc, 0, 0, clientrc.right - clientrc.left, clientrc.bottom - clientrc.top))
+ {
+ if (clientrc.right < g_ddraw->width)
+ {
+ switch (wParam)
+ {
+ case WMSZ_TOPRIGHT:
+ case WMSZ_BOTTOMRIGHT:
+ case WMSZ_RIGHT:
+ case WMSZ_BOTTOM:
+ case WMSZ_TOP:
+ {
+ windowrc->right += g_ddraw->width - clientrc.right;
+ break;
+ }
+ case WMSZ_TOPLEFT:
+ case WMSZ_BOTTOMLEFT:
+ case WMSZ_LEFT:
+ {
+ windowrc->left -= g_ddraw->width - clientrc.right;
+ break;
+ }
+ }
+ }
+
+ if (clientrc.bottom < g_ddraw->height)
+ {
+ switch (wParam)
+ {
+ case WMSZ_BOTTOMLEFT:
+ case WMSZ_BOTTOMRIGHT:
+ case WMSZ_BOTTOM:
+ case WMSZ_RIGHT:
+ case WMSZ_LEFT:
+ {
+ windowrc->bottom += g_ddraw->height - clientrc.bottom;
+ break;
+ }
+ case WMSZ_TOPLEFT:
+ case WMSZ_TOPRIGHT:
+ case WMSZ_TOP:
+ {
+ windowrc->top -= g_ddraw->height - clientrc.bottom;
+ break;
+ }
+ }
+ }
+ }
+
+ //save new window position
+ if (CopyRect(&clientrc, windowrc) &&
+ util_unadjust_window_rect(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)))
+ {
+ g_config.window_rect.left = clientrc.left;
+ g_config.window_rect.top = clientrc.top;
+ g_config.window_rect.right = clientrc.right - clientrc.left;
+ g_config.window_rect.bottom = clientrc.bottom - clientrc.top;
+ }
+
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case WM_SIZE:
+ {
+ if (g_ddraw->windowed)
+ {
+ if (wParam == SIZE_RESTORED)
+ {
+ if (in_size_move && !g_ddraw->render.thread)
+ {
+ g_config.window_rect.right = LOWORD(lParam);
+ g_config.window_rect.bottom = HIWORD(lParam);
+ }
+ /*
+ else if (g_ddraw->wine)
+ {
+ WindowRect.right = LOWORD(lParam);
+ WindowRect.bottom = HIWORD(lParam);
+ if (WindowRect.right != g_ddraw->render.width || WindowRect.bottom != g_ddraw->render.height)
+ dd_SetDisplayMode(g_ddraw->width, g_ddraw->height, g_ddraw->bpp);
+ }
+ */
+ }
+ }
+
+ if (!g_ddraw->handlemouse)
+ {
+ redraw_count = 2;
+ RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam); /* Carmageddon fix */
+ }
+ case WM_MOVE:
+ {
+ if (g_ddraw->windowed)
+ {
+ int x = (int)(short)LOWORD(lParam);
+ int y = (int)(short)HIWORD(lParam);
+
+ if (x != -32000 && y != -32000)
+ util_update_bnet_pos(x, y);
+
+ if (in_size_move || g_ddraw->wine)
+ {
+ if (x != -32000)
+ g_config.window_rect.left = x; // -32000 = Exit/Minimize
+
+ if (y != -32000)
+ g_config.window_rect.top = y;
+ }
+ }
+
+ if (!g_ddraw->handlemouse)
+ RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
+
+ if (g_ddraw->sierrahack)
+ {
+ lParam = 0;
+ break;
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam); /* Carmageddon fix */
+ }
+
+ /* C&C and RA really don't want to close down */
+ case WM_SYSCOMMAND:
+ if (wParam == SC_CLOSE && !GameHandlesClose)
+ {
+ exit(0);
+ }
+
+ if (wParam == SC_KEYMENU)
+ return 0;
+
+ if (!GameHandlesClose)
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+
+ break;
+
+ //workaround for a bug where sometimes a background window steals the focus
+ case WM_WINDOWPOSCHANGING:
+ {
+ if (g_ddraw->locked)
+ {
+ WINDOWPOS *pos = (WINDOWPOS *)lParam;
+
+ if (pos->flags == SWP_NOMOVE + SWP_NOSIZE)
+ {
+ mouse_unlock();
+
+ if (GetForegroundWindow() == g_ddraw->hwnd)
+ mouse_lock();
+ }
+ }
+ break;
+ }
+
+ case WM_MOUSELEAVE:
+ mouse_unlock();
+ return 0;
+
+ case WM_ACTIVATE:
+ if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE)
+ {
+ if (!g_ddraw->windowed)
+ {
+ if (g_ddraw->renderer != d3d9_render_main)
+ {
+ ChangeDisplaySettings(&g_ddraw->render.mode, CDS_FULLSCREEN);
+
+ if (wParam == WA_ACTIVE)
+ {
+ mouse_lock();
+ }
+ }
+ }
+
+ if (!g_ddraw->handlemouse)
+ RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ else if (wParam == WA_INACTIVE)
+ {
+ if (!g_ddraw->windowed && !g_ddraw->locked && g_ddraw->noactivateapp && !g_ddraw->devmode)
+ return 0;
+
+ mouse_unlock();
+
+ if (g_ddraw->wine && g_ddraw->last_set_window_pos_tick + 500 > timeGetTime())
+ return 0;
+
+ /* minimize our window on defocus when in fullscreen */
+ if (!g_ddraw->windowed)
+ {
+ if (g_ddraw->renderer != d3d9_render_main)
+ {
+ ShowWindow(g_ddraw->hwnd, SW_MINIMIZE);
+ ChangeDisplaySettings(NULL, g_ddraw->bnet_active ? CDS_FULLSCREEN : 0);
+ }
+ }
+ }
+ return 0;
+
+ case WM_ACTIVATEAPP:
+ /* C&C and RA stop drawing when they receive this with FALSE wParam, disable in windowed mode */
+ if (g_ddraw->windowed || g_ddraw->noactivateapp)
+ {
+ // let it pass through once (tiberian sun)
+ static BOOL one_time;
+
+ if (wParam && !one_time && !g_ddraw->handlemouse && g_ddraw->noactivateapp)
+ {
+ one_time = TRUE;
+ break;
+ }
+
+ return 0;
+ }
+ break;
+ case WM_AUTORENDERER:
+ {
+ mouse_unlock();
+ real_SetWindowPos(g_ddraw->hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ real_SetWindowPos(g_ddraw->hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ mouse_lock();
+ return 0;
+ }
+ case WM_NCLBUTTONDBLCLK:
+ {
+ util_toggle_fullscreen();
+ return 0;
+ }
+ case WM_SYSKEYDOWN:
+ {
+ BOOL context_code = (lParam & (1 << 29)) != 0;
+ BOOL key_state = (lParam & (1 << 30)) != 0;
+
+ if (wParam == VK_RETURN && context_code && !key_state)
+ {
+ util_toggle_fullscreen();
+ return 0;
+ }
+ break;
+ }
+ case WM_KEYDOWN:
+ if(wParam == VK_CONTROL || wParam == VK_TAB)
+ {
+ if(GetAsyncKeyState(VK_CONTROL) & 0x8000 && GetAsyncKeyState(VK_TAB) & 0x8000)
+ {
+ mouse_unlock();
+ return 0;
+ }
+ }
+ if (wParam == VK_CONTROL || wParam == VK_MENU)
+ {
+ if ((GetAsyncKeyState(VK_RMENU) & 0x8000) && GetAsyncKeyState(VK_RCONTROL) & 0x8000)
+ {
+ mouse_unlock();
+ return 0;
+ }
+ }
+ break;
+
+ case WM_KEYUP:
+ if (wParam == VK_SNAPSHOT)
+ ss_take_screenshot(g_ddraw->primary);
+
+ break;
+
+
+ /* button up messages reactivate cursor lock */
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ if (!g_ddraw->devmode && !g_ddraw->locked)
+ {
+ int x = GET_X_LPARAM(lParam);
+ int y = GET_Y_LPARAM(lParam);
+
+ if (x > g_ddraw->render.viewport.x + g_ddraw->render.viewport.width ||
+ x < g_ddraw->render.viewport.x ||
+ y > g_ddraw->render.viewport.y + g_ddraw->render.viewport.height ||
+ y < g_ddraw->render.viewport.y)
+ {
+ g_ddraw->cursor.x = g_ddraw->width / 2;
+ g_ddraw->cursor.y = g_ddraw->height / 2;
+ }
+ else
+ {
+ g_ddraw->cursor.x = (x - g_ddraw->render.viewport.x) * g_ddraw->render.unscale_w;
+ g_ddraw->cursor.y = (y - g_ddraw->render.viewport.y) * g_ddraw->render.unscale_h;
+ }
+
+ mouse_lock();
+ return 0;
+ }
+ /* fall through for lParam */
+
+ /* down messages are ignored if we have no cursor lock */
+ case WM_XBUTTONDBLCLK:
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONUP:
+ case WM_MOUSEWHEEL:
+ case WM_MOUSEHOVER:
+ case WM_LBUTTONDBLCLK:
+ case WM_MBUTTONDBLCLK:
+ case WM_RBUTTONDBLCLK:
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_MOUSEMOVE:
+
+ if (!g_ddraw->devmode)
+ {
+ if (!g_ddraw->locked)
+ {
+ return 0;
+ }
+
+ if(g_ddraw->adjmouse)
+ {
+ fake_GetCursorPos(NULL); /* update our own cursor */
+ lParam = MAKELPARAM(g_ddraw->cursor.x, g_ddraw->cursor.y);
+ }
+ }
+
+ if (g_ddraw->devmode)
+ {
+ mouse_lock();
+ g_ddraw->cursor.x = GET_X_LPARAM(lParam);
+ g_ddraw->cursor.y = GET_Y_LPARAM(lParam);
+ }
+ break;
+
+ case WM_PARENTNOTIFY:
+ {
+ if (!g_ddraw->handlemouse)
+ {
+ switch (LOWORD(wParam))
+ {
+ case WM_DESTROY: //Workaround for invisible menu on Load/Save/Delete in Tiberian Sun
+ redraw_count = 2;
+ break;
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_XBUTTONDOWN:
+ {
+ if (!g_ddraw->devmode && !g_ddraw->locked)
+ {
+ int x = GET_X_LPARAM(lParam);
+ int y = GET_Y_LPARAM(lParam);
+
+ g_ddraw->cursor.x = (x - g_ddraw->render.viewport.x) * g_ddraw->render.unscale_w;
+ g_ddraw->cursor.y = (y - g_ddraw->render.viewport.y) * g_ddraw->render.unscale_h;
+
+ g_ddraw->hidecursor = FALSE;
+ mouse_lock();
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case WM_PAINT:
+ {
+ if (!g_ddraw->handlemouse && redraw_count > 0)
+ {
+ redraw_count--;
+ RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+
+ EnterCriticalSection(&g_ddraw->cs);
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ LeaveCriticalSection(&g_ddraw->cs);
+ break;
+ }
+ case WM_ERASEBKGND:
+ {
+ EnterCriticalSection(&g_ddraw->cs);
+ FillRect(g_ddraw->render.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
+ ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
+ LeaveCriticalSection(&g_ddraw->cs);
+ break;
+ }
+ }
+
+ return g_ddraw->wndproc(hWnd, uMsg, wParam, lParam);
+}