diff --git a/README.md b/README.md
index 94b6d39..7485601 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Another War
- Anstoss 3
- Arcanum: Of Steamworks and Magick Obscura
+- Arcatera the Dark Brotherhood
- Army Men 2
- Army Men: Air Tactics
- Army Men: Toys in Space
@@ -96,6 +97,8 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Blood II - The Chosen
- Blue's 123 Time Activities
- Blue's Treasure Hunt
+- Broken Sword
+- Broken Sword 2: The Smoking Mirror
- Caesar III (Sierra - 1998)
- Call To Power 2
- Callus 95 - CPS-1 (Capcom Play System 1) emulator
@@ -131,6 +134,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Commandos
- Commandos - Beyond The Call Of Duty
- Commandos 2
+- Commando 2004 (only with /ddraw command line parameter)
- Constructor
- Corsairs Gold
- Cossacks (Steam+GOG)
@@ -140,8 +144,10 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Cyberchase Carnival Chaos
- Cyberchase Castleblanca Quest
- Cydonia Mars - The First Manned Mission
+- Cloud Kingdom 3 (only with /ddraw command line parameter)
- Dark Earth
- Dark Reign: The Future of War
+- Dark Secret of Africa
- Day Of The Tentacle
- Daytona
- Daytona USA (Sega - 1996)
@@ -160,6 +166,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Divine Divinity
- Dominion - Storm Over Gift 3
- Doom 95
+- Dracula
- Dragon Throne: Battle of Red Cliffs
- Dreams to Realty
- DuelSavior
@@ -196,6 +203,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Full Throttle
- Future Cop L.A.P.D
- G-Police
+- Gateway (Remake)
- Geneforge
- Gilbert Goodmate And The Mushroom Of Phungoria
- Gorasul: The Legacy of the Dragon
@@ -264,6 +272,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Majesty Gold
- Majesty Gold HD
- Mario Sorb 3
+- Meat Puppet
- Mech Warrior 3
- Megaman X4
- Metal Gear Solid
@@ -275,6 +284,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Moorhuhn Adventure: Schatz des Pharao and Fluch des Goldes)
- Moorhuhn Winter Editon
- MiG-29 Fulcrum
+- Mission Deliver Kindness
- Moto Racer
- Moto Racer 2
- Nancy Drew: Danger on Deception Island
@@ -374,6 +384,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Silver (needs "SilverUK GeForce2 And Radeon Patch")
- Sim City 3000
- Sim Copter
+- SimTunes
- Sim Theme Park (aka Theme Park World)
- SimCoaster / Theme Park Inc
- Simon the Sorcerer 1/2 (windows 95 version)
@@ -413,6 +424,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Sudden Strike 2
- Superbike 2000
- Swarog
+- The Jungle Book Groove Party
- The Curse Of Monkey Island
- The Dig
- The Last Express
@@ -447,6 +459,7 @@ Wine (Linux/macOS/Android) only: override `ddraw` in [winecfg](https://wiki.wine
- Virtua Fighter 2
- Virtua Fighter PC
- Virtual Springfield
+- Virtual On: Cyber Troopers
- WarGames
- War Wind
- War Wind II - Human Onslaught
diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj
index a4d025d..3f5d12d 100644
--- a/cnc-ddraw.vcxproj
+++ b/cnc-ddraw.vcxproj
@@ -27,6 +27,7 @@
+
@@ -80,6 +81,7 @@
+
diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters
index 0f07cb0..b15230e 100644
--- a/cnc-ddraw.vcxproj.filters
+++ b/cnc-ddraw.vcxproj.filters
@@ -168,6 +168,9 @@
Source Files
+
+ Source Files
+
@@ -299,6 +302,9 @@
Header Files
+
+ Header Files
+
diff --git a/config/ConfigFormUnit.cpp b/config/ConfigFormUnit.cpp
index 02723d7..7d40a88 100644
--- a/config/ConfigFormUnit.cpp
+++ b/config/ConfigFormUnit.cpp
@@ -9,7 +9,6 @@
#include
#include
#include
-#include
#include "ConfigFormUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
@@ -132,31 +131,31 @@ void TConfigForm::ApplyTranslation(TIniFile *ini)
ConfigForm->Caption = L"cnc-ddraw 配置";
DisplayBtn->Caption = L"显示设置";
AdvancedBtn->Caption = L"高级设置";
- HotkeyBtn->Caption = L"热键设置";
+ HotkeyBtn->Caption = L"快捷键设置";
CompatibilityBtn->Caption = L"兼容性设置";
RestoreDefaultsBtn->Caption = L"恢复默认设置";
PresentationLbl->Caption = L"显示方式";
- MaintasLbl->Caption = L"保持纵横比";
- VsyncLbl->Caption = L"打开垂直同步";
+ MaintasLbl->Caption = L"保持宽高比";
+ VsyncLbl->Caption = L"启用垂直同步";
AdjmouseLbl->Caption = L"调整鼠标灵敏度";
- DevmodeLbl->Caption = L"锁定光标到窗口/屏幕";
+ DevmodeLbl->Caption = L"将光标锁定到窗口/屏幕";
RendererLbl->Caption = L"渲染器";
BorderLbl->Caption = L"在窗口模式下显示窗口边框";
SavesettingsLbl->Caption = L"记住窗口位置和大小";
- ShaderLbl->Caption = L"OpenGL着色器";
- MaxfpsLbl->Caption = L"限制帧率";
- BoxingLbl->Caption = L"打开窗盒显示/整数缩放";
+ ShaderLbl->Caption = L"OpenGL 着色器";
+ MaxfpsLbl->Caption = L"限制帧速率";
+ BoxingLbl->Caption = L"启用整数缩放";
ToggleWindowedLbl->Caption = L"切换窗口模式";
MaximizeWindowLbl->Caption = L"最大化窗口";
UnlockCursor1Lbl->Caption = L"解锁光标 1";
UnlockCursor2Lbl->Caption = L"解锁光标 2";
- ScreenshotLbl->Caption = L"截屏";
- MaxgameticksLbl->Caption = L"限制游戏速率";
+ ScreenshotLbl->Caption = L"截图";
+ MaxgameticksLbl->Caption = L"限制游戏速度";
NoactivateappLbl->Caption = L"修复损坏的Alt+Tab功能";
- ResolutionsLbl->Caption = L"解锁其他屏幕分辨率";
- MinfpsLbl->Caption = L"强制高FPS / 修复使用Freesync/G-Sync的卡顿问题";
- SinglecpuLbl->Caption = L"修复性能不佳和声音问题";
- NonexclusiveLbl->Caption = L"修复不显示的视频/UI元素";
+ ResolutionsLbl->Caption = L"解锁额外的屏幕分辨率";
+ MinfpsLbl->Caption = L"强制高 FPS / 修复 Freesync/G-Sync 卡顿";
+ SinglecpuLbl->Caption = L"修复低性能和声音问题";
+ NonexclusiveLbl->Caption = L"修复不显示的视频/UI 元素";
RendererCbx->Items->Clear();
RendererCbx->AddItem(L"自动", NULL);
@@ -173,25 +172,26 @@ void TConfigForm::ApplyTranslation(TIniFile *ini)
MaxgameticksCbx->Items->Clear();
MaxgameticksCbx->AddItem(L"无限制", NULL);
MaxgameticksCbx->AddItem(L"与显示器刷新率同步", NULL);
- MaxgameticksCbx->AddItem(L"模拟60hz刷新率显示器", NULL);
- MaxgameticksCbx->AddItem(L"1000tick每秒", NULL);
- MaxgameticksCbx->AddItem(L"500tick每秒", NULL);
- MaxgameticksCbx->AddItem(L"250tick每秒", NULL);
- MaxgameticksCbx->AddItem(L"125tick每秒", NULL);
- MaxgameticksCbx->AddItem(L"60tick每秒", NULL);
- MaxgameticksCbx->AddItem(L"30tick每秒", NULL);
- MaxgameticksCbx->AddItem(L"25tick每秒", NULL);
- MaxgameticksCbx->AddItem(L"15tick每秒", NULL);
+ MaxgameticksCbx->AddItem(L"模拟 60hz 刷新率显示器", NULL);
+ MaxgameticksCbx->AddItem(L"1000 次每秒", NULL);
+ MaxgameticksCbx->AddItem(L"500 次每秒", NULL);
+ MaxgameticksCbx->AddItem(L"250 次每秒", NULL);
+ MaxgameticksCbx->AddItem(L"125 次每秒", NULL);
+ MaxgameticksCbx->AddItem(L"60 次每秒", NULL);
+ MaxgameticksCbx->AddItem(L"30 次每秒", NULL);
+ MaxgameticksCbx->AddItem(L"25 次每秒", NULL);
+ MaxgameticksCbx->AddItem(L"15 次每秒", NULL);
System::UnicodeString shaderHint =
- L"某些着色器仅在打开放大功能时生效。\n\n";
+ L"一些着色器只有在启用放大时才有效。\n\n";
System::UnicodeString upscaleHint =
- L"必须打开放大功能才能使此设置生效。\n\n";
+ L"必须启用放大才能使此设置生效。\n\n";
System::UnicodeString enableUpscaleHint =
- L"要打开放大功能,请将显示方式设置为‘无边框’或‘拉伸至全屏’。\n"
- "对于‘窗口化’显示方式,您必须调整窗口大小或最大化窗口。";
+ L"要启用放大,请将显示方式设置为“无边框” \n"
+ "或“拉伸至全屏”。对于“窗口化”, \n"
+ "你必须调整窗口大小或将窗口开启最大化。";
ShaderLbl->Hint = shaderHint + enableUpscaleHint;
ShaderD3DCbx->Hint = shaderHint + enableUpscaleHint;
@@ -773,6 +773,87 @@ void TConfigForm::ApplyTranslation(TIniFile *ini)
BoxingLbl->Hint = upscaleHint + enableUpscaleHint;
BoxingChk->Hint = upscaleHint + enableUpscaleHint;
}
+ else if (lang == "polish" || (lang == "auto" && priID == LANG_POLISH)) {
+ LanguageImg->Visible = true;
+
+ /* -polish - made by WaRzillA @ github */
+
+ ConfigForm->Caption = L"Konfiguracja cnc-ddraw";
+ DisplayBtn->Caption = L"Ustawienia wyświetlania";
+ AdvancedBtn->Caption = L"Ustawienia zaawansowane";
+ HotkeyBtn->Caption = L"Skróty klawiaturowe";
+ CompatibilityBtn->Caption = L"Ustawienia kompatybilności";
+ RestoreDefaultsBtn->Caption = L"Przywróć ustawienia domyślne";
+ PresentationLbl->Caption = L"Tryb wyświetlania";
+ MaintasLbl->Caption = L"Zachowaj proporcje obrazu";
+ VsyncLbl->Caption = L"Włącz VSync";
+ AdjmouseLbl->Caption = L"Dostosuj czułość myszy";
+ DevmodeLbl->Caption = L"Zablokuj kursor w oknie/na ekranie";
+ RendererLbl->Caption = L"Silnik renderowania";
+ BorderLbl->Caption = L"Pokaż ramki okna w trybie okienkowym";
+ SavesettingsLbl->Caption = L"Zapamiętaj pozycję i rozmiar okna";
+ ShaderLbl->Caption = L"Shader OpenGL";
+ MaxfpsLbl->Caption = L"Ogranicz liczbę klatek na sekundę";
+ BoxingLbl->Caption = L"Włącz windowboxing / integer scaling ";
+ ToggleWindowedLbl->Caption = L"Przełącz na tryb okienkowy";
+ MaximizeWindowLbl->Caption = L"Maksymalizuj okno";
+ UnlockCursor1Lbl->Caption = L"Odblokuj kursor 1";
+ UnlockCursor2Lbl->Caption = L"Odblokuj kursor 2";
+ ScreenshotLbl->Caption = L"Zrzut ekranu";
+ MaxgameticksLbl->Caption = L"Ogranicz prędkość gry";
+ NoactivateappLbl->Caption = L"Napraw nieprawidłowe działanie Alt+Tab";
+ ResolutionsLbl->Caption = L"Odblokuj dodatkowe rozdzielczości ekranu";
+ MinfpsLbl->Caption = L"Wymuś wysokie FPS / Napraw zacinanie Freesync/G-Sync";
+ SinglecpuLbl->Caption = L"Napraw problemy z wydajnością i dźwiękiem";
+ NonexclusiveLbl->Caption = L"Napraw niewidoczne filmy / elementy interfejsu";
+
+ RendererCbx->Items->Clear();
+ RendererCbx->AddItem(L"Automatyczny", NULL);
+ RendererCbx->AddItem(L"Direct3D 9", NULL);
+ RendererCbx->AddItem(L"OpenGL", NULL);
+ RendererCbx->AddItem(L"GDI", NULL);
+
+ PresentationCbx->Items->Clear();
+ PresentationCbx->AddItem(L"Pełny ekran", NULL);
+ PresentationCbx->AddItem(L"Pełny ekran z upscalingiem", NULL);
+ PresentationCbx->AddItem(L"Tryb bezramkowy", NULL);
+ PresentationCbx->AddItem(L"Tryb okienkowy", NULL);
+
+ MaxgameticksCbx->Items->Clear();
+ MaxgameticksCbx->AddItem(L"Bez limitu", NULL);
+ MaxgameticksCbx->AddItem(L"Synchronizacja z odświeżaniem monitora", NULL);
+ MaxgameticksCbx->AddItem(L"Symulacja monitora 60 Hz", NULL);
+ MaxgameticksCbx->AddItem(L"1000 tików na sekundę", NULL);
+ MaxgameticksCbx->AddItem(L"500 tików na sekundę", NULL);
+ MaxgameticksCbx->AddItem(L"250 tików na sekundę", NULL);
+ MaxgameticksCbx->AddItem(L"125 tików na sekundę", NULL);
+ MaxgameticksCbx->AddItem(L"60 tików na sekundę", NULL);
+ MaxgameticksCbx->AddItem(L"30 tików na sekundę", NULL);
+ MaxgameticksCbx->AddItem(L"25 tików na sekundę", NULL);
+ MaxgameticksCbx->AddItem(L"15 tików na sekundę", NULL);
+
+ System::UnicodeString shaderHint =
+ L"Niektóre shadery działają tylko wtedy, gdy włączone jest skalowanie. \n\n";
+
+ System::UnicodeString upscaleHint =
+ L"Skalowanie musi być włączone, aby ta opcja działała. \n\n";
+
+ System::UnicodeString enableUpscaleHint =
+ L"Aby włączyć skalowanie, ustaw tryb wyświetlania na 'Tryb bezramkowy' \n"
+ "lub 'Pełny ekran z upscalingiem'. Dla 'Tryb okienkowy' \n"
+ "musisz zmienić rozmiar lub zmaksymalizować okno.";
+
+ ShaderLbl->Hint = shaderHint + enableUpscaleHint;
+ ShaderD3DCbx->Hint = shaderHint + enableUpscaleHint;
+ ShaderCbx->Hint = shaderHint + enableUpscaleHint;
+
+ MaintasLbl->Hint = upscaleHint + enableUpscaleHint;
+ MaintasChk->Hint = upscaleHint + enableUpscaleHint;
+ AdjmouseLbl->Hint = upscaleHint + enableUpscaleHint;
+ AdjmouseChk->Hint = upscaleHint + enableUpscaleHint;
+ BoxingLbl->Hint = upscaleHint + enableUpscaleHint;
+ BoxingChk->Hint = upscaleHint + enableUpscaleHint;
+ }
else {
IsEnglish = true;
@@ -825,6 +906,12 @@ void TConfigForm::ApplyTranslation(TIniFile *ini)
LanguageImg->Picture->Graphic = png;
LanguageImg->Visible = true;
}
+ else if (priID == LANG_POLISH) {
+ TPngImage *png = new TPngImage();
+ png->LoadFromResourceName((int)HInstance, "PngImage_PL");
+ LanguageImg->Picture->Graphic = png;
+ LanguageImg->Visible = true;
+ }
} catch (...) {
}
@@ -1198,11 +1285,6 @@ void __fastcall TConfigForm::FormCreate(TObject *Sender)
delete ini;
- VsyncChk->Enabled = VsyncAllowed();
- if (!VsyncChk->Enabled) {
- VsyncChk->State = tssOff;
- }
-
Initialized = true;
}
@@ -1624,31 +1706,8 @@ bool TConfigForm::GetBool(TIniFile *ini, System::UnicodeString key, bool defValu
return s == "true" || s == "yes" || s == "1";
}
-bool TConfigForm::VsyncAllowed()
-{
- if (GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "wine_get_version")) {
- return true;
- }
-
- if (!IsWindows8OrGreater()) {
- return true;
- }
-
- if (NonexclusiveChk->State == tssOff &&
- (PresentationCbx->ItemIndex == 0 || PresentationCbx->ItemIndex == 1)) {
- return true;
- }
-
- return false;
-}
-
void __fastcall TConfigForm::PresentationCbxChange(TObject *Sender)
{
- VsyncChk->Enabled = VsyncAllowed();
- if (!VsyncChk->Enabled) {
- VsyncChk->State = tssOff;
- }
-
SaveSettings();
}
@@ -1757,11 +1816,6 @@ void __fastcall TConfigForm::SinglecpuChkClick(TObject *Sender)
void __fastcall TConfigForm::NonexclusiveChkClick(TObject *Sender)
{
- VsyncChk->Enabled = VsyncAllowed();
- if (!VsyncChk->Enabled) {
- VsyncChk->State = tssOff;
- }
-
SaveSettings();
}
diff --git a/config/ConfigFormUnit.dfm b/config/ConfigFormUnit.dfm
index a34dc9f..4f108df 100644
--- a/config/ConfigFormUnit.dfm
+++ b/config/ConfigFormUnit.dfm
@@ -2677,7 +2677,7 @@ object ConfigForm: TConfigForm
61C0650530766087F0B9DE67A1EF3B173173597F3B695CC608E0B202F8FC22D7
BBBF4CD8CBB88CCBB88CCBB88CCBB88CCBB88CCBB88CCBB88CCBB88CCBB88CCB
B88CB18EFF1FA2974C1C31AF16A40000000049454E44AE426082}
- Position = poDesktopCenter
+ Position = poScreenCenter
OnActivate = FormActivate
OnCreate = FormCreate
DesignSize = (
diff --git a/config/ConfigFormUnit.h b/config/ConfigFormUnit.h
index 8a46bf8..8a8a14c 100644
--- a/config/ConfigFormUnit.h
+++ b/config/ConfigFormUnit.h
@@ -118,7 +118,6 @@ private: // Benutzer-Deklarationen
virtual void __fastcall CreateParams(TCreateParams & Params);
void SaveSettings();
bool GetBool(TIniFile *ini, System::UnicodeString key, bool defValue);
- bool VsyncAllowed();
void ApplyTranslation(TIniFile *ini);
System::UnicodeString GetKeyText(WORD key);
WORD GetKeyCode(System::UnicodeString text);
diff --git a/config/Resources/pl.png b/config/Resources/pl.png
new file mode 100644
index 0000000..d413d01
Binary files /dev/null and b/config/Resources/pl.png differ
diff --git a/config/cnc-ddraw config.cbproj b/config/cnc-ddraw config.cbproj
index b2de346..7792b8b 100644
--- a/config/cnc-ddraw config.cbproj
+++ b/config/cnc-ddraw config.cbproj
@@ -227,6 +227,10 @@
RCDATA
PngImage_IT
+
+ RCDATA
+ PngImage_PL
+
RCDATA
PngImage_RU
@@ -364,7 +368,7 @@
- cnc-ddraw_config.exe
+ cnc-ddraw config.exe
true
@@ -430,6 +434,12 @@
true
+
+
+ .\
+ true
+
+
1
diff --git a/config/cnc-ddraw config_resources.rc b/config/cnc-ddraw config_resources.rc
index 9d29fa1..b077d3a 100644
--- a/config/cnc-ddraw config_resources.rc
+++ b/config/cnc-ddraw config_resources.rc
@@ -4,6 +4,7 @@ PngImage_ES RCDATA "Resources\\ES.png"
PngImage_FR RCDATA "Resources\\fr.png"
PngImage_HU RCDATA "Resources\\hu.png"
PngImage_IT RCDATA "Resources\\IT.png"
+PngImage_PL RCDATA "Resources\\pl.png"
PngImage_RU RCDATA "Resources\\RU.png"
PngImage_US RCDATA "Resources\\US.png"
PngImage_VN RCDATA "Resources\\VN.png"
diff --git a/inc/config.h b/inc/config.h
index d1600d5..e15bece 100644
--- a/inc/config.h
+++ b/inc/config.h
@@ -80,6 +80,7 @@ typedef struct CNCDDRAWCONFIG
BOOL limit_gdi_handles;
BOOL remove_menu;
int refresh_rate;
+ int terminate_process;
/* Hotkeys */
@@ -105,6 +106,7 @@ typedef struct CNCDDRAWCONFIG
BOOL carma95_hack;
BOOL sirtech_hack;
BOOL flightsim98_hack;
+ BOOL darkcolony_hack;
} CNCDDRAWCONFIG;
diff --git a/inc/delay_imports.h b/inc/delay_imports.h
new file mode 100644
index 0000000..ba654ed
--- /dev/null
+++ b/inc/delay_imports.h
@@ -0,0 +1,25 @@
+#ifndef DELAY_IMPORTS_H
+#define DELAY_IMPORTS_H
+
+#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
+#define ThreadQuerySetWin32StartAddress 9
+
+typedef NTSTATUS(WINAPI* RTLVERIFYVERSIONINFOPROC)(PRTL_OSVERSIONINFOEXW, ULONG, ULONGLONG);
+typedef const char* (CDECL* WINE_GET_VERSIONPROC)();
+typedef void (CDECL* WINE_GET_HOST_VERSIONPROC)(const char** sysname, const char** release);
+typedef NTSTATUS(WINAPI* NTQUERYINFORMATIONTHREADPROC)(HANDLE, LONG, PVOID, ULONG, PULONG);
+
+typedef ULONGLONG(WINAPI* VERSETCONDITIONMASKPROC)(ULONGLONG, DWORD, BYTE);
+typedef BOOL(WINAPI* GETMODULEHANDLEEXAPROC)(DWORD, LPCSTR, HMODULE*);
+
+extern NTQUERYINFORMATIONTHREADPROC delay_NtQueryInformationThread;
+extern RTLVERIFYVERSIONINFOPROC delay_RtlVerifyVersionInfo;
+extern WINE_GET_VERSIONPROC delay_wine_get_version;
+extern WINE_GET_HOST_VERSIONPROC delay_wine_get_host_version;
+
+extern VERSETCONDITIONMASKPROC delay_VerSetConditionMask;
+extern GETMODULEHANDLEEXAPROC delay_GetModuleHandleExA;
+
+void delay_imports_init();
+
+#endif
diff --git a/inc/hook.h b/inc/hook.h
index 089f668..23de636 100644
--- a/inc/hook.h
+++ b/inc/hook.h
@@ -18,7 +18,7 @@ typedef struct HOOKLISTDATA {
HMODULE mod;
} HOOKLISTDATA;
-typedef struct HOOKLIST { char module_name[32]; HOOKLISTDATA data[38]; } HOOKLIST;
+typedef struct HOOKLIST { char module_name[32]; HOOKLISTDATA data[39]; } HOOKLIST;
typedef BOOL(WINAPI* GETCURSORPOSPROC)(LPPOINT);
typedef BOOL(WINAPI* CLIPCURSORPROC)(const RECT*);
@@ -64,6 +64,7 @@ typedef BOOL(WINAPI* SETWINDOWPLACEMENTPROC)(HWND, const WINDOWPLACEMENT*);
typedef BOOL(WINAPI* ENUMDISPLAYSETTINGSAPROC)(LPCSTR, DWORD, DEVMODEA*);
typedef LRESULT(WINAPI* DEFWINDOWPROCAPROC)(HWND, UINT, WPARAM, LPARAM);
typedef HWND(WINAPI* SETPARENTPROC)(HWND, HWND);
+typedef HDC (WINAPI* BEGINPAINTPROC)(HWND, LPPAINTSTRUCT);
typedef SHORT(WINAPI* GETKEYSTATEPROC)(int);
typedef SHORT(WINAPI* GETASYNCKEYSTATEPROC)(int);
@@ -127,6 +128,7 @@ extern SETWINDOWPLACEMENTPROC real_SetWindowPlacement;
extern ENUMDISPLAYSETTINGSAPROC real_EnumDisplaySettingsA;
extern DEFWINDOWPROCAPROC real_DefWindowProcA;
extern SETPARENTPROC real_SetParent;
+extern BEGINPAINTPROC real_BeginPaint;
extern GETKEYSTATEPROC real_GetKeyState;
extern GETASYNCKEYSTATEPROC real_GetAsyncKeyState;
extern GETDEVICECAPSPROC real_GetDeviceCaps;
diff --git a/inc/utils.h b/inc/utils.h
index 9f7f0ee..3833ede 100644
--- a/inc/utils.h
+++ b/inc/utils.h
@@ -6,8 +6,9 @@
HMODULE WINAPI util_enumerate_modules(_In_opt_ HMODULE hModuleLast);
+void util_set_process_affinity();
+void util_set_thread_affinity(DWORD tid);
void util_pull_messages();
-unsigned long util_get_crc32(char* filename);
DWORD util_get_timestamp(HMODULE mod);
FARPROC util_get_iat_proc(HMODULE mod, char* module_name, char* function_name);
BOOL util_caller_is_ddraw_wrapper(void* return_address);
diff --git a/inc/version.h b/inc/version.h
index 045beec..29e19fa 100644
--- a/inc/version.h
+++ b/inc/version.h
@@ -7,7 +7,7 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 1
#define VERSION_BUILD 0
-#define VERSION_REVISION 0
+#define VERSION_REVISION 1
#define VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION
#define VERSION_STRING ver_str(VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION)
diff --git a/inc/versionhelpers.h b/inc/versionhelpers.h
index fa542ac..36f2dd6 100644
--- a/inc/versionhelpers.h
+++ b/inc/versionhelpers.h
@@ -33,7 +33,6 @@
#define VerSetConditionMask verhelp_set_mask
#endif
-void verhelp_init();
BOOL verhelp_verify_version(PRTL_OSVERSIONINFOEXW versionInfo, ULONG typeMask, ULONGLONG conditionMask);
ULONGLONG verhelp_set_mask(ULONGLONG ConditionMask, DWORD TypeMask, BYTE Condition);
const char* verhelp_wine_get_version();
@@ -61,6 +60,17 @@ VERSIONHELPERAPI IsWindowsVersion(DWORD major, DWORD minor, DWORD build, WORD se
VER_SERVICEPACKMAJOR, VER_EQUAL));
}
+VERSIONHELPERAPI IsWindowsVersionExcactBuild(DWORD major, DWORD minor, DWORD build, WORD servpack)
+{
+ RTL_OSVERSIONINFOEXW vi = { sizeof(vi),major,minor,build,0,{0},servpack };
+ return verhelp_verify_version(&vi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER | VER_SERVICEPACKMAJOR,
+ VerSetConditionMask(VerSetConditionMask(VerSetConditionMask(VerSetConditionMask(0,
+ VER_MAJORVERSION, VER_EQUAL),
+ VER_MINORVERSION, VER_EQUAL),
+ VER_BUILDNUMBER, VER_EQUAL),
+ VER_SERVICEPACKMAJOR, VER_EQUAL));
+}
+
VERSIONHELPERAPI IsWindowsVersionAnySP(DWORD major, DWORD minor, DWORD build)
{
RTL_OSVERSIONINFOEXW vi = { sizeof(vi),major,minor,build,0,{0},0 };
@@ -136,6 +146,10 @@ VERSIONHELPERAPI IsWindows11OrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN11), LOBYTE(_WIN32_WINNT_WIN11), 22000, 0);
}
+VERSIONHELPERAPI IsWindows11Version24H2OrGreater(void) {
+ return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN11), LOBYTE(_WIN32_WINNT_WIN11), 26100, 0);
+}
+
VERSIONHELPERAPI IsWindowsServer(void) {
OSVERSIONINFOEXW vi = {sizeof(vi),0,0,0,0,{0},0,0,0,VER_NT_WORKSTATION};
return !verhelp_verify_version(&vi, VER_PRODUCT_TYPE, VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL));
@@ -213,6 +227,10 @@ VERSIONHELPERAPI IsWindows11(void) {
return IsWindowsVersion(HIBYTE(_WIN32_WINNT_WIN11), LOBYTE(_WIN32_WINNT_WIN11), 22000, 0);
}
+VERSIONHELPERAPI IsWindows11Version24H2(void) {
+ return IsWindowsVersionExcactBuild(HIBYTE(_WIN32_WINNT_WIN11), LOBYTE(_WIN32_WINNT_WIN11), 26100, 0);
+}
+
VERSIONHELPERAPI IsWine(void) {
return verhelp_wine_get_version() != NULL;
}
diff --git a/inc/winapi_hooks.h b/inc/winapi_hooks.h
index cab3ab6..ad44c7e 100644
--- a/inc/winapi_hooks.h
+++ b/inc/winapi_hooks.h
@@ -39,6 +39,7 @@ BOOL WINAPI fake_SetWindowPlacement(HWND hWnd, const WINDOWPLACEMENT* lpwndpl);
BOOL WINAPI fake_EnumDisplaySettingsA(LPCSTR lpszDeviceName, DWORD iModeNum, DEVMODEA* lpDevMode);
LRESULT WINAPI fake_DefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
HWND WINAPI fake_SetParent(HWND hWndChild, HWND hWndNewParent);
+HDC WINAPI fake_BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
SHORT WINAPI fake_GetKeyState(int nVirtKey);
SHORT WINAPI fake_GetAsyncKeyState(int vKey);
int WINAPI fake_GetDeviceCaps(HDC hdc, int index);
diff --git a/src/config.c b/src/config.c
index 8f30eac..36b756a 100644
--- a/src/config.c
+++ b/src/config.c
@@ -93,6 +93,7 @@ void cfg_load()
GET_BOOL(g_config.limit_gdi_handles, "limit_gdi_handles", FALSE);
GET_BOOL(g_config.remove_menu, "remove_menu", FALSE);
GET_INT(g_config.refresh_rate, "refresh_rate", 0);
+ GET_BOOL(g_config.terminate_process, "terminate_process", FALSE);
/* Hotkeys */
@@ -115,6 +116,7 @@ void cfg_load()
GET_BOOL(g_config.carma95_hack, "carma95_hack", FALSE);
GET_BOOL(g_config.sirtech_hack, "sirtech_hack", FALSE);
GET_BOOL(g_config.flightsim98_hack, "flightsim98_hack", FALSE);
+ GET_BOOL(g_config.darkcolony_hack, "darkcolony_hack", FALSE);
GameHandlesClose = GameHandlesClose || g_config.infantryhack;
@@ -336,6 +338,7 @@ static void cfg_create_ini()
"limit_gdi_handles=false\n"
"remove_menu=false\n"
"refresh_rate=0\n"
+ "terminate_process=false\n"
"\n"
"\n"
"\n"
@@ -371,7 +374,7 @@ static void cfg_create_ini()
"; The following settings are for cnc-ddraw config.exe\n"
"\n"
"\n"
- "; cnc-ddraw config program language, possible values: auto, english, chinese, german, spanish, russian, hungarian, french, italian, vietnamese\n"
+ "; cnc-ddraw config program language, possible values: auto, english, chinese, german, spanish, russian, hungarian, french, italian, vietnamese, polish\n"
"configlang=auto\n"
"\n"
"; cnc-ddraw config program theme, possible values: Windows10, Cobalt XEMedia\n"
@@ -389,15 +392,24 @@ static void cfg_create_ini()
"; The following settings override all settings shown above, section name = executable name\n"
"\n"
"\n"
+ "; 101: The Airborne Invasion of Normandy\n"
+ "[101]\n"
+ "terminate_process=true\n"
+ "\n"
"; 7th Legion\n"
"[legion]\n"
"maxgameticks=25\n"
- "singlecpu=false\n"
"\n"
"; Atrox\n"
"[Atrox]\n"
"nonexclusive=true\n"
"\n"
+ "; Arcatera the Dark Brotherhood\n"
+ "[darksun]\n"
+ "maxgameticks=60\n"
+ "maxfps=60\n"
+ "minfps=-1\n"
+ "\n"
"; Atomic Bomberman\n"
"[BM]\n"
"maxgameticks=60\n"
@@ -430,10 +442,6 @@ static void cfg_create_ini()
"nonexclusive=true\n"
"adjmouse=true\n"
"\n"
- "; Abomination - The Nemesis Project\n"
- "[abomb]\n"
- "singlecpu=false\n"
- "\n"
"; American Conquest / Cossacks\n"
"[DMCR]\n"
"resolutions=2\n"
@@ -530,14 +538,10 @@ static void cfg_create_ini()
"[AN]\n"
"adjmouse=true\n"
"\n"
- "; Another War\n"
- "[AnotherWar]\n"
- "singlecpu=false\n"
- "\n"
"; Atlantis\n"
"[ATLANTIS]\n"
"renderer=opengl\n"
- "maxgameticks=60\n"
+ "maxgameticks=30\n"
"center_cursor_fix=true\n"
"\n"
"; Airline Tycoon Deluxe\n"
@@ -652,10 +656,6 @@ static void cfg_create_ini()
"noactivateapp=true\n"
"nonexclusive=true\n"
"\n"
- "; Championship Manager 99-00\n"
- "[cm9900]\n"
- "singlecpu=false\n"
- "\n"
"; Command & Conquer: Sole Survivor\n"
"[SOLE]\n"
"maxgameticks=120\n"
@@ -804,6 +804,14 @@ static void cfg_create_ini()
"nonexclusive=true\n"
"adjmouse=true\n"
"\n"
+ "; Cloud Kingdom 3 (only with /ddraw command line parameter)\n"
+ "[Clouds Kingdom 3]\n"
+ "fake_mode=320x240x32\n"
+ "\n"
+ "; Commando 2004 (only with /ddraw command line parameter)\n"
+ "[commando]\n"
+ "fake_mode=320x240x32\n"
+ "\n"
"; Chris Sawyer's Locomotion\n"
"[LOCO/2]\n"
"checkfile=.\\LOCO.EXE\n"
@@ -819,21 +827,30 @@ static void cfg_create_ini()
"\n"
"; Close Combat 2: A Bridge Too Far\n"
"[cc2]\n"
+ "maxgameticks=20\n"
+ "limiter_type=4\n"
+ "minfps=15\n"
"adjmouse=true\n"
"nonexclusive=true\n"
"\n"
"; Close Combat 3: The Russian Front\n"
"[cc3]\n"
+ "maxgameticks=30\n"
+ "limiter_type=2\n"
"adjmouse=true\n"
"nonexclusive=true\n"
"\n"
"; Close Combat 4: The Battle of the Bulge\n"
"[cc4]\n"
+ "maxgameticks=30\n"
+ "limiter_type=2\n"
"adjmouse=true\n"
"nonexclusive=true\n"
"\n"
"; Close Combat 5: Invasion: Normandy\n"
"[cc5]\n"
+ "maxgameticks=30\n"
+ "limiter_type=2\n"
"adjmouse=true\n"
"nonexclusive=true\n"
"\n"
@@ -864,6 +881,12 @@ static void cfg_create_ini()
"[corsairs]\n"
"adjmouse=true\n"
"\n"
+ "; Dark Colony\n"
+ "[dc16]\n"
+ "maxgameticks=30\n"
+ "darkcolony_hack=true\n"
+ "hook_peekmessage=true\n"
+ "\n"
"; Divine Divinity\n"
"[div]\n"
"resolutions=2\n"
@@ -879,6 +902,12 @@ static void cfg_create_ini()
"noactivateapp=true\n"
"limiter_type=2\n"
"\n"
+ "; Dark Secret of Africa\n"
+ "[Game/5]\n"
+ "checkfile=.\\CONFIG.CFG\n"
+ "maxfps=60\n"
+ "minfps=-1\n"
+ "\n"
"; Dark Reign: The Future of War\n"
"[DKReign]\n"
"maxgameticks=60\n"
@@ -921,10 +950,6 @@ static void cfg_create_ini()
"[dominion]\n"
"flipclear=true\n"
"\n"
- "; Excalibur 2555AD\n"
- "[_FISH]\n"
- "singlecpu=false\n"
- "\n"
"; Escape Velocity Nova\n"
"[EV Nova]\n"
"nonexclusive=true\n"
@@ -951,10 +976,6 @@ static void cfg_create_ini()
"[f-16]\n"
"resolutions=1\n"
"\n"
- "; Fable\n"
- "[FABLE]\n"
- "singlecpu=false\n"
- "\n"
"; Fallout Tactics: Brotherhood of Steel\n"
"[BOS/2]\n"
"checkfile=.\\binkw32.dll\n"
@@ -968,10 +989,6 @@ static void cfg_create_ini()
"[FT Tools]\n"
"hook_peekmessage=true\n"
"\n"
- "; Falcon 4.0 (Microprose version)\n"
- "[falcon4]\n"
- "singlecpu=false\n"
- "\n"
"; Flight Simulator 98\n"
"[FLTSIM95]\n"
"flightsim98_hack=true\n"
@@ -984,6 +1001,11 @@ static void cfg_create_ini()
"[mrazik]\n"
"guard_lines=0\n"
"\n"
+ "; Fable\n"
+ "[Fable]\n"
+ "maxgameticks=59\n"
+ "limiter_type=4\n"
+ "\n"
"; Final Liberation: Warhammer Epic 40000\n"
"[Epic40k]\n"
"hook_peekmessage=true\n"
@@ -1038,7 +1060,6 @@ static void cfg_create_ini()
"; G-Police\n"
"[GPOLICE]\n"
"maxgameticks=60\n"
- "singlecpu=false\n"
"\n"
"; Gangsters: Organized Crime\n"
"[gangsters]\n"
@@ -1090,6 +1111,8 @@ static void cfg_create_ini()
"; Heroes of Might and Magic II: The Succession Wars\n"
"[HEROES2W]\n"
"adjmouse=true\n"
+ "game_handles_close=true\n"
+ "keytogglefullscreen2=0x73\n"
"\n"
"; Heroes of Might and Magic III\n"
"[Heroes3]\n"
@@ -1190,6 +1213,12 @@ static void cfg_create_ini()
"sirtech_hack=true\n"
"fix_alt_key_stuck=true\n"
"\n"
+ "; Jagged Alliance 2 - Vengeance Reloaded mod German exe\n"
+ "[JA2_Vengeance_DE]\n"
+ "singlecpu=false\n"
+ "sirtech_hack=true\n"
+ "fix_alt_key_stuck=true\n"
+ "\n"
"; Jeopardy! - NOT WORKING YET\n"
"[jeoppc]\n"
"singlecpu=false\n"
@@ -1280,10 +1309,6 @@ static void cfg_create_ini()
"[Lionheart]\n"
"hook_peekmessage=true\n"
"\n"
- "; Links Extreme\n"
- "[EXTREME]\n"
- "singlecpu=false\n"
- "\n"
"; Lost Vikings 2\n"
"[LOSTV95]\n"
"fake_mode=320x240x16\n"
@@ -1291,7 +1316,6 @@ static void cfg_create_ini()
"; Nightmare Creatures\n"
"[NC]\n"
"maxgameticks=30\n"
- "singlecpu=false\n"
"\n"
"; Moto Racer (software mode)\n"
"[moto]\n"
@@ -1351,10 +1375,18 @@ static void cfg_create_ini()
"[MajestyHD - Old]\n"
"adjmouse=true\n"
"\n"
+ "; Meat Puppet\n"
+ "[meat]\n"
+ "hook_peekmessage=true\n"
+ "\n"
"; Mech Warrior 3\n"
"[Mech3]\n"
"nonexclusive=true\n"
"\n"
+ "; Men In Black - NOT WORKING YET\n"
+ "[MIB]\n"
+ "hook=2\n"
+ "\n"
"; Moorhuhn 2\n"
"[Moorhuhn2]\n"
"fix_alt_key_stuck=true\n"
@@ -1500,10 +1532,6 @@ static void cfg_create_ini()
"[Pax Imperia]\n"
"nonexclusive=true\n"
"\n"
- "; Panzer Dragoon\n"
- "[PANZERDG]\n"
- "singlecpu=false\n"
- "\n"
"; Play with the Teletubbies\n"
"[PlayWTT]\n"
"hook=3\n"
@@ -1561,35 +1589,22 @@ static void cfg_create_ini()
"[RtK]\n"
"fixchilds=3\n"
"lock_mouse_top_left=true\n"
- "singlecpu=false\n"
"limiter_type=2\n"
"game_handles_close=true\n"
"maxgameticks=59\n"
"anti_aliased_fonts_min_size=99\n"
"\n"
- "; Rent-A-Hero\n"
- "[Rent-A-Hero]\n"
- "singlecpu=false\n"
- "\n"
"; ROAD RASH\n"
"[RoadRash]\n"
"adjmouse=true\n"
"nonexclusive=true\n"
"\n"
- "; Rising Lands (patched)\n"
- "[Rising]\n"
- "singlecpu=false\n"
- "\n"
"; Robin Hood - The Legend of Sherwood (GOG)\n"
"[Game/4]\n"
"checkfile=.\\Robin Hood.exe\n"
"singlecpu=false\n"
"fix_not_responding=true\n"
"\n"
- "; Roland Garros 98 (software mode)\n"
- "[rg98]\n"
- "singlecpu=false\n"
- "\n"
"; Robin Hood - The Legend of Sherwood (Steam)\n"
"[_rh]\n"
"singlecpu=false\n"
@@ -1600,6 +1615,11 @@ static void cfg_create_ini()
"singlecpu=false\n"
"fix_not_responding=true\n"
"\n"
+ "; Rising Lands\n"
+ "[Rising]\n"
+ "maxgameticks=30\n"
+ "limiter_type=4\n"
+ "\n"
"; Scooby-Doo(TM), Case File #1 The Glowing Bug Man - NOT WORKING YET\n"
"[Case File #1]\n"
"windowed=true\n"
@@ -1611,9 +1631,12 @@ static void cfg_create_ini()
"fake_mode=352x240x32\n"
"fix_not_responding=true\n"
"\n"
+ "; Seven Games of the Soul\n"
+ "[faust]\n"
+ "maxgameticks=25\n"
+ "\n"
"; Swarog\n"
"[Swarog]\n"
- "singlecpu=false\n"
"maxfps=60\n"
"maxgameticks=60\n"
"minfps=-1\n"
@@ -1710,12 +1733,25 @@ static void cfg_create_ini()
"; Sim City 3000\n"
"[SC3]\n"
"minfps=-2\n"
- "maxgameticks=60"
+ "maxgameticks=60\n"
+ "\n"
+ "; SimTunes\n"
+ "[SIMTUNES]\n"
+ "terminate_process=true\n"
+ "hook=3\n"
+ "\n"
+ "; Street Wars: Constructor Underworld\n"
+ "[Sw]\n"
+ "checkfile=.\\smackw32.dll\n"
+ "maxgameticks=30\n"
+ "limiter_type=4\n"
"\n"
"; Shadow Watch\n"
- "[sw]\n"
+ "[sw/2]\n"
+ "checkfile=.\\Dx.dll\n"
"adjmouse=true\n"
- "maxgameticks=30"
+ "maxgameticks=30\n"
+ "hook_peekmessage=true\n"
"\n"
"; Shadow Flare\n"
"[ShadowFlare]\n"
@@ -1732,10 +1768,6 @@ static void cfg_create_ini()
"maxgameticks=30\n"
"limiter_type=4\n"
"\n"
- "; The Curse Of Monkey Island\n"
- "[COMI]\n"
- "singlecpu=false\n"
- "\n"
"; The Tone Rebellion\n"
"[Float]\n"
"hook_peekmessage=true\n"
@@ -1755,7 +1787,6 @@ static void cfg_create_ini()
"; Virtual Springfield\n"
"[VIRTUAL]\n"
"game_handles_close=true\n"
- "singlecpu=false\n"
"\n"
"; Total Annihilation: Kingdoms\n"
"[Kingdoms]\n"
@@ -1767,10 +1798,6 @@ static void cfg_create_ini()
"lock_mouse_top_left=true\n"
"fixchilds=3\n"
"\n"
- "; The Neverhood\n"
- "[nhc]\n"
- "singlecpu=false\n"
- "\n"
"; The X-Files DVD\n"
"[XFiles]\n"
"windowed=true\n"
@@ -1834,6 +1861,7 @@ static void cfg_create_ini()
"adjmouse=false\n"
"lock_mouse_top_left=true\n"
"center_cursor_fix=true\n"
+ "noactivateapp=true\n"
"\n"
"; Uprising\n"
"[uprising]\n"
@@ -1844,10 +1872,6 @@ static void cfg_create_ini()
"renderer=opengl\n"
"adjmouse=true\n"
"\n"
- "; Unreal\n"
- "[Unreal]\n"
- "noactivateapp=true\n"
- "\n"
"; Vermeer\n"
"[vermeer]\n"
"adjmouse=true\n"
@@ -1857,6 +1881,13 @@ static void cfg_create_ini()
"[VF2]\n"
"fake_mode=640x480x8\n"
"\n"
+ "; Virtual On: Cyber Troopers\n"
+ "[V_ON]\n"
+ "devmode=true\n"
+ "windowed=true\n"
+ "fullscreen=true\n"
+ "toggle_borderless=true\n"
+ "\n"
"; Wall Street Trader 2000 - NOT WORKING YET\n"
"[WSTrader]\n"
"nonexclusive=false\n"
@@ -1872,10 +1903,6 @@ static void cfg_create_ini()
"[WH40K]\n"
"maxgameticks=250\n"
"\n"
- "; Weird War\n"
- "[WeirdWar]\n"
- "singlecpu=false\n"
- "\n"
"; Wizardry 8\n"
"[Wiz8]\n"
"sirtech_hack=true\n"
@@ -1902,7 +1929,6 @@ static void cfg_create_ini()
"\n"
"; Jeff Wayne's 'The War Of The Worlds'\n"
"[WoW]\n"
- "singlecpu=false\n"
"minfps=-1\n"
"\n"
"; Zeus and Poseidon\n"
@@ -1912,7 +1938,6 @@ static void cfg_create_ini()
"; Zork Nemesis\n"
"[znemesis]\n"
"fix_not_responding=true\n"
- "singlecpu=false\n"
"maxgameticks=60\n"
"limiter_type=4\n"
"\n"
diff --git a/src/dd.c b/src/dd.c
index e69063a..b9e5b12 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -518,6 +518,7 @@ HRESULT dd_GetCaps(LPDDCAPS_DX1 lpDDDriverCaps, LPDDCAPS_DX1 lpDDEmulCaps)
memset(lpDDEmulCaps, 0, size);
lpDDEmulCaps->dwSize = size;
+ lpDDEmulCaps->dwCaps = DDCAPS_BLTSTRETCH;
}
return DD_OK;
@@ -889,6 +890,7 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl
g_config.windowed = TRUE;
g_config.fullscreen = TRUE;
+ g_config.toggle_borderless = TRUE;
border = FALSE;
/* prevent OpenGL from going automatically into fullscreen exclusive mode */
@@ -1252,6 +1254,7 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl
g_ddraw.render.run = FALSE;
g_config.windowed = TRUE;
g_config.fullscreen = TRUE;
+ g_config.toggle_borderless = TRUE;
return dd_SetDisplayMode(dwWidth, dwHeight, dwBPP, dwFlags);
}
@@ -1268,6 +1271,7 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl
g_ddraw.render.run = FALSE;
g_config.windowed = TRUE;
g_config.fullscreen = TRUE;
+ g_config.toggle_borderless = TRUE;
return dd_SetDisplayMode(dwWidth, dwHeight, dwBPP, dwFlags);
}
}
@@ -1824,7 +1828,17 @@ HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOute
if (g_config.singlecpu)
{
- SetProcessAffinityMask(proc, 1);
+ if (!IsWine() && IsWindows11Version24H2OrGreater())
+ {
+ if (GetProcessAffinityMask(proc, &proc_affinity, &system_affinity))
+ SetProcessAffinityMask(proc, system_affinity);
+
+ util_set_process_affinity();
+ }
+ else
+ {
+ SetProcessAffinityMask(proc, 1);
+ }
}
else if (GetProcessAffinityMask(proc, &proc_affinity, &system_affinity))
{
diff --git a/src/ddpalette.c b/src/ddpalette.c
index 4288b89..e51df8e 100644
--- a/src/ddpalette.c
+++ b/src/ddpalette.c
@@ -109,7 +109,7 @@ HRESULT dd_CreatePalette(
p->lpVtbl = &g_ddp_vtbl;
p->flags = dwFlags;
- ddp_SetEntries(p, dwFlags, 0, 256, lpDDColorArray);
+ ddp_SetEntries(p, dwFlags, 0, 256, lpDDColorArray);
IDirectDrawPalette_AddRef(p);
*lpDDPalette = p;
diff --git a/src/ddsurface.c b/src/ddsurface.c
index 4fd92c1..96d69de 100644
--- a/src/ddsurface.c
+++ b/src/ddsurface.c
@@ -909,6 +909,11 @@ HRESULT dds_GetClipper(IDirectDrawSurfaceImpl* This, IDirectDrawClipperImpl** lp
HRESULT dds_GetColorKey(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDCOLORKEY lpColorKey)
{
+ if (!(This->flags & DDSD_CKSRCBLT))
+ {
+ return DDERR_NOCOLORKEY;
+ }
+
if (dwFlags != DDCKEY_SRCBLT || !lpColorKey)
{
TRACE(" NOT_IMPLEMENTED dwFlags=%08X, lpColorKey=%p\n", dwFlags, lpColorKey);
@@ -1548,17 +1553,18 @@ HRESULT dd_CreateSurface(
if (dst_surface->hdc)
InterlockedIncrement(&g_dds_gdi_handles);
+ // CreateDIBSection cannot handle values higher than a WORD - 0xFF00 (guard lines);
+ DWORD map_offset = min(65280, dst_surface->pitch * g_config.guard_lines);
+
dst_surface->mapping =
CreateFileMappingA(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE | SEC_COMMIT,
0,
- bmp_size + 256,
+ bmp_size + 256 + map_offset,
NULL);
- DWORD map_offset = 0;
-
if (dst_surface->mapping)
{
LPVOID data = MapViewOfFile(dst_surface->mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
diff --git a/src/debug.c b/src/debug.c
index 9d615b5..b030114 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -17,6 +17,7 @@
#include "crc32.h"
#include "dllmain.h"
#include "config.h"
+#include "delay_imports.h"
double g_dbg_frame_time = 0;
@@ -89,10 +90,7 @@ LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception)
HMODULE mod = NULL;
char filename[MAX_PATH] = { 0 };
- BOOL(WINAPI * getModuleHandleExA)(DWORD, LPCSTR, HMODULE*) =
- (void*)real_GetProcAddress(real_LoadLibraryA("Kernel32.dll"), "GetModuleHandleExA");
-
- if (getModuleHandleExA && getModuleHandleExA(
+ if (delay_GetModuleHandleExA && delay_GetModuleHandleExA(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
exception->ExceptionRecord->ExceptionAddress,
&mod))
diff --git a/src/delay_imports.c b/src/delay_imports.c
new file mode 100644
index 0000000..2b23dda
--- /dev/null
+++ b/src/delay_imports.c
@@ -0,0 +1,30 @@
+#include
+#include "versionhelpers.h"
+#include "delay_imports.h"
+
+NTQUERYINFORMATIONTHREADPROC delay_NtQueryInformationThread;
+RTLVERIFYVERSIONINFOPROC delay_RtlVerifyVersionInfo;
+WINE_GET_VERSIONPROC delay_wine_get_version;
+WINE_GET_HOST_VERSIONPROC delay_wine_get_host_version;
+
+VERSETCONDITIONMASKPROC delay_VerSetConditionMask;
+GETMODULEHANDLEEXAPROC delay_GetModuleHandleExA;
+
+void delay_imports_init()
+{
+ HMODULE mod = GetModuleHandleA("ntdll.dll");
+ if (mod)
+ {
+ delay_NtQueryInformationThread = (NTQUERYINFORMATIONTHREADPROC)GetProcAddress(mod, "NtQueryInformationThread");
+ delay_RtlVerifyVersionInfo = (RTLVERIFYVERSIONINFOPROC)GetProcAddress(mod, "RtlVerifyVersionInfo");
+ delay_wine_get_version = (WINE_GET_VERSIONPROC)GetProcAddress(mod, "wine_get_version");
+ delay_wine_get_host_version = (WINE_GET_HOST_VERSIONPROC)GetProcAddress(mod, "wine_get_host_version");
+ }
+
+ mod = GetModuleHandleA("Kernel32.dll");
+ if (mod)
+ {
+ delay_VerSetConditionMask = (VERSETCONDITIONMASKPROC)GetProcAddress(mod, "VerSetConditionMask");
+ delay_GetModuleHandleExA = (GETMODULEHANDLEEXAPROC)GetProcAddress(mod, "GetModuleHandleExA");
+ }
+}
diff --git a/src/dllmain.c b/src/dllmain.c
index 97d675f..8832177 100644
--- a/src/dllmain.c
+++ b/src/dllmain.c
@@ -12,6 +12,7 @@
#include "indeo.h"
#include "utils.h"
#include "versionhelpers.h"
+#include "delay_imports.h"
#include "keyboard.h"
@@ -33,7 +34,7 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
g_ddraw_module = hDll;
- verhelp_init();
+ delay_imports_init();
if (GetEnvironmentVariable("cnc_ddraw_config_init", NULL, 0))
{
@@ -178,8 +179,18 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
if (g_dbg_exception_handle && remove_handler)
remove_handler(g_dbg_exception_handle);
+ if (g_config.terminate_process == 2)
+ TerminateProcess(GetCurrentProcess(), 0);
+
break;
}
+ case DLL_THREAD_ATTACH:
+ {
+ if (g_config.singlecpu && !IsWine() && IsWindows11Version24H2OrGreater())
+ {
+ util_set_thread_affinity(GetCurrentThreadId());
+ }
+ }
}
return TRUE;
diff --git a/src/hook.c b/src/hook.c
index 1e536fb..29846c7 100644
--- a/src/hook.c
+++ b/src/hook.c
@@ -55,6 +55,7 @@ SETWINDOWPLACEMENTPROC real_SetWindowPlacement = SetWindowPlacement;
ENUMDISPLAYSETTINGSAPROC real_EnumDisplaySettingsA = EnumDisplaySettingsA;
DEFWINDOWPROCAPROC real_DefWindowProcA = DefWindowProcA;
SETPARENTPROC real_SetParent = SetParent;
+BEGINPAINTPROC real_BeginPaint = BeginPaint;
GETKEYSTATEPROC real_GetKeyState = GetKeyState;
GETASYNCKEYSTATEPROC real_GetAsyncKeyState = GetAsyncKeyState;
GETDEVICECAPSPROC real_GetDeviceCaps = GetDeviceCaps;
@@ -119,6 +120,7 @@ HOOKLIST g_hook_hooklist[] =
{ "EnumDisplaySettingsA", (PROC)fake_EnumDisplaySettingsA, (PROC*)&real_EnumDisplaySettingsA, 0 },
{ "DefWindowProcA", (PROC)fake_DefWindowProcA, (PROC*)&real_DefWindowProcA, 0 },
{ "SetParent", (PROC)fake_SetParent, (PROC*)&real_SetParent, 0 },
+ { "BeginPaint", (PROC)fake_BeginPaint, (PROC*)&real_BeginPaint, 0 },
{ "GetKeyState", (PROC)fake_GetKeyState, (PROC*)&real_GetKeyState, 0 },
{ "GetAsyncKeyState", (PROC)fake_GetAsyncKeyState, (PROC*)&real_GetAsyncKeyState, 0 },
{ "SetForegroundWindow", (PROC)fake_SetForegroundWindow, (PROC*)&real_SetForegroundWindow, 0 },
diff --git a/src/keyboard.c b/src/keyboard.c
index 2ca9fbb..f54ba63 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -86,9 +86,22 @@ LRESULT CALLBACK keyboard_hook_proc(int code, WPARAM wParam, LPARAM lParam)
return 1;
}
- if (wParam == g_config.hotkeys.screenshot && key_released)
+ if (wParam == g_config.hotkeys.screenshot)
{
- ss_take_screenshot(g_ddraw.primary);
+ // VK_SNAPSHOT does not have a KEYDOWN event...
+ if (g_config.hotkeys.screenshot == VK_SNAPSHOT)
+ {
+ if (key_released)
+ {
+ ss_take_screenshot(g_ddraw.primary);
+ return 1;
+ }
+ }
+ else if (key_triggered)
+ {
+ ss_take_screenshot(g_ddraw.primary);
+ return 1;
+ }
}
if (wParam == g_config.hotkeys.unlock_cursor1 || wParam == VK_CONTROL)
diff --git a/src/render_ogl.c b/src/render_ogl.c
index cf85022..aae1d34 100644
--- a/src/render_ogl.c
+++ b/src/render_ogl.c
@@ -253,8 +253,8 @@ static void ogl_build_programs()
if (_stricmp(g_oglu_version_long, "4.0.0 - Build 10.18.10.4252") == 0 ||
_stricmp(g_oglu_version_long, "4.0.0 - Build 10.18.10.5161") == 0)
{
- shader_path[0] = 0;
- g_config.shader[0] = 0;
+ //shader_path[0] = 0;
+ //g_config.shader[0] = 0;
}
/* detect common upscaling shaders and disable them if no upscaling is required */
diff --git a/src/utils.c b/src/utils.c
index d96920b..fafd4ed 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
#include "ddraw.h"
#include "debug.h"
#include "dd.h"
@@ -12,6 +13,7 @@
#include "utils.h"
#include "config.h"
#include "versionhelpers.h"
+#include "delay_imports.h"
/*
@@ -71,6 +73,88 @@ HMODULE WINAPI util_enumerate_modules(_In_opt_ HMODULE hModuleLast)
return NULL;
}
+void util_set_process_affinity()
+{
+#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
+ HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+ if (snap == INVALID_HANDLE_VALUE)
+ return;
+
+ THREADENTRY32 entry = { 0 };
+ entry.dwSize = sizeof(THREADENTRY32);
+
+ if (!Thread32First(snap, &entry))
+ {
+ CloseHandle(snap);
+ return;
+ }
+
+ do
+ {
+ if (entry.th32OwnerProcessID == GetCurrentProcessId())
+ {
+ util_set_thread_affinity(entry.th32ThreadID);
+ }
+ } while (Thread32Next(snap, &entry));
+
+ CloseHandle(snap);
+#endif
+}
+
+void util_set_thread_affinity(DWORD tid)
+{
+#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
+ HANDLE thread = OpenThread(THREAD_QUERY_INFORMATION | THREAD_SET_INFORMATION, FALSE, tid);
+ if (thread)
+ {
+ void* start = NULL;
+ NTSTATUS status = STATUS_PENDING;
+
+ if (delay_NtQueryInformationThread)
+ {
+ status =
+ delay_NtQueryInformationThread(thread, ThreadQuerySetWin32StartAddress, &start, sizeof(start), NULL);
+ }
+
+ if (status == STATUS_SUCCESS && start && delay_GetModuleHandleExA)
+ {
+ char game_exe_path[MAX_PATH] = { 0 };
+ char game_dir[MAX_PATH] = { 0 };
+
+ if (GetModuleFileNameA(NULL, game_exe_path, sizeof(game_exe_path)))
+ {
+ _splitpath(game_exe_path, NULL, game_dir, NULL, NULL);
+
+ char mod_path[MAX_PATH] = { 0 };
+ char mod_dir[MAX_PATH] = { 0 };
+ char mod_filename[MAX_PATH] = { 0 };
+ HMODULE mod = NULL;
+
+ if (delay_GetModuleHandleExA(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, start, &mod))
+ {
+ if (GetModuleFileNameA(mod, mod_path, sizeof(mod_path)))
+ {
+ _splitpath(mod_path, NULL, mod_dir, mod_filename, NULL);
+
+ if (_strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0) // _strcmpi(mod_filename, "WINMM") == 0
+ {
+ SetThreadAffinityMask(thread, 1);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ SetThreadAffinityMask(thread, 1);
+ }
+
+ CloseHandle(thread);
+ }
+#endif
+}
+
void util_pull_messages()
{
if (g_config.fix_not_responding &&
@@ -183,10 +267,7 @@ FARPROC util_get_iat_proc(HMODULE mod, char* module_name, char* function_name)
BOOL util_caller_is_ddraw_wrapper(void* return_address)
{
- BOOL (WINAPI *getModuleHandleExA)(DWORD, LPCSTR, HMODULE*) =
- (void*)real_GetProcAddress(real_LoadLibraryA("Kernel32.dll"), "GetModuleHandleExA");
-
- if (!getModuleHandleExA)
+ if (!delay_GetModuleHandleExA)
return FALSE;
void* directDrawCreate = (void*)util_get_iat_proc(GetModuleHandleA(NULL), "ddraw.dll", "DirectDrawCreate");
@@ -200,9 +281,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address)
HMODULE D3dHook_dll = GetModuleHandleA("D3dHook.dll");
if (D3dHook_dll)
{
- if ((getModuleHandleExA(flags, return_address, &mod) && mod == D3dHook_dll) ||
- (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == D3dHook_dll) ||
- (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == D3dHook_dll))
+ if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == D3dHook_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == D3dHook_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == D3dHook_dll))
{
MessageBoxA(
NULL,
@@ -218,9 +299,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address)
HMODULE wndmode_dll = GetModuleHandleA("wndmode.dll");
if (wndmode_dll)
{
- if ((getModuleHandleExA(flags, return_address, &mod) && mod == wndmode_dll) ||
- (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == wndmode_dll) ||
- (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == wndmode_dll))
+ if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == wndmode_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == wndmode_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == wndmode_dll))
{
MessageBoxA(
NULL,
@@ -236,9 +317,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address)
HMODULE windmode_dll = GetModuleHandleA("windmode.dll");
if (windmode_dll)
{
- if ((getModuleHandleExA(flags, return_address, &mod) && mod == windmode_dll) ||
- (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == windmode_dll) ||
- (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == windmode_dll))
+ if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == windmode_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == windmode_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == windmode_dll))
{
MessageBoxA(
NULL,
@@ -254,9 +335,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address)
HMODULE dxwnd_dll = GetModuleHandleA("dxwnd.dll");
if (dxwnd_dll)
{
- if ((getModuleHandleExA(flags, return_address, &mod) && mod == dxwnd_dll) ||
- (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == dxwnd_dll) ||
- (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == dxwnd_dll))
+ if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == dxwnd_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == dxwnd_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == dxwnd_dll))
{
MessageBoxA(
NULL,
@@ -272,9 +353,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address)
HMODULE age_dll = GetModuleHandleA("age.dll");
if (age_dll)
{
- if ((getModuleHandleExA(flags, return_address, &mod) && mod == age_dll) ||
- (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == age_dll) ||
- (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == age_dll))
+ if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == age_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == age_dll) ||
+ (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == age_dll))
{
HKEY hkey;
LONG status =
diff --git a/src/versionhelpers.c b/src/versionhelpers.c
index 7c19528..f9f35c2 100644
--- a/src/versionhelpers.c
+++ b/src/versionhelpers.c
@@ -1,56 +1,30 @@
#include
#include "versionhelpers.h"
+#include "delay_imports.h"
-typedef NTSTATUS(WINAPI* RTLVERIFYVERSIONINFOPROC)(PRTL_OSVERSIONINFOEXW, ULONG, ULONGLONG);
-typedef ULONGLONG(WINAPI* VERSETCONDITIONMASKPROC)(ULONGLONG, DWORD, BYTE);
-typedef const char* (CDECL* WINE_GET_VERSIONPROC)();
-typedef void (CDECL* WINE_GET_HOST_VERSIONPROC)(const char** sysname, const char** release);
-
-static RTLVERIFYVERSIONINFOPROC RtlVerifyVersionInfo;
-static VERSETCONDITIONMASKPROC VerSetConditionMaskProc;
-static WINE_GET_VERSIONPROC wine_get_version;
-static WINE_GET_HOST_VERSIONPROC wine_get_host_version;
-
-/* GetProcAddress is rather slow so we use a function to initialize it once on startup */
-void verhelp_init()
-{
- HMODULE mod = GetModuleHandleA("ntdll.dll");
- if (mod)
- {
- RtlVerifyVersionInfo = (RTLVERIFYVERSIONINFOPROC)GetProcAddress(mod, "RtlVerifyVersionInfo");
- wine_get_version = (WINE_GET_VERSIONPROC)GetProcAddress(mod, "wine_get_version");
- wine_get_host_version = (WINE_GET_HOST_VERSIONPROC)GetProcAddress(mod, "wine_get_host_version");
- }
-
- mod = GetModuleHandleA("Kernel32.dll");
- if (mod)
- {
- VerSetConditionMaskProc = (VERSETCONDITIONMASKPROC)GetProcAddress(mod, "VerSetConditionMask");
- }
-}
BOOL verhelp_verify_version(PRTL_OSVERSIONINFOEXW versionInfo, ULONG typeMask, ULONGLONG conditionMask)
{
- return RtlVerifyVersionInfo ?
- RtlVerifyVersionInfo(versionInfo, typeMask, conditionMask) == 0 :
+ return delay_RtlVerifyVersionInfo ?
+ delay_RtlVerifyVersionInfo(versionInfo, typeMask, conditionMask) == 0 :
VerifyVersionInfoW(versionInfo, typeMask, conditionMask);
}
ULONGLONG verhelp_set_mask(ULONGLONG ConditionMask, DWORD TypeMask, BYTE Condition)
{
- return VerSetConditionMaskProc ? VerSetConditionMaskProc(ConditionMask, TypeMask, Condition) : 0;
+ return delay_VerSetConditionMask ? delay_VerSetConditionMask(ConditionMask, TypeMask, Condition) : 0;
}
const char* verhelp_wine_get_version()
{
- return wine_get_version ? wine_get_version() : NULL;
+ return delay_wine_get_version ? delay_wine_get_version() : NULL;
}
void verhelp_wine_get_host_version(const char** sysname, const char** release)
{
- if (wine_get_host_version)
+ if (delay_wine_get_host_version)
{
- wine_get_host_version(sysname, release);
+ delay_wine_get_host_version(sysname, release);
return;
}
diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c
index fc6fdbd..33655c1 100644
--- a/src/winapi_hooks.c
+++ b/src/winapi_hooks.c
@@ -780,6 +780,14 @@ BOOL WINAPI fake_GetMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wM
BOOL WINAPI fake_PeekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
{
+ if (g_config.darkcolony_hack && !hWnd)
+ {
+ hWnd = g_ddraw.hwnd;
+
+ MSG msg;
+ real_PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE);
+ }
+
if (g_config.limiter_type == LIMIT_PEEKMESSAGE &&
g_ddraw.ticks_limiter.tick_length > 0 &&
InterlockedExchange(&g_ddraw.render.screen_updated, FALSE))
@@ -915,6 +923,26 @@ HWND WINAPI fake_SetParent(HWND hWndChild, HWND hWndNewParent)
return real_SetParent(hWndChild, hWndNewParent);
}
+HDC WINAPI fake_BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint)
+{
+ if (g_ddraw.ref && g_ddraw.width && g_ddraw.hwnd && g_ddraw.hwnd == hWnd && lpPaint)
+ {
+ HDC result = real_BeginPaint(hWnd, lpPaint);
+
+ if (result)
+ {
+ lpPaint->rcPaint.left = 0;
+ lpPaint->rcPaint.top = 0;
+ lpPaint->rcPaint.right = g_ddraw.width;
+ lpPaint->rcPaint.bottom = g_ddraw.height;
+ }
+
+ return result;
+ }
+
+ return real_BeginPaint(hWnd, lpPaint);
+}
+
SHORT WINAPI fake_GetKeyState(int nVirtKey)
{
if (g_config.windowed && g_ddraw.ref && g_ddraw.hwnd && !util_in_foreground())
@@ -956,12 +984,12 @@ int WINAPI fake_GetDeviceCaps(HDC hdc, int index)
bpp = strtoul(e + 1, &e, 0);
}
- if (bpp && index == BITSPIXEL && (g_config.hook != 2 || g_ddraw.renderer == gdi_render_main))
+ if (bpp && index == BITSPIXEL)
{
return bpp;
}
- if (bpp == 8 && (g_config.hook != 2 || g_ddraw.renderer == gdi_render_main))
+ if (bpp == 8)
{
if (index == RASTERCAPS)
{
@@ -1093,12 +1121,36 @@ BOOL WINAPI fake_StretchBlt(
else if (
g_ddraw.width > 0 &&
g_ddraw.render.hdc &&
- (hwnd == g_ddraw.hwnd || (real_GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TRANSPARENT)))
+ (hwnd == g_ddraw.hwnd ||
+ (real_GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TRANSPARENT) ||
+ strcmp(class_name, "AVIWnd32") == 0))
{
+ POINT pt = { 0 };
+ real_MapWindowPoints(hwnd, g_ddraw.hwnd, &pt, 1);
+
+ if (hwnd != g_ddraw.hwnd && strcmp(class_name, "AVIWnd32") == 0)
+ {
+ LONG exstyle = real_GetWindowLongA(hwnd, GWL_EXSTYLE);
+ if (!(exstyle & WS_EX_TRANSPARENT))
+ {
+ real_SetWindowLongA(hwnd, GWL_EXSTYLE, exstyle | WS_EX_TRANSPARENT);
+
+ real_SetWindowPos(
+ hwnd,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ SWP_ASYNCWINDOWPOS | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
+ );
+ }
+ }
+
return real_StretchBlt(
hwnd == g_ddraw.hwnd ? hdcDest : g_ddraw.render.hdc,
- (int)(roundf(xDest * g_ddraw.render.scale_w)) + g_ddraw.render.viewport.x,
- (int)(roundf(yDest * g_ddraw.render.scale_h)) + g_ddraw.render.viewport.y,
+ (int)(roundf((xDest + pt.x) * g_ddraw.render.scale_w)) + g_ddraw.render.viewport.x,
+ (int)(roundf((yDest + pt.y) * g_ddraw.render.scale_h)) + g_ddraw.render.viewport.y,
(int)(roundf(wDest * g_ddraw.render.scale_w)),
(int)(roundf(hDest * g_ddraw.render.scale_h)),
hdcSrc,
@@ -2002,6 +2054,14 @@ HWND WINAPI fake_CreateWindowExA(
dwStyle &= ~WS_POPUP;
}
+ /* Dark Colony */
+ if (HIWORD(lpClassName) && _strcmpi(lpClassName, "Merc Direct Draw Driver") == 0 &&
+ lpWindowName && _strcmpi(lpWindowName, "Direct Draw Driver") == 0 &&
+ !dwExStyle)
+ {
+ dwExStyle |= WS_EX_APPWINDOW;
+ }
+
/* Fallout 1/2 */
if (HIWORD(lpClassName) && _strcmpi(lpClassName, "GNW95 Class") == 0 &&
lpWindowName && strstr(lpWindowName, "FALLOUT"))
@@ -2038,6 +2098,28 @@ HWND WINAPI fake_CreateWindowExA(
Y = pt.y + align_y;
}
+ /* Metal Knight Movies */
+ if (HIWORD(lpClassName) && _strcmpi(lpClassName, "Afx:400000:3:0:1900011:0") == 0 &&
+ lpWindowName && _strcmpi(lpWindowName, "AVI player") == 0 &&
+ dwStyle == WS_POPUP &&
+ dwExStyle == WS_EX_TOPMOST &&
+ g_ddraw.ref && g_ddraw.hwnd &&
+ g_ddraw.width)
+ {
+ dwExStyle = 0;
+
+ POINT pt = { 0, 0 };
+ real_ClientToScreen(g_ddraw.hwnd, &pt);
+
+ int added_height = g_ddraw.render.height - g_ddraw.height;
+ int added_width = g_ddraw.render.width - g_ddraw.width;
+ int align_y = added_height > 0 ? added_height / 2 : 0;
+ int align_x = added_width > 0 ? added_width / 2 : 0;
+
+ X += pt.x + align_x;
+ Y += pt.y + align_y;
+ }
+
/* Disney Trivia Challenge */
if (HIWORD(lpClassName) && _strcmpi(lpClassName, "Disney Trivia Challenge") == 0 &&
hWndParent && (dwStyle & WS_CHILD))
diff --git a/src/wndproc.c b/src/wndproc.c
index 76f3387..3555058 100644
--- a/src/wndproc.c
+++ b/src/wndproc.c
@@ -49,6 +49,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
case WM_NCPAINT:
case WM_CANCELMODE:
case WM_DISPLAYCHANGE:
+ case WM_NCCALCSIZE:
{
return real_DefWindowProcA(hWnd, uMsg, wParam, lParam);
}
@@ -619,6 +620,9 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
if (wParam == SC_CLOSE && !GameHandlesClose)
{
+ if (g_config.terminate_process)
+ g_config.terminate_process = 2;
+
ExitProcess(0);
//_exit(0);
}
@@ -850,6 +854,11 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
}
case WM_SYSKEYDOWN:
{
+ if (wParam == VK_F4)
+ {
+ return real_DefWindowProcA(hWnd, uMsg, wParam, lParam);
+ }
+
break;
}
case WM_SYSKEYUP: