2010-10-10 19:41:47 +03:00
|
|
|
/*
|
|
|
|
* 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>
|
2011-08-21 10:34:42 +03:00
|
|
|
#include <windowsx.h>
|
2018-12-01 01:16:24 +01:00
|
|
|
#include <winuser.h>
|
2010-10-10 19:41:47 +03:00
|
|
|
#include <stdio.h>
|
2010-11-06 21:30:48 +02:00
|
|
|
#include <ctype.h>
|
2018-10-03 09:51:15 +02:00
|
|
|
#include <d3d9.h>
|
2018-11-14 07:00:42 +01:00
|
|
|
#include <initguid.h>
|
2010-10-10 19:41:47 +03:00
|
|
|
#include "ddraw.h"
|
2010-10-17 00:41:14 +03:00
|
|
|
#include "main.h"
|
2018-10-24 04:21:22 +02:00
|
|
|
#include "opengl.h"
|
2010-10-10 19:41:47 +03:00
|
|
|
#include "palette.h"
|
|
|
|
#include "surface.h"
|
2010-10-20 18:45:27 +03:00
|
|
|
#include "clipper.h"
|
2019-03-19 06:57:49 +01:00
|
|
|
#include "hook.h"
|
|
|
|
#include "mouse.h"
|
2018-10-15 03:31:57 +02:00
|
|
|
#include "render_d3d9.h"
|
2010-10-10 19:41:47 +03:00
|
|
|
|
2012-12-31 22:52:44 +01:00
|
|
|
#define IDR_MYMENU 93
|
|
|
|
|
2010-11-20 21:08:17 +02:00
|
|
|
BOOL screenshot(struct IDirectDrawSurfaceImpl *);
|
2018-10-25 07:03:01 +02:00
|
|
|
void Settings_Load();
|
2018-11-07 23:28:19 +01:00
|
|
|
void Settings_Save(RECT *lpRect, int windowState);
|
2019-04-06 05:35:23 +02:00
|
|
|
void DInput_Hook();
|
|
|
|
void DInput_UnHook();
|
2010-11-20 21:08:17 +02:00
|
|
|
|
2010-10-24 01:02:08 +03:00
|
|
|
IDirectDrawImpl *ddraw = NULL;
|
|
|
|
|
2018-10-27 16:44:09 +02:00
|
|
|
RECT WindowRect = { .left = -32000, .top = -32000, .right = 0, .bottom = 0 };
|
2018-11-07 23:28:19 +01:00
|
|
|
int WindowState = -1;
|
2018-10-15 00:01:31 +02:00
|
|
|
BOOL Direct3D9Active;
|
2018-11-16 01:14:05 +01:00
|
|
|
BOOL GameHandlesClose;
|
2018-11-16 06:37:11 +01:00
|
|
|
BOOL ChildWindowExists;
|
2019-03-17 01:18:37 +01:00
|
|
|
DWORD NvOptimusEnablement = 1;
|
|
|
|
DWORD AmdPowerXpressRequestHighPerformance = 1;
|
2020-09-19 11:23:06 +02:00
|
|
|
HMODULE DDrawModule;
|
2017-11-13 13:50:54 +01:00
|
|
|
|
2018-08-03 03:37:23 +02:00
|
|
|
//BOOL WINAPI DllMainCRTStartup(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
|
2017-11-13 13:50:54 +01:00
|
|
|
BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
2017-11-12 14:57:27 +01:00
|
|
|
{
|
2017-11-13 13:50:54 +01:00
|
|
|
switch (dwReason)
|
2017-11-12 14:57:27 +01:00
|
|
|
{
|
2017-11-13 13:50:54 +01:00
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
{
|
2020-09-19 11:23:06 +02:00
|
|
|
DDrawModule = hDll;
|
|
|
|
|
2019-04-01 22:32:53 +02:00
|
|
|
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)
|
|
|
|
{
|
2019-07-25 20:27:04 +02:00
|
|
|
char mes[128] = { 0 };
|
|
|
|
|
|
|
|
_snprintf(
|
|
|
|
mes,
|
|
|
|
sizeof(mes),
|
|
|
|
"Please disable the '%s' compatibility mode for all game executables and "
|
2019-04-01 22:32:53 +02:00
|
|
|
"then try to start the game again.",
|
2019-07-25 20:27:04 +02:00
|
|
|
s);
|
|
|
|
|
|
|
|
MessageBoxA(NULL, mes, "Compatibility modes detected - cnc-ddraw", MB_OK);
|
2019-04-01 22:32:53 +02:00
|
|
|
|
|
|
|
//return FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = strtok(NULL, " ");
|
|
|
|
}
|
|
|
|
}
|
2019-07-25 20:27:04 +02:00
|
|
|
|
2018-10-26 07:24:38 +02:00
|
|
|
printf("cnc-ddraw DLL_PROCESS_ATTACH\n");
|
2017-11-13 13:50:54 +01:00
|
|
|
|
2017-11-13 14:55:06 +01:00
|
|
|
//SetProcessPriorityBoost(GetCurrentProcess(), TRUE);
|
2018-03-09 14:38:02 +01:00
|
|
|
|
2018-03-10 10:19:54 +01:00
|
|
|
BOOL setDpiAware = FALSE;
|
|
|
|
HMODULE hShcore = GetModuleHandle("shcore.dll");
|
|
|
|
typedef HRESULT (__stdcall* SetProcessDpiAwareness_)(PROCESS_DPI_AWARENESS value);
|
|
|
|
if(hShcore)
|
2018-03-09 14:38:02 +01:00
|
|
|
{
|
2018-03-11 10:34:46 +01:00
|
|
|
SetProcessDpiAwareness_ setProcessDpiAwareness =
|
|
|
|
(SetProcessDpiAwareness_)GetProcAddress(hShcore, "SetProcessDpiAwareness");
|
|
|
|
|
2018-03-10 10:19:54 +01:00
|
|
|
if (setProcessDpiAwareness)
|
|
|
|
{
|
|
|
|
HRESULT result = setProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
|
|
|
setDpiAware = result == S_OK || result == E_ACCESSDENIED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!setDpiAware)
|
|
|
|
{
|
|
|
|
HMODULE hUser32 = GetModuleHandle("user32.dll");
|
|
|
|
typedef BOOL (__stdcall* SetProcessDPIAware_)();
|
|
|
|
if(hUser32)
|
|
|
|
{
|
2018-03-11 10:34:46 +01:00
|
|
|
SetProcessDPIAware_ setProcessDPIAware =
|
|
|
|
(SetProcessDPIAware_)GetProcAddress(hUser32, "SetProcessDPIAware");
|
|
|
|
|
2018-03-10 10:19:54 +01:00
|
|
|
if (setProcessDPIAware)
|
|
|
|
setProcessDPIAware();
|
|
|
|
}
|
2018-03-09 14:38:02 +01:00
|
|
|
}
|
|
|
|
|
2017-11-13 13:50:54 +01:00
|
|
|
timeBeginPeriod(1);
|
2019-04-06 05:35:23 +02:00
|
|
|
DInput_Hook();
|
2017-11-13 13:50:54 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
{
|
2018-10-26 07:24:38 +02:00
|
|
|
printf("cnc-ddraw DLL_PROCESS_DETACH\n");
|
2017-11-13 13:50:54 +01:00
|
|
|
|
2018-11-07 23:28:19 +01:00
|
|
|
Settings_Save(&WindowRect, WindowState);
|
2017-11-13 13:50:54 +01:00
|
|
|
|
|
|
|
timeEndPeriod(1);
|
2019-04-06 05:35:23 +02:00
|
|
|
Hook_Exit();
|
|
|
|
DInput_UnHook();
|
2017-11-13 13:50:54 +01:00
|
|
|
break;
|
|
|
|
}
|
2017-11-12 14:57:27 +01:00
|
|
|
}
|
2017-11-13 13:50:54 +01:00
|
|
|
|
|
|
|
return TRUE;
|
2017-11-12 14:57:27 +01:00
|
|
|
}
|
|
|
|
|
2018-11-15 09:45:24 +01:00
|
|
|
BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
|
|
|
|
{
|
|
|
|
IDirectDrawSurfaceImpl *this = (IDirectDrawSurfaceImpl *)lParam;
|
|
|
|
|
|
|
|
RECT size;
|
|
|
|
RECT pos;
|
|
|
|
|
2019-03-19 06:57:49 +01:00
|
|
|
if (real_GetClientRect(hWnd, &size) && real_GetWindowRect(hWnd, &pos) && size.right > 1 && size.bottom > 1)
|
2018-11-22 13:39:03 +01:00
|
|
|
{
|
|
|
|
ChildWindowExists = TRUE;
|
2018-11-15 09:45:24 +01:00
|
|
|
|
2018-11-22 13:39:03 +01:00
|
|
|
HDC hDC = GetDC(hWnd);
|
2018-11-15 09:45:24 +01:00
|
|
|
|
2018-11-22 13:39:03 +01:00
|
|
|
MapWindowPoints(HWND_DESKTOP, ddraw->hWnd, (LPPOINT)&pos, 2);
|
|
|
|
|
|
|
|
BitBlt(hDC, 0, 0, size.right, size.bottom, this->hDC, pos.left, pos.top, SRCCOPY);
|
|
|
|
|
|
|
|
ReleaseDC(hWnd, hDC);
|
|
|
|
}
|
2018-11-15 09:45:24 +01:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-10-25 04:15:53 +02:00
|
|
|
static unsigned char getPixel(int x, int y)
|
|
|
|
{
|
|
|
|
return ((unsigned char *)ddraw->primary->surface)[y*ddraw->primary->lPitch + x*ddraw->primary->lXPitch];
|
|
|
|
}
|
|
|
|
|
|
|
|
int* InMovie = (int*)0x00665F58;
|
|
|
|
int* IsVQA640 = (int*)0x0065D7BC;
|
|
|
|
BYTE* ShouldStretch = (BYTE*)0x00607D78;
|
|
|
|
|
|
|
|
BOOL detect_cutscene()
|
|
|
|
{
|
|
|
|
if (ddraw->width <= CUTSCENE_WIDTH || ddraw->height <= CUTSCENE_HEIGHT)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (ddraw->isredalert)
|
|
|
|
{
|
|
|
|
if ((*InMovie && !*IsVQA640) || *ShouldStretch)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else if (ddraw->iscnc1)
|
|
|
|
{
|
|
|
|
return getPixel(CUTSCENE_WIDTH + 1, 0) == 0 || getPixel(CUTSCENE_WIDTH + 5, 1) == 0 ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-11-28 13:28:07 +01:00
|
|
|
void LimitGameTicks()
|
2018-10-31 11:48:41 +01:00
|
|
|
{
|
2018-11-29 17:45:10 +01:00
|
|
|
if (ddraw->ticksLimiter.hTimer)
|
2018-10-31 11:48:41 +01:00
|
|
|
{
|
2018-11-29 21:26:43 +01:00
|
|
|
FILETIME ft = { 0 };
|
2018-11-29 17:45:10 +01:00
|
|
|
GetSystemTimeAsFileTime(&ft);
|
|
|
|
|
|
|
|
if (CompareFileTime((FILETIME *)&ddraw->ticksLimiter.dueTime, &ft) == -1)
|
|
|
|
{
|
|
|
|
memcpy(&ddraw->ticksLimiter.dueTime, &ft, sizeof(LARGE_INTEGER));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WaitForSingleObject(ddraw->ticksLimiter.hTimer, ddraw->ticksLimiter.ticklength * 2);
|
|
|
|
}
|
2018-10-31 11:48:41 +01:00
|
|
|
|
2018-11-29 17:45:10 +01:00
|
|
|
ddraw->ticksLimiter.dueTime.QuadPart += ddraw->ticksLimiter.tickLengthNs;
|
|
|
|
SetWaitableTimer(ddraw->ticksLimiter.hTimer, &ddraw->ticksLimiter.dueTime, 0, NULL, NULL, FALSE);
|
|
|
|
}
|
2018-10-31 11:48:41 +01:00
|
|
|
else
|
2018-11-29 17:45:10 +01:00
|
|
|
{
|
|
|
|
static DWORD nextGameTick;
|
|
|
|
if (!nextGameTick)
|
|
|
|
{
|
|
|
|
nextGameTick = timeGetTime();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
nextGameTick += ddraw->ticksLimiter.ticklength;
|
|
|
|
DWORD tickCount = timeGetTime();
|
|
|
|
|
|
|
|
int sleepTime = nextGameTick - tickCount;
|
|
|
|
if (sleepTime <= 0 || sleepTime > ddraw->ticksLimiter.ticklength)
|
|
|
|
nextGameTick = tickCount;
|
|
|
|
else
|
|
|
|
Sleep(sleepTime);
|
|
|
|
}
|
2018-10-31 11:48:41 +01:00
|
|
|
}
|
|
|
|
|
2019-08-07 02:04:07 +02:00
|
|
|
void UpdateBnetPos(int newX, int newY)
|
2019-08-06 04:37:06 +02:00
|
|
|
{
|
2019-08-07 02:04:07 +02:00
|
|
|
static int oldX = -32000;
|
|
|
|
static int oldY = -32000;
|
|
|
|
|
2019-08-08 03:55:04 +02:00
|
|
|
if (oldX == -32000 || oldY == -32000 || !ddraw->bnetActive)
|
2019-08-07 02:04:07 +02:00
|
|
|
{
|
|
|
|
oldX = newX;
|
|
|
|
oldY = newY;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-08-06 09:26:17 +02:00
|
|
|
POINT pt = { 0, 0 };
|
2019-08-06 07:19:00 +02:00
|
|
|
real_ClientToScreen(ddraw->hWnd, &pt);
|
|
|
|
|
2019-08-06 09:26:17 +02:00
|
|
|
RECT mainrc;
|
2019-08-06 07:19:00 +02:00
|
|
|
SetRect(&mainrc, pt.x, pt.y, pt.x + ddraw->width, pt.y + ddraw->height);
|
|
|
|
|
|
|
|
int adjY = 0;
|
|
|
|
int adjX = 0;
|
|
|
|
|
2019-08-06 04:37:06 +02:00
|
|
|
HWND hWnd = FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL);
|
|
|
|
|
|
|
|
while (hWnd != NULL)
|
|
|
|
{
|
|
|
|
RECT rc;
|
|
|
|
real_GetWindowRect(hWnd, &rc);
|
|
|
|
|
2019-08-06 07:19:00 +02:00
|
|
|
OffsetRect(&rc, newX - oldX, newY - oldY);
|
|
|
|
|
2019-08-06 04:37:06 +02:00
|
|
|
real_SetWindowPos(
|
|
|
|
hWnd,
|
|
|
|
0,
|
2019-08-06 07:19:00 +02:00
|
|
|
rc.left,
|
|
|
|
rc.top,
|
2019-08-06 04:37:06 +02:00
|
|
|
0,
|
|
|
|
0,
|
|
|
|
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
|
|
|
|
2019-08-08 09:58:12 +02:00
|
|
|
if (rc.bottom - rc.top <= ddraw->height)
|
|
|
|
{
|
|
|
|
if (rc.bottom > mainrc.bottom && abs(mainrc.bottom - rc.bottom) > abs(adjY))
|
|
|
|
adjY = mainrc.bottom - rc.bottom;
|
|
|
|
else if (rc.top < mainrc.top && abs(mainrc.top - rc.top) > abs(adjY))
|
|
|
|
adjY = mainrc.top - rc.top;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rc.right - rc.left <= ddraw->width)
|
|
|
|
{
|
|
|
|
if (rc.right > mainrc.right && abs(mainrc.right - rc.right) > abs(adjX))
|
|
|
|
adjX = mainrc.right - rc.right;
|
|
|
|
else if (rc.left < mainrc.left && abs(mainrc.left - rc.left) > abs(adjX))
|
|
|
|
adjX = mainrc.left - rc.left;
|
|
|
|
}
|
2019-08-06 07:19:00 +02:00
|
|
|
|
2019-08-06 04:37:06 +02:00
|
|
|
hWnd = FindWindowEx(HWND_DESKTOP, hWnd, "SDlgDialog", NULL);
|
|
|
|
}
|
2019-08-06 07:19:00 +02:00
|
|
|
|
|
|
|
if (adjX || adjY)
|
|
|
|
{
|
|
|
|
HWND hWnd = FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL);
|
|
|
|
|
|
|
|
while (hWnd != NULL)
|
|
|
|
{
|
|
|
|
RECT rc;
|
|
|
|
real_GetWindowRect(hWnd, &rc);
|
|
|
|
|
|
|
|
OffsetRect(&rc, adjX, adjY);
|
|
|
|
|
|
|
|
real_SetWindowPos(
|
|
|
|
hWnd,
|
|
|
|
0,
|
|
|
|
rc.left,
|
|
|
|
rc.top,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
|
|
|
|
|
|
|
hWnd = FindWindowEx(HWND_DESKTOP, hWnd, "SDlgDialog", NULL);
|
|
|
|
}
|
|
|
|
}
|
2019-08-07 02:04:07 +02:00
|
|
|
|
|
|
|
oldX = newX;
|
|
|
|
oldY = newY;
|
2019-08-06 04:37:06 +02:00
|
|
|
}
|
|
|
|
|
2010-10-23 19:25:02 +03:00
|
|
|
HRESULT __stdcall ddraw_Compact(IDirectDrawImpl *This)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::Compact(This=%p)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT __stdcall ddraw_DuplicateSurface(IDirectDrawImpl *This, LPDIRECTDRAWSURFACE src, LPDIRECTDRAWSURFACE *dest)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::DuplicateSurface(This=%p, ...)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2018-10-26 05:27:10 +02:00
|
|
|
HRESULT __stdcall ddraw_EnumDisplayModes(IDirectDrawImpl *This, DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback)
|
2010-10-23 19:25:02 +03:00
|
|
|
{
|
2018-10-26 05:27:10 +02:00
|
|
|
DWORD i = 0;
|
|
|
|
DDSURFACEDESC s;
|
|
|
|
|
2018-10-27 09:23:00 +02:00
|
|
|
printf("DirectDraw::EnumDisplayModes(This=%p, dwFlags=%08X, lpDDSurfaceDesc=%p, lpContext=%p, lpEnumModesCallback=%p)\n", This, (unsigned int)dwFlags, lpDDSurfaceDesc, lpContext, lpEnumModesCallback);
|
2018-10-26 05:27:10 +02:00
|
|
|
|
|
|
|
if (lpDDSurfaceDesc != NULL)
|
|
|
|
{
|
2019-08-30 05:37:29 +02:00
|
|
|
//return DDERR_UNSUPPORTED;
|
2018-10-26 05:27:10 +02:00
|
|
|
}
|
|
|
|
|
2018-11-24 23:36:38 +01:00
|
|
|
// Some games crash when you feed them with too many resolutions...
|
|
|
|
|
|
|
|
if (This->bpp)
|
2018-10-30 17:54:14 +01:00
|
|
|
{
|
2018-11-24 23:36:38 +01:00
|
|
|
printf(" This->bpp=%d\n", This->bpp);
|
2018-11-14 05:35:59 +01:00
|
|
|
|
2018-11-24 23:36:38 +01:00
|
|
|
//set up some filters to keep the list short
|
|
|
|
DWORD refreshRate = 0;
|
|
|
|
DWORD bpp = 0;
|
2018-11-24 23:54:59 +01:00
|
|
|
DWORD flags = 99998;
|
2018-11-24 23:48:37 +01:00
|
|
|
DWORD fixedOutput = 99998;
|
2018-11-24 23:36:38 +01:00
|
|
|
DEVMODE m;
|
2018-11-26 12:11:23 +01:00
|
|
|
memset(&m, 0, sizeof(DEVMODE));
|
|
|
|
m.dmSize = sizeof(DEVMODE);
|
|
|
|
|
2018-11-24 23:36:38 +01:00
|
|
|
while (EnumDisplaySettings(NULL, i, &m))
|
2018-11-14 05:35:59 +01:00
|
|
|
{
|
2018-11-24 23:36:38 +01:00
|
|
|
if (refreshRate != 60 && m.dmDisplayFrequency >= 50)
|
|
|
|
refreshRate = m.dmDisplayFrequency;
|
|
|
|
|
|
|
|
if (bpp != 32 && m.dmBitsPerPel >= 16)
|
|
|
|
bpp = m.dmBitsPerPel;
|
|
|
|
|
2018-11-24 23:54:59 +01:00
|
|
|
if (flags != 0)
|
2018-11-24 23:36:38 +01:00
|
|
|
flags = m.dmDisplayFlags;
|
|
|
|
|
2018-11-24 23:48:37 +01:00
|
|
|
if (fixedOutput != DMDFO_DEFAULT)
|
2018-11-24 23:36:38 +01:00
|
|
|
fixedOutput = m.dmDisplayFixedOutput;
|
|
|
|
|
2018-11-26 12:11:23 +01:00
|
|
|
memset(&m, 0, sizeof(DEVMODE));
|
|
|
|
m.dmSize = sizeof(DEVMODE);
|
2018-11-24 23:36:38 +01:00
|
|
|
i++;
|
2018-11-14 05:35:59 +01:00
|
|
|
}
|
2018-10-30 17:54:14 +01:00
|
|
|
|
2018-11-26 12:11:23 +01:00
|
|
|
memset(&m, 0, sizeof(DEVMODE));
|
|
|
|
m.dmSize = sizeof(DEVMODE);
|
2018-11-24 23:36:38 +01:00
|
|
|
i = 0;
|
|
|
|
while (EnumDisplaySettings(NULL, i, &m))
|
|
|
|
{
|
|
|
|
if (refreshRate == m.dmDisplayFrequency &&
|
|
|
|
bpp == m.dmBitsPerPel &&
|
|
|
|
flags == m.dmDisplayFlags &&
|
|
|
|
fixedOutput == m.dmDisplayFixedOutput)
|
|
|
|
{
|
2018-10-26 10:34:45 +02:00
|
|
|
#if _DEBUG_X
|
2018-11-24 23:36:38 +01:00
|
|
|
printf(" %d: %dx%d@%d %d bpp\n", (int)i, (int)m.dmPelsWidth, (int)m.dmPelsHeight, (int)m.dmDisplayFrequency, (int)m.dmBitsPerPel);
|
2018-10-26 10:34:45 +02:00
|
|
|
#endif
|
2018-11-24 23:36:38 +01:00
|
|
|
memset(&s, 0, sizeof(DDSURFACEDESC));
|
|
|
|
s.dwSize = sizeof(DDSURFACEDESC);
|
|
|
|
s.dwFlags = DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_PIXELFORMAT;
|
|
|
|
s.dwHeight = m.dmPelsHeight;
|
|
|
|
s.dwWidth = m.dmPelsWidth;
|
|
|
|
s.dwRefreshRate = 60;
|
|
|
|
s.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
|
|
|
|
|
|
|
s.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
|
|
|
|
s.ddpfPixelFormat.dwRGBBitCount = 8;
|
|
|
|
|
|
|
|
if (This->bpp == 16)
|
|
|
|
{
|
|
|
|
s.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
|
|
|
s.ddpfPixelFormat.dwRGBBitCount = 16;
|
|
|
|
s.ddpfPixelFormat.dwRBitMask = 0xF800;
|
|
|
|
s.ddpfPixelFormat.dwGBitMask = 0x07E0;
|
|
|
|
s.ddpfPixelFormat.dwBBitMask = 0x001F;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
|
|
|
|
{
|
|
|
|
printf(" DDENUMRET_CANCEL returned, stopping\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-11-26 12:11:23 +01:00
|
|
|
memset(&m, 0, sizeof(DEVMODE));
|
|
|
|
m.dmSize = sizeof(DEVMODE);
|
2018-11-24 23:36:38 +01:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SIZE resolutions[] =
|
2018-10-26 05:27:10 +02:00
|
|
|
{
|
2018-11-24 23:36:38 +01:00
|
|
|
{ 320, 200 },
|
|
|
|
{ 640, 400 },
|
|
|
|
{ 640, 480 },
|
|
|
|
{ 800, 600 },
|
|
|
|
{ 1024, 768 },
|
|
|
|
{ 1280, 1024 },
|
|
|
|
{ 1280, 720 },
|
|
|
|
{ 1920, 1080 },
|
|
|
|
};
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(resolutions) / sizeof(resolutions[0]); i++)
|
|
|
|
{
|
|
|
|
memset(&s, 0, sizeof(DDSURFACEDESC));
|
|
|
|
s.dwSize = sizeof(DDSURFACEDESC);
|
|
|
|
s.dwFlags = DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_PIXELFORMAT;
|
|
|
|
s.dwHeight = resolutions[i].cy;
|
|
|
|
s.dwWidth = resolutions[i].cx;
|
|
|
|
s.dwRefreshRate = 60;
|
|
|
|
s.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
|
|
|
s.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
|
|
|
|
s.ddpfPixelFormat.dwRGBBitCount = 8;
|
|
|
|
|
|
|
|
if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
|
|
|
|
{
|
|
|
|
printf(" DDENUMRET_CANCEL returned, stopping\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
s.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
|
|
|
s.ddpfPixelFormat.dwRGBBitCount = 16;
|
|
|
|
s.ddpfPixelFormat.dwRBitMask = 0xF800;
|
|
|
|
s.ddpfPixelFormat.dwGBitMask = 0x07E0;
|
|
|
|
s.ddpfPixelFormat.dwBBitMask = 0x001F;
|
|
|
|
|
|
|
|
if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
|
|
|
|
{
|
|
|
|
printf(" DDENUMRET_CANCEL returned, stopping\n");
|
|
|
|
break;
|
|
|
|
}
|
2018-10-26 05:27:10 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-24 23:36:38 +01:00
|
|
|
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT __stdcall ddraw_EnumSurfaces(IDirectDrawImpl *This, DWORD a, LPDDSURFACEDESC b, LPVOID c, LPDDENUMSURFACESCALLBACK d)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::EnumSurfaces(This=%p, ...)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT __stdcall ddraw_FlipToGDISurface(IDirectDrawImpl *This)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::FlipToGDISurface(This=%p)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2010-10-23 17:04:01 +03:00
|
|
|
HRESULT __stdcall ddraw_GetCaps(IDirectDrawImpl *This, LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDEmulCaps)
|
2010-10-10 19:41:47 +03:00
|
|
|
{
|
2010-10-16 23:22:43 +03:00
|
|
|
printf("DirectDraw::GetCaps(This=%p, lpDDDriverCaps=%p, lpDDEmulCaps=%p)\n", This, lpDDDriverCaps, lpDDEmulCaps);
|
2010-10-16 21:14:26 +03:00
|
|
|
|
2010-10-16 23:22:43 +03:00
|
|
|
if(lpDDDriverCaps)
|
|
|
|
{
|
|
|
|
lpDDDriverCaps->dwSize = sizeof(DDCAPS);
|
2018-11-17 08:23:49 +01:00
|
|
|
lpDDDriverCaps->dwCaps = DDCAPS_BLT | DDCAPS_PALETTE | DDCAPS_BLTCOLORFILL | DDCAPS_BLTSTRETCH | DDCAPS_CANCLIP;
|
2010-10-16 23:22:43 +03:00
|
|
|
lpDDDriverCaps->dwCKeyCaps = 0;
|
2018-11-17 08:23:49 +01:00
|
|
|
lpDDDriverCaps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE;
|
2010-10-16 23:22:43 +03:00
|
|
|
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;
|
2018-11-28 12:45:47 +01:00
|
|
|
lpDDDriverCaps->ddsCaps.dwCaps = DDSCAPS_FLIP;
|
2010-10-16 23:22:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if(lpDDEmulCaps)
|
|
|
|
{
|
|
|
|
lpDDEmulCaps->dwSize = 0;
|
|
|
|
}
|
2010-10-16 21:14:26 +03:00
|
|
|
|
2010-10-10 19:41:47 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2010-10-23 19:25:02 +03:00
|
|
|
HRESULT __stdcall ddraw_GetDisplayMode(IDirectDrawImpl *This, LPDDSURFACEDESC a)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::GetDisplayMode(This=%p, ...)\n", This);
|
2020-09-24 10:29:18 +02:00
|
|
|
return DDERR_UNSUPPORTEDMODE;
|
2010-10-23 19:25:02 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT __stdcall ddraw_GetFourCCCodes(IDirectDrawImpl *This, LPDWORD a, LPDWORD b)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::GetFourCCCodes(This=%p, ...)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT __stdcall ddraw_GetGDISurface(IDirectDrawImpl *This, LPDIRECTDRAWSURFACE *a)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::GetGDISurface(This=%p, ...)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT __stdcall ddraw_GetMonitorFrequency(IDirectDrawImpl *This, LPDWORD a)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::GetMonitorFrequency(This=%p, ...)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT __stdcall ddraw_GetScanLine(IDirectDrawImpl *This, LPDWORD a)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::GetScanLine(This=%p, ...)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2018-10-30 08:29:19 +01:00
|
|
|
HRESULT __stdcall ddraw_GetVerticalBlankStatus(IDirectDrawImpl *This, LPBOOL lpbIsInVB)
|
2010-10-23 19:25:02 +03:00
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::GetVerticalBlankStatus(This=%p, ...)\n", This);
|
2018-10-30 08:29:19 +01:00
|
|
|
*lpbIsInVB = TRUE;
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT __stdcall ddraw_Initialize(IDirectDrawImpl *This, GUID *a)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::Initialize(This=%p, ...)\n", This);
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2010-10-23 17:04:01 +03:00
|
|
|
HRESULT __stdcall ddraw_RestoreDisplayMode(IDirectDrawImpl *This)
|
2010-10-17 21:38:40 +03:00
|
|
|
{
|
2010-10-23 17:04:01 +03:00
|
|
|
printf("DirectDraw::RestoreDisplayMode(This=%p)\n", This);
|
2010-11-15 22:25:12 +02:00
|
|
|
|
2010-11-13 10:49:46 +02:00
|
|
|
if(!This->render.run)
|
|
|
|
{
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2017-11-17 23:08:13 +01:00
|
|
|
/* only stop drawing in GL mode when minimized */
|
2018-10-15 00:01:31 +02:00
|
|
|
if (This->renderer != render_soft_main)
|
2017-11-17 23:08:13 +01:00
|
|
|
{
|
|
|
|
EnterCriticalSection(&This->cs);
|
|
|
|
This->render.run = FALSE;
|
|
|
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
|
|
|
LeaveCriticalSection(&This->cs);
|
|
|
|
|
2018-10-27 02:28:07 +02:00
|
|
|
if (This->render.thread)
|
|
|
|
{
|
|
|
|
WaitForSingleObject(This->render.thread, INFINITE);
|
|
|
|
This->render.thread = NULL;
|
|
|
|
}
|
2018-10-15 00:01:31 +02:00
|
|
|
|
|
|
|
if (This->renderer == render_d3d9_main)
|
2018-10-15 00:57:05 +02:00
|
|
|
Direct3D9_Release();
|
2017-11-17 23:08:13 +01:00
|
|
|
}
|
2018-07-07 09:17:26 +02:00
|
|
|
|
2010-11-12 19:50:00 +02:00
|
|
|
if(!ddraw->windowed)
|
|
|
|
{
|
2018-10-15 00:01:31 +02:00
|
|
|
if (!Direct3D9Active)
|
2020-09-30 09:50:52 +02:00
|
|
|
ChangeDisplaySettings(NULL, 0);
|
2010-11-12 19:50:00 +02:00
|
|
|
}
|
2010-11-13 10:49:46 +02:00
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2018-11-25 15:05:09 +01:00
|
|
|
BOOL GetLowestResolution(float ratio, SIZE *outRes, DWORD minWidth, DWORD minHeight, DWORD maxWidth, DWORD maxHeight)
|
|
|
|
{
|
|
|
|
BOOL result = FALSE;
|
|
|
|
int orgRatio = (int)(ratio * 100);
|
|
|
|
SIZE lowest = { .cx = maxWidth + 1, .cy = maxHeight + 1 };
|
|
|
|
DWORD i = 0;
|
|
|
|
DEVMODE m;
|
2018-11-26 12:11:23 +01:00
|
|
|
memset(&m, 0, sizeof(DEVMODE));
|
|
|
|
m.dmSize = sizeof(DEVMODE);
|
2018-11-25 15:05:09 +01:00
|
|
|
|
|
|
|
while (EnumDisplaySettings(NULL, i, &m))
|
|
|
|
{
|
2018-11-25 15:38:43 +01:00
|
|
|
if (m.dmPelsWidth >= minWidth &&
|
|
|
|
m.dmPelsHeight >= minHeight &&
|
2018-11-25 15:05:09 +01:00
|
|
|
m.dmPelsWidth <= maxWidth &&
|
|
|
|
m.dmPelsHeight <= maxHeight &&
|
|
|
|
m.dmPelsWidth < lowest.cx &&
|
|
|
|
m.dmPelsHeight < lowest.cy)
|
|
|
|
{
|
|
|
|
int resRatio = (int)(((float)m.dmPelsWidth / m.dmPelsHeight) * 100);
|
|
|
|
|
|
|
|
if (resRatio == orgRatio)
|
|
|
|
{
|
|
|
|
result = TRUE;
|
|
|
|
outRes->cx = lowest.cx = m.dmPelsWidth;
|
|
|
|
outRes->cy = lowest.cy = m.dmPelsHeight;
|
|
|
|
}
|
|
|
|
}
|
2018-11-26 12:11:23 +01:00
|
|
|
memset(&m, 0, sizeof(DEVMODE));
|
|
|
|
m.dmSize = sizeof(DEVMODE);
|
2018-11-25 15:05:09 +01:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:01:31 +02:00
|
|
|
void InitDirect3D9()
|
|
|
|
{
|
2018-10-15 00:57:05 +02:00
|
|
|
Direct3D9Active = Direct3D9_Create();
|
2018-10-15 00:01:31 +02:00
|
|
|
if (!Direct3D9Active)
|
|
|
|
{
|
2018-10-15 00:57:05 +02:00
|
|
|
Direct3D9_Release();
|
2018-10-15 00:01:31 +02:00
|
|
|
ShowDriverWarning = TRUE;
|
|
|
|
ddraw->renderer = render_soft_main;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-04 19:35:38 +01:00
|
|
|
// LastSetWindowPosTick = Workaround for a wine+gnome bug where each SetWindowPos call triggers a WA_INACTIVE message
|
|
|
|
DWORD LastSetWindowPosTick;
|
|
|
|
|
2010-11-13 10:49:46 +02:00
|
|
|
HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD height, DWORD bpp)
|
|
|
|
{
|
|
|
|
printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
|
|
|
|
|
2018-11-14 05:35:59 +01:00
|
|
|
if (bpp != 8 && bpp != 16)
|
2018-10-30 08:29:19 +01:00
|
|
|
return DDERR_INVALIDMODE;
|
|
|
|
|
2018-10-27 02:28:07 +02:00
|
|
|
if (This->render.thread)
|
|
|
|
{
|
|
|
|
EnterCriticalSection(&This->cs);
|
|
|
|
This->render.run = FALSE;
|
|
|
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
|
|
|
LeaveCriticalSection(&This->cs);
|
|
|
|
|
|
|
|
WaitForSingleObject(This->render.thread, INFINITE);
|
|
|
|
This->render.thread = NULL;
|
|
|
|
}
|
|
|
|
|
2018-10-26 05:27:10 +02:00
|
|
|
if (!This->mode.dmPelsWidth)
|
|
|
|
{
|
|
|
|
This->mode.dmSize = sizeof(DEVMODE);
|
|
|
|
This->mode.dmDriverExtra = 0;
|
2010-11-13 10:49:46 +02:00
|
|
|
|
2018-10-26 05:27:10 +02:00
|
|
|
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &This->mode) == FALSE)
|
|
|
|
{
|
|
|
|
/* not expected */
|
|
|
|
return DDERR_UNSUPPORTED;
|
|
|
|
}
|
2018-10-27 16:44:09 +02:00
|
|
|
|
2019-03-19 06:57:49 +01:00
|
|
|
const HANDLE hbicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, real_GetSystemMetrics(SM_CXICON), real_GetSystemMetrics(SM_CYICON), 0);
|
2018-10-27 16:44:09 +02:00
|
|
|
if (hbicon)
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SendMessageA(This->hWnd, WM_SETICON, ICON_BIG, (LPARAM)hbicon);
|
2018-10-27 16:44:09 +02:00
|
|
|
|
2019-03-19 06:57:49 +01:00
|
|
|
const HANDLE hsicon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MYMENU), IMAGE_ICON, real_GetSystemMetrics(SM_CXSMICON), real_GetSystemMetrics(SM_CYSMICON), 0);
|
2018-10-27 16:44:09 +02:00
|
|
|
if (hsicon)
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SendMessageA(This->hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hsicon);
|
2018-10-26 05:27:10 +02:00
|
|
|
}
|
2018-10-27 16:44:09 +02:00
|
|
|
|
2018-11-04 19:35:38 +01:00
|
|
|
if (ddraw->altenter)
|
|
|
|
{
|
|
|
|
ddraw->altenter = FALSE;
|
|
|
|
This->render.width = ddraw->width;
|
|
|
|
This->render.height = ddraw->height;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
This->render.width = WindowRect.right;
|
|
|
|
This->render.height = WindowRect.bottom;
|
|
|
|
}
|
2010-11-13 10:49:46 +02:00
|
|
|
|
2019-08-13 10:21:13 +02:00
|
|
|
//temporary fix: center window for games that keep changing their resolution
|
|
|
|
if (This->width && This->bpp == bpp && (This->width != width || This->height != height))
|
|
|
|
{
|
|
|
|
WindowRect.left = -32000;
|
|
|
|
WindowRect.top = -32000;
|
|
|
|
}
|
|
|
|
|
2010-11-13 10:49:46 +02:00
|
|
|
This->width = width;
|
|
|
|
This->height = height;
|
|
|
|
This->bpp = bpp;
|
|
|
|
|
2018-03-23 03:21:16 +01:00
|
|
|
ddraw->cursor.x = width / 2;
|
|
|
|
ddraw->cursor.y = height / 2;
|
2011-07-08 18:22:43 +03:00
|
|
|
|
2019-08-19 17:02:36 +02:00
|
|
|
BOOL border = This->border;
|
|
|
|
|
2017-11-20 05:11:39 +01:00
|
|
|
if(This->fullscreen)
|
|
|
|
{
|
|
|
|
This->render.width = This->mode.dmPelsWidth;
|
|
|
|
This->render.height = This->mode.dmPelsHeight;
|
2018-10-05 10:01:38 +02:00
|
|
|
|
|
|
|
if (This->windowed) //windowed-fullscreen aka borderless
|
|
|
|
{
|
2019-08-19 17:02:36 +02:00
|
|
|
border = FALSE;
|
2018-10-27 16:44:09 +02:00
|
|
|
WindowRect.left = -32000;
|
|
|
|
WindowRect.top = -32000;
|
2018-10-05 10:01:38 +02:00
|
|
|
|
|
|
|
// prevent OpenGL from going automatically into fullscreen exclusive mode
|
|
|
|
if (This->renderer == render_main)
|
|
|
|
This->render.height++;
|
|
|
|
|
|
|
|
}
|
2017-11-20 05:11:39 +01:00
|
|
|
}
|
|
|
|
|
2010-11-13 10:49:46 +02:00
|
|
|
if(This->render.width < This->width)
|
|
|
|
{
|
|
|
|
This->render.width = This->width;
|
|
|
|
}
|
|
|
|
if(This->render.height < This->height)
|
|
|
|
{
|
|
|
|
This->render.height = This->height;
|
|
|
|
}
|
|
|
|
|
2011-08-22 17:40:21 +03:00
|
|
|
This->render.run = TRUE;
|
2017-11-15 18:42:42 +01:00
|
|
|
|
2018-11-24 13:34:25 +01:00
|
|
|
BOOL lockMouse = ddraw->locked || This->fullscreen;
|
2010-11-13 10:49:46 +02:00
|
|
|
mouse_unlock();
|
2012-12-31 22:52:44 +01:00
|
|
|
|
2017-11-14 23:41:52 +01:00
|
|
|
memset(&This->render.mode, 0, sizeof(DEVMODE));
|
|
|
|
This->render.mode.dmSize = sizeof(DEVMODE);
|
|
|
|
This->render.mode.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT;
|
|
|
|
This->render.mode.dmPelsWidth = This->render.width;
|
|
|
|
This->render.mode.dmPelsHeight = This->render.height;
|
|
|
|
if(This->render.bpp)
|
|
|
|
{
|
|
|
|
This->render.mode.dmFields |= DM_BITSPERPEL;
|
|
|
|
This->render.mode.dmBitsPerPel = This->render.bpp;
|
|
|
|
}
|
|
|
|
|
2018-11-05 20:48:42 +01:00
|
|
|
BOOL maintas = ddraw->maintas;
|
|
|
|
|
2018-11-23 15:01:36 +01:00
|
|
|
if (!This->windowed)
|
2017-11-20 00:56:56 +01:00
|
|
|
{
|
|
|
|
// Making sure the chosen resolution is valid
|
2018-11-23 15:01:36 +01:00
|
|
|
int oldWidth = This->render.width;
|
|
|
|
int oldHeight = This->render.height;
|
|
|
|
|
|
|
|
if (ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
|
2017-11-20 00:56:56 +01:00
|
|
|
{
|
2018-11-23 15:01:36 +01:00
|
|
|
// fail... compare resolutions
|
|
|
|
if (This->render.width > This->mode.dmPelsWidth || This->render.height > This->mode.dmPelsHeight)
|
2017-11-20 00:56:56 +01:00
|
|
|
{
|
2018-11-25 15:05:09 +01:00
|
|
|
// chosen game resolution higher than current resolution, use windowed mode for this case
|
2018-11-23 15:01:36 +01:00
|
|
|
This->windowed = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Try 2x scaling
|
|
|
|
This->render.width *= 2;
|
|
|
|
This->render.height *= 2;
|
|
|
|
|
|
|
|
This->render.mode.dmPelsWidth = This->render.width;
|
|
|
|
This->render.mode.dmPelsHeight = This->render.height;
|
|
|
|
|
|
|
|
if ((This->render.width > This->mode.dmPelsWidth || This->render.height > This->mode.dmPelsHeight) ||
|
|
|
|
ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
|
2017-11-20 00:56:56 +01:00
|
|
|
{
|
2018-11-25 15:05:09 +01:00
|
|
|
SIZE res = {0};
|
|
|
|
|
|
|
|
//try to get a resolution with the same aspect ratio as the requested resolution
|
|
|
|
BOOL foundRes = GetLowestResolution(
|
|
|
|
(float)oldWidth / oldHeight,
|
|
|
|
&res,
|
2018-11-25 15:38:43 +01:00
|
|
|
oldWidth + 1, //don't return the original resolution since we tested that one already
|
|
|
|
oldHeight + 1,
|
2018-11-25 15:05:09 +01:00
|
|
|
This->mode.dmPelsWidth,
|
|
|
|
This->mode.dmPelsHeight);
|
|
|
|
|
|
|
|
if (!foundRes)
|
|
|
|
{
|
|
|
|
//try to get a resolution with the same aspect ratio as the current display mode
|
|
|
|
foundRes = GetLowestResolution(
|
|
|
|
(float)This->mode.dmPelsWidth / This->mode.dmPelsHeight,
|
|
|
|
&res,
|
|
|
|
oldWidth,
|
|
|
|
oldHeight,
|
|
|
|
This->mode.dmPelsWidth,
|
|
|
|
This->mode.dmPelsHeight);
|
|
|
|
|
|
|
|
if (foundRes)
|
|
|
|
maintas = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
This->render.width = res.cx;
|
|
|
|
This->render.height = res.cy;
|
2018-11-23 15:01:36 +01:00
|
|
|
|
2017-11-20 00:56:56 +01:00
|
|
|
This->render.mode.dmPelsWidth = This->render.width;
|
|
|
|
This->render.mode.dmPelsHeight = This->render.height;
|
2018-11-25 15:05:09 +01:00
|
|
|
|
|
|
|
if (!foundRes || ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
|
2017-11-20 00:56:56 +01:00
|
|
|
{
|
2018-11-25 15:05:09 +01:00
|
|
|
// try current display settings
|
|
|
|
This->render.width = This->mode.dmPelsWidth;
|
|
|
|
This->render.height = This->mode.dmPelsHeight;
|
2018-11-23 15:01:36 +01:00
|
|
|
|
2017-11-20 00:56:56 +01:00
|
|
|
This->render.mode.dmPelsWidth = This->render.width;
|
|
|
|
This->render.mode.dmPelsHeight = This->render.height;
|
2018-11-23 15:01:36 +01:00
|
|
|
|
2018-11-25 15:05:09 +01:00
|
|
|
if (ChangeDisplaySettings(&This->render.mode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
|
|
|
|
{
|
|
|
|
// everything failed, use windowed mode instead
|
|
|
|
This->render.width = oldWidth;
|
|
|
|
This->render.height = oldHeight;
|
|
|
|
|
|
|
|
This->render.mode.dmPelsWidth = This->render.width;
|
|
|
|
This->render.mode.dmPelsHeight = This->render.height;
|
|
|
|
|
|
|
|
This->windowed = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
maintas = TRUE;
|
2017-11-20 00:56:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-11-16 06:37:11 +01:00
|
|
|
|
2018-11-16 08:58:39 +01:00
|
|
|
if (!ddraw->handlemouse)
|
2018-11-16 11:53:35 +01:00
|
|
|
This->boxing = maintas = FALSE;
|
2017-11-20 00:56:56 +01:00
|
|
|
|
2018-03-19 00:32:13 +01:00
|
|
|
This->render.viewport.width = This->render.width;
|
|
|
|
This->render.viewport.height = This->render.height;
|
|
|
|
This->render.viewport.x = 0;
|
|
|
|
This->render.viewport.y = 0;
|
2018-03-15 20:49:27 +01:00
|
|
|
|
2018-03-19 00:32:13 +01:00
|
|
|
if (This->boxing)
|
2018-03-15 20:49:27 +01:00
|
|
|
{
|
2018-03-19 00:32:13 +01:00
|
|
|
This->render.viewport.width = This->width;
|
|
|
|
This->render.viewport.height = This->height;
|
2018-03-15 20:49:27 +01:00
|
|
|
|
|
|
|
int i;
|
|
|
|
for (i = 20; i-- > 1;)
|
|
|
|
{
|
2018-03-19 00:32:13 +01:00
|
|
|
if (This->width * i <= This->render.width && This->height * i <= This->render.height)
|
2018-03-15 20:49:27 +01:00
|
|
|
{
|
2018-03-19 00:32:13 +01:00
|
|
|
This->render.viewport.width *= i;
|
|
|
|
This->render.viewport.height *= i;
|
2018-03-15 20:49:27 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-19 00:32:13 +01:00
|
|
|
This->render.viewport.y = This->render.height / 2 - This->render.viewport.height / 2;
|
|
|
|
This->render.viewport.x = This->render.width / 2 - This->render.viewport.width / 2;
|
2018-03-15 20:49:27 +01:00
|
|
|
}
|
2018-11-05 20:48:42 +01:00
|
|
|
else if (maintas)
|
2018-03-15 20:49:27 +01:00
|
|
|
{
|
2018-03-19 00:32:13 +01:00
|
|
|
This->render.viewport.width = This->render.width;
|
|
|
|
This->render.viewport.height = ((float)This->height / This->width) * This->render.viewport.width;
|
2018-03-15 20:49:27 +01:00
|
|
|
|
2018-03-19 00:32:13 +01:00
|
|
|
if (This->render.viewport.height > This->render.height)
|
2018-03-15 20:49:27 +01:00
|
|
|
{
|
2018-03-19 00:32:13 +01:00
|
|
|
This->render.viewport.width =
|
|
|
|
((float)This->render.viewport.width / This->render.viewport.height) * This->render.height;
|
2018-03-15 20:49:27 +01:00
|
|
|
|
2018-03-19 00:32:13 +01:00
|
|
|
This->render.viewport.height = This->render.height;
|
2018-03-15 20:49:27 +01:00
|
|
|
}
|
|
|
|
|
2018-03-19 00:32:13 +01:00
|
|
|
This->render.viewport.y = This->render.height / 2 - This->render.viewport.height / 2;
|
|
|
|
This->render.viewport.x = This->render.width / 2 - This->render.viewport.width / 2;
|
2018-03-15 20:49:27 +01:00
|
|
|
}
|
|
|
|
|
2018-11-16 02:59:42 +01:00
|
|
|
This->render.scaleW = ((float)This->render.viewport.width / This->width);
|
|
|
|
This->render.scaleH = ((float)This->render.viewport.height / This->height);
|
|
|
|
This->render.unScaleW = ((float)This->width / This->render.viewport.width);
|
|
|
|
This->render.unScaleH = ((float)This->height / This->render.viewport.height);
|
|
|
|
|
2018-10-27 02:28:07 +02:00
|
|
|
if (This->windowed)
|
2010-11-13 10:49:46 +02:00
|
|
|
{
|
2019-08-13 10:02:32 +02:00
|
|
|
MSG msg; // workaround for "Not Responding" window problem in cnc games
|
|
|
|
PeekMessage(&msg, ddraw->hWnd, 0, 0, PM_NOREMOVE);
|
|
|
|
|
2019-08-19 17:02:36 +02:00
|
|
|
if (!border)
|
2010-11-13 10:49:46 +02:00
|
|
|
{
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowLongA(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
|
2018-10-27 02:28:07 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowLongA(This->hWnd, GWL_STYLE, (GetWindowLong(This->hWnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW) & ~WS_MAXIMIZEBOX);
|
2010-11-13 10:49:46 +02:00
|
|
|
}
|
2018-10-27 02:28:07 +02:00
|
|
|
|
2018-11-05 14:05:32 +01:00
|
|
|
if (ddraw->wine)
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowLongA(This->hWnd, GWL_STYLE, (GetWindowLong(This->hWnd, GWL_STYLE) | WS_MINIMIZEBOX) & ~(WS_MAXIMIZEBOX | WS_THICKFRAME));
|
2018-11-05 14:05:32 +01:00
|
|
|
|
2018-10-27 02:28:07 +02:00
|
|
|
/* center the window with correct dimensions */
|
2018-10-27 16:44:09 +02:00
|
|
|
int x = (WindowRect.left != -32000) ? WindowRect.left : (This->mode.dmPelsWidth / 2) - (This->render.width / 2);
|
|
|
|
int y = (WindowRect.top != -32000) ? WindowRect.top : (This->mode.dmPelsHeight / 2) - (This->render.height / 2);
|
2018-10-27 02:28:07 +02:00
|
|
|
RECT dst = { x, y, This->render.width + x, This->render.height + y };
|
|
|
|
AdjustWindowRect(&dst, GetWindowLong(This->hWnd, GWL_STYLE), FALSE);
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowPos(ddraw->hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
|
|
real_MoveWindow(This->hWnd, dst.left, dst.top, (dst.right - dst.left), (dst.bottom - dst.top), TRUE);
|
2018-10-27 02:28:07 +02:00
|
|
|
|
|
|
|
if (This->renderer == render_d3d9_main)
|
|
|
|
InitDirect3D9();
|
2018-10-30 14:35:13 +01:00
|
|
|
|
|
|
|
if (lockMouse)
|
|
|
|
mouse_lock();
|
2010-11-13 10:49:46 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-17 22:44:54 +02:00
|
|
|
LONG style = GetWindowLong(This->hWnd, GWL_STYLE);
|
|
|
|
|
|
|
|
if ((style & WS_CAPTION))
|
|
|
|
{
|
|
|
|
real_SetWindowLongA(This->hWnd, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:01:31 +02:00
|
|
|
if (This->renderer == render_d3d9_main)
|
|
|
|
InitDirect3D9();
|
|
|
|
|
2018-11-23 15:01:36 +01:00
|
|
|
if (!Direct3D9Active && ChangeDisplaySettings(&This->render.mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
2010-11-13 10:49:46 +02:00
|
|
|
{
|
2018-11-23 15:01:36 +01:00
|
|
|
This->render.run = FALSE;
|
|
|
|
return DDERR_INVALIDMODE;
|
2010-11-13 10:49:46 +02:00
|
|
|
}
|
2018-08-07 02:44:11 +02:00
|
|
|
|
2018-08-12 13:12:04 +02:00
|
|
|
if (ddraw->wine)
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowLongA(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) | WS_MINIMIZEBOX);
|
2018-08-12 13:12:04 +02:00
|
|
|
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowPos(This->hWnd, HWND_TOPMOST, 0, 0, This->render.width, This->render.height, SWP_SHOWWINDOW);
|
2018-11-04 19:35:38 +01:00
|
|
|
LastSetWindowPosTick = timeGetTime();
|
|
|
|
|
2018-03-11 11:43:43 +01:00
|
|
|
mouse_lock();
|
2010-11-13 10:49:46 +02:00
|
|
|
}
|
2017-11-15 18:42:42 +01:00
|
|
|
|
2018-03-23 00:52:08 +01:00
|
|
|
if(This->render.viewport.x != 0 || This->render.viewport.y != 0)
|
2018-03-23 00:35:19 +01:00
|
|
|
{
|
|
|
|
RedrawWindow(This->hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
|
|
|
|
}
|
2018-10-08 08:42:08 +02:00
|
|
|
|
2017-11-15 18:42:42 +01:00
|
|
|
if(This->render.thread == NULL)
|
|
|
|
{
|
2018-10-27 17:39:43 +02:00
|
|
|
InterlockedExchange(&ddraw->render.paletteUpdated, TRUE);
|
|
|
|
InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
|
|
|
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
|
|
|
|
2017-11-15 18:42:42 +01:00
|
|
|
This->render.thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)This->renderer, NULL, 0, NULL);
|
|
|
|
}
|
2010-11-13 10:49:46 +02:00
|
|
|
|
2020-09-25 08:07:41 +02:00
|
|
|
if (ddraw->sierrahack)
|
|
|
|
{
|
2020-09-24 10:29:18 +02:00
|
|
|
PostMessageA(ddraw->hWnd, WM_MOVE, 0, MAKELPARAM(-32000, -32000));
|
2020-09-25 08:07:41 +02:00
|
|
|
PostMessageA(ddraw->hWnd, WM_DISPLAYCHANGE, ddraw->bpp, MAKELPARAM(ddraw->width, ddraw->height));
|
|
|
|
}
|
2020-09-24 10:29:18 +02:00
|
|
|
|
2010-11-12 19:50:00 +02:00
|
|
|
return DD_OK;
|
2010-10-17 21:38:40 +03:00
|
|
|
}
|
|
|
|
|
2018-11-02 02:21:16 +01:00
|
|
|
HRESULT __stdcall ddraw_SetDisplayMode2(IDirectDrawImpl *This, DWORD width, DWORD height, DWORD bpp, DWORD refreshRate, DWORD flags)
|
|
|
|
{
|
2018-11-18 13:11:05 +01:00
|
|
|
printf("DirectDraw::SetDisplayMode2(refreshRate=%d, flags=%d)\n", (unsigned int)refreshRate, (unsigned int)flags);
|
|
|
|
|
2018-11-02 02:21:16 +01:00
|
|
|
return ddraw_SetDisplayMode(This, width, height, bpp);
|
|
|
|
}
|
|
|
|
|
2017-11-15 03:20:12 +01:00
|
|
|
void ToggleFullscreen()
|
|
|
|
{
|
2019-08-08 07:13:53 +02:00
|
|
|
if (ddraw->bnetActive)
|
2019-08-06 04:37:06 +02:00
|
|
|
return;
|
|
|
|
|
2017-11-15 03:20:12 +01:00
|
|
|
if (ddraw->windowed)
|
|
|
|
{
|
2018-03-09 19:11:19 +01:00
|
|
|
mouse_unlock();
|
2018-11-07 23:28:19 +01:00
|
|
|
WindowState = ddraw->windowed = FALSE;
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowLongA(ddraw->hWnd, GWL_STYLE, GetWindowLong(ddraw->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
|
2018-11-04 19:35:38 +01:00
|
|
|
ddraw->altenter = TRUE;
|
2018-11-14 05:35:59 +01:00
|
|
|
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
|
2019-08-07 02:04:07 +02:00
|
|
|
UpdateBnetPos(0, 0);
|
2018-03-09 19:11:19 +01:00
|
|
|
mouse_lock();
|
2017-11-15 03:20:12 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-03-09 19:11:19 +01:00
|
|
|
mouse_unlock();
|
2018-11-07 23:28:19 +01:00
|
|
|
WindowState = ddraw->windowed = TRUE;
|
2018-08-07 02:08:40 +02:00
|
|
|
|
2018-11-04 19:35:38 +01:00
|
|
|
if (Direct3D9Active)
|
|
|
|
Direct3D9_Reset();
|
|
|
|
else
|
2020-09-30 09:50:52 +02:00
|
|
|
ChangeDisplaySettings(NULL, ddraw->bnetActive ? CDS_FULLSCREEN : 0);
|
2018-08-07 02:08:40 +02:00
|
|
|
|
2018-11-14 05:35:59 +01:00
|
|
|
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
|
2018-10-15 00:01:31 +02:00
|
|
|
mouse_lock();
|
2017-11-15 03:20:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-28 06:46:35 +01:00
|
|
|
BOOL UnadjustWindowRectEx(LPRECT prc, DWORD dwStyle, BOOL fMenu, DWORD dwExStyle)
|
|
|
|
{
|
|
|
|
RECT rc;
|
|
|
|
SetRectEmpty(&rc);
|
|
|
|
|
|
|
|
BOOL fRc = AdjustWindowRectEx(&rc, dwStyle, fMenu, dwExStyle);
|
|
|
|
if (fRc)
|
|
|
|
{
|
|
|
|
prc->left -= rc.left;
|
|
|
|
prc->top -= rc.top;
|
|
|
|
prc->right -= rc.right;
|
|
|
|
prc->bottom -= rc.bottom;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fRc;
|
|
|
|
}
|
|
|
|
|
2019-08-14 17:53:36 +02:00
|
|
|
void SetWindowRect(int x, int y, int width, int height, UINT flags)
|
|
|
|
{
|
|
|
|
if (ddraw->windowed)
|
|
|
|
{
|
|
|
|
if (ddraw->render.thread)
|
|
|
|
{
|
|
|
|
EnterCriticalSection(&ddraw->cs);
|
|
|
|
ddraw->render.run = FALSE;
|
|
|
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
|
|
|
LeaveCriticalSection(&ddraw->cs);
|
|
|
|
|
|
|
|
WaitForSingleObject(ddraw->render.thread, INFINITE);
|
|
|
|
ddraw->render.thread = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & SWP_NOMOVE) == 0)
|
|
|
|
{
|
|
|
|
WindowRect.left = x;
|
|
|
|
WindowRect.top = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & SWP_NOSIZE) == 0)
|
|
|
|
{
|
|
|
|
WindowRect.bottom = height;
|
|
|
|
WindowRect.right = width;
|
|
|
|
}
|
|
|
|
|
|
|
|
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-24 01:02:08 +03:00
|
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2017-11-15 18:42:42 +01:00
|
|
|
RECT rc = { 0, 0, ddraw->render.width, ddraw->render.height };
|
2018-10-27 16:44:09 +02:00
|
|
|
static BOOL inSizeMove = FALSE;
|
2018-11-15 09:45:24 +01:00
|
|
|
static int redrawCount = 0;
|
2017-11-15 18:42:42 +01:00
|
|
|
|
2010-10-24 01:02:08 +03:00
|
|
|
switch(uMsg)
|
|
|
|
{
|
2019-11-18 15:01:03 +01:00
|
|
|
//case WM_NCACTIVATE:
|
2018-12-02 06:21:36 +01:00
|
|
|
case WM_GETMINMAXINFO:
|
|
|
|
case WM_MOVING:
|
2018-12-01 01:43:05 +01:00
|
|
|
case WM_NCLBUTTONDOWN:
|
|
|
|
case WM_NCLBUTTONUP:
|
2018-12-01 00:25:16 +01:00
|
|
|
case WM_NCPAINT:
|
|
|
|
{
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
}
|
2019-08-13 15:46:05 +02:00
|
|
|
case WM_NCHITTEST:
|
|
|
|
{
|
|
|
|
LRESULT result = DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
|
|
|
|
if (!ddraw->resizable)
|
|
|
|
{
|
|
|
|
switch (result)
|
|
|
|
{
|
|
|
|
case HTBOTTOM:
|
|
|
|
case HTBOTTOMLEFT:
|
|
|
|
case HTBOTTOMRIGHT:
|
|
|
|
case HTLEFT:
|
|
|
|
case HTRIGHT:
|
|
|
|
case HTTOP:
|
|
|
|
case HTTOPLEFT:
|
|
|
|
case HTTOPRIGHT:
|
|
|
|
return HTBORDER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2018-12-01 01:16:24 +01:00
|
|
|
case WM_SETCURSOR:
|
|
|
|
{
|
|
|
|
// show resize cursor on window borders
|
|
|
|
if ((HWND)wParam == ddraw->hWnd)
|
|
|
|
{
|
|
|
|
WORD message = HIWORD(lParam);
|
|
|
|
|
|
|
|
if (message == WM_MOUSEMOVE)
|
|
|
|
{
|
|
|
|
WORD htcode = LOWORD(lParam);
|
|
|
|
|
|
|
|
switch (htcode)
|
|
|
|
{
|
|
|
|
case HTCAPTION:
|
|
|
|
case HTMINBUTTON:
|
|
|
|
case HTMAXBUTTON:
|
|
|
|
case HTCLOSE:
|
|
|
|
case HTBOTTOM:
|
|
|
|
case HTBOTTOMLEFT:
|
|
|
|
case HTBOTTOMRIGHT:
|
|
|
|
case HTLEFT:
|
|
|
|
case HTRIGHT:
|
|
|
|
case HTTOP:
|
|
|
|
case HTTOPLEFT:
|
|
|
|
case HTTOPRIGHT:
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
2019-08-09 06:27:33 +02:00
|
|
|
case HTCLIENT:
|
|
|
|
if (!ddraw->locked)
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
2018-12-01 01:16:24 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2018-10-15 00:01:31 +02:00
|
|
|
case WM_D3D9DEVICELOST:
|
2018-10-09 09:16:00 +02:00
|
|
|
{
|
2018-11-12 00:39:47 +01:00
|
|
|
if (Direct3D9Active && Direct3D9_OnDeviceLost())
|
2018-10-09 09:16:00 +02:00
|
|
|
{
|
2018-10-15 00:01:31 +02:00
|
|
|
if (!ddraw->windowed)
|
2018-10-09 09:16:00 +02:00
|
|
|
mouse_lock();
|
|
|
|
}
|
2018-10-09 09:33:17 +02:00
|
|
|
return 0;
|
2018-10-09 09:16:00 +02:00
|
|
|
}
|
2019-08-08 12:40:20 +02:00
|
|
|
case WM_TIMER:
|
|
|
|
{
|
|
|
|
switch (wParam)
|
|
|
|
{
|
|
|
|
case IDT_TIMER_LEAVE_BNET:
|
|
|
|
{
|
|
|
|
KillTimer(ddraw->hWnd, IDT_TIMER_LEAVE_BNET);
|
|
|
|
|
|
|
|
if (!ddraw->windowed)
|
|
|
|
ddraw->bnetWasFullscreen = FALSE;
|
|
|
|
|
2019-08-19 17:02:36 +02:00
|
|
|
if (!ddraw->bnetActive)
|
2019-08-08 12:40:20 +02:00
|
|
|
{
|
2019-08-19 17:02:36 +02:00
|
|
|
if (ddraw->bnetWasFullscreen)
|
|
|
|
{
|
|
|
|
int ws = WindowState;
|
|
|
|
ToggleFullscreen();
|
|
|
|
WindowState = ws;
|
|
|
|
ddraw->bnetWasFullscreen = FALSE;
|
|
|
|
}
|
|
|
|
else if (ddraw->bnetWasUpscaled)
|
|
|
|
{
|
|
|
|
SetWindowRect(0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
|
|
ddraw->bnetWasUpscaled = FALSE;
|
|
|
|
}
|
2019-08-08 12:40:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2018-08-14 15:43:48 +02:00
|
|
|
case WM_WINDOWPOSCHANGED:
|
|
|
|
{
|
|
|
|
WINDOWPOS *pos = (WINDOWPOS *)lParam;
|
|
|
|
|
|
|
|
if (ddraw->wine && !ddraw->windowed && (pos->x > 0 || pos->y > 0) && LastSetWindowPosTick + 500 < timeGetTime())
|
|
|
|
PostMessage(ddraw->hWnd, WM_WINEFULLSCREEN, 0, 0);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WM_WINEFULLSCREEN:
|
|
|
|
{
|
|
|
|
if (!ddraw->windowed)
|
|
|
|
{
|
|
|
|
LastSetWindowPosTick = timeGetTime();
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 1, 1, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW);
|
|
|
|
real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW);
|
2018-08-14 15:43:48 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2018-10-27 16:44:09 +02:00
|
|
|
case WM_ENTERSIZEMOVE:
|
|
|
|
{
|
|
|
|
if (ddraw->windowed)
|
|
|
|
{
|
|
|
|
inSizeMove = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WM_EXITSIZEMOVE:
|
|
|
|
{
|
|
|
|
if (ddraw->windowed)
|
|
|
|
{
|
|
|
|
inSizeMove = FALSE;
|
|
|
|
|
|
|
|
if (!ddraw->render.thread)
|
|
|
|
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WM_SIZING:
|
|
|
|
{
|
2018-10-28 06:46:35 +01:00
|
|
|
RECT *windowrc = (RECT *)lParam;
|
|
|
|
|
2018-10-27 16:44:09 +02:00
|
|
|
if (ddraw->windowed)
|
|
|
|
{
|
2018-10-28 06:46:35 +01:00
|
|
|
if (inSizeMove)
|
2018-10-27 16:44:09 +02:00
|
|
|
{
|
2018-10-28 06:46:35 +01:00
|
|
|
if (ddraw->render.thread)
|
|
|
|
{
|
|
|
|
EnterCriticalSection(&ddraw->cs);
|
|
|
|
ddraw->render.run = FALSE;
|
|
|
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
|
|
|
LeaveCriticalSection(&ddraw->cs);
|
|
|
|
|
|
|
|
WaitForSingleObject(ddraw->render.thread, INFINITE);
|
|
|
|
ddraw->render.thread = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
RECT clientrc = { 0 };
|
|
|
|
|
2018-11-01 20:09:42 +01:00
|
|
|
// maintain aspect ratio
|
2018-10-28 06:46:35 +01:00
|
|
|
if (ddraw->maintas &&
|
|
|
|
CopyRect(&clientrc, windowrc) &&
|
|
|
|
UnadjustWindowRectEx(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)) &&
|
|
|
|
SetRect(&clientrc, 0, 0, clientrc.right - clientrc.left, clientrc.bottom - clientrc.top))
|
|
|
|
{
|
|
|
|
float scaleH = (float)ddraw->height / ddraw->width;
|
|
|
|
float scaleW = (float)ddraw->width / ddraw->height;
|
|
|
|
|
|
|
|
switch (wParam)
|
|
|
|
{
|
|
|
|
case WMSZ_BOTTOMLEFT:
|
|
|
|
case WMSZ_BOTTOMRIGHT:
|
|
|
|
case WMSZ_LEFT:
|
|
|
|
case WMSZ_RIGHT:
|
|
|
|
{
|
|
|
|
windowrc->bottom += scaleH * clientrc.right - clientrc.bottom;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WMSZ_TOP:
|
|
|
|
case WMSZ_BOTTOM:
|
|
|
|
{
|
|
|
|
windowrc->right += scaleW * clientrc.bottom - clientrc.right;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WMSZ_TOPRIGHT:
|
|
|
|
case WMSZ_TOPLEFT:
|
|
|
|
{
|
|
|
|
windowrc->top -= scaleH * clientrc.right - clientrc.bottom;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-10-28 12:38:57 +01:00
|
|
|
}
|
2018-10-28 06:46:35 +01:00
|
|
|
|
2018-11-01 20:09:42 +01:00
|
|
|
//enforce minimum window size
|
2018-10-28 12:38:57 +01:00
|
|
|
if (CopyRect(&clientrc, windowrc) &&
|
|
|
|
UnadjustWindowRectEx(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)) &&
|
|
|
|
SetRect(&clientrc, 0, 0, clientrc.right - clientrc.left, clientrc.bottom - clientrc.top))
|
|
|
|
{
|
|
|
|
if (clientrc.right < ddraw->width)
|
|
|
|
{
|
|
|
|
switch (wParam)
|
|
|
|
{
|
|
|
|
case WMSZ_TOPRIGHT:
|
|
|
|
case WMSZ_BOTTOMRIGHT:
|
|
|
|
case WMSZ_RIGHT:
|
2018-10-28 13:00:50 +01:00
|
|
|
case WMSZ_BOTTOM:
|
|
|
|
case WMSZ_TOP:
|
2018-10-28 12:41:08 +01:00
|
|
|
{
|
|
|
|
windowrc->right += ddraw->width - clientrc.right;
|
|
|
|
break;
|
|
|
|
}
|
2018-10-28 12:38:57 +01:00
|
|
|
case WMSZ_TOPLEFT:
|
|
|
|
case WMSZ_BOTTOMLEFT:
|
|
|
|
case WMSZ_LEFT:
|
2018-10-28 12:41:08 +01:00
|
|
|
{
|
|
|
|
windowrc->left -= ddraw->width - clientrc.right;
|
|
|
|
break;
|
|
|
|
}
|
2018-10-28 12:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (clientrc.bottom < ddraw->height)
|
|
|
|
{
|
|
|
|
switch (wParam)
|
|
|
|
{
|
|
|
|
case WMSZ_BOTTOMLEFT:
|
|
|
|
case WMSZ_BOTTOMRIGHT:
|
|
|
|
case WMSZ_BOTTOM:
|
2018-10-28 13:00:50 +01:00
|
|
|
case WMSZ_RIGHT:
|
|
|
|
case WMSZ_LEFT:
|
2018-10-28 12:38:57 +01:00
|
|
|
{
|
2018-10-28 12:41:08 +01:00
|
|
|
windowrc->bottom += ddraw->height - clientrc.bottom;
|
|
|
|
break;
|
2018-10-28 12:38:57 +01:00
|
|
|
}
|
|
|
|
case WMSZ_TOPLEFT:
|
|
|
|
case WMSZ_TOPRIGHT:
|
|
|
|
case WMSZ_TOP:
|
|
|
|
{
|
2018-10-28 12:41:08 +01:00
|
|
|
windowrc->top -= ddraw->height - clientrc.bottom;
|
|
|
|
break;
|
2018-10-28 12:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-10-28 06:46:35 +01:00
|
|
|
}
|
2018-08-14 15:43:48 +02:00
|
|
|
|
2018-11-01 20:09:42 +01:00
|
|
|
//save new window position
|
|
|
|
if (CopyRect(&clientrc, windowrc) &&
|
|
|
|
UnadjustWindowRectEx(&clientrc, GetWindowLong(hWnd, GWL_STYLE), FALSE, GetWindowLong(hWnd, GWL_EXSTYLE)))
|
|
|
|
{
|
|
|
|
WindowRect.left = clientrc.left;
|
|
|
|
WindowRect.top = clientrc.top;
|
|
|
|
WindowRect.right = clientrc.right - clientrc.left;
|
|
|
|
WindowRect.bottom = clientrc.bottom - clientrc.top;
|
|
|
|
}
|
|
|
|
|
2018-10-28 12:38:57 +01:00
|
|
|
return TRUE;
|
2018-10-27 16:44:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2017-11-21 16:20:04 +01:00
|
|
|
case WM_SIZE:
|
2018-10-27 16:44:09 +02:00
|
|
|
{
|
|
|
|
if (ddraw->windowed)
|
|
|
|
{
|
2018-11-05 14:05:32 +01:00
|
|
|
if (wParam == SIZE_RESTORED)
|
2018-10-27 16:44:09 +02:00
|
|
|
{
|
2018-11-05 14:05:32 +01:00
|
|
|
if (inSizeMove && !ddraw->render.thread)
|
|
|
|
{
|
|
|
|
WindowRect.right = LOWORD(lParam);
|
|
|
|
WindowRect.bottom = HIWORD(lParam);
|
|
|
|
}
|
2018-11-16 00:40:34 +01:00
|
|
|
/*
|
2018-11-05 14:05:32 +01:00
|
|
|
else if (ddraw->wine)
|
|
|
|
{
|
|
|
|
WindowRect.right = LOWORD(lParam);
|
|
|
|
WindowRect.bottom = HIWORD(lParam);
|
2018-11-05 14:16:30 +01:00
|
|
|
if (WindowRect.right != ddraw->render.width || WindowRect.bottom != ddraw->render.height)
|
|
|
|
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
|
2018-11-05 14:05:32 +01:00
|
|
|
}
|
2018-11-16 00:40:34 +01:00
|
|
|
*/
|
2018-10-27 16:44:09 +02:00
|
|
|
}
|
|
|
|
}
|
2018-12-11 08:56:22 +01:00
|
|
|
|
|
|
|
if (!ddraw->handlemouse)
|
|
|
|
{
|
|
|
|
redrawCount = 2;
|
|
|
|
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
|
|
|
|
}
|
|
|
|
|
2017-11-21 16:20:04 +01:00
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam); /* Carmageddon fix */
|
2018-10-27 16:44:09 +02:00
|
|
|
}
|
2017-11-12 14:57:27 +01:00
|
|
|
case WM_MOVE:
|
|
|
|
{
|
2018-11-01 20:09:42 +01:00
|
|
|
if (ddraw->windowed)
|
2017-11-12 14:57:27 +01:00
|
|
|
{
|
2019-08-06 04:37:06 +02:00
|
|
|
int x = (int)(short)LOWORD(lParam);
|
|
|
|
int y = (int)(short)HIWORD(lParam);
|
|
|
|
|
2019-08-08 03:55:04 +02:00
|
|
|
if (x != -32000 && y != -32000)
|
2019-08-07 02:04:07 +02:00
|
|
|
UpdateBnetPos(x, y);
|
2018-11-01 20:09:42 +01:00
|
|
|
|
2018-11-09 00:30:29 +01:00
|
|
|
if (inSizeMove || ddraw->wine)
|
2018-11-01 20:09:42 +01:00
|
|
|
{
|
|
|
|
if (x != -32000)
|
|
|
|
WindowRect.left = x; // -32000 = Exit/Minimize
|
|
|
|
|
|
|
|
if (y != -32000)
|
|
|
|
WindowRect.top = y;
|
|
|
|
}
|
2017-11-12 14:57:27 +01:00
|
|
|
}
|
2017-11-21 16:20:04 +01:00
|
|
|
|
2018-11-16 08:58:39 +01:00
|
|
|
if (!ddraw->handlemouse)
|
2018-11-15 09:45:24 +01:00
|
|
|
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
|
|
|
|
|
2020-09-25 08:07:41 +02:00
|
|
|
if (ddraw->sierrahack)
|
2020-09-24 10:29:18 +02:00
|
|
|
{
|
|
|
|
lParam = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-11-21 16:20:04 +01:00
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam); /* Carmageddon fix */
|
2017-11-12 14:57:27 +01:00
|
|
|
}
|
2011-09-11 19:12:07 +03:00
|
|
|
|
|
|
|
/* C&C and RA really don't want to close down */
|
2010-11-13 10:49:46 +02:00
|
|
|
case WM_SYSCOMMAND:
|
2018-11-16 01:14:05 +01:00
|
|
|
if (wParam == SC_CLOSE && !GameHandlesClose)
|
2010-11-13 10:49:46 +02:00
|
|
|
{
|
|
|
|
exit(0);
|
|
|
|
}
|
2018-11-17 08:33:36 +01:00
|
|
|
|
2019-11-16 12:00:09 +01:00
|
|
|
if (wParam == SC_KEYMENU)
|
|
|
|
return 0;
|
|
|
|
|
2018-11-17 08:33:36 +01:00
|
|
|
if (!GameHandlesClose)
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
|
|
|
|
break;
|
2011-09-11 19:12:07 +03:00
|
|
|
|
2019-08-07 13:26:40 +02:00
|
|
|
//workaround for a bug where sometimes a background window steals the focus
|
|
|
|
case WM_WINDOWPOSCHANGING:
|
|
|
|
{
|
|
|
|
if (ddraw->locked)
|
|
|
|
{
|
|
|
|
WINDOWPOS *pos = (WINDOWPOS *)lParam;
|
|
|
|
|
|
|
|
if (pos->flags == SWP_NOMOVE + SWP_NOSIZE)
|
|
|
|
{
|
|
|
|
mouse_unlock();
|
|
|
|
|
|
|
|
if (GetForegroundWindow() == ddraw->hWnd)
|
|
|
|
mouse_lock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case WM_MOUSELEAVE:
|
|
|
|
mouse_unlock();
|
|
|
|
return 0;
|
|
|
|
|
2011-09-11 19:12:07 +03:00
|
|
|
case WM_ACTIVATE:
|
|
|
|
if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE)
|
2011-01-10 22:17:29 +02:00
|
|
|
{
|
2011-09-11 19:12:07 +03:00
|
|
|
if (!ddraw->windowed)
|
|
|
|
{
|
2018-10-15 00:01:31 +02:00
|
|
|
if (!Direct3D9Active)
|
2018-08-07 03:57:46 +02:00
|
|
|
{
|
2019-09-08 13:19:02 +02:00
|
|
|
ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
|
2018-10-08 08:42:08 +02:00
|
|
|
|
|
|
|
if (wParam == WA_ACTIVE)
|
|
|
|
{
|
|
|
|
mouse_lock();
|
|
|
|
}
|
2018-08-07 03:57:46 +02:00
|
|
|
}
|
2018-03-11 11:43:43 +01:00
|
|
|
}
|
2018-11-15 09:45:24 +01:00
|
|
|
|
2018-11-16 08:58:39 +01:00
|
|
|
if (!ddraw->handlemouse)
|
2018-11-15 09:45:24 +01:00
|
|
|
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
|
2011-01-10 22:17:29 +02:00
|
|
|
}
|
2011-09-11 19:12:07 +03:00
|
|
|
else if (wParam == WA_INACTIVE)
|
2010-10-25 18:51:39 +03:00
|
|
|
{
|
2019-11-18 14:59:45 +01:00
|
|
|
if (!ddraw->windowed && !ddraw->locked && ddraw->noactivateapp && !ddraw->devmode)
|
2018-11-16 07:27:05 +01:00
|
|
|
return 0;
|
|
|
|
|
2018-08-09 11:39:11 +02:00
|
|
|
mouse_unlock();
|
|
|
|
|
2018-08-09 11:19:36 +02:00
|
|
|
if (ddraw->wine && LastSetWindowPosTick + 500 > timeGetTime())
|
|
|
|
return 0;
|
|
|
|
|
2011-09-11 19:12:07 +03:00
|
|
|
/* minimize our window on defocus when in fullscreen */
|
|
|
|
if (!ddraw->windowed)
|
2010-11-16 19:13:59 +02:00
|
|
|
{
|
2018-10-15 00:01:31 +02:00
|
|
|
if (!Direct3D9Active)
|
2018-10-08 08:42:08 +02:00
|
|
|
{
|
|
|
|
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
|
2020-09-30 09:50:52 +02:00
|
|
|
ChangeDisplaySettings(NULL, ddraw->bnetActive ? CDS_FULLSCREEN : 0);
|
2018-10-08 08:42:08 +02:00
|
|
|
}
|
2010-11-16 19:13:59 +02:00
|
|
|
}
|
2011-09-11 19:12:07 +03:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_ACTIVATEAPP:
|
|
|
|
/* C&C and RA stop drawing when they receive this with FALSE wParam, disable in windowed mode */
|
2018-03-19 02:27:55 +01:00
|
|
|
if (ddraw->windowed || ddraw->noactivateapp)
|
2011-09-11 19:12:07 +03:00
|
|
|
{
|
2018-11-16 07:56:32 +01:00
|
|
|
// let it pass through once (tiberian sun)
|
|
|
|
static BOOL oneTime;
|
2018-11-16 08:58:39 +01:00
|
|
|
if (wParam && !oneTime && !ddraw->handlemouse && ddraw->noactivateapp)
|
2018-11-16 07:56:32 +01:00
|
|
|
{
|
|
|
|
oneTime = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-09-11 19:12:07 +03:00
|
|
|
return 0;
|
2010-11-16 19:13:59 +02:00
|
|
|
}
|
2010-11-21 17:50:20 +02:00
|
|
|
break;
|
2018-06-26 18:02:03 +02:00
|
|
|
case WM_AUTORENDERER:
|
|
|
|
{
|
|
|
|
mouse_unlock();
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowPos(ddraw->hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
|
|
real_SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
2018-06-26 18:02:03 +02:00
|
|
|
mouse_lock();
|
|
|
|
return 0;
|
|
|
|
}
|
2017-11-15 05:31:08 +01:00
|
|
|
case WM_NCLBUTTONDBLCLK:
|
|
|
|
{
|
|
|
|
ToggleFullscreen();
|
|
|
|
return 0;
|
|
|
|
}
|
2017-11-14 23:41:52 +01:00
|
|
|
case WM_SYSKEYDOWN:
|
|
|
|
{
|
2019-11-15 08:14:03 +01:00
|
|
|
BOOL contextCode = (lParam & (1 << 29)) != 0;
|
|
|
|
BOOL keyState = (lParam & (1 << 30)) != 0;
|
2019-11-15 07:46:46 +01:00
|
|
|
|
|
|
|
if (wParam == VK_RETURN && contextCode && !keyState)
|
2017-11-14 23:41:52 +01:00
|
|
|
{
|
2017-11-15 03:20:12 +01:00
|
|
|
ToggleFullscreen();
|
2017-11-14 23:41:52 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2010-10-24 01:02:08 +03:00
|
|
|
case WM_KEYDOWN:
|
2010-11-16 18:14:02 +02:00
|
|
|
if(wParam == VK_CONTROL || wParam == VK_TAB)
|
2010-10-24 01:02:08 +03:00
|
|
|
{
|
2010-11-17 18:53:39 +02:00
|
|
|
if(GetAsyncKeyState(VK_CONTROL) & 0x8000 && GetAsyncKeyState(VK_TAB) & 0x8000)
|
2010-11-16 18:14:02 +02:00
|
|
|
{
|
|
|
|
mouse_unlock();
|
2011-09-11 19:12:07 +03:00
|
|
|
return 0;
|
2010-11-16 18:14:02 +02:00
|
|
|
}
|
2010-10-24 01:02:08 +03:00
|
|
|
}
|
2019-03-20 06:53:01 +01:00
|
|
|
if (wParam == VK_CONTROL || wParam == VK_MENU)
|
2018-11-16 12:23:19 +01:00
|
|
|
{
|
|
|
|
if ((GetAsyncKeyState(VK_RMENU) & 0x8000) && GetAsyncKeyState(VK_RCONTROL) & 0x8000)
|
|
|
|
{
|
|
|
|
mouse_unlock();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2011-09-11 19:12:07 +03:00
|
|
|
break;
|
|
|
|
|
2018-07-16 12:27:41 +02:00
|
|
|
case WM_KEYUP:
|
|
|
|
if (wParam == VK_SNAPSHOT)
|
|
|
|
screenshot(ddraw->primary);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
2011-09-11 19:12:07 +03:00
|
|
|
/* button up messages reactivate cursor lock */
|
2011-04-02 21:57:37 +03:00
|
|
|
case WM_LBUTTONUP:
|
2011-07-08 18:22:43 +03:00
|
|
|
case WM_RBUTTONUP:
|
2011-09-11 19:12:07 +03:00
|
|
|
case WM_MBUTTONUP:
|
2018-03-09 13:50:56 +01:00
|
|
|
if (!ddraw->devmode && !ddraw->locked)
|
2011-04-02 21:57:37 +03:00
|
|
|
{
|
2018-03-16 18:57:59 +01:00
|
|
|
int x = GET_X_LPARAM(lParam);
|
|
|
|
int y = GET_Y_LPARAM(lParam);
|
2018-03-15 20:49:27 +01:00
|
|
|
|
|
|
|
if (x > ddraw->render.viewport.x + ddraw->render.viewport.width ||
|
|
|
|
x < ddraw->render.viewport.x ||
|
|
|
|
y > ddraw->render.viewport.y + ddraw->render.viewport.height ||
|
|
|
|
y < ddraw->render.viewport.y)
|
|
|
|
{
|
|
|
|
ddraw->cursor.x = ddraw->width / 2;
|
|
|
|
ddraw->cursor.y = ddraw->height / 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-11-16 02:59:42 +01:00
|
|
|
ddraw->cursor.x = (x - ddraw->render.viewport.x) * ddraw->render.unScaleW;
|
|
|
|
ddraw->cursor.y = (y - ddraw->render.viewport.y) * ddraw->render.unScaleH;
|
2018-03-15 20:49:27 +01:00
|
|
|
}
|
|
|
|
|
2011-04-02 21:57:37 +03:00
|
|
|
mouse_lock();
|
|
|
|
return 0;
|
|
|
|
}
|
2011-09-11 19:12:07 +03:00
|
|
|
/* fall through for lParam */
|
|
|
|
|
|
|
|
/* down messages are ignored if we have no cursor lock */
|
2018-11-23 15:26:27 +01:00
|
|
|
case WM_XBUTTONDBLCLK:
|
|
|
|
case WM_XBUTTONDOWN:
|
|
|
|
case WM_XBUTTONUP:
|
|
|
|
case WM_MOUSEWHEEL:
|
|
|
|
case WM_MOUSEHOVER:
|
2018-11-21 19:15:21 +01:00
|
|
|
case WM_LBUTTONDBLCLK:
|
|
|
|
case WM_MBUTTONDBLCLK:
|
|
|
|
case WM_RBUTTONDBLCLK:
|
2010-10-24 01:02:08 +03:00
|
|
|
case WM_LBUTTONDOWN:
|
2010-11-07 12:10:09 +02:00
|
|
|
case WM_RBUTTONDOWN:
|
2010-12-11 14:45:09 +02:00
|
|
|
case WM_MBUTTONDOWN:
|
2011-09-11 19:12:07 +03:00
|
|
|
case WM_MOUSEMOVE:
|
2011-07-08 18:22:43 +03:00
|
|
|
|
2018-03-11 21:23:22 +01:00
|
|
|
if (!ddraw->devmode)
|
2018-03-09 13:50:56 +01:00
|
|
|
{
|
2018-03-11 21:23:22 +01:00
|
|
|
if (!ddraw->locked)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ddraw->adjmouse)
|
|
|
|
{
|
|
|
|
fake_GetCursorPos(NULL); /* update our own cursor */
|
|
|
|
lParam = MAKELPARAM(ddraw->cursor.x, ddraw->cursor.y);
|
|
|
|
}
|
2010-10-24 01:02:08 +03:00
|
|
|
}
|
2012-08-09 14:35:28 +03:00
|
|
|
|
|
|
|
if (ddraw->devmode)
|
|
|
|
{
|
|
|
|
mouse_lock();
|
2018-03-09 18:20:09 +01:00
|
|
|
ddraw->cursor.x = GET_X_LPARAM(lParam);
|
|
|
|
ddraw->cursor.y = GET_Y_LPARAM(lParam);
|
2012-08-09 14:35:28 +03:00
|
|
|
}
|
2011-09-11 19:12:07 +03:00
|
|
|
break;
|
2010-12-11 14:45:09 +02:00
|
|
|
|
2018-11-15 09:45:24 +01:00
|
|
|
case WM_PARENTNOTIFY:
|
|
|
|
{
|
2019-08-10 18:53:37 +02:00
|
|
|
if (!ddraw->handlemouse)
|
|
|
|
{
|
|
|
|
switch (LOWORD(wParam))
|
|
|
|
{
|
|
|
|
case WM_DESTROY: //Workaround for invisible menu on Load/Save/Delete in Tiberian Sun
|
|
|
|
redrawCount = 2;
|
|
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
|
|
case WM_MBUTTONDOWN:
|
|
|
|
case WM_RBUTTONDOWN:
|
|
|
|
case WM_XBUTTONDOWN:
|
|
|
|
{
|
|
|
|
if (!ddraw->devmode && !ddraw->locked)
|
|
|
|
{
|
|
|
|
int x = GET_X_LPARAM(lParam);
|
|
|
|
int y = GET_Y_LPARAM(lParam);
|
|
|
|
|
|
|
|
ddraw->cursor.x = (x - ddraw->render.viewport.x) * ddraw->render.unScaleW;
|
|
|
|
ddraw->cursor.y = (y - ddraw->render.viewport.y) * ddraw->render.unScaleH;
|
|
|
|
|
2019-08-11 11:06:30 +02:00
|
|
|
ddraw->hidecursor = FALSE;
|
2019-08-10 18:53:37 +02:00
|
|
|
mouse_lock();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-11-15 09:45:24 +01:00
|
|
|
break;
|
|
|
|
}
|
2017-11-15 18:42:42 +01:00
|
|
|
case WM_PAINT:
|
2018-11-15 09:45:24 +01:00
|
|
|
{
|
2018-11-16 08:58:39 +01:00
|
|
|
if (!ddraw->handlemouse && redrawCount > 0)
|
2018-11-15 09:45:24 +01:00
|
|
|
{
|
|
|
|
redrawCount--;
|
|
|
|
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
|
|
|
|
}
|
|
|
|
|
2017-11-15 18:42:42 +01:00
|
|
|
EnterCriticalSection(&ddraw->cs);
|
|
|
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
|
|
|
LeaveCriticalSection(&ddraw->cs);
|
|
|
|
break;
|
2018-11-15 09:45:24 +01:00
|
|
|
}
|
2017-11-15 18:42:42 +01:00
|
|
|
case WM_ERASEBKGND:
|
2018-11-15 09:45:24 +01:00
|
|
|
{
|
2017-11-15 18:42:42 +01:00
|
|
|
EnterCriticalSection(&ddraw->cs);
|
2018-11-15 09:45:24 +01:00
|
|
|
FillRect(ddraw->render.hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
2017-11-15 18:42:42 +01:00
|
|
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
|
|
|
LeaveCriticalSection(&ddraw->cs);
|
|
|
|
break;
|
2018-11-15 09:45:24 +01:00
|
|
|
}
|
2010-10-24 01:02:08 +03:00
|
|
|
}
|
|
|
|
|
2011-09-11 19:12:07 +03:00
|
|
|
return ddraw->WndProc(hWnd, uMsg, wParam, lParam);
|
2010-10-24 01:02:08 +03:00
|
|
|
}
|
|
|
|
|
2010-10-23 17:04:01 +03:00
|
|
|
HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DWORD dwFlags)
|
2010-10-10 19:41:47 +03:00
|
|
|
{
|
2010-11-16 18:07:59 +02:00
|
|
|
PIXELFORMATDESCRIPTOR pfd;
|
|
|
|
|
2010-10-10 19:41:47 +03:00
|
|
|
printf("DirectDraw::SetCooperativeLevel(This=%p, hWnd=0x%08X, dwFlags=0x%08X)\n", This, (unsigned int)hWnd, (unsigned int)dwFlags);
|
2010-10-17 14:19:48 +03:00
|
|
|
|
2010-10-23 00:15:11 +03:00
|
|
|
/* Red Alert for some weird reason does this on Windows XP */
|
|
|
|
if(hWnd == NULL)
|
|
|
|
{
|
2018-10-30 17:54:14 +01:00
|
|
|
return DD_OK;
|
2010-10-23 00:15:11 +03:00
|
|
|
}
|
|
|
|
|
2011-08-22 17:40:21 +03:00
|
|
|
if (This->hWnd == NULL)
|
|
|
|
{
|
|
|
|
This->hWnd = hWnd;
|
|
|
|
}
|
2010-10-17 14:19:48 +03:00
|
|
|
|
2018-10-29 05:47:01 +01:00
|
|
|
if (!This->WndProc)
|
|
|
|
{
|
2019-03-19 06:57:49 +01:00
|
|
|
Hook_Init();
|
2010-10-27 20:13:32 +03:00
|
|
|
|
2018-10-29 05:47:01 +01:00
|
|
|
This->WndProc = (LRESULT(CALLBACK *)(HWND, UINT, WPARAM, LPARAM))GetWindowLong(hWnd, GWL_WNDPROC);
|
2011-08-21 10:34:42 +03:00
|
|
|
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowLongA(This->hWnd, GWL_WNDPROC, (LONG)WndProc);
|
2010-10-23 00:15:11 +03:00
|
|
|
|
2018-10-29 05:47:01 +01:00
|
|
|
if (!This->render.hDC)
|
|
|
|
{
|
|
|
|
This->render.hDC = GetDC(This->hWnd);
|
|
|
|
|
|
|
|
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
|
|
|
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
|
|
|
pfd.nVersion = 1;
|
|
|
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | (This->renderer == render_main ? PFD_SUPPORT_OPENGL : 0);
|
|
|
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
|
|
pfd.cColorBits = ddraw->render.bpp ? ddraw->render.bpp : ddraw->mode.dmBitsPerPel;
|
|
|
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
|
|
SetPixelFormat(This->render.hDC, ChoosePixelFormat(This->render.hDC, &pfd), &pfd);
|
|
|
|
}
|
2010-11-16 18:07:59 +02:00
|
|
|
|
2018-12-01 02:02:55 +01:00
|
|
|
if (ddraw->handlemouse && ddraw->windowed)
|
|
|
|
{
|
2019-03-19 06:57:49 +01:00
|
|
|
while (real_ShowCursor(FALSE) > 0); //workaround for direct input games
|
|
|
|
while (real_ShowCursor(TRUE) < 0);
|
2018-12-01 02:02:55 +01:00
|
|
|
}
|
|
|
|
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetCursor(LoadCursor(NULL, IDC_ARROW));
|
2011-07-09 18:29:58 +03:00
|
|
|
|
2018-10-29 05:47:01 +01:00
|
|
|
GetWindowText(This->hWnd, (LPTSTR)&This->title, sizeof(This->title));
|
2010-11-21 17:11:47 +02:00
|
|
|
|
2018-10-29 05:47:01 +01:00
|
|
|
ddraw->isredalert = strcmp(This->title, "Red Alert") == 0;
|
|
|
|
ddraw->iscnc1 = strcmp(This->title, "Command & Conquer") == 0;
|
|
|
|
|
|
|
|
if (This->vhack && !ddraw->isredalert && !ddraw->iscnc1)
|
|
|
|
This->vhack = 0;
|
|
|
|
}
|
2011-03-24 19:41:36 +02:00
|
|
|
|
2010-10-10 19:41:47 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2010-10-23 19:25:02 +03:00
|
|
|
HRESULT __stdcall ddraw_WaitForVerticalBlank(IDirectDrawImpl *This, DWORD a, HANDLE b)
|
|
|
|
{
|
2017-11-26 09:09:38 +01:00
|
|
|
#if _DEBUG_X
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDraw::WaitForVerticalBlank(This=%p, ...)\n", This);
|
2010-10-23 19:54:45 +03:00
|
|
|
#endif
|
2010-10-23 19:25:02 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2019-08-30 05:37:29 +02:00
|
|
|
HRESULT __stdcall ddraw_GetAvailableVidMem(IDirectDrawImpl *This, LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree)
|
|
|
|
{
|
|
|
|
printf("??? DirectDraw::GetAvailableVidMem(This=%p)\n", This);
|
|
|
|
|
|
|
|
*lpdwTotal = 16777216;
|
|
|
|
*lpdwFree = 16777216;
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2018-11-02 03:20:36 +01:00
|
|
|
ULONG __stdcall ddraw_AddRef(IDirectDrawImpl *This)
|
|
|
|
{
|
|
|
|
printf("DirectDraw::AddRef(This=%p)\n", This);
|
|
|
|
|
|
|
|
This->Ref++;
|
|
|
|
|
|
|
|
return This->Ref;
|
|
|
|
}
|
|
|
|
|
2010-10-23 17:04:01 +03:00
|
|
|
HRESULT __stdcall ddraw_QueryInterface(IDirectDrawImpl *This, REFIID riid, void **obj)
|
2010-10-10 19:41:47 +03:00
|
|
|
{
|
2010-10-17 21:38:40 +03:00
|
|
|
printf("DirectDraw::QueryInterface(This=%p, riid=%08X, obj=%p)\n", This, (unsigned int)riid, obj);
|
2011-07-01 10:55:10 +03:00
|
|
|
|
2018-11-02 02:21:16 +01:00
|
|
|
if (riid && !IsEqualGUID(&IID_IDirectDraw, riid))
|
2018-11-02 03:20:36 +01:00
|
|
|
{
|
2019-04-14 07:52:40 +02:00
|
|
|
printf(" GUID = %08X\n", ((GUID *)riid)->Data1);
|
2018-11-02 03:20:36 +01:00
|
|
|
|
|
|
|
ddraw_AddRef(This);
|
2018-11-18 07:06:13 +01:00
|
|
|
*obj = This;
|
2018-11-18 13:11:05 +01:00
|
|
|
|
|
|
|
if (!IsEqualGUID(&IID_IMediaStream, riid) && !IsEqualGUID(&IID_IAMMediaStream, riid))
|
|
|
|
This->lpVtbl->SetDisplayMode2 = ddraw_SetDisplayMode2;
|
|
|
|
|
2018-11-18 07:06:13 +01:00
|
|
|
return S_OK;
|
2018-11-02 03:20:36 +01:00
|
|
|
}
|
2018-11-02 02:21:16 +01:00
|
|
|
|
2011-07-01 10:55:10 +03:00
|
|
|
*obj = This;
|
|
|
|
|
2018-11-18 07:06:13 +01:00
|
|
|
return DDERR_UNSUPPORTED;
|
2010-10-10 19:41:47 +03:00
|
|
|
}
|
|
|
|
|
2010-10-23 17:04:01 +03:00
|
|
|
ULONG __stdcall ddraw_Release(IDirectDrawImpl *This)
|
2010-10-10 19:41:47 +03:00
|
|
|
{
|
2010-10-17 21:38:40 +03:00
|
|
|
printf("DirectDraw::Release(This=%p)\n", This);
|
|
|
|
|
|
|
|
This->Ref--;
|
2010-10-10 19:41:47 +03:00
|
|
|
|
2010-10-17 21:38:40 +03:00
|
|
|
if(This->Ref == 0)
|
2010-10-10 19:41:47 +03:00
|
|
|
{
|
2018-11-19 07:40:07 +01:00
|
|
|
printf(" Released (%p)\n", This);
|
|
|
|
|
2018-11-26 12:11:23 +01:00
|
|
|
if (This->bpp)
|
|
|
|
Settings_Save(&WindowRect, WindowState);
|
|
|
|
|
2017-11-17 23:08:13 +01:00
|
|
|
if(This->render.run)
|
2017-11-15 18:42:42 +01:00
|
|
|
{
|
|
|
|
EnterCriticalSection(&This->cs);
|
2017-11-17 23:08:13 +01:00
|
|
|
This->render.run = FALSE;
|
|
|
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
2017-11-15 18:42:42 +01:00
|
|
|
LeaveCriticalSection(&This->cs);
|
2017-11-17 23:08:13 +01:00
|
|
|
|
2018-10-27 02:28:07 +02:00
|
|
|
if (This->render.thread)
|
|
|
|
{
|
|
|
|
WaitForSingleObject(This->render.thread, INFINITE);
|
|
|
|
This->render.thread = NULL;
|
|
|
|
}
|
2018-10-15 00:01:31 +02:00
|
|
|
|
|
|
|
if (This->renderer == render_d3d9_main)
|
2020-09-24 10:29:18 +02:00
|
|
|
{
|
2018-10-15 00:57:05 +02:00
|
|
|
Direct3D9_Release();
|
2020-09-24 10:29:18 +02:00
|
|
|
}
|
|
|
|
else if (!ddraw->windowed)
|
|
|
|
{
|
2020-09-30 09:50:52 +02:00
|
|
|
ChangeDisplaySettings(NULL, 0);
|
2020-09-24 10:29:18 +02:00
|
|
|
}
|
2017-11-15 18:42:42 +01:00
|
|
|
}
|
2011-08-28 13:56:10 +03:00
|
|
|
|
2010-11-16 18:07:59 +02:00
|
|
|
if(This->render.hDC)
|
|
|
|
{
|
|
|
|
ReleaseDC(This->hWnd, This->render.hDC);
|
|
|
|
This->render.hDC = NULL;
|
|
|
|
}
|
|
|
|
|
2018-11-29 17:45:10 +01:00
|
|
|
if (This->ticksLimiter.hTimer)
|
|
|
|
{
|
|
|
|
CancelWaitableTimer(This->ticksLimiter.hTimer);
|
|
|
|
CloseHandle(This->ticksLimiter.hTimer);
|
|
|
|
This->ticksLimiter.hTimer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (This->flipLimiter.hTimer)
|
|
|
|
{
|
|
|
|
CancelWaitableTimer(This->flipLimiter.hTimer);
|
|
|
|
CloseHandle(This->flipLimiter.hTimer);
|
|
|
|
This->flipLimiter.hTimer = NULL;
|
|
|
|
}
|
|
|
|
|
2018-11-29 21:26:43 +01:00
|
|
|
if (This->fpsLimiter.hTimer)
|
|
|
|
{
|
|
|
|
CancelWaitableTimer(This->fpsLimiter.hTimer);
|
|
|
|
CloseHandle(This->fpsLimiter.hTimer);
|
|
|
|
This->fpsLimiter.hTimer = NULL;
|
|
|
|
}
|
|
|
|
|
2010-11-15 22:25:12 +02:00
|
|
|
DeleteCriticalSection(&This->cs);
|
|
|
|
|
2010-11-08 21:42:23 +02:00
|
|
|
/* restore old wndproc, subsequent ddraw creation will otherwise fail */
|
2019-03-19 06:57:49 +01:00
|
|
|
real_SetWindowLongA(This->hWnd, GWL_WNDPROC, (LONG)This->WndProc);
|
2010-11-18 16:47:25 +02:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
2010-10-24 01:02:08 +03:00
|
|
|
ddraw = NULL;
|
2010-10-10 19:41:47 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2020-09-26 15:04:27 +02:00
|
|
|
else
|
|
|
|
{
|
2020-09-27 13:38:41 +02:00
|
|
|
if (!This->tm2hack)
|
|
|
|
This->lpVtbl->SetDisplayMode1 = ddraw_SetDisplayMode;
|
2020-09-26 15:04:27 +02:00
|
|
|
}
|
2010-10-10 19:41:47 +03:00
|
|
|
|
2020-09-27 13:38:41 +02:00
|
|
|
if (This->tm2hack)
|
2020-09-23 04:37:28 +02:00
|
|
|
return 0;
|
|
|
|
|
2010-10-17 21:38:40 +03:00
|
|
|
return This->Ref;
|
2010-10-10 19:41:47 +03:00
|
|
|
}
|
|
|
|
|
2010-10-23 17:04:01 +03:00
|
|
|
struct IDirectDrawImplVtbl iface =
|
2010-10-10 19:41:47 +03:00
|
|
|
{
|
|
|
|
/* IUnknown */
|
2010-10-17 21:38:40 +03:00
|
|
|
ddraw_QueryInterface,
|
|
|
|
ddraw_AddRef,
|
|
|
|
ddraw_Release,
|
2010-10-23 17:04:01 +03:00
|
|
|
/* IDirectDrawImpl */
|
2010-10-23 19:25:02 +03:00
|
|
|
ddraw_Compact,
|
2010-10-20 18:45:27 +03:00
|
|
|
ddraw_CreateClipper,
|
2010-10-10 19:41:47 +03:00
|
|
|
ddraw_CreatePalette,
|
|
|
|
ddraw_CreateSurface,
|
2010-10-23 19:25:02 +03:00
|
|
|
ddraw_DuplicateSurface,
|
|
|
|
ddraw_EnumDisplayModes,
|
|
|
|
ddraw_EnumSurfaces,
|
|
|
|
ddraw_FlipToGDISurface,
|
2010-10-16 23:22:43 +03:00
|
|
|
ddraw_GetCaps,
|
2010-10-23 19:25:02 +03:00
|
|
|
ddraw_GetDisplayMode,
|
|
|
|
ddraw_GetFourCCCodes,
|
|
|
|
ddraw_GetGDISurface,
|
|
|
|
ddraw_GetMonitorFrequency,
|
|
|
|
ddraw_GetScanLine,
|
|
|
|
ddraw_GetVerticalBlankStatus,
|
|
|
|
ddraw_Initialize,
|
2010-10-17 21:38:40 +03:00
|
|
|
ddraw_RestoreDisplayMode,
|
2010-10-10 19:41:47 +03:00
|
|
|
ddraw_SetCooperativeLevel,
|
|
|
|
ddraw_SetDisplayMode,
|
2019-08-30 05:37:29 +02:00
|
|
|
ddraw_WaitForVerticalBlank,
|
|
|
|
ddraw_GetAvailableVidMem
|
2010-10-10 19:41:47 +03:00
|
|
|
};
|
|
|
|
|
2020-07-23 22:45:46 +02:00
|
|
|
HRESULT WINAPI DirectDrawCreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, IUnknown FAR *pUnkOuter)
|
|
|
|
{
|
|
|
|
return ddraw_CreateClipper(NULL, dwFlags, lplpDDClipper, pUnkOuter);
|
|
|
|
}
|
|
|
|
|
2017-11-14 20:13:55 +01:00
|
|
|
HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACK lpCallback, LPVOID lpContext)
|
|
|
|
{
|
2019-04-14 08:22:00 +02:00
|
|
|
printf("??? DirectDrawEnumerateA(lpCallback=%p, lpContext=%p)\n", lpCallback, lpContext);
|
2018-10-30 19:38:32 +01:00
|
|
|
|
|
|
|
if (lpCallback)
|
|
|
|
lpCallback(NULL, "display", "(null)", lpContext);
|
|
|
|
|
2017-11-14 20:13:55 +01:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2010-10-23 00:15:11 +03:00
|
|
|
int stdout_open = 0;
|
2010-10-10 19:41:47 +03:00
|
|
|
HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter)
|
|
|
|
{
|
2010-10-20 18:45:27 +03:00
|
|
|
#if _DEBUG
|
2010-10-23 00:15:11 +03:00
|
|
|
if(!stdout_open)
|
|
|
|
{
|
2019-04-14 07:28:06 +02:00
|
|
|
freopen("cnc-ddraw.log", "w", stdout);
|
2018-05-06 10:52:06 +02:00
|
|
|
setvbuf(stdout, NULL, _IOLBF, 1024);
|
2010-10-23 00:15:11 +03:00
|
|
|
stdout_open = 1;
|
2020-01-15 00:48:39 +01:00
|
|
|
|
|
|
|
HKEY hKey;
|
|
|
|
LONG status =
|
|
|
|
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0L, KEY_READ, &hKey);
|
|
|
|
|
|
|
|
if (status == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
char name[256] = {0};
|
|
|
|
DWORD nameSize = sizeof(name);
|
|
|
|
RegQueryValueExA(hKey, "ProductName", NULL, NULL, (PVOID)&name, &nameSize);
|
|
|
|
|
|
|
|
char build[256] = {0};
|
|
|
|
DWORD buildSize = sizeof(build);
|
|
|
|
RegQueryValueExA(hKey, "BuildLab", NULL, NULL, (PVOID)&build, &buildSize);
|
|
|
|
|
|
|
|
printf("%s (%s)\n", name, build);
|
|
|
|
}
|
2010-10-23 00:15:11 +03:00
|
|
|
}
|
2010-10-20 18:45:27 +03:00
|
|
|
#endif
|
|
|
|
|
2010-10-24 19:47:51 +03:00
|
|
|
printf("DirectDrawCreate(lpGUID=%p, lplpDD=%p, pUnkOuter=%p)\n", lpGUID, lplpDD, pUnkOuter);
|
|
|
|
|
2010-10-24 01:02:08 +03:00
|
|
|
if(ddraw)
|
|
|
|
{
|
2010-11-06 21:42:37 +02:00
|
|
|
/* FIXME: check the calling module before passing the call! */
|
2018-11-13 07:29:48 +01:00
|
|
|
if (ddraw->DirectDrawCreate)
|
|
|
|
return ddraw->DirectDrawCreate(lpGUID, lplpDD, pUnkOuter);
|
2010-11-06 21:42:37 +02:00
|
|
|
|
2010-10-24 01:02:08 +03:00
|
|
|
return DDERR_DIRECTDRAWALREADYCREATED;
|
2010-11-06 21:42:37 +02:00
|
|
|
}
|
|
|
|
|
2010-10-24 01:02:08 +03:00
|
|
|
IDirectDrawImpl *This = (IDirectDrawImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
|
2010-10-23 17:04:01 +03:00
|
|
|
This->lpVtbl = &iface;
|
2010-10-10 19:41:47 +03:00
|
|
|
printf(" This = %p\n", This);
|
|
|
|
*lplpDD = (LPDIRECTDRAW)This;
|
2010-11-23 17:36:12 +02:00
|
|
|
This->Ref = 0;
|
|
|
|
ddraw_AddRef(This);
|
|
|
|
|
2010-10-24 01:02:08 +03:00
|
|
|
ddraw = This;
|
2010-10-27 20:13:32 +03:00
|
|
|
|
2018-10-24 04:21:22 +02:00
|
|
|
if (!This->real_dll)
|
|
|
|
This->real_dll = LoadLibrary("system32\\ddraw.dll");
|
|
|
|
|
2018-11-13 07:29:48 +01:00
|
|
|
if(This->real_dll && !This->DirectDrawCreate)
|
2010-11-23 17:36:12 +02:00
|
|
|
{
|
2018-11-13 07:29:48 +01:00
|
|
|
This->DirectDrawCreate =
|
|
|
|
(HRESULT(WINAPI *)(GUID FAR*, LPDIRECTDRAW FAR*, IUnknown FAR*))GetProcAddress(This->real_dll, "DirectDrawCreate");
|
2019-05-09 10:25:00 +02:00
|
|
|
|
|
|
|
if (This->DirectDrawCreate == DirectDrawCreate)
|
|
|
|
This->DirectDrawCreate = NULL;
|
2010-11-06 21:42:37 +02:00
|
|
|
}
|
|
|
|
|
2010-11-15 22:25:12 +02:00
|
|
|
InitializeCriticalSection(&This->cs);
|
2017-11-15 18:42:42 +01:00
|
|
|
This->render.sem = CreateSemaphore(NULL, 0, 1, NULL);
|
2010-11-15 22:25:12 +02:00
|
|
|
|
2018-08-09 11:19:36 +02:00
|
|
|
This->wine = GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0;
|
|
|
|
|
2018-10-25 07:03:01 +02:00
|
|
|
Settings_Load();
|
2012-12-31 22:52:44 +01:00
|
|
|
|
2010-10-10 19:41:47 +03:00
|
|
|
return DD_OK;
|
|
|
|
}
|