refactoring
This commit is contained in:
parent
95afd87656
commit
baaa87b18f
62 changed files with 7231 additions and 6636 deletions
28
Makefile
28
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
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\clipper.c" />
|
||||
<ClCompile Include="src\ddclipper.c" />
|
||||
<ClCompile Include="src\debug.c" />
|
||||
<ClCompile Include="src\detours\creatwth.cpp" />
|
||||
<ClCompile Include="src\detours\detours.cpp" />
|
||||
|
@ -26,37 +26,58 @@
|
|||
<ClCompile Include="src\detours\uimports.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dinput.c" />
|
||||
<ClCompile Include="src\directinput.c" />
|
||||
<ClCompile Include="src\dllmain.c" />
|
||||
<ClCompile Include="src\utils.c" />
|
||||
<ClCompile Include="src\hook.c" />
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDraw.c" />
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDrawClipper.c" />
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDrawPalette.c" />
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDrawSurface.c" />
|
||||
<ClCompile Include="src\lodepng.c" />
|
||||
<ClCompile Include="src\main.c" />
|
||||
<ClCompile Include="src\dd.c" />
|
||||
<ClCompile Include="src\mouse.c" />
|
||||
<ClCompile Include="src\opengl.c" />
|
||||
<ClCompile Include="src\palette.c" />
|
||||
<ClCompile Include="src\render.c" />
|
||||
<ClCompile Include="src\opengl_utils.c" />
|
||||
<ClCompile Include="src\ddpalette.c" />
|
||||
<ClCompile Include="src\render_ogl.c" />
|
||||
<ClCompile Include="src\render_d3d9.c" />
|
||||
<ClCompile Include="src\render_soft.c" />
|
||||
<ClCompile Include="src\render_gdi.c" />
|
||||
<ClCompile Include="src\screenshot.c" />
|
||||
<ClCompile Include="src\settings.c" />
|
||||
<ClCompile Include="src\surface.c" />
|
||||
<ClCompile Include="src\config.c" />
|
||||
<ClCompile Include="src\ddsurface.c" />
|
||||
<ClCompile Include="src\winapi_hooks.c" />
|
||||
<ClCompile Include="src\wndproc.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="inc\clipper.h" />
|
||||
<ClInclude Include="inc\d3d9shader.h" />
|
||||
<ClInclude Include="inc\ddclipper.h" />
|
||||
<ClInclude Include="inc\directinput.h" />
|
||||
<ClInclude Include="inc\dllmain.h" />
|
||||
<ClInclude Include="inc\glcorearb.h" />
|
||||
<ClInclude Include="inc\utils.h" />
|
||||
<ClInclude Include="inc\hook.h" />
|
||||
<ClInclude Include="inc\IDirectDraw.h" />
|
||||
<ClInclude Include="inc\IDirectDrawClipper.h" />
|
||||
<ClInclude Include="inc\IDirectDrawPalette.h" />
|
||||
<ClInclude Include="inc\IDirectDrawSurface.h" />
|
||||
<ClInclude Include="inc\KHR\khrplatform.h" />
|
||||
<ClInclude Include="inc\lodepng.h" />
|
||||
<ClInclude Include="inc\mouse.h" />
|
||||
<ClInclude Include="inc\render_d3d9.h" />
|
||||
<ClInclude Include="inc\ddraw.h" />
|
||||
<ClInclude Include="inc\debug.h" />
|
||||
<ClInclude Include="inc\main.h" />
|
||||
<ClInclude Include="inc\opengl.h" />
|
||||
<ClInclude Include="inc\palette.h" />
|
||||
<ClInclude Include="inc\dd.h" />
|
||||
<ClInclude Include="inc\opengl_utils.h" />
|
||||
<ClInclude Include="inc\ddpalette.h" />
|
||||
<ClInclude Include="inc\openglshader.h" />
|
||||
<ClInclude Include="inc\d3d9shader.h" />
|
||||
<ClInclude Include="inc\render_ogl.h" />
|
||||
<ClInclude Include="inc\render_gdi.h" />
|
||||
<ClInclude Include="inc\scale_pattern.h" />
|
||||
<ClInclude Include="inc\surface.h" />
|
||||
<ClInclude Include="inc\screenshot.h" />
|
||||
<ClInclude Include="inc\config.h" />
|
||||
<ClInclude Include="inc\ddsurface.h" />
|
||||
<ClInclude Include="inc\winapi_hooks.h" />
|
||||
<ClInclude Include="inc\wndproc.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ddraw.rc" />
|
||||
|
|
|
@ -16,53 +16,26 @@
|
|||
<Filter Include="Source Files\detours">
|
||||
<UniqueIdentifier>{af194dd7-3316-4887-93d6-9f2af2135f94}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\IDirectDraw">
|
||||
<UniqueIdentifier>{37ee5b88-e57f-4c55-a43e-e475cf4e8920}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\clipper.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\debug.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\mouse.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\palette.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\render.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\render_soft.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\screenshot.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\surface.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\opengl.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\render_d3d9.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\settings.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\lodepng.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dinput.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\detours\disolx64.cpp">
|
||||
<Filter>Source Files\detours</Filter>
|
||||
</ClCompile>
|
||||
|
@ -96,35 +69,71 @@
|
|||
<ClCompile Include="src\detours\disolia64.cpp">
|
||||
<Filter>Source Files\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\hook.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDraw.c">
|
||||
<Filter>Source Files\IDirectDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dllmain.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\wndproc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\utils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\render_ogl.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDrawPalette.c">
|
||||
<Filter>Source Files\IDirectDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ddpalette.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDrawClipper.c">
|
||||
<Filter>Source Files\IDirectDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ddclipper.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\IDirectDraw\IDirectDrawSurface.c">
|
||||
<Filter>Source Files\IDirectDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ddsurface.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\winapi_hooks.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\directinput.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\render_gdi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\config.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\opengl_utils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="inc\clipper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\ddraw.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\debug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\main.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\palette.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\surface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\opengl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\openglshader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\d3d9shader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\render_d3d9.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -146,6 +155,63 @@
|
|||
<ClInclude Include="inc\hook.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\IDirectDraw.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\directinput.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\wndproc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\screenshot.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\render_ogl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\dd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\IDirectDrawPalette.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\ddpalette.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\IDirectDrawClipper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\ddclipper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\IDirectDrawSurface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\ddsurface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\winapi_hooks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\d3d9shader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\dllmain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\render_gdi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="inc\opengl_utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ddraw.rc">
|
||||
|
|
14
ddraw.def
14
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
|
||||
|
|
2
ddraw.rc
2
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)
|
||||
|
|
71
inc/IDirectDraw.h
Normal file
71
inc/IDirectDraw.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
#ifndef IDIRECTDRAW_H
|
||||
#define IDIRECTDRAW_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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
|
40
inc/IDirectDrawClipper.h
Normal file
40
inc/IDirectDrawClipper.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef IDIRECTDRAWCLIPPER_H
|
||||
#define IDIRECTDRAWCLIPPER_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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
|
42
inc/IDirectDrawPalette.h
Normal file
42
inc/IDirectDrawPalette.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef IDIRECTDRAWPALETTE_H
|
||||
#define IDIRECTDRAWPALETTE_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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
|
|
@ -1,38 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SURFACE_H
|
||||
#define SURFACE_H
|
||||
#ifndef IDIRECTDRAWSURFACE_H
|
||||
#define IDIRECTDRAWSURFACE_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CLIPPER_H
|
||||
#define CLIPPER_H
|
||||
|
||||
#include <windows.h>
|
||||
#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
|
23
inc/config.h
Normal file
23
inc/config.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
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
|
|
@ -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
|
118
inc/dd.h
Normal file
118
inc/dd.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
#ifndef DD_H
|
||||
#define DD_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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
|
11
inc/ddclipper.h
Normal file
11
inc/ddclipper.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef DDCLIPPER_H
|
||||
#define DDCLIPPER_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include "ddraw.h"
|
||||
|
||||
|
||||
HRESULT dd_CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter);
|
||||
|
||||
#endif
|
14
inc/ddpalette.h
Normal file
14
inc/ddpalette.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef DDPALETTE_H
|
||||
#define DDPALETTE_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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
|
|
@ -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
|
||||
|
|
32
inc/ddsurface.h
Normal file
32
inc/ddsurface.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef DDSURFACE_H
|
||||
#define DDSURFACE_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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
|
57
inc/debug.h
57
inc/debug.h
|
@ -1,17 +1,25 @@
|
|||
#pragma once
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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
|
||||
|
|
7
inc/directinput.h
Normal file
7
inc/directinput.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef DINPUTINPUT_H
|
||||
#define DINPUTINPUT_H
|
||||
|
||||
void dinput_hook();
|
||||
void dinput_unhook();
|
||||
|
||||
#endif
|
16
inc/dllmain.h
Normal file
16
inc/dllmain.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef DLLMAIN_H
|
||||
#define DLLMAIN_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
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
|
16
inc/hook.h
16
inc/hook.h
|
@ -1,8 +1,10 @@
|
|||
#ifndef HOOK_H
|
||||
#define HOOK_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
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
|
||||
|
|
190
inc/main.h
190
inc/main.h
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#include <windows.h>
|
||||
#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
|
29
inc/mouse.h
29
inc/mouse.h
|
@ -1,37 +1,8 @@
|
|||
#ifndef MOUSE_H
|
||||
#define MOUSE_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PALETTE_H
|
||||
#define PALETTE_H
|
||||
|
||||
#include <windows.h>
|
||||
#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
|
|
@ -1,11 +1,35 @@
|
|||
#pragma once
|
||||
#ifndef RENDER_D3D9_H
|
||||
#define RENDER_D3D9_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
|
||||
#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
|
||||
|
|
10
inc/render_gdi.h
Normal file
10
inc/render_gdi.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef RENDER_GDI_H
|
||||
#define RENDER_GDI_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
DWORD WINAPI gdi_render_main(void);
|
||||
|
||||
#endif
|
40
inc/render_ogl.h
Normal file
40
inc/render_ogl.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef RENDER_OGL_H
|
||||
#define RENDER_OGL_H
|
||||
|
||||
#include <windows.h>
|
||||
#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
|
10
inc/screenshot.h
Normal file
10
inc/screenshot.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef SCREENSHOT_H
|
||||
#define SCREENSHOT_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include "ddsurface.h"
|
||||
|
||||
BOOL ss_take_screenshot(struct IDirectDrawSurfaceImpl* src);
|
||||
|
||||
#endif
|
20
inc/utils.h
Normal file
20
inc/utils.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#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
|
36
inc/winapi_hooks.h
Normal file
36
inc/winapi_hooks.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef WINAPI_HOOKS_H
|
||||
#define WINAPI_HOOKS_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
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
|
12
inc/wndproc.h
Normal file
12
inc/wndproc.h
Normal file
|
@ -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
|
369
src/IDirectDraw/IDirectDraw.c
Normal file
369
src/IDirectDraw/IDirectDraw.c
Normal file
|
@ -0,0 +1,369 @@
|
|||
#include <initguid.h>
|
||||
#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,
|
||||
};
|
99
src/IDirectDraw/IDirectDrawClipper.c
Normal file
99
src/IDirectDraw/IDirectDrawClipper.c
Normal file
|
@ -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
|
||||
};
|
84
src/IDirectDraw/IDirectDrawPalette.c
Normal file
84
src/IDirectDraw/IDirectDrawPalette.c
Normal file
|
@ -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
|
||||
};
|
377
src/IDirectDraw/IDirectDrawSurface.c
Normal file
377
src/IDirectDraw/IDirectDrawSurface.c
Normal file
|
@ -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
|
||||
};
|
119
src/clipper.c
119
src/clipper.c
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
|
@ -2,214 +2,205 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <d3d9.h>
|
||||
#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);
|
||||
}
|
776
src/dd.c
Normal file
776
src/dd.c
Normal file
|
@ -0,0 +1,776 @@
|
|||
#include <windows.h>
|
||||
#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;
|
||||
}
|
21
src/ddclipper.c
Normal file
21
src/ddclipper.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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;
|
||||
}
|
65
src/ddpalette.c
Normal file
65
src/ddpalette.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#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;
|
||||
}
|
887
src/ddsurface.c
Normal file
887
src/ddsurface.c
Normal file
|
@ -0,0 +1,887 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
345
src/debug.c
345
src/debug.c
|
@ -1,41 +1,72 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#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
|
||||
}
|
||||
|
|
99
src/dinput.c
99
src/dinput.c
|
@ -1,99 +0,0 @@
|
|||
#include <windows.h>
|
||||
#include <dinput.h>
|
||||
#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"));
|
||||
}
|
101
src/directinput.c
Normal file
101
src/directinput.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <dinput.h>
|
||||
#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"));
|
||||
}
|
181
src/dllmain.c
Normal file
181
src/dllmain.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
#include <windows.h>
|
||||
#include <ddraw.h>
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
287
src/hook.c
287
src/hook.c
|
@ -1,15 +1,18 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2035
src/main.c
2035
src/main.c
File diff suppressed because it is too large
Load diff
508
src/mouse.c
508
src/mouse.c
|
@ -1,213 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#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);
|
146
src/palette.c
146
src/palette.c
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
||||
|
1049
src/render.c
1049
src/render.c
File diff suppressed because it is too large
Load diff
|
@ -1,58 +1,64 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <d3d9.h>
|
||||
#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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
181
src/render_gdi.c
Normal file
181
src/render_gdi.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
1025
src/render_ogl.c
Normal file
1025
src/render_ogl.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,193 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -1,28 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#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<strlen(title); i++) {
|
||||
if (title[i] == ' ')
|
||||
|
|
1408
src/surface.c
1408
src/surface.c
File diff suppressed because it is too large
Load diff
301
src/utils.c
Normal file
301
src/utils.c
Normal file
|
@ -0,0 +1,301 @@
|
|||
#include <windows.h>
|
||||
#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;
|
||||
}
|
425
src/winapi_hooks.c
Normal file
425
src/winapi_hooks.c
Normal file
|
@ -0,0 +1,425 @@
|
|||
#include <windows.h>
|
||||
#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);
|
||||
}
|
620
src/wndproc.c
Normal file
620
src/wndproc.c
Normal file
|
@ -0,0 +1,620 @@
|
|||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue