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
|
LIBS = -lgdi32 -lwinmm
|
||||||
|
|
||||||
FILES = src/debug.c \
|
FILES = src/debug.c \
|
||||||
src/main.c \
|
src/dd.c \
|
||||||
src/mouse.c \
|
src/ddpalette.c \
|
||||||
src/palette.c \
|
src/ddsurface.c \
|
||||||
src/surface.c \
|
src/ddclipper.c \
|
||||||
src/clipper.c \
|
src/IDirectDraw/IDirectDraw.c \
|
||||||
src/render.c \
|
src/IDirectDraw/IDirectDrawPalette.c \
|
||||||
src/render_soft.c \
|
src/IDirectDraw/IDirectDrawClipper.c \
|
||||||
|
src/IDirectDraw/IDirectDrawSurface.c \
|
||||||
|
src/render_ogl.c \
|
||||||
|
src/render_gdi.c \
|
||||||
src/render_d3d9.c \
|
src/render_d3d9.c \
|
||||||
|
src/mouse.c \
|
||||||
|
src/winapi_hooks.c \
|
||||||
src/screenshot.c \
|
src/screenshot.c \
|
||||||
src/settings.c \
|
src/config.c \
|
||||||
src/lodepng.c \
|
src/lodepng.c \
|
||||||
src/dinput.c \
|
src/directinput.c \
|
||||||
src/hook.c \
|
src/hook.c \
|
||||||
src/opengl.c
|
src/dllmain.c \
|
||||||
|
src/wndproc.c \
|
||||||
|
src/utils.c \
|
||||||
|
src/opengl_utils.c
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(WINDRES) -J rc ddraw.rc ddraw.rc.o
|
$(WINDRES) -J rc ddraw.rc ddraw.rc.o
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\clipper.c" />
|
<ClCompile Include="src\ddclipper.c" />
|
||||||
<ClCompile Include="src\debug.c" />
|
<ClCompile Include="src\debug.c" />
|
||||||
<ClCompile Include="src\detours\creatwth.cpp" />
|
<ClCompile Include="src\detours\creatwth.cpp" />
|
||||||
<ClCompile Include="src\detours\detours.cpp" />
|
<ClCompile Include="src\detours\detours.cpp" />
|
||||||
|
@ -26,37 +26,58 @@
|
||||||
<ClCompile Include="src\detours\uimports.cpp">
|
<ClCompile Include="src\detours\uimports.cpp">
|
||||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</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\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\lodepng.c" />
|
||||||
<ClCompile Include="src\main.c" />
|
<ClCompile Include="src\dd.c" />
|
||||||
<ClCompile Include="src\mouse.c" />
|
<ClCompile Include="src\mouse.c" />
|
||||||
<ClCompile Include="src\opengl.c" />
|
<ClCompile Include="src\opengl_utils.c" />
|
||||||
<ClCompile Include="src\palette.c" />
|
<ClCompile Include="src\ddpalette.c" />
|
||||||
<ClCompile Include="src\render.c" />
|
<ClCompile Include="src\render_ogl.c" />
|
||||||
<ClCompile Include="src\render_d3d9.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\screenshot.c" />
|
||||||
<ClCompile Include="src\settings.c" />
|
<ClCompile Include="src\config.c" />
|
||||||
<ClCompile Include="src\surface.c" />
|
<ClCompile Include="src\ddsurface.c" />
|
||||||
|
<ClCompile Include="src\winapi_hooks.c" />
|
||||||
|
<ClCompile Include="src\wndproc.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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\glcorearb.h" />
|
||||||
|
<ClInclude Include="inc\utils.h" />
|
||||||
<ClInclude Include="inc\hook.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\KHR\khrplatform.h" />
|
||||||
<ClInclude Include="inc\lodepng.h" />
|
<ClInclude Include="inc\lodepng.h" />
|
||||||
<ClInclude Include="inc\mouse.h" />
|
<ClInclude Include="inc\mouse.h" />
|
||||||
<ClInclude Include="inc\render_d3d9.h" />
|
<ClInclude Include="inc\render_d3d9.h" />
|
||||||
<ClInclude Include="inc\ddraw.h" />
|
<ClInclude Include="inc\ddraw.h" />
|
||||||
<ClInclude Include="inc\debug.h" />
|
<ClInclude Include="inc\debug.h" />
|
||||||
<ClInclude Include="inc\main.h" />
|
<ClInclude Include="inc\dd.h" />
|
||||||
<ClInclude Include="inc\opengl.h" />
|
<ClInclude Include="inc\opengl_utils.h" />
|
||||||
<ClInclude Include="inc\palette.h" />
|
<ClInclude Include="inc\ddpalette.h" />
|
||||||
<ClInclude Include="inc\openglshader.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\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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="ddraw.rc" />
|
<ResourceCompile Include="ddraw.rc" />
|
||||||
|
|
|
@ -16,53 +16,26 @@
|
||||||
<Filter Include="Source Files\detours">
|
<Filter Include="Source Files\detours">
|
||||||
<UniqueIdentifier>{af194dd7-3316-4887-93d6-9f2af2135f94}</UniqueIdentifier>
|
<UniqueIdentifier>{af194dd7-3316-4887-93d6-9f2af2135f94}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Source Files\IDirectDraw">
|
||||||
|
<UniqueIdentifier>{37ee5b88-e57f-4c55-a43e-e475cf4e8920}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\clipper.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\debug.c">
|
<ClCompile Include="src\debug.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\main.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\mouse.c">
|
<ClCompile Include="src\mouse.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</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">
|
<ClCompile Include="src\screenshot.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</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">
|
<ClCompile Include="src\render_d3d9.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\settings.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\lodepng.c">
|
<ClCompile Include="src\lodepng.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</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">
|
<ClCompile Include="src\detours\disolx64.cpp">
|
||||||
<Filter>Source Files\detours</Filter>
|
<Filter>Source Files\detours</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -96,35 +69,71 @@
|
||||||
<ClCompile Include="src\detours\disolia64.cpp">
|
<ClCompile Include="src\detours\disolia64.cpp">
|
||||||
<Filter>Source Files\detours</Filter>
|
<Filter>Source Files\detours</Filter>
|
||||||
</ClCompile>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="inc\clipper.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="inc\ddraw.h">
|
<ClInclude Include="inc\ddraw.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="inc\debug.h">
|
<ClInclude Include="inc\debug.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</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">
|
<ClInclude Include="inc\openglshader.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="inc\d3d9shader.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="inc\render_d3d9.h">
|
<ClInclude Include="inc\render_d3d9.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -146,6 +155,63 @@
|
||||||
<ClInclude Include="inc\hook.h">
|
<ClInclude Include="inc\hook.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="ddraw.rc">
|
<ResourceCompile Include="ddraw.rc">
|
||||||
|
|
14
ddraw.def
14
ddraw.def
|
@ -1,10 +1,10 @@
|
||||||
LIBRARY ddraw.dll
|
LIBRARY ddraw.dll
|
||||||
|
|
||||||
EXPORTS
|
EXPORTS
|
||||||
DirectDrawCreate @1
|
DirectDrawCreate @8
|
||||||
DirectDrawEnumerateA @2
|
DirectDrawCreateClipper @9
|
||||||
DirectDrawCreateClipper @10
|
DirectDrawEnumerateA @11
|
||||||
GameHandlesClose DATA
|
GameHandlesClose DATA
|
||||||
NvOptimusEnablement DATA
|
NvOptimusEnablement DATA
|
||||||
AmdPowerXpressRequestHighPerformance DATA
|
AmdPowerXpressRequestHighPerformance DATA
|
||||||
pvBmpBits DATA
|
pvBmpBits = g_fake_primary_surface_export DATA
|
||||||
|
|
2
ddraw.rc
2
ddraw.rc
|
@ -4,7 +4,7 @@
|
||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_BUILD 7
|
#define VERSION_BUILD 7
|
||||||
#define VERSION_REVISION 1
|
#define VERSION_REVISION 2
|
||||||
|
|
||||||
#define VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION
|
#define VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION
|
||||||
#define VERSION_STRING ver_str(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 @@
|
||||||
/*
|
#ifndef IDIRECTDRAWSURFACE_H
|
||||||
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
|
#define IDIRECTDRAWSURFACE_H
|
||||||
*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include "IDirectDrawPalette.h"
|
||||||
#include "ddraw.h"
|
#include "ddraw.h"
|
||||||
#include "palette.h"
|
|
||||||
|
|
||||||
HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC DDSurfaceDesc, LPDIRECTDRAWSURFACE FAR *DDSurface, IUnknown FAR * unkOuter);
|
|
||||||
|
|
||||||
struct IDirectDrawSurfaceImpl;
|
struct IDirectDrawSurfaceImpl;
|
||||||
struct IDirectDrawSurfaceImplVtbl;
|
struct IDirectDrawSurfaceImplVtbl;
|
||||||
|
|
||||||
extern struct IDirectDrawSurfaceImpl *ddraw_primary;
|
|
||||||
|
|
||||||
typedef struct IDirectDrawSurfaceImpl
|
typedef struct IDirectDrawSurfaceImpl
|
||||||
{
|
{
|
||||||
struct IDirectDrawSurfaceImplVtbl *lpVtbl;
|
struct IDirectDrawSurfaceImplVtbl *lpVtbl;
|
||||||
|
|
||||||
ULONG Ref;
|
ULONG ref;
|
||||||
|
|
||||||
DWORD width;
|
DWORD width;
|
||||||
DWORD height;
|
DWORD height;
|
||||||
|
@ -43,18 +25,20 @@ typedef struct IDirectDrawSurfaceImpl
|
||||||
IDirectDrawPaletteImpl *palette;
|
IDirectDrawPaletteImpl *palette;
|
||||||
|
|
||||||
void *surface;
|
void *surface;
|
||||||
DWORD lPitch;
|
DWORD l_pitch;
|
||||||
DWORD lXPitch;
|
DWORD lx_pitch;
|
||||||
|
|
||||||
PBITMAPINFO bmi;
|
PBITMAPINFO bmi;
|
||||||
HBITMAP bitmap;
|
HBITMAP bitmap;
|
||||||
HDC hDC;
|
HDC hdc;
|
||||||
DDCOLORKEY colorKey;
|
DDCOLORKEY color_key;
|
||||||
DWORD lastFlipTick;
|
DWORD last_flip_tick;
|
||||||
DWORD lastBltTick;
|
DWORD last_blt_tick;
|
||||||
|
|
||||||
} IDirectDrawSurfaceImpl;
|
} IDirectDrawSurfaceImpl;
|
||||||
|
|
||||||
|
typedef struct IDirectDrawSurfaceImplVtbl IDirectDrawSurfaceImplVtbl;
|
||||||
|
|
||||||
struct IDirectDrawSurfaceImplVtbl
|
struct IDirectDrawSurfaceImplVtbl
|
||||||
{
|
{
|
||||||
/* IUnknown */
|
/* IUnknown */
|
||||||
|
@ -96,7 +80,8 @@ struct IDirectDrawSurfaceImplVtbl
|
||||||
HRESULT (__stdcall *UpdateOverlay)(IDirectDrawSurfaceImpl*, LPRECT, LPDIRECTDRAWSURFACE,LPRECT,DWORD, LPDDOVERLAYFX);
|
HRESULT (__stdcall *UpdateOverlay)(IDirectDrawSurfaceImpl*, LPRECT, LPDIRECTDRAWSURFACE,LPRECT,DWORD, LPDDOVERLAYFX);
|
||||||
HRESULT (__stdcall *UpdateOverlayDisplay)(IDirectDrawSurfaceImpl*, DWORD);
|
HRESULT (__stdcall *UpdateOverlayDisplay)(IDirectDrawSurfaceImpl*, DWORD);
|
||||||
HRESULT (__stdcall *UpdateOverlayZOrder)(IDirectDrawSurfaceImpl*, DWORD, LPDIRECTDRAWSURFACE);
|
HRESULT (__stdcall *UpdateOverlayZOrder)(IDirectDrawSurfaceImpl*, DWORD, LPDIRECTDRAWSURFACE);
|
||||||
} IDirectDrawSurfaceImplVtbl;
|
};
|
||||||
|
|
||||||
|
extern struct IDirectDrawSurfaceImplVtbl g_dds_vtbl;
|
||||||
|
|
||||||
#endif
|
#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
|
#if 0
|
||||||
//
|
//
|
||||||
// Generated by Microsoft (R) HLSL Shader Compiler 10.1
|
// Generated by Microsoft (R) HLSL Shader Compiler 10.1
|
||||||
|
@ -42,7 +45,7 @@ float4 main(float2 texCoords : TEXCOORD) : COLOR
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const BYTE PalettePixelShaderSrc[] =
|
const BYTE D3D9_PALETTE_SHADER[] =
|
||||||
{
|
{
|
||||||
0, 2, 255, 255, 254, 255,
|
0, 2, 255, 255, 254, 255,
|
||||||
44, 0, 67, 84, 65, 66,
|
44, 0, 67, 84, 65, 66,
|
||||||
|
@ -99,3 +102,5 @@ const BYTE PalettePixelShaderSrc[] =
|
||||||
0, 8, 15, 128, 0, 0,
|
0, 8, 15, 128, 0, 0,
|
||||||
228, 128, 255, 255, 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
|
* 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
|
#ifdef STREAMING
|
||||||
typedef DWORD (FAR PASCAL *LPSURFACESTREAMINGCALLBACK)(DWORD);
|
typedef DWORD (FAR PASCAL *LPSURFACESTREAMINGCALLBACK)(DWORD);
|
||||||
#endif
|
#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
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#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;
|
void dbg_counter_start();
|
||||||
extern DWORD DebugFrameCount;
|
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
|
//#define _DEBUG 1
|
||||||
|
|
||||||
|
@ -21,14 +29,35 @@ extern DWORD DebugFrameCount;
|
||||||
//log everything (slow)
|
//log everything (slow)
|
||||||
//#define _DEBUG_X 1
|
//#define _DEBUG_X 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|
||||||
#ifdef _DEBUG_S
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define printf(format, ...)
|
#define dprintf(format, ...)
|
||||||
#endif
|
#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
|
#ifndef HOOK_H
|
||||||
#define HOOK_H
|
#define HOOK_H
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI* GETCURSORPOSPROC)(LPPOINT);
|
typedef BOOL (WINAPI* GETCURSORPOSPROC)(LPPOINT);
|
||||||
typedef BOOL(WINAPI* CLIPCURSORPROC)(const RECT*);
|
typedef BOOL(WINAPI* CLIPCURSORPROC)(const RECT*);
|
||||||
typedef int (WINAPI* SHOWCURSORPROC)(BOOL);
|
typedef int (WINAPI* SHOWCURSORPROC)(BOOL);
|
||||||
|
@ -55,13 +57,13 @@ extern LOADLIBRARYWPROC real_LoadLibraryW;
|
||||||
extern LOADLIBRARYEXAPROC real_LoadLibraryExA;
|
extern LOADLIBRARYEXAPROC real_LoadLibraryExA;
|
||||||
extern LOADLIBRARYEXWPROC real_LoadLibraryExW;
|
extern LOADLIBRARYEXWPROC real_LoadLibraryExW;
|
||||||
|
|
||||||
extern int HookingMethod;
|
extern int g_hook_method;
|
||||||
extern BOOL Hook_Active;
|
extern BOOL g_hook_active;
|
||||||
|
|
||||||
void Hook_Init();
|
void hook_init();
|
||||||
void Hook_Exit();
|
void hook_exit();
|
||||||
void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction);
|
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_create(char *moduleName, char *functionName, PROC newFunction, PROC *function);
|
||||||
void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *function);
|
void hook_revert(char *moduleName, char *functionName, PROC newFunction, PROC *function);
|
||||||
|
|
||||||
#endif
|
#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
|
#ifndef MOUSE_H
|
||||||
#define MOUSE_H
|
#define MOUSE_H
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
void mouse_lock();
|
void mouse_lock();
|
||||||
void mouse_unlock();
|
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
|
#endif
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#ifndef OPENGL_UTILS_H
|
||||||
|
#define OPENGL_UTILS_H
|
||||||
#include "glcorearb.h"
|
#include "glcorearb.h"
|
||||||
|
|
||||||
// wgl
|
// wgl
|
||||||
|
@ -32,11 +33,11 @@ extern PFNGLVERTEX2FPROC glVertex2f;
|
||||||
// <--- compat profile only
|
// <--- compat profile only
|
||||||
|
|
||||||
|
|
||||||
BOOL OpenGL_LoadDll();
|
BOOL oglu_load_dll();
|
||||||
void OpenGL_Init();
|
void oglu_init();
|
||||||
BOOL OpenGL_ExtExists(char *ext, HDC hdc);
|
BOOL oglu_ext_exists(char *ext, HDC hdc);
|
||||||
GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource);
|
GLuint oglu_build_program(const GLchar *vertSource, const GLchar *fragSource);
|
||||||
GLuint OpenGL_BuildProgramFromFile(const char *filePath);
|
GLuint oglu_build_program_from_file(const char *filePath);
|
||||||
|
|
||||||
extern PFNGLVIEWPORTPROC glViewport;
|
extern PFNGLVIEWPORTPROC glViewport;
|
||||||
extern PFNGLBINDTEXTUREPROC glBindTexture;
|
extern PFNGLBINDTEXTUREPROC glBindTexture;
|
||||||
|
@ -52,7 +53,6 @@ extern PFNGLGETTEXIMAGEPROC glGetTexImage;
|
||||||
extern PFNGLPIXELSTOREIPROC glPixelStorei;
|
extern PFNGLPIXELSTOREIPROC glPixelStorei;
|
||||||
extern PFNGLENABLEPROC glEnable;
|
extern PFNGLENABLEPROC glEnable;
|
||||||
extern PFNGLCLEARPROC glClear;
|
extern PFNGLCLEARPROC glClear;
|
||||||
|
|
||||||
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||||
extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
||||||
extern PFNGLUSEPROGRAMPROC glUseProgram;
|
extern PFNGLUSEPROGRAMPROC glUseProgram;
|
||||||
|
@ -84,13 +84,11 @@ extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||||
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||||
extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
||||||
extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
|
extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
|
||||||
|
|
||||||
extern PFNGLCREATESHADERPROC glCreateShader;
|
extern PFNGLCREATESHADERPROC glCreateShader;
|
||||||
extern PFNGLDELETESHADERPROC glDeleteShader;
|
extern PFNGLDELETESHADERPROC glDeleteShader;
|
||||||
extern PFNGLSHADERSOURCEPROC glShaderSource;
|
extern PFNGLSHADERSOURCEPROC glShaderSource;
|
||||||
extern PFNGLCOMPILESHADERPROC glCompileShader;
|
extern PFNGLCOMPILESHADERPROC glCompileShader;
|
||||||
extern PFNGLGETSHADERIVPROC glGetShaderiv;
|
extern PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||||
|
|
||||||
extern PFNGLGENBUFFERSPROC glGenBuffers;
|
extern PFNGLGENBUFFERSPROC glGenBuffers;
|
||||||
extern PFNGLBINDBUFFERPROC glBindBuffer;
|
extern PFNGLBINDBUFFERPROC glBindBuffer;
|
||||||
extern PFNGLBUFFERDATAPROC glBufferData;
|
extern PFNGLBUFFERDATAPROC glBufferData;
|
||||||
|
@ -102,21 +100,18 @@ extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||||
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||||
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||||
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||||
|
|
||||||
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
|
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||||
|
|
||||||
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||||
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||||
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||||
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||||
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
||||||
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||||
|
|
||||||
extern PFNGLTEXBUFFERPROC glTexBuffer;
|
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;
|
#endif
|
||||||
extern BOOL OpenGL_GotVersion3;
|
|
||||||
|
|
||||||
extern char OpenGL_Version[];
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
#ifndef OPENGLSHADER_H
|
||||||
|
#define OPENGLSHADER_H
|
||||||
|
|
||||||
// old
|
// old
|
||||||
|
|
||||||
const char PassthroughVertShader110Src[] =
|
const char PASSTHROUGH_VERT_SHADER_110[] =
|
||||||
"#version 110\n"
|
"#version 110\n"
|
||||||
"varying vec2 TEX0; \n"
|
"varying vec2 TEX0; \n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -10,7 +13,7 @@ const char PassthroughVertShader110Src[] =
|
||||||
" TEX0 = gl_MultiTexCoord0.xy; \n"
|
" TEX0 = gl_MultiTexCoord0.xy; \n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
const char PaletteFragShader110Src[] =
|
const char PALETTE_FRAG_SHADER_110[] =
|
||||||
"#version 110\n"
|
"#version 110\n"
|
||||||
"uniform sampler2D SurfaceTex; \n"
|
"uniform sampler2D SurfaceTex; \n"
|
||||||
"uniform sampler2D PaletteTex; \n"
|
"uniform sampler2D PaletteTex; \n"
|
||||||
|
@ -23,7 +26,7 @@ const char PaletteFragShader110Src[] =
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
const char PassthroughFragShader110Src[] =
|
const char PASSTHROUGH_FRAG_SHADER_110[] =
|
||||||
"#version 110\n"
|
"#version 110\n"
|
||||||
"uniform sampler2D SurfaceTex; \n"
|
"uniform sampler2D SurfaceTex; \n"
|
||||||
"varying vec2 TEX0; \n"
|
"varying vec2 TEX0; \n"
|
||||||
|
@ -36,7 +39,7 @@ const char PassthroughFragShader110Src[] =
|
||||||
|
|
||||||
// new
|
// new
|
||||||
|
|
||||||
const char PassthroughVertShaderSrc[] =
|
const char PASSTHROUGH_VERT_SHADER[] =
|
||||||
"#version 130\n"
|
"#version 130\n"
|
||||||
"in vec4 VertexCoord;\n"
|
"in vec4 VertexCoord;\n"
|
||||||
"in vec4 COLOR;\n"
|
"in vec4 COLOR;\n"
|
||||||
|
@ -53,7 +56,7 @@ const char PassthroughVertShaderSrc[] =
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
const char PaletteFragShaderSrc[] =
|
const char PALETTE_FRAG_SHADER[] =
|
||||||
"#version 130\n"
|
"#version 130\n"
|
||||||
"out vec4 FragColor;\n"
|
"out vec4 FragColor;\n"
|
||||||
"uniform sampler2D SurfaceTex;\n"
|
"uniform sampler2D SurfaceTex;\n"
|
||||||
|
@ -67,7 +70,7 @@ const char PaletteFragShaderSrc[] =
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
const char PassthroughFragShaderSrc[] =
|
const char PASSTHROUGH_FRAG_SHADER[] =
|
||||||
"#version 130\n"
|
"#version 130\n"
|
||||||
"out vec4 FragColor;\n"
|
"out vec4 FragColor;\n"
|
||||||
"uniform sampler2D SurfaceTex;\n"
|
"uniform sampler2D SurfaceTex;\n"
|
||||||
|
@ -78,3 +81,5 @@ const char PassthroughFragShaderSrc[] =
|
||||||
" vec4 texel = texture(SurfaceTex, TEX0.xy);\n"
|
" vec4 texel = texture(SurfaceTex, TEX0.xy);\n"
|
||||||
" FragColor = texel;\n"
|
" FragColor = texel;\n"
|
||||||
"}\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;
|
typedef struct CUSTOMVERTEX { float x, y, z, rhw, u, v; } CUSTOMVERTEX;
|
||||||
|
|
||||||
DWORD WINAPI render_d3d9_main(void);
|
typedef struct d3d9_renderer
|
||||||
BOOL Direct3D9_Create();
|
{
|
||||||
BOOL Direct3D9_Reset();
|
HMODULE hmodule;
|
||||||
BOOL Direct3D9_Release();
|
D3DPRESENT_PARAMETERS params;
|
||||||
BOOL Direct3D9_OnDeviceLost();
|
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 <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
#include "main.h"
|
#include "config.h"
|
||||||
#include "opengl.h"
|
#include "dd.h"
|
||||||
#include "render_d3d9.h"
|
#include "render_d3d9.h"
|
||||||
|
#include "render_gdi.h"
|
||||||
|
#include "render_ogl.h"
|
||||||
#include "hook.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 BOOL cfg_get_bool(LPCSTR key, BOOL defaultValue);
|
||||||
static int GetInt(LPCSTR key, int defaultValue);
|
static int cfg_get_int(LPCSTR key, int defaultValue);
|
||||||
static DWORD GetString(LPCSTR key, LPCSTR defaultValue, LPSTR outString, DWORD outSize);
|
static DWORD cfg_get_string(LPCSTR key, LPCSTR defaultValue, LPSTR outString, DWORD outSize);
|
||||||
static void CreateSettingsIni();
|
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
|
//set up settings ini
|
||||||
char cwd[MAX_PATH];
|
char cwd[MAX_PATH];
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
GetCurrentDirectoryA(sizeof(cwd), cwd);
|
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)
|
if (GetFileAttributes(g_config.ini_path) == INVALID_FILE_ATTRIBUTES)
|
||||||
CreateSettingsIni();
|
cfg_create_ini();
|
||||||
|
|
||||||
//get process filename
|
//get process filename
|
||||||
char ProcessFilePath[MAX_PATH] = { 0 };
|
char process_file_path[MAX_PATH] = { 0 };
|
||||||
GetModuleFileNameA(NULL, ProcessFilePath, MAX_PATH);
|
GetModuleFileNameA(NULL, process_file_path, MAX_PATH);
|
||||||
_splitpath(ProcessFilePath, NULL, NULL, ProcessFileName, NULL);
|
_splitpath(process_file_path, NULL, NULL, g_config.process_file_name, NULL);
|
||||||
|
|
||||||
//load settings from ini
|
//load settings from ini
|
||||||
ddraw->windowed = GetBool("windowed", FALSE);
|
g_ddraw->windowed = cfg_get_bool("windowed", FALSE);
|
||||||
ddraw->border = GetBool("border", TRUE);
|
g_ddraw->border = cfg_get_bool("border", TRUE);
|
||||||
ddraw->boxing = GetBool("boxing", FALSE);
|
g_ddraw->boxing = cfg_get_bool("boxing", FALSE);
|
||||||
ddraw->maintas = GetBool("maintas", FALSE);
|
g_ddraw->maintas = cfg_get_bool("maintas", FALSE);
|
||||||
ddraw->adjmouse = GetBool("adjmouse", FALSE);
|
g_ddraw->adjmouse = cfg_get_bool("adjmouse", FALSE);
|
||||||
ddraw->devmode = GetBool("devmode", FALSE);
|
g_ddraw->devmode = cfg_get_bool("devmode", FALSE);
|
||||||
ddraw->vsync = GetBool("vsync", FALSE);
|
g_ddraw->vsync = cfg_get_bool("vsync", FALSE);
|
||||||
ddraw->noactivateapp = GetBool("noactivateapp", FALSE);
|
g_ddraw->noactivateapp = cfg_get_bool("noactivateapp", FALSE);
|
||||||
ddraw->vhack = GetBool("vhack", FALSE);
|
g_ddraw->vhack = cfg_get_bool("vhack", FALSE);
|
||||||
ddraw->accurateTimers = GetBool("accuratetimers", FALSE);
|
g_ddraw->accurate_timers = cfg_get_bool("accuratetimers", FALSE);
|
||||||
ddraw->resizable = GetBool("resizable", TRUE);
|
g_ddraw->resizable = cfg_get_bool("resizable", TRUE);
|
||||||
ddraw->nonexclusive = GetBool("nonexclusive", FALSE);
|
g_ddraw->nonexclusive = cfg_get_bool("nonexclusive", FALSE);
|
||||||
ddraw->tm2hack = GetBool("tm2hack", FALSE); // Twisted Metal 2 hack
|
g_ddraw->sierrahack = cfg_get_bool("sierrahack", FALSE); // Sierra Caesar III, Pharaoh, and Zeus hack
|
||||||
ddraw->sierrahack = GetBool("sierrahack", FALSE); // Sierra Caesar III, Pharaoh, and Zeus hack
|
|
||||||
|
|
||||||
WindowRect.right = GetInt("width", 0);
|
g_config.window_rect.right = cfg_get_int("width", 0);
|
||||||
WindowRect.bottom = GetInt("height", 0);
|
g_config.window_rect.bottom = cfg_get_int("height", 0);
|
||||||
WindowRect.left = GetInt("posX", -32000);
|
g_config.window_rect.left = cfg_get_int("posX", -32000);
|
||||||
WindowRect.top = GetInt("posY", -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
|
#ifdef _MSC_VER
|
||||||
HookingMethod = GetInt("hook", 4);
|
g_hook_method = cfg_get_int("hook", 4);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ddraw->render.maxfps = GetInt("maxfps", 60);
|
g_ddraw->render.maxfps = cfg_get_int("maxfps", 60);
|
||||||
|
|
||||||
if (ddraw->render.maxfps)
|
if (g_ddraw->render.maxfps)
|
||||||
ddraw->render.forcefps = GetBool("forcefps", FALSE);
|
g_ddraw->render.forcefps = cfg_get_bool("forcefps", FALSE);
|
||||||
|
|
||||||
if (ddraw->accurateTimers || ddraw->vsync)
|
if (g_ddraw->accurate_timers || g_ddraw->vsync)
|
||||||
ddraw->fpsLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
g_ddraw->fps_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||||
//can't fully set it up here due to missing ddraw->mode.dmDisplayFrequency
|
//can't fully set it up here due to missing g_ddraw->mode.dmDisplayFrequency
|
||||||
|
|
||||||
int maxTicks = GetInt("maxgameticks", 0);
|
int max_ticks = cfg_get_int("maxgameticks", 0);
|
||||||
if (maxTicks > 0 && maxTicks <= 1000)
|
if (max_ticks > 0 && max_ticks <= 1000)
|
||||||
{
|
{
|
||||||
if (ddraw->accurateTimers)
|
if (g_ddraw->accurate_timers)
|
||||||
ddraw->ticksLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
g_ddraw->ticks_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||||
|
|
||||||
float len = 1000.0f / maxTicks;
|
float len = 1000.0f / max_ticks;
|
||||||
ddraw->ticksLimiter.tickLengthNs = len * 10000;
|
g_ddraw->ticks_limiter.tick_length_ns = len * 10000;
|
||||||
ddraw->ticksLimiter.ticklength = len + 0.5f;
|
g_ddraw->ticks_limiter.tick_length = len + 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxTicks >= 0)
|
if (max_ticks >= 0)
|
||||||
{
|
{
|
||||||
//always using 60 fps for flip...
|
//always using 60 fps for flip...
|
||||||
if (ddraw->accurateTimers)
|
if (g_ddraw->accurate_timers)
|
||||||
ddraw->flipLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
g_ddraw->flip_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||||
|
|
||||||
float flipLen = 1000.0f / 60;
|
float flip_len = 1000.0f / 60;
|
||||||
ddraw->flipLimiter.tickLengthNs = flipLen * 10000;
|
g_ddraw->flip_limiter.tick_length_ns = flip_len * 10000;
|
||||||
ddraw->flipLimiter.ticklength = flipLen + 0.5f;
|
g_ddraw->flip_limiter.tick_length = flip_len + 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ddraw->fullscreen = GetBool("fullscreen", FALSE)))
|
if ((g_ddraw->fullscreen = cfg_get_bool("fullscreen", FALSE)))
|
||||||
WindowRect.left = WindowRect.top = -32000;
|
g_config.window_rect.left = g_config.window_rect.top = -32000;
|
||||||
|
|
||||||
if (!(ddraw->handlemouse = GetBool("handlemouse", TRUE)))
|
if (!(g_ddraw->handlemouse = cfg_get_bool("handlemouse", TRUE)))
|
||||||
ddraw->adjmouse = TRUE;
|
g_ddraw->adjmouse = TRUE;
|
||||||
|
|
||||||
if (GetBool("singlecpu", TRUE))
|
if (cfg_get_bool("singlecpu", TRUE))
|
||||||
{
|
{
|
||||||
SetProcessAffinityMask(GetCurrentProcess(), 1);
|
SetProcessAffinityMask(GetCurrentProcess(), 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD systemAffinity;
|
DWORD system_affinity;
|
||||||
DWORD procAffinity;
|
DWORD proc_affinity;
|
||||||
HANDLE proc = GetCurrentProcess();
|
HANDLE proc = GetCurrentProcess();
|
||||||
if (GetProcessAffinityMask(proc, &procAffinity, &systemAffinity))
|
if (GetProcessAffinityMask(proc, &proc_affinity, &system_affinity))
|
||||||
SetProcessAffinityMask(proc, systemAffinity);
|
SetProcessAffinityMask(proc, system_affinity);
|
||||||
}
|
}
|
||||||
|
|
||||||
ddraw->render.bpp = GetInt("bpp", 0);
|
g_ddraw->render.bpp = cfg_get_int("bpp", 0);
|
||||||
if (ddraw->render.bpp != 16 && ddraw->render.bpp != 24 && ddraw->render.bpp != 32)
|
|
||||||
ddraw->render.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
|
// 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));
|
cfg_get_string("renderer", "auto", tmp, sizeof(tmp));
|
||||||
printf("Using %s renderer\n", tmp);
|
dprintf(" Using %s renderer\n", tmp);
|
||||||
|
|
||||||
if (tolower(tmp[0]) == 's' || tolower(tmp[0]) == 'g') //gdi
|
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
|
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
|
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
|
else
|
||||||
{
|
{
|
||||||
ShowDriverWarning = TRUE;
|
g_ddraw->show_driver_warning = TRUE;
|
||||||
ddraw->renderer = render_soft_main;
|
g_ddraw->renderer = gdi_render_main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //auto
|
else //auto
|
||||||
{
|
{
|
||||||
LPDIRECT3D9 d3d = NULL;
|
if (!g_ddraw->wine && d3d9_is_available())
|
||||||
|
|
||||||
// Windows = Direct3D 9, Wine = OpenGL
|
|
||||||
if (!ddraw->wine && (Direct3D9_hModule = LoadLibrary("d3d9.dll")))
|
|
||||||
{
|
{
|
||||||
IDirect3D9 *(WINAPI *D3DCreate9)(UINT) =
|
g_ddraw->renderer = d3d9_render_main;
|
||||||
(IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(Direct3D9_hModule, "Direct3DCreate9");
|
|
||||||
|
|
||||||
if (D3DCreate9 && (d3d = D3DCreate9(D3D_SDK_VERSION)))
|
|
||||||
IDirect3D9_Release(d3d);
|
|
||||||
}
|
}
|
||||||
|
else if (oglu_load_dll())
|
||||||
if (d3d)
|
|
||||||
{
|
{
|
||||||
ddraw->renderer = render_d3d9_main;
|
g_ddraw->renderer = ogl_render_main;
|
||||||
}
|
|
||||||
else if (OpenGL_LoadDll())
|
|
||||||
{
|
|
||||||
ddraw->renderer = render_main;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShowDriverWarning = TRUE;
|
g_ddraw->show_driver_warning = TRUE;
|
||||||
ddraw->renderer = render_soft_main;
|
g_ddraw->renderer = gdi_render_main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings_Save(RECT *lpRect, int windowState)
|
void cfg_save()
|
||||||
{
|
{
|
||||||
if (!SaveSettings)
|
if (!g_config.save_settings)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char buf[16];
|
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);
|
sprintf(buf, "%ld", g_config.window_rect.right);
|
||||||
WritePrivateProfileString(section, "width", buf, SettingsIniPath);
|
WritePrivateProfileString(section, "width", buf, g_config.ini_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpRect->bottom)
|
if (g_config.window_rect.bottom)
|
||||||
{
|
{
|
||||||
sprintf(buf, "%ld", lpRect->bottom);
|
sprintf(buf, "%ld", g_config.window_rect.bottom);
|
||||||
WritePrivateProfileString(section, "height", buf, SettingsIniPath);
|
WritePrivateProfileString(section, "height", buf, g_config.ini_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpRect->left != -32000)
|
if (g_config.window_rect.left != -32000)
|
||||||
{
|
{
|
||||||
sprintf(buf, "%ld", lpRect->left);
|
sprintf(buf, "%ld", g_config.window_rect.left);
|
||||||
WritePrivateProfileString(section, "posX", buf, SettingsIniPath);
|
WritePrivateProfileString(section, "posX", buf, g_config.ini_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpRect->top != -32000)
|
if (g_config.window_rect.top != -32000)
|
||||||
{
|
{
|
||||||
sprintf(buf, "%ld", lpRect->top);
|
sprintf(buf, "%ld", g_config.window_rect.top);
|
||||||
WritePrivateProfileString(section, "posY", buf, SettingsIniPath);
|
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)
|
if (fh)
|
||||||
{
|
{
|
||||||
fputs(
|
fputs(
|
||||||
|
@ -483,7 +474,6 @@ static void CreateSettingsIni()
|
||||||
"nonexclusive=true\n"
|
"nonexclusive=true\n"
|
||||||
"maxgameticks=60\n"
|
"maxgameticks=60\n"
|
||||||
"handlemouse=false\n"
|
"handlemouse=false\n"
|
||||||
"tm2hack=true\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"; Caesar III\n"
|
"; Caesar III\n"
|
||||||
"[c3]\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)
|
if (s > 0)
|
||||||
{
|
{
|
||||||
char buf[MAX_PATH] = { 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)
|
if (GetFileAttributes(buf) != INVALID_FILE_ATTRIBUTES)
|
||||||
return s;
|
return s;
|
||||||
|
@ -524,24 +517,24 @@ static DWORD GetString(LPCSTR key, LPCSTR defaultValue, LPSTR outString, DWORD o
|
||||||
return s;
|
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];
|
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);
|
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];
|
char def_value[16];
|
||||||
_snprintf(defvalue, sizeof(defvalue), "%d", defaultValue);
|
_snprintf(def_value, sizeof(def_value), "%d", defaultValue);
|
||||||
|
|
||||||
char value[16];
|
char value[16];
|
||||||
GetString(key, defvalue, value, sizeof(value));
|
cfg_get_string(key, def_value, value, sizeof(value));
|
||||||
|
|
||||||
return atoi(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 <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "main.h"
|
#include "dd.h"
|
||||||
#include "surface.h"
|
#include "ddraw.h"
|
||||||
|
#include "ddsurface.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
double DebugFrameTime = 0;
|
|
||||||
DWORD DebugFrameCount = 0;
|
|
||||||
|
|
||||||
static LONGLONG CounterStartTime = 0;
|
double g_dbg_frame_time = 0;
|
||||||
static double CounterFreq = 0.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;
|
LARGE_INTEGER li;
|
||||||
QueryPerformanceFrequency(&li);
|
QueryPerformanceFrequency(&li);
|
||||||
CounterFreq = (double)(li.QuadPart) / 1000.0;
|
g_dbg_counter_freq = (double)(li.QuadPart) / 1000.0;
|
||||||
QueryPerformanceCounter(&li);
|
QueryPerformanceCounter(&li);
|
||||||
CounterStartTime = li.QuadPart;
|
g_dbg_counter_start_time = li.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
double CounterStop()
|
double dbg_counter_stop()
|
||||||
{
|
{
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
QueryPerformanceCounter(&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_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
char buffer[512];
|
char buffer[512] = { 0 };
|
||||||
_vsnprintf(buffer, sizeof(buffer), format, args);
|
_vsnprintf(buffer, sizeof(buffer), format, args);
|
||||||
OutputDebugStringA(buffer);
|
OutputDebugStringA(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dprintf(const char *fmt, ...)
|
int dbg_printf(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
static CRITICAL_SECTION cs;
|
static CRITICAL_SECTION cs;
|
||||||
static BOOL initialized;
|
static BOOL initialized;
|
||||||
|
@ -65,42 +96,292 @@ int dprintf(const char *fmt, ...)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawFrameInfoStart()
|
void dbg_draw_frame_info_start()
|
||||||
{
|
{
|
||||||
static DWORD tick_fps = 0;
|
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)
|
if (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)
|
||||||
SetDIBColorTable(ddraw->primary->hDC, 0, 256, 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();
|
DWORD tick_start = timeGetTime();
|
||||||
if (tick_start >= tick_fps)
|
if (tick_start >= tick_fps)
|
||||||
{
|
{
|
||||||
_snprintf(
|
_snprintf(
|
||||||
debugText,
|
debug_text,
|
||||||
sizeof(debugText),
|
sizeof(debug_text)-1,
|
||||||
"FPS: %lu | Time: %2.2f ms ",
|
"FPS: %lu | Time: %2.2f ms ",
|
||||||
DebugFrameCount,
|
g_dbg_frame_count,
|
||||||
DebugFrameTime);
|
g_dbg_frame_time);
|
||||||
|
|
||||||
DebugFrameCount = 0;
|
g_dbg_frame_count = 0;
|
||||||
tick_fps = tick_start + 1000;
|
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)
|
if (g_dbg_frame_count == 1)
|
||||||
DebugFrameTime = CounterStop();
|
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 <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "main.h"
|
#include "dd.h"
|
||||||
#include "mouse.h"
|
#include "winapi_hooks.h"
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
|
#include "dllmain.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include "detours.h"
|
#include "detours.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOL Hook_Active;
|
BOOL g_hook_active;
|
||||||
int HookingMethod = 1;
|
int g_hook_method = 1;
|
||||||
|
|
||||||
GETCURSORPOSPROC real_GetCursorPos = GetCursorPos;
|
GETCURSORPOSPROC real_GetCursorPos = GetCursorPos;
|
||||||
CLIPCURSORPROC real_ClipCursor = ClipCursor;
|
CLIPCURSORPROC real_ClipCursor = ClipCursor;
|
||||||
SHOWCURSORPROC real_ShowCursor = ShowCursor;
|
SHOWCURSORPROC real_ShowCursor = ShowCursor;
|
||||||
|
@ -37,66 +40,66 @@ LOADLIBRARYEXAPROC real_LoadLibraryExA = LoadLibraryExA;
|
||||||
LOADLIBRARYEXWPROC real_LoadLibraryExW = LoadLibraryExW;
|
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;
|
return;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMod;
|
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)hmod;
|
||||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew);
|
PIMAGE_NT_HEADERS nt_headers = (PIMAGE_NT_HEADERS)((DWORD)dos_header + (DWORD)dos_header->e_lfanew);
|
||||||
if (pNTHeaders->Signature != IMAGE_NT_SIGNATURE)
|
if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDosHeader +
|
PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header +
|
||||||
(DWORD)(pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
|
(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;
|
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 first_thunk =
|
||||||
(PIMAGE_THUNK_DATA)((DWORD)pDosHeader + (DWORD)pImportDescriptor->FirstThunk);
|
(PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->FirstThunk);
|
||||||
|
|
||||||
PIMAGE_THUNK_DATA pOrigFirstThunk =
|
PIMAGE_THUNK_DATA original_first_thunk =
|
||||||
(PIMAGE_THUNK_DATA)((DWORD)pDosHeader + (DWORD)pImportDescriptor->OriginalFirstThunk);
|
(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 import =
|
||||||
(PIMAGE_IMPORT_BY_NAME)((DWORD)pDosHeader + pOrigFirstThunk->u1.AddressOfData);
|
(PIMAGE_IMPORT_BY_NAME)((DWORD)dos_header + original_first_thunk->u1.AddressOfData);
|
||||||
|
|
||||||
if ((pOrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0 &&
|
if ((original_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0 &&
|
||||||
_stricmp((const char*)pImport->Name, functionName) == 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;
|
first_thunk->u1.Function = (DWORD)new_function;
|
||||||
VirtualProtect(&pFirstThunk->u1.Function, sizeof(DWORD), oldProtect, &oldProtect);
|
VirtualProtect(&first_thunk->u1.Function, sizeof(DWORD), old_protect, &old_protect);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFirstThunk++;
|
first_thunk++;
|
||||||
pOrigFirstThunk++;
|
original_first_thunk++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pImportDescriptor++;
|
import_desc++;
|
||||||
}
|
}
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
}
|
}
|
||||||
|
@ -106,42 +109,42 @@ void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newF
|
||||||
#endif
|
#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
|
#ifdef _MSC_VER
|
||||||
if (HookingMethod == 2)
|
if (g_hook_method == 2)
|
||||||
{
|
{
|
||||||
DetourTransactionBegin();
|
DetourTransactionBegin();
|
||||||
DetourUpdateThread(GetCurrentThread());
|
DetourUpdateThread(GetCurrentThread());
|
||||||
DetourAttach((PVOID *)function, (PVOID)newFunction);
|
DetourAttach((PVOID *)function, (PVOID)new_function);
|
||||||
DetourTransactionCommit();
|
DetourTransactionCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HookingMethod == 3 || HookingMethod == 4)
|
if (g_hook_method == 3 || g_hook_method == 4)
|
||||||
{
|
{
|
||||||
WCHAR gameExePath[MAX_PATH] = { 0 };
|
WCHAR game_exe_path[MAX_PATH] = { 0 };
|
||||||
WCHAR gameDir[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 mod_path[MAX_PATH] = { 0 };
|
||||||
WCHAR modDir[MAX_PATH] = { 0 };
|
WCHAR mod_dir[MAX_PATH] = { 0 };
|
||||||
HMODULE hMod = NULL;
|
HMODULE hmod = NULL;
|
||||||
|
|
||||||
while (hMod = DetourEnumerateModules(hMod))
|
while (hmod = DetourEnumerateModules(hmod))
|
||||||
{
|
{
|
||||||
if (hMod == DDrawModule)
|
if (hmod == g_ddraw_module)
|
||||||
continue;
|
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
|
#endif
|
||||||
|
|
||||||
if (HookingMethod == 1)
|
if (g_hook_method == 1)
|
||||||
{
|
{
|
||||||
Hook_PatchIAT(GetModuleHandle(NULL), moduleName, functionName, newFunction);
|
hook_patch_iat(GetModuleHandle(NULL), module_name, function_name, new_function);
|
||||||
Hook_PatchIAT(GetModuleHandle("storm.dll"), moduleName, functionName, newFunction);
|
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
|
#ifdef _MSC_VER
|
||||||
if (HookingMethod == 2)
|
if (g_hook_method == 2)
|
||||||
{
|
{
|
||||||
DetourTransactionBegin();
|
DetourTransactionBegin();
|
||||||
DetourUpdateThread(GetCurrentThread());
|
DetourUpdateThread(GetCurrentThread());
|
||||||
DetourDetach((PVOID *)function, (PVOID)newFunction);
|
DetourDetach((PVOID *)function, (PVOID)new_function);
|
||||||
DetourTransactionCommit();
|
DetourTransactionCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HookingMethod == 3 || HookingMethod == 4)
|
if (g_hook_method == 3 || g_hook_method == 4)
|
||||||
{
|
{
|
||||||
WCHAR gameExePath[MAX_PATH] = { 0 };
|
WCHAR game_exe_path[MAX_PATH] = { 0 };
|
||||||
WCHAR gameDir[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 mod_path[MAX_PATH] = { 0 };
|
||||||
WCHAR modDir[MAX_PATH] = { 0 };
|
WCHAR mod_dir[MAX_PATH] = { 0 };
|
||||||
HMODULE hMod = NULL;
|
HMODULE hmod = NULL;
|
||||||
|
|
||||||
while (hMod = DetourEnumerateModules(hMod))
|
while (hmod = DetourEnumerateModules(hmod))
|
||||||
{
|
{
|
||||||
if (hMod == DDrawModule)
|
if (hmod == g_ddraw_module)
|
||||||
continue;
|
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(
|
hook_patch_iat(
|
||||||
hMod,
|
hmod,
|
||||||
moduleName,
|
module_name,
|
||||||
functionName,
|
function_name,
|
||||||
GetProcAddress(GetModuleHandle(moduleName), functionName));
|
GetProcAddress(GetModuleHandle(module_name), function_name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,28 +206,28 @@ void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *f
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (HookingMethod == 1)
|
if (g_hook_method == 1)
|
||||||
{
|
{
|
||||||
Hook_PatchIAT(
|
hook_patch_iat(
|
||||||
GetModuleHandle(NULL),
|
GetModuleHandle(NULL),
|
||||||
moduleName,
|
module_name,
|
||||||
functionName,
|
function_name,
|
||||||
GetProcAddress(GetModuleHandle(moduleName), functionName));
|
GetProcAddress(GetModuleHandle(module_name), function_name));
|
||||||
|
|
||||||
Hook_PatchIAT(
|
hook_patch_iat(
|
||||||
GetModuleHandle("storm.dll"),
|
GetModuleHandle("storm.dll"),
|
||||||
moduleName,
|
module_name,
|
||||||
functionName,
|
function_name,
|
||||||
GetProcAddress(GetModuleHandle(moduleName), functionName));
|
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
|
#ifdef _MSC_VER
|
||||||
if (!Hook_Active && HookingMethod == 3)
|
if (!g_hook_active && g_hook_method == 3)
|
||||||
{
|
{
|
||||||
FARPROC proc = GetProcAddress(GetModuleHandle("kernelbase.dll"), "LoadLibraryExW");
|
FARPROC proc = GetProcAddress(GetModuleHandle("kernelbase.dll"), "LoadLibraryExW");
|
||||||
|
|
||||||
|
@ -238,48 +241,48 @@ void Hook_Init()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Hook_Active = TRUE;
|
g_hook_active = TRUE;
|
||||||
|
|
||||||
Hook_Create("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
|
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", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor);
|
||||||
Hook_Create("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor);
|
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", "SetCursor", (PROC)fake_SetCursor, (PROC *)&real_SetCursor);
|
||||||
Hook_Create("user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect, (PROC *)&real_GetWindowRect);
|
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", "GetClientRect", (PROC)fake_GetClientRect, (PROC *)&real_GetClientRect);
|
||||||
Hook_Create("user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen, (PROC *)&real_ClientToScreen);
|
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", "ScreenToClient", (PROC)fake_ScreenToClient, (PROC *)&real_ScreenToClient);
|
||||||
Hook_Create("user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos, (PROC *)&real_SetCursorPos);
|
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", "GetClipCursor", (PROC)fake_GetClipCursor, (PROC *)&real_GetClipCursor);
|
||||||
Hook_Create("user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC *)&real_WindowFromPoint);
|
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", "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC *)&real_GetCursorInfo);
|
||||||
Hook_Create("user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC *)&real_GetSystemMetrics);
|
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", "SetWindowPos", (PROC)fake_SetWindowPos, (PROC *)&real_SetWindowPos);
|
||||||
Hook_Create("user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow);
|
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", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA);
|
||||||
Hook_Create("user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA);
|
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", "EnableWindow", (PROC)fake_EnableWindow, (PROC *)&real_EnableWindow);
|
||||||
Hook_Create("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
|
hook_create("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
|
||||||
Hook_Create("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
|
hook_create("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
|
||||||
Hook_Create("gdi32.dll", "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps);
|
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", "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA);
|
||||||
Hook_Create("kernel32.dll", "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW);
|
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", "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA);
|
||||||
Hook_Create("kernel32.dll", "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW);
|
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
|
#ifdef _MSC_VER
|
||||||
if (HookingMethod == 3)
|
if (g_hook_method == 3)
|
||||||
{
|
{
|
||||||
DetourTransactionBegin();
|
DetourTransactionBegin();
|
||||||
DetourUpdateThread(GetCurrentThread());
|
DetourUpdateThread(GetCurrentThread());
|
||||||
|
@ -288,34 +291,34 @@ void Hook_Exit()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Hook_Revert("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
|
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", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor);
|
||||||
Hook_Revert("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor);
|
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", "SetCursor", (PROC)fake_SetCursor, (PROC *)&real_SetCursor);
|
||||||
Hook_Revert("user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect, (PROC *)&real_GetWindowRect);
|
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", "GetClientRect", (PROC)fake_GetClientRect, (PROC *)&real_GetClientRect);
|
||||||
Hook_Revert("user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen, (PROC *)&real_ClientToScreen);
|
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", "ScreenToClient", (PROC)fake_ScreenToClient, (PROC *)&real_ScreenToClient);
|
||||||
Hook_Revert("user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos, (PROC *)&real_SetCursorPos);
|
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", "GetClipCursor", (PROC)fake_GetClipCursor, (PROC *)&real_GetClipCursor);
|
||||||
Hook_Revert("user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC *)&real_WindowFromPoint);
|
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", "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC *)&real_GetCursorInfo);
|
||||||
Hook_Revert("user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC *)&real_GetSystemMetrics);
|
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", "SetWindowPos", (PROC)fake_SetWindowPos, (PROC *)&real_SetWindowPos);
|
||||||
Hook_Revert("user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow);
|
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", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA);
|
||||||
Hook_Revert("user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA);
|
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", "EnableWindow", (PROC)fake_EnableWindow, (PROC *)&real_EnableWindow);
|
||||||
Hook_Revert("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
|
hook_revert("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
|
||||||
Hook_Revert("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
|
hook_revert("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
|
||||||
Hook_Revert("gdi32.dll", "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps);
|
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", "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA);
|
||||||
Hook_Revert("kernel32.dll", "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW);
|
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", "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA);
|
||||||
Hook_Revert("kernel32.dll", "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW);
|
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 @@
|
||||||
/*
|
#define WIN32_LEAN_AND_MEAN
|
||||||
* 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 <windows.h>
|
||||||
#include <stdio.h>
|
#include "dd.h"
|
||||||
#include "main.h"
|
|
||||||
#include "surface.h"
|
|
||||||
#include "hook.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()
|
void mouse_lock()
|
||||||
{
|
{
|
||||||
RECT rc;
|
RECT rc;
|
||||||
|
|
||||||
if (ddraw->bnetActive)
|
if (g_ddraw->bnet_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ddraw->devmode)
|
if (g_ddraw->devmode)
|
||||||
{
|
{
|
||||||
if (ddraw->handlemouse)
|
if (g_ddraw->handlemouse)
|
||||||
while(real_ShowCursor(FALSE) > 0);
|
while(real_ShowCursor(FALSE) > 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Hook_Active && !ddraw->locked)
|
if (g_hook_active && !g_ddraw->locked)
|
||||||
{
|
{
|
||||||
// Get the window client area.
|
// 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.right = g_ddraw->render.viewport.width;
|
||||||
rc.bottom = ddraw->render.viewport.height;
|
rc.bottom = g_ddraw->render.viewport.height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc.right = ddraw->width;
|
rc.right = g_ddraw->width;
|
||||||
rc.bottom = ddraw->height;
|
rc.bottom = g_ddraw->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the client area to screen coordinates.
|
// Convert the client area to screen coordinates.
|
||||||
POINT pt = { rc.left, rc.top };
|
POINT pt = { rc.left, rc.top };
|
||||||
POINT pt2 = { rc.right, rc.bottom };
|
POINT pt2 = { rc.right, rc.bottom };
|
||||||
real_ClientToScreen(ddraw->hWnd, &pt);
|
real_ClientToScreen(g_ddraw->hwnd, &pt);
|
||||||
real_ClientToScreen(ddraw->hWnd, &pt2);
|
real_ClientToScreen(g_ddraw->hwnd, &pt2);
|
||||||
|
|
||||||
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
|
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(
|
real_SetCursorPos(
|
||||||
rc.left + (ddraw->cursor.x * ddraw->render.scaleW),
|
rc.left + (g_ddraw->cursor.x * g_ddraw->render.scale_w),
|
||||||
rc.top + ((ddraw->cursor.y - yAdjust) * ddraw->render.scaleH));
|
rc.top + ((g_ddraw->cursor.y - g_ddraw->mouse_y_adjust) * g_ddraw->render.scale_h));
|
||||||
}
|
}
|
||||||
else
|
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);
|
real_ClipCursor(&rc);
|
||||||
while (real_ShowCursor(FALSE) > 0);
|
while (real_ShowCursor(FALSE) > 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ddraw->hidecursor)
|
if (g_ddraw->hidecursor)
|
||||||
{
|
{
|
||||||
ddraw->hidecursor = FALSE;
|
g_ddraw->hidecursor = FALSE;
|
||||||
real_ShowCursor(FALSE);
|
real_ShowCursor(FALSE);
|
||||||
}
|
}
|
||||||
real_ClipCursor(&rc);
|
real_ClipCursor(&rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
ddraw->locked = TRUE;
|
g_ddraw->locked = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,34 +80,34 @@ void mouse_unlock()
|
||||||
{
|
{
|
||||||
RECT rc;
|
RECT rc;
|
||||||
|
|
||||||
if (ddraw->devmode)
|
if (g_ddraw->devmode)
|
||||||
{
|
{
|
||||||
if (ddraw->handlemouse)
|
if (g_ddraw->handlemouse)
|
||||||
while(real_ShowCursor(TRUE) < 0);
|
while(real_ShowCursor(TRUE) < 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Hook_Active)
|
if(!g_hook_active)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ddraw->locked)
|
if(g_ddraw->locked)
|
||||||
{
|
{
|
||||||
ddraw->locked = FALSE;
|
g_ddraw->locked = FALSE;
|
||||||
|
|
||||||
// Get the window client area.
|
// Get the window client area.
|
||||||
real_GetClientRect(ddraw->hWnd, &rc);
|
real_GetClientRect(g_ddraw->hwnd, &rc);
|
||||||
|
|
||||||
// Convert the client area to screen coordinates.
|
// Convert the client area to screen coordinates.
|
||||||
POINT pt = { rc.left, rc.top };
|
POINT pt = { rc.left, rc.top };
|
||||||
POINT pt2 = { rc.right, rc.bottom };
|
POINT pt2 = { rc.right, rc.bottom };
|
||||||
real_ClientToScreen(ddraw->hWnd, &pt);
|
real_ClientToScreen(g_ddraw->hwnd, &pt);
|
||||||
real_ClientToScreen(ddraw->hWnd, &pt2);
|
real_ClientToScreen(g_ddraw->hwnd, &pt2);
|
||||||
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
|
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
|
||||||
|
|
||||||
if (ddraw->handlemouse)
|
if (g_ddraw->handlemouse)
|
||||||
{
|
{
|
||||||
while (real_ShowCursor(TRUE) < 0);
|
while (real_ShowCursor(TRUE) < 0);
|
||||||
real_SetCursor(LoadCursor(NULL, IDC_ARROW));
|
real_SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||||
|
@ -252,7 +117,7 @@ void mouse_unlock()
|
||||||
CURSORINFO ci = { .cbSize = sizeof(CURSORINFO) };
|
CURSORINFO ci = { .cbSize = sizeof(CURSORINFO) };
|
||||||
if (real_GetCursorInfo(&ci) && ci.flags == 0)
|
if (real_GetCursorInfo(&ci) && ci.flags == 0)
|
||||||
{
|
{
|
||||||
ddraw->hidecursor = TRUE;
|
g_ddraw->hidecursor = TRUE;
|
||||||
while (real_ShowCursor(TRUE) < 0);
|
while (real_ShowCursor(TRUE) < 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,308 +126,7 @@ void mouse_unlock()
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
|
|
||||||
real_SetCursorPos(
|
real_SetCursorPos(
|
||||||
rc.left + ddraw->render.viewport.x + (ddraw->cursor.x * ddraw->render.scaleW),
|
rc.left + g_ddraw->render.viewport.x + (g_ddraw->cursor.x * g_ddraw->render.scale_w),
|
||||||
rc.top + ddraw->render.viewport.y + ((ddraw->cursor.y + yAdjust) * ddraw->render.scaleH));
|
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 <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "opengl.h"
|
#include "opengl_utils.h"
|
||||||
|
|
||||||
PFNWGLCREATECONTEXTPROC xwglCreateContext;
|
PFNWGLCREATECONTEXTPROC xwglCreateContext;
|
||||||
PFNWGLDELETECONTEXTPROC xwglDeleteContext;
|
PFNWGLDELETECONTEXTPROC xwglDeleteContext;
|
||||||
|
@ -21,13 +21,10 @@ PFNGLGETTEXIMAGEPROC glGetTexImage;
|
||||||
PFNGLPIXELSTOREIPROC glPixelStorei;
|
PFNGLPIXELSTOREIPROC glPixelStorei;
|
||||||
PFNGLENABLEPROC glEnable;
|
PFNGLENABLEPROC glEnable;
|
||||||
PFNGLCLEARPROC glClear;
|
PFNGLCLEARPROC glClear;
|
||||||
|
|
||||||
PFNGLBEGINPROC glBegin;
|
PFNGLBEGINPROC glBegin;
|
||||||
PFNGLENDPROC glEnd;
|
PFNGLENDPROC glEnd;
|
||||||
PFNGLTEXCOORD2FPROC glTexCoord2f;
|
PFNGLTEXCOORD2FPROC glTexCoord2f;
|
||||||
PFNGLVERTEX2FPROC glVertex2f;
|
PFNGLVERTEX2FPROC glVertex2f;
|
||||||
|
|
||||||
// Program
|
|
||||||
PFNGLCREATEPROGRAMPROC glCreateProgram;
|
PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||||
PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
||||||
PFNGLUSEPROGRAMPROC glUseProgram;
|
PFNGLUSEPROGRAMPROC glUseProgram;
|
||||||
|
@ -59,13 +56,11 @@ PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||||
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
||||||
PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
|
PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
|
||||||
|
|
||||||
PFNGLCREATESHADERPROC glCreateShader;
|
PFNGLCREATESHADERPROC glCreateShader;
|
||||||
PFNGLDELETESHADERPROC glDeleteShader;
|
PFNGLDELETESHADERPROC glDeleteShader;
|
||||||
PFNGLSHADERSOURCEPROC glShaderSource;
|
PFNGLSHADERSOURCEPROC glShaderSource;
|
||||||
PFNGLCOMPILESHADERPROC glCompileShader;
|
PFNGLCOMPILESHADERPROC glCompileShader;
|
||||||
PFNGLGETSHADERIVPROC glGetShaderiv;
|
PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||||
|
|
||||||
PFNGLGENBUFFERSPROC glGenBuffers;
|
PFNGLGENBUFFERSPROC glGenBuffers;
|
||||||
PFNGLBINDBUFFERPROC glBindBuffer;
|
PFNGLBINDBUFFERPROC glBindBuffer;
|
||||||
PFNGLBUFFERDATAPROC glBufferData;
|
PFNGLBUFFERDATAPROC glBufferData;
|
||||||
|
@ -77,59 +72,53 @@ PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||||
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||||
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||||
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||||
|
|
||||||
PFNGLACTIVETEXTUREPROC glActiveTexture;
|
PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||||
|
|
||||||
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||||
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||||
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||||
PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||||
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
||||||
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||||
|
|
||||||
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
|
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
|
||||||
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
|
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
|
||||||
|
|
||||||
PFNGLTEXBUFFERPROC glTexBuffer;
|
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 oglu_load_dll()
|
||||||
BOOL OpenGL_GotVersion3;
|
|
||||||
|
|
||||||
char OpenGL_Version[128];
|
|
||||||
|
|
||||||
BOOL OpenGL_LoadDll()
|
|
||||||
{
|
{
|
||||||
if (!OpenGL_hModule)
|
if (!g_oglu_hmodule)
|
||||||
OpenGL_hModule = LoadLibrary("opengl32.dll");
|
g_oglu_hmodule = LoadLibrary("opengl32.dll");
|
||||||
|
|
||||||
if (OpenGL_hModule)
|
if (g_oglu_hmodule)
|
||||||
{
|
{
|
||||||
xwglCreateContext = (PFNWGLCREATECONTEXTPROC)GetProcAddress(OpenGL_hModule, "wglCreateContext");
|
xwglCreateContext = (PFNWGLCREATECONTEXTPROC)GetProcAddress(g_oglu_hmodule, "wglCreateContext");
|
||||||
xwglDeleteContext = (PFNWGLDELETECONTEXTPROC)GetProcAddress(OpenGL_hModule, "wglDeleteContext");
|
xwglDeleteContext = (PFNWGLDELETECONTEXTPROC)GetProcAddress(g_oglu_hmodule, "wglDeleteContext");
|
||||||
xwglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress(OpenGL_hModule, "wglGetProcAddress");
|
xwglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress(g_oglu_hmodule, "wglGetProcAddress");
|
||||||
xwglMakeCurrent = (PFNWGLMAKECURRENTPROC)GetProcAddress(OpenGL_hModule, "wglMakeCurrent");
|
xwglMakeCurrent = (PFNWGLMAKECURRENTPROC)GetProcAddress(g_oglu_hmodule, "wglMakeCurrent");
|
||||||
|
|
||||||
glViewport = (PFNGLVIEWPORTPROC)GetProcAddress(OpenGL_hModule, "glViewport");
|
glViewport = (PFNGLVIEWPORTPROC)GetProcAddress(g_oglu_hmodule, "glViewport");
|
||||||
glBindTexture = (PFNGLBINDTEXTUREPROC)GetProcAddress(OpenGL_hModule, "glBindTexture");
|
glBindTexture = (PFNGLBINDTEXTUREPROC)GetProcAddress(g_oglu_hmodule, "glBindTexture");
|
||||||
glGenTextures = (PFNGLGENTEXTURESPROC)GetProcAddress(OpenGL_hModule, "glGenTextures");
|
glGenTextures = (PFNGLGENTEXTURESPROC)GetProcAddress(g_oglu_hmodule, "glGenTextures");
|
||||||
glTexParameteri = (PFNGLTEXPARAMETERIPROC)GetProcAddress(OpenGL_hModule, "glTexParameteri");
|
glTexParameteri = (PFNGLTEXPARAMETERIPROC)GetProcAddress(g_oglu_hmodule, "glTexParameteri");
|
||||||
glDeleteTextures = (PFNGLDELETETEXTURESPROC)GetProcAddress(OpenGL_hModule, "glDeleteTextures");
|
glDeleteTextures = (PFNGLDELETETEXTURESPROC)GetProcAddress(g_oglu_hmodule, "glDeleteTextures");
|
||||||
glTexImage2D = (PFNGLTEXIMAGE2DPROC)GetProcAddress(OpenGL_hModule, "glTexImage2D");
|
glTexImage2D = (PFNGLTEXIMAGE2DPROC)GetProcAddress(g_oglu_hmodule, "glTexImage2D");
|
||||||
glDrawElements = (PFNGLDRAWELEMENTSPROC)GetProcAddress(OpenGL_hModule, "glDrawElements");
|
glDrawElements = (PFNGLDRAWELEMENTSPROC)GetProcAddress(g_oglu_hmodule, "glDrawElements");
|
||||||
glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)GetProcAddress(OpenGL_hModule, "glTexSubImage2D");
|
glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)GetProcAddress(g_oglu_hmodule, "glTexSubImage2D");
|
||||||
glGetError = (PFNGLGETERRORPROC)GetProcAddress(OpenGL_hModule, "glGetError");
|
glGetError = (PFNGLGETERRORPROC)GetProcAddress(g_oglu_hmodule, "glGetError");
|
||||||
glGetString = (PFNGLGETSTRINGPROC)GetProcAddress(OpenGL_hModule, "glGetString");
|
glGetString = (PFNGLGETSTRINGPROC)GetProcAddress(g_oglu_hmodule, "glGetString");
|
||||||
glGetTexImage = (PFNGLGETTEXIMAGEPROC)GetProcAddress(OpenGL_hModule, "glGetTexImage");
|
glGetTexImage = (PFNGLGETTEXIMAGEPROC)GetProcAddress(g_oglu_hmodule, "glGetTexImage");
|
||||||
glPixelStorei = (PFNGLPIXELSTOREIPROC)GetProcAddress(OpenGL_hModule, "glPixelStorei");
|
glPixelStorei = (PFNGLPIXELSTOREIPROC)GetProcAddress(g_oglu_hmodule, "glPixelStorei");
|
||||||
glEnable = (PFNGLENABLEPROC)GetProcAddress(OpenGL_hModule, "glEnable");
|
glEnable = (PFNGLENABLEPROC)GetProcAddress(g_oglu_hmodule, "glEnable");
|
||||||
glClear = (PFNGLCLEARPROC)GetProcAddress(OpenGL_hModule, "glClear");
|
glClear = (PFNGLCLEARPROC)GetProcAddress(g_oglu_hmodule, "glClear");
|
||||||
|
|
||||||
glBegin = (PFNGLBEGINPROC)GetProcAddress(OpenGL_hModule, "glBegin");
|
glBegin = (PFNGLBEGINPROC)GetProcAddress(g_oglu_hmodule, "glBegin");
|
||||||
glEnd = (PFNGLENDPROC)GetProcAddress(OpenGL_hModule, "glEnd");
|
glEnd = (PFNGLENDPROC)GetProcAddress(g_oglu_hmodule, "glEnd");
|
||||||
glTexCoord2f = (PFNGLTEXCOORD2FPROC)GetProcAddress(OpenGL_hModule, "glTexCoord2f");
|
glTexCoord2f = (PFNGLTEXCOORD2FPROC)GetProcAddress(g_oglu_hmodule, "glTexCoord2f");
|
||||||
glVertex2f = (PFNGLVERTEX2FPROC)GetProcAddress(OpenGL_hModule, "glVertex2f");
|
glVertex2f = (PFNGLVERTEX2FPROC)GetProcAddress(g_oglu_hmodule, "glVertex2f");
|
||||||
}
|
}
|
||||||
|
|
||||||
return xwglCreateContext && xwglDeleteContext && xwglGetProcAddress && xwglMakeCurrent && glViewport &&
|
return xwglCreateContext && xwglDeleteContext && xwglGetProcAddress && xwglMakeCurrent && glViewport &&
|
||||||
|
@ -138,7 +127,7 @@ BOOL OpenGL_LoadDll()
|
||||||
glEnable && glClear && glBegin && glEnd && glTexCoord2f && glVertex2f;
|
glEnable && glClear && glBegin && glEnd && glTexCoord2f && glVertex2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGL_Init()
|
void oglu_init()
|
||||||
{
|
{
|
||||||
// Program
|
// Program
|
||||||
glCreateProgram = (PFNGLCREATEPROGRAMPROC)xwglGetProcAddress("glCreateProgram");
|
glCreateProgram = (PFNGLCREATEPROGRAMPROC)xwglGetProcAddress("glCreateProgram");
|
||||||
|
@ -170,13 +159,11 @@ void OpenGL_Init()
|
||||||
glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)xwglGetProcAddress("glVertexAttrib4fv");
|
glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)xwglGetProcAddress("glVertexAttrib4fv");
|
||||||
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)xwglGetProcAddress("glEnableVertexAttribArray");
|
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)xwglGetProcAddress("glEnableVertexAttribArray");
|
||||||
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)xwglGetProcAddress("glBindAttribLocation");
|
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)xwglGetProcAddress("glBindAttribLocation");
|
||||||
|
|
||||||
glCreateShader = (PFNGLCREATESHADERPROC)xwglGetProcAddress("glCreateShader");
|
glCreateShader = (PFNGLCREATESHADERPROC)xwglGetProcAddress("glCreateShader");
|
||||||
glDeleteShader = (PFNGLDELETESHADERPROC)xwglGetProcAddress("glDeleteShader");
|
glDeleteShader = (PFNGLDELETESHADERPROC)xwglGetProcAddress("glDeleteShader");
|
||||||
glShaderSource = (PFNGLSHADERSOURCEPROC)xwglGetProcAddress("glShaderSource");
|
glShaderSource = (PFNGLSHADERSOURCEPROC)xwglGetProcAddress("glShaderSource");
|
||||||
glCompileShader = (PFNGLCOMPILESHADERPROC)xwglGetProcAddress("glCompileShader");
|
glCompileShader = (PFNGLCOMPILESHADERPROC)xwglGetProcAddress("glCompileShader");
|
||||||
glGetShaderiv = (PFNGLGETSHADERIVPROC)xwglGetProcAddress("glGetShaderiv");
|
glGetShaderiv = (PFNGLGETSHADERIVPROC)xwglGetProcAddress("glGetShaderiv");
|
||||||
|
|
||||||
glGenBuffers = (PFNGLGENBUFFERSPROC)xwglGetProcAddress("glGenBuffers");
|
glGenBuffers = (PFNGLGENBUFFERSPROC)xwglGetProcAddress("glGenBuffers");
|
||||||
glBindBuffer = (PFNGLBINDBUFFERPROC)xwglGetProcAddress("glBindBuffer");
|
glBindBuffer = (PFNGLBINDBUFFERPROC)xwglGetProcAddress("glBindBuffer");
|
||||||
glBufferData = (PFNGLBUFFERDATAPROC)xwglGetProcAddress("glBufferData");
|
glBufferData = (PFNGLBUFFERDATAPROC)xwglGetProcAddress("glBufferData");
|
||||||
|
@ -188,9 +175,7 @@ void OpenGL_Init()
|
||||||
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)xwglGetProcAddress("glGenVertexArrays");
|
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)xwglGetProcAddress("glGenVertexArrays");
|
||||||
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)xwglGetProcAddress("glBindVertexArray");
|
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)xwglGetProcAddress("glBindVertexArray");
|
||||||
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)xwglGetProcAddress("glDeleteVertexArrays");
|
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)xwglGetProcAddress("glDeleteVertexArrays");
|
||||||
|
|
||||||
glActiveTexture = (PFNGLACTIVETEXTUREPROC)xwglGetProcAddress("glActiveTexture");
|
glActiveTexture = (PFNGLACTIVETEXTUREPROC)xwglGetProcAddress("glActiveTexture");
|
||||||
|
|
||||||
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)xwglGetProcAddress("glGenFramebuffers");
|
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)xwglGetProcAddress("glGenFramebuffers");
|
||||||
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)xwglGetProcAddress("glBindFramebuffer");
|
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)xwglGetProcAddress("glBindFramebuffer");
|
||||||
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)xwglGetProcAddress("glFramebufferTexture2D");
|
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)xwglGetProcAddress("glFramebufferTexture2D");
|
||||||
|
@ -206,23 +191,23 @@ void OpenGL_Init()
|
||||||
char *glversion = (char *)glGetString(GL_VERSION);
|
char *glversion = (char *)glGetString(GL_VERSION);
|
||||||
if (glversion)
|
if (glversion)
|
||||||
{
|
{
|
||||||
strncpy(OpenGL_Version, glversion, sizeof(OpenGL_Version));
|
strncpy(g_oglu_version, glversion, sizeof(g_oglu_version)-1);
|
||||||
const char deli[2] = " ";
|
const char deli[2] = " ";
|
||||||
strtok(OpenGL_Version, deli);
|
strtok(g_oglu_version, deli);
|
||||||
}
|
}
|
||||||
else
|
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 &&
|
glCheckFramebufferStatus && glUniform4f && glActiveTexture && glUniform1i &&
|
||||||
glGetAttribLocation && glGenBuffers && glBindBuffer && glBufferData && glVertexAttribPointer &&
|
glGetAttribLocation && glGenBuffers && glBindBuffer && glBufferData && glVertexAttribPointer &&
|
||||||
glEnableVertexAttribArray && glUniform2fv && glUniformMatrix4fv && glGenVertexArrays && glBindVertexArray &&
|
glEnableVertexAttribArray && glUniform2fv && glUniformMatrix4fv && glGenVertexArrays && glBindVertexArray &&
|
||||||
glGetUniformLocation && glversion && glversion[0] != '2';
|
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);
|
char *glext = (char *)glGetString(GL_EXTENSIONS);
|
||||||
if (glext)
|
if (glext)
|
||||||
|
@ -244,46 +229,46 @@ BOOL OpenGL_ExtExists(char *ext, HDC hdc)
|
||||||
return FALSE;
|
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 ||
|
if (!glCreateShader || !glShaderSource || !glCompileShader || !glCreateProgram ||
|
||||||
!glAttachShader || !glLinkProgram || !glUseProgram || !glDetachShader)
|
!glAttachShader || !glLinkProgram || !glUseProgram || !glDetachShader)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
|
GLuint vert_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
|
GLuint frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
if (!vertShader || !fragShader)
|
if (!vert_shader || !frag_shader)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
glShaderSource(vertShader, 1, &vertSource, NULL);
|
glShaderSource(vert_shader, 1, &vertSource, NULL);
|
||||||
glShaderSource(fragShader, 1, &fragSource, NULL);
|
glShaderSource(frag_shader, 1, &fragSource, NULL);
|
||||||
|
|
||||||
GLint isCompiled = 0;
|
GLint is_compiled = 0;
|
||||||
|
|
||||||
glCompileShader(vertShader);
|
glCompileShader(vert_shader);
|
||||||
if (glGetShaderiv)
|
if (glGetShaderiv)
|
||||||
{
|
{
|
||||||
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &isCompiled);
|
glGetShaderiv(vert_shader, GL_COMPILE_STATUS, &is_compiled);
|
||||||
if (isCompiled == GL_FALSE)
|
if (is_compiled == GL_FALSE)
|
||||||
{
|
{
|
||||||
if (glDeleteShader)
|
if (glDeleteShader)
|
||||||
glDeleteShader(vertShader);
|
glDeleteShader(vert_shader);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glCompileShader(fragShader);
|
glCompileShader(frag_shader);
|
||||||
if (glGetShaderiv)
|
if (glGetShaderiv)
|
||||||
{
|
{
|
||||||
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &isCompiled);
|
glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &is_compiled);
|
||||||
if (isCompiled == GL_FALSE)
|
if (is_compiled == GL_FALSE)
|
||||||
{
|
{
|
||||||
if (glDeleteShader)
|
if (glDeleteShader)
|
||||||
{
|
{
|
||||||
glDeleteShader(fragShader);
|
glDeleteShader(frag_shader);
|
||||||
glDeleteShader(vertShader);
|
glDeleteShader(vert_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -293,21 +278,21 @@ GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource)
|
||||||
GLuint program = glCreateProgram();
|
GLuint program = glCreateProgram();
|
||||||
if (program)
|
if (program)
|
||||||
{
|
{
|
||||||
glAttachShader(program, vertShader);
|
glAttachShader(program, vert_shader);
|
||||||
glAttachShader(program, fragShader);
|
glAttachShader(program, frag_shader);
|
||||||
|
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
||||||
glDetachShader(program, vertShader);
|
glDetachShader(program, vert_shader);
|
||||||
glDetachShader(program, fragShader);
|
glDetachShader(program, frag_shader);
|
||||||
glDeleteShader(vertShader);
|
glDeleteShader(vert_shader);
|
||||||
glDeleteShader(fragShader);
|
glDeleteShader(frag_shader);
|
||||||
|
|
||||||
if (glGetProgramiv)
|
if (glGetProgramiv)
|
||||||
{
|
{
|
||||||
GLint isLinked = 0;
|
GLint is_linked = 0;
|
||||||
glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
|
glGetProgramiv(program, GL_LINK_STATUS, &is_linked);
|
||||||
if (isLinked == GL_FALSE)
|
if (is_linked == GL_FALSE)
|
||||||
{
|
{
|
||||||
if (glDeleteProgram)
|
if (glDeleteProgram)
|
||||||
glDeleteProgram(program);
|
glDeleteProgram(program);
|
||||||
|
@ -320,7 +305,7 @@ GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource)
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint OpenGL_BuildProgramFromFile(const char *filePath)
|
GLuint oglu_build_program_from_file(const char *filePath)
|
||||||
{
|
{
|
||||||
GLuint program = 0;
|
GLuint program = 0;
|
||||||
|
|
||||||
|
@ -328,47 +313,47 @@ GLuint OpenGL_BuildProgramFromFile(const char *filePath)
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
long fileSize = ftell(file);
|
long file_size = ftell(file);
|
||||||
fseek(file, 0, SEEK_SET);
|
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)
|
if (source)
|
||||||
{
|
{
|
||||||
fread(source, fileSize, 1, file);
|
fread(source, file_size, 1, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
char *vertSource = calloc(fileSize + 50, 1);
|
char *vert_source = calloc(file_size + 50, 1);
|
||||||
char *fragSource = calloc(fileSize + 50, 1);
|
char *frag_source = calloc(file_size + 50, 1);
|
||||||
|
|
||||||
if (fragSource && vertSource)
|
if (frag_source && vert_source)
|
||||||
{
|
{
|
||||||
char *versionStart = strstr(source, "#version");
|
char *version_start = strstr(source, "#version");
|
||||||
if (versionStart)
|
if (version_start)
|
||||||
{
|
{
|
||||||
const char deli[2] = "\n";
|
const char deli[2] = "\n";
|
||||||
char *version = strtok(versionStart, deli);
|
char *version = strtok(version_start, deli);
|
||||||
|
|
||||||
strcpy(vertSource, source);
|
strcpy(vert_source, source);
|
||||||
strcpy(fragSource, source);
|
strcpy(frag_source, source);
|
||||||
strcat(vertSource, "\n#define VERTEX\n");
|
strcat(vert_source, "\n#define VERTEX\n");
|
||||||
strcat(fragSource, "\n#define FRAGMENT\n");
|
strcat(frag_source, "\n#define FRAGMENT\n");
|
||||||
strcat(vertSource, version + strlen(version) + 1);
|
strcat(vert_source, version + strlen(version) + 1);
|
||||||
strcat(fragSource, 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
|
else
|
||||||
{
|
{
|
||||||
strcpy(vertSource, "#define VERTEX\n");
|
strcpy(vert_source, "#define VERTEX\n");
|
||||||
strcpy(fragSource, "#define FRAGMENT\n");
|
strcpy(frag_source, "#define FRAGMENT\n");
|
||||||
strcat(vertSource, source);
|
strcat(vert_source, source);
|
||||||
strcat(fragSource, source);
|
strcat(frag_source, source);
|
||||||
|
|
||||||
program = OpenGL_BuildProgram(vertSource, fragSource);
|
program = oglu_build_program(vert_source, frag_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(vertSource);
|
free(vert_source);
|
||||||
free(fragSource);
|
free(frag_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(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 <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
#include "main.h"
|
#include "dd.h"
|
||||||
#include "surface.h"
|
#include "ddsurface.h"
|
||||||
#include "d3d9shader.h"
|
#include "d3d9shader.h"
|
||||||
#include "render_d3d9.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 d3d9_renderer g_d3d9;
|
||||||
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 BOOL CreateResources();
|
BOOL d3d9_is_available()
|
||||||
static BOOL SetStates();
|
|
||||||
static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch);
|
|
||||||
static void SetMaxFPS();
|
|
||||||
|
|
||||||
BOOL Direct3D9_Create()
|
|
||||||
{
|
{
|
||||||
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;
|
return FALSE;
|
||||||
|
|
||||||
if (!Direct3D9_hModule)
|
if (!g_d3d9.hmodule)
|
||||||
Direct3D9_hModule = LoadLibrary("d3d9.dll");
|
g_d3d9.hmodule = LoadLibrary("d3d9.dll");
|
||||||
|
|
||||||
if (Direct3D9_hModule)
|
if (g_d3d9.hmodule)
|
||||||
{
|
{
|
||||||
IDirect3D9 *(WINAPI *D3DCreate9)(UINT) =
|
IDirect3D9 *(WINAPI *d3d_create9)(UINT) =
|
||||||
(IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(Direct3D9_hModule, "Direct3DCreate9");
|
(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;
|
g_d3d9.params.Windowed = g_ddraw->windowed;
|
||||||
D3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
g_d3d9.params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||||
D3dpp.hDeviceWindow = ddraw->hWnd;
|
g_d3d9.params.hDeviceWindow = g_ddraw->hwnd;
|
||||||
D3dpp.PresentationInterval = ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
g_d3d9.params.PresentationInterval = g_ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||||
D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
|
g_d3d9.params.BackBufferWidth = g_d3d9.params.Windowed ? 0 : g_ddraw->render.width;
|
||||||
D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
|
g_d3d9.params.BackBufferHeight = g_d3d9.params.Windowed ? 0 : g_ddraw->render.height;
|
||||||
D3dpp.BackBufferFormat = BitsPerPixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
|
g_d3d9.params.BackBufferFormat = g_d3d9.bits_per_pixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
|
||||||
D3dpp.BackBufferCount = 1;
|
g_d3d9.params.BackBufferCount = 1;
|
||||||
|
|
||||||
DWORD behaviorFlags[] = {
|
DWORD behavior_flags[] = {
|
||||||
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
|
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
|
||||||
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
|
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
|
||||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||||
|
@ -61,18 +67,18 @@ BOOL Direct3D9_Create()
|
||||||
};
|
};
|
||||||
|
|
||||||
int i;
|
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(
|
if (SUCCEEDED(
|
||||||
IDirect3D9_CreateDevice(
|
IDirect3D9_CreateDevice(
|
||||||
D3d,
|
g_d3d9.instance,
|
||||||
D3DADAPTER_DEFAULT,
|
D3DADAPTER_DEFAULT,
|
||||||
D3DDEVTYPE_HAL,
|
D3DDEVTYPE_HAL,
|
||||||
ddraw->hWnd,
|
g_ddraw->hwnd,
|
||||||
D3DCREATE_MULTITHREADED | behaviorFlags[i],
|
D3DCREATE_MULTITHREADED | behavior_flags[i],
|
||||||
&D3dpp,
|
&g_d3d9.params,
|
||||||
&D3dDev)))
|
&g_d3d9.device)))
|
||||||
return D3dDev && CreateResources() && SetStates();
|
return g_d3d9.device && d3d9_create_resouces() && d3d9_set_states();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,177 +86,177 @@ BOOL Direct3D9_Create()
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL Direct3D9_OnDeviceLost()
|
BOOL d3d9_on_device_lost()
|
||||||
{
|
{
|
||||||
if (D3dDev && IDirect3DDevice9_TestCooperativeLevel(D3dDev) == D3DERR_DEVICENOTRESET)
|
if (g_d3d9.device && IDirect3DDevice9_TestCooperativeLevel(g_d3d9.device) == D3DERR_DEVICENOTRESET)
|
||||||
return Direct3D9_Reset();
|
return d3d9_reset();
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL Direct3D9_Reset()
|
BOOL d3d9_reset()
|
||||||
{
|
{
|
||||||
D3dpp.Windowed = ddraw->windowed;
|
g_d3d9.params.Windowed = g_ddraw->windowed;
|
||||||
D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
|
g_d3d9.params.BackBufferWidth = g_d3d9.params.Windowed ? 0 : g_ddraw->render.width;
|
||||||
D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
|
g_d3d9.params.BackBufferHeight = g_d3d9.params.Windowed ? 0 : g_ddraw->render.height;
|
||||||
D3dpp.BackBufferFormat = BitsPerPixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
|
g_d3d9.params.BackBufferFormat = g_d3d9.bits_per_pixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
|
||||||
|
|
||||||
if (D3dDev && SUCCEEDED(IDirect3DDevice9_Reset(D3dDev, &D3dpp)))
|
if (g_d3d9.device && SUCCEEDED(IDirect3DDevice9_Reset(g_d3d9.device, &g_d3d9.params)))
|
||||||
return SetStates();
|
return d3d9_set_states();
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL Direct3D9_Release()
|
BOOL d3d9_release()
|
||||||
{
|
{
|
||||||
if (VertexBuf)
|
if (g_d3d9.vertex_buf)
|
||||||
{
|
{
|
||||||
IDirect3DVertexBuffer9_Release(VertexBuf);
|
IDirect3DVertexBuffer9_Release(g_d3d9.vertex_buf);
|
||||||
VertexBuf = NULL;
|
g_d3d9.vertex_buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
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]);
|
IDirect3DTexture9_Release(g_d3d9.surface_tex[i]);
|
||||||
SurfaceTex[i] = NULL;
|
g_d3d9.surface_tex[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PaletteTex[i])
|
if (g_d3d9.palette_tex[i])
|
||||||
{
|
{
|
||||||
IDirect3DTexture9_Release(PaletteTex[i]);
|
IDirect3DTexture9_Release(g_d3d9.palette_tex[i]);
|
||||||
PaletteTex[i] = NULL;
|
g_d3d9.palette_tex[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PixelShader)
|
if (g_d3d9.pixel_shader)
|
||||||
{
|
{
|
||||||
IDirect3DPixelShader9_Release(PixelShader);
|
IDirect3DPixelShader9_Release(g_d3d9.pixel_shader);
|
||||||
PixelShader = NULL;
|
g_d3d9.pixel_shader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (D3dDev)
|
if (g_d3d9.device)
|
||||||
{
|
{
|
||||||
IDirect3DDevice9_Release(D3dDev);
|
IDirect3DDevice9_Release(g_d3d9.device);
|
||||||
D3dDev = NULL;
|
g_d3d9.device = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (D3d)
|
if (g_d3d9.instance)
|
||||||
{
|
{
|
||||||
IDirect3D9_Release(D3d);
|
IDirect3D9_Release(g_d3d9.instance);
|
||||||
D3d = NULL;
|
g_d3d9.instance = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CreateResources()
|
static BOOL d3d9_create_resouces()
|
||||||
{
|
{
|
||||||
BOOL err = FALSE;
|
BOOL err = FALSE;
|
||||||
|
|
||||||
int width = ddraw->width;
|
int width = g_ddraw->width;
|
||||||
int height = ddraw->height;
|
int height = g_ddraw->height;
|
||||||
|
|
||||||
int texWidth =
|
int tex_width =
|
||||||
width <= 1024 ? 1024 : width <= 2048 ? 2048 : width <= 4096 ? 4096 : width;
|
width <= 1024 ? 1024 : width <= 2048 ? 2048 : width <= 4096 ? 4096 : width;
|
||||||
|
|
||||||
int texHeight =
|
int tex_height =
|
||||||
height <= texWidth ? texWidth : height <= 2048 ? 2048 : height <= 4096 ? 4096 : 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;;
|
g_d3d9.scale_w = (float)width / tex_width;;
|
||||||
ScaleH = (float)height / texHeight;
|
g_d3d9.scale_h = (float)height / tex_height;
|
||||||
|
|
||||||
err = err || FAILED(
|
err = err || FAILED(
|
||||||
IDirect3DDevice9_CreateVertexBuffer(
|
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;
|
int i;
|
||||||
for (i = 0; i < TEXTURE_COUNT; i++)
|
for (i = 0; i < D3D9_TEXTURE_COUNT; i++)
|
||||||
{
|
{
|
||||||
err = err || FAILED(
|
err = err || FAILED(
|
||||||
IDirect3DDevice9_CreateTexture(
|
IDirect3DDevice9_CreateTexture(
|
||||||
D3dDev,
|
g_d3d9.device,
|
||||||
texWidth,
|
tex_width,
|
||||||
texHeight,
|
tex_height,
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
ddraw->bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_L8,
|
g_ddraw->bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_L8,
|
||||||
D3DPOOL_MANAGED,
|
D3DPOOL_MANAGED,
|
||||||
&SurfaceTex[i],
|
&g_d3d9.surface_tex[i],
|
||||||
0));
|
0));
|
||||||
|
|
||||||
err = err || !SurfaceTex[i];
|
err = err || !g_d3d9.surface_tex[i];
|
||||||
|
|
||||||
if (ddraw->bpp == 8)
|
if (g_ddraw->bpp == 8)
|
||||||
{
|
{
|
||||||
err = err || FAILED(
|
err = err || FAILED(
|
||||||
IDirect3DDevice9_CreateTexture(
|
IDirect3DDevice9_CreateTexture(
|
||||||
D3dDev,
|
g_d3d9.device,
|
||||||
256,
|
256,
|
||||||
256,
|
256,
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
D3DFMT_X8R8G8B8,
|
D3DFMT_X8R8G8B8,
|
||||||
D3DPOOL_MANAGED,
|
D3DPOOL_MANAGED,
|
||||||
&PaletteTex[i],
|
&g_d3d9.palette_tex[i],
|
||||||
0));
|
0));
|
||||||
|
|
||||||
err = err || !PaletteTex[i];
|
err = err || !g_d3d9.palette_tex[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ddraw->bpp == 8)
|
if (g_ddraw->bpp == 8)
|
||||||
{
|
{
|
||||||
err = err || FAILED(
|
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;
|
BOOL err = FALSE;
|
||||||
|
|
||||||
err = err || FAILED(IDirect3DDevice9_SetFVF(D3dDev, D3DFVF_XYZRHW | D3DFVF_TEX1));
|
err = err || FAILED(IDirect3DDevice9_SetFVF(g_d3d9.device, D3DFVF_XYZRHW | D3DFVF_TEX1));
|
||||||
err = err || FAILED(IDirect3DDevice9_SetStreamSource(D3dDev, 0, VertexBuf, 0, sizeof(CUSTOMVERTEX)));
|
err = err || FAILED(IDirect3DDevice9_SetStreamSource(g_d3d9.device, 0, g_d3d9.vertex_buf, 0, sizeof(CUSTOMVERTEX)));
|
||||||
err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 0, (IDirect3DBaseTexture9 *)SurfaceTex[0]));
|
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_SetTexture(g_d3d9.device, 1, (IDirect3DBaseTexture9 *)g_d3d9.palette_tex[0]));
|
||||||
err = err || FAILED(IDirect3DDevice9_SetPixelShader(D3dDev, PixelShader));
|
err = err || FAILED(IDirect3DDevice9_SetPixelShader(g_d3d9.device, g_d3d9.pixel_shader));
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DVIEWPORT9 viewData = {
|
D3DVIEWPORT9 view_data = {
|
||||||
ddraw->render.viewport.x,
|
g_ddraw->render.viewport.x,
|
||||||
ddraw->render.viewport.y,
|
g_ddraw->render.viewport.y,
|
||||||
ddraw->render.viewport.width,
|
g_ddraw->render.viewport.width,
|
||||||
ddraw->render.viewport.height,
|
g_ddraw->render.viewport.height,
|
||||||
0.0f,
|
0.0f,
|
||||||
1.0f };
|
1.0f };
|
||||||
|
|
||||||
err = err || FAILED(IDirect3DDevice9_SetViewport(D3dDev, &viewData));
|
err = err || FAILED(IDirect3DDevice9_SetViewport(g_d3d9.device, &view_data));
|
||||||
|
|
||||||
return !err;
|
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 vpX = stretch ? (float)g_ddraw->render.viewport.x : 0.0f;
|
||||||
float vpY = stretch ? (float)ddraw->render.viewport.y : 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 vpW = stretch ? (float)(g_ddraw->render.viewport.width + g_ddraw->render.viewport.x) : (float)g_ddraw->width;
|
||||||
float vpH = stretch ? (float)(ddraw->render.viewport.height + ddraw->render.viewport.y) : (float)ddraw->height;
|
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 sH = in_cutscene ? g_d3d9.scale_h * ((float)CUTSCENE_HEIGHT / g_ddraw->height) : g_d3d9.scale_h;
|
||||||
float sW = inCutscene ? ScaleW * ((float)CUTSCENE_WIDTH / ddraw->width) : ScaleW;
|
float sW = in_cutscene ? g_d3d9.scale_w * ((float)CUTSCENE_WIDTH / g_ddraw->width) : g_d3d9.scale_w;
|
||||||
|
|
||||||
CUSTOMVERTEX vertices[] =
|
CUSTOMVERTEX vertices[] =
|
||||||
{
|
{
|
||||||
|
@ -261,197 +267,198 @@ static BOOL UpdateVertices(BOOL inCutscene, BOOL stretch)
|
||||||
};
|
};
|
||||||
|
|
||||||
void *data;
|
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));
|
memcpy(data, vertices, sizeof(vertices));
|
||||||
|
|
||||||
IDirect3DVertexBuffer9_Unlock(VertexBuf);
|
IDirect3DVertexBuffer9_Unlock(g_d3d9.vertex_buf);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetMaxFPS()
|
static void d3d9_set_max_fps()
|
||||||
{
|
{
|
||||||
int maxFPS = ddraw->render.maxfps;
|
int max_fps = g_ddraw->render.maxfps;
|
||||||
ddraw->fpsLimiter.tickLengthNs = 0;
|
|
||||||
ddraw->fpsLimiter.ticklength = 0;
|
|
||||||
|
|
||||||
if (maxFPS < 0 || ddraw->vsync)
|
g_ddraw->fps_limiter.tick_length_ns = 0;
|
||||||
maxFPS = ddraw->mode.dmDisplayFrequency;
|
g_ddraw->fps_limiter.tick_length = 0;
|
||||||
|
|
||||||
if (maxFPS > 1000)
|
if (max_fps < 0 || g_ddraw->vsync)
|
||||||
maxFPS = 0;
|
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;
|
float len = 1000.0f / max_fps;
|
||||||
ddraw->fpsLimiter.tickLengthNs = len * 10000;
|
g_ddraw->fps_limiter.tick_length_ns = len * 10000;
|
||||||
ddraw->fpsLimiter.ticklength = len;// + 0.5f;
|
g_ddraw->fps_limiter.tick_length = len;// + 0.5f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD WINAPI render_d3d9_main(void)
|
DWORD WINAPI d3d9_render_main(void)
|
||||||
{
|
{
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
|
|
||||||
SetMaxFPS();
|
d3d9_set_max_fps();
|
||||||
|
|
||||||
DWORD tickStart = 0;
|
DWORD tick_start = 0;
|
||||||
DWORD tickEnd = 0;
|
DWORD tick_end = 0;
|
||||||
BOOL needsUpdate = FALSE;
|
BOOL needs_update = FALSE;
|
||||||
|
|
||||||
while (ddraw->render.run &&
|
while (g_ddraw->render.run &&
|
||||||
(ddraw->render.forcefps || WaitForSingleObject(ddraw->render.sem, 200) != WAIT_FAILED))
|
(g_ddraw->render.forcefps || WaitForSingleObject(g_ddraw->render.sem, 200) != WAIT_FAILED))
|
||||||
{
|
{
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
DrawFrameInfoStart();
|
DrawFrameInfoStart();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int texIndex = 0, palIndex = 0;
|
static int tex_index = 0, palIndex = 0;
|
||||||
|
|
||||||
if (ddraw->fpsLimiter.ticklength > 0)
|
if (g_ddraw->fps_limiter.tick_length > 0)
|
||||||
tickStart = timeGetTime();
|
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))
|
if (!InterlockedExchange(&g_ddraw->incutscene, TRUE))
|
||||||
UpdateVertices(TRUE, TRUE);
|
d3d9_update_vertices(TRUE, TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (InterlockedExchange(&ddraw->incutscene, FALSE))
|
if (InterlockedExchange(&g_ddraw->incutscene, FALSE))
|
||||||
UpdateVertices(FALSE, TRUE);
|
d3d9_update_vertices(FALSE, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DLOCKED_RECT lock_rc;
|
D3DLOCKED_RECT lock_rc;
|
||||||
|
|
||||||
if (InterlockedExchange(&ddraw->render.surfaceUpdated, FALSE))
|
if (InterlockedExchange(&g_ddraw->render.surface_updated, FALSE))
|
||||||
{
|
{
|
||||||
if (++texIndex >= TEXTURE_COUNT)
|
if (++tex_index >= D3D9_TEXTURE_COUNT)
|
||||||
texIndex = 0;
|
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])) &&
|
if (SUCCEEDED(IDirect3DDevice9_SetTexture(g_d3d9.device, 0, (IDirect3DBaseTexture9 *)g_d3d9.surface_tex[tex_index])) &&
|
||||||
SUCCEEDED(IDirect3DTexture9_LockRect(SurfaceTex[texIndex], 0, &lock_rc, &rc, 0)))
|
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;
|
unsigned char *dst = (unsigned char *)lock_rc.pBits;
|
||||||
|
|
||||||
int i;
|
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;
|
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;
|
palIndex = 0;
|
||||||
|
|
||||||
RECT rc = { 0,0,256,1 };
|
RECT rc = { 0,0,256,1 };
|
||||||
|
|
||||||
if (SUCCEEDED(IDirect3DDevice9_SetTexture(D3dDev, 1, (IDirect3DBaseTexture9 *)PaletteTex[palIndex])) &&
|
if (SUCCEEDED(IDirect3DDevice9_SetTexture(g_d3d9.device, 1, (IDirect3DBaseTexture9 *)g_d3d9.palette_tex[palIndex])) &&
|
||||||
SUCCEEDED(IDirect3DTexture9_LockRect(PaletteTex[palIndex], 0, &lock_rc, &rc, 0)))
|
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;
|
g_ddraw->child_window_exists = FALSE;
|
||||||
EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary);
|
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))
|
if (!needs_update && d3d9_update_vertices(FALSE, FALSE))
|
||||||
needsUpdate = TRUE;
|
needs_update = TRUE;
|
||||||
}
|
}
|
||||||
else if (needsUpdate)
|
else if (needs_update)
|
||||||
{
|
{
|
||||||
if (UpdateVertices(FALSE, TRUE))
|
if (d3d9_update_vertices(FALSE, TRUE))
|
||||||
needsUpdate = FALSE;
|
needs_update = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&ddraw->cs);
|
LeaveCriticalSection(&g_ddraw->cs);
|
||||||
|
|
||||||
IDirect3DDevice9_BeginScene(D3dDev);
|
IDirect3DDevice9_BeginScene(g_d3d9.device);
|
||||||
IDirect3DDevice9_DrawPrimitive(D3dDev, D3DPT_TRIANGLESTRIP, 0, 2);
|
IDirect3DDevice9_DrawPrimitive(g_d3d9.device, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||||
IDirect3DDevice9_EndScene(D3dDev);
|
IDirect3DDevice9_EndScene(g_d3d9.device);
|
||||||
|
|
||||||
if (ddraw->bnetActive)
|
if (g_ddraw->bnet_active)
|
||||||
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 (FAILED(IDirect3DDevice9_Present(D3dDev, NULL, NULL, NULL, NULL)))
|
if (FAILED(IDirect3DDevice9_Present(g_d3d9.device, NULL, NULL, NULL, NULL)))
|
||||||
{
|
{
|
||||||
DWORD_PTR dwResult;
|
DWORD_PTR result;
|
||||||
SendMessageTimeout(ddraw->hWnd, WM_D3D9DEVICELOST, 0, 0, 0, 1000, &dwResult);
|
SendMessageTimeout(g_ddraw->hwnd, WM_D3D9DEVICELOST, 0, 0, 0, 1000, &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
DrawFrameInfoEnd();
|
DrawFrameInfoEnd();
|
||||||
#endif
|
#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);
|
WaitForSingleObject(g_ddraw->fps_limiter.htimer, g_ddraw->fps_limiter.tick_length * 2);
|
||||||
LARGE_INTEGER liDueTime = { .QuadPart = -ddraw->fpsLimiter.tickLengthNs };
|
LARGE_INTEGER due_time = { .QuadPart = -g_ddraw->fps_limiter.tick_length_ns };
|
||||||
SetWaitableTimer(ddraw->fpsLimiter.hTimer, &liDueTime, 0, NULL, NULL, FALSE);
|
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &due_time, 0, NULL, NULL, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FILETIME ft = { 0 };
|
FILETIME ft = { 0 };
|
||||||
GetSystemTimeAsFileTime(&ft);
|
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
|
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;
|
g_ddraw->fps_limiter.due_time.QuadPart += g_ddraw->fps_limiter.tick_length_ns;
|
||||||
SetWaitableTimer(ddraw->fpsLimiter.hTimer, &ddraw->fpsLimiter.dueTime, 0, NULL, NULL, FALSE);
|
SetWaitableTimer(g_ddraw->fps_limiter.htimer, &g_ddraw->fps_limiter.due_time, 0, NULL, NULL, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tickEnd = timeGetTime();
|
tick_end = timeGetTime();
|
||||||
|
|
||||||
if (tickEnd - tickStart < ddraw->fpsLimiter.ticklength)
|
if (tick_end - tick_start < g_ddraw->fps_limiter.tick_length)
|
||||||
Sleep(ddraw->fpsLimiter.ticklength - (tickEnd - tickStart));
|
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 @@
|
||||||
/*
|
#define WIN32_LEAN_AND_MEAN
|
||||||
* 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 <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "ddraw.h"
|
#include "dd.h"
|
||||||
#include "palette.h"
|
#include "ddpalette.h"
|
||||||
#include "surface.h"
|
#include "ddsurface.h"
|
||||||
#include "lodepng.h"
|
#include "lodepng.h"
|
||||||
|
|
||||||
BOOL screenshot(struct IDirectDrawSurfaceImpl *src)
|
BOOL ss_take_screenshot(struct IDirectDrawSurfaceImpl *src)
|
||||||
{
|
{
|
||||||
if (!src || !src->palette || !src->surface)
|
if (!src || !src->palette || !src->surface)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -33,7 +18,7 @@ BOOL screenshot(struct IDirectDrawSurfaceImpl *src)
|
||||||
char str_time[64];
|
char str_time[64];
|
||||||
time_t t = time(NULL);
|
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++) {
|
for (i = 0; i<strlen(title); i++) {
|
||||||
if (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