diff --git a/Include/dxwnd.h b/Include/dxwnd.h
index 5e11017..7ab2887 100644
--- a/Include/dxwnd.h
+++ b/Include/dxwnd.h
@@ -157,6 +157,7 @@
#define QUARTERBLT 0x00000100 // Consider a screen update (to count or limit FPS) only blt operations bigger than a quarter of the whole primary surface
#define NOIMAGEHLP 0x00000200 // Interceptd Imagehlp.dll unsupported calls (used by "the 5th element")
#define BILINEARFILTER 0x00000400 // experimental bilinear filtering
+#define REPLACEPRIVOPS 0x00000800 // replace privileged opcodes, such as IN (Ubik)
// logging Tflags DWORD:
#define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general
diff --git a/build/Resources_CN.dll b/build/Resources_CN.dll
index 3a23f3b..20dcfab 100644
--- a/build/Resources_CN.dll
+++ b/build/Resources_CN.dll
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:441255a55dfe46ee221c48c22ab6f091ee7d0c851e900abe2d866e2837580db1
+oid sha256:3c96c942826339906499d13f0a0b4bfe56365ca9bb956d61968865eea475e83d
size 132608
diff --git a/build/Resources_IT.dll b/build/Resources_IT.dll
index b54d3de..02dbf38 100644
--- a/build/Resources_IT.dll
+++ b/build/Resources_IT.dll
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:aff84e4a82ca05d2e25f680d370216a871fa466b01525e1aa60d66e895fcdead
+oid sha256:4afa46ffdb77508826da9be40dfb13fbbe6fddfb268c477d8189fba258280b58
size 139264
diff --git a/build/Resources_RU.dll b/build/Resources_RU.dll
index b3e0cb0..3834e92 100644
--- a/build/Resources_RU.dll
+++ b/build/Resources_RU.dll
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:31953821448e01fefdb6409799a8dac114cf7ef92cfa4f5b009559403e20a7b9
-size 141312
+oid sha256:15292e556b28f6c70341556e7e982256f6913f907f8cb970b9bbad6ea9e900fd
+size 141824
diff --git a/build/dxwnd.dll b/build/dxwnd.dll
index 3096175..70f6722 100644
--- a/build/dxwnd.dll
+++ b/build/dxwnd.dll
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:5440c78286a678a28b71b54f938b0ff377b7811d6601f3d5b00aaffc39d7811a
-size 531968
+oid sha256:66fc7e3018d4d23c86d3c1c2bd2059713c55356b6c547891c0b05a3ec37bbbbf
+size 532992
diff --git a/build/dxwnd.exe b/build/dxwnd.exe
index 04c7c98..fc100b9 100644
--- a/build/dxwnd.exe
+++ b/build/dxwnd.exe
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:155274eb76f293c76375ddbf6fb233076d82307a6afd440a11417e3673ece4ad
-size 559104
+oid sha256:398e28489fc7d5eff0a809c8248039a3cd69ac3cee7e64f9931092bbec27416a
+size 559616
diff --git a/build/exports/Area 51.dxw b/build/exports/Area 51.dxw
new file mode 100644
index 0000000..ba2838c
--- /dev/null
+++ b/build/exports/Area 51.dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Area 51
+path0=D:\Games\Area 51\area51.exe
+launchpath0=
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=134217763
+flagg0=1207959552
+flagh0=20
+flagi0=138412036
+flagj0=8320
+tflag0=0
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Black Thorn (emulated).dxw b/build/exports/Black Thorn (emulated).dxw
new file mode 100644
index 0000000..07abab6
--- /dev/null
+++ b/build/exports/Black Thorn (emulated).dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Black Thorn
+path0=D:\Games\Black Thorn\BlackThorn.exe
+launchpath0=
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=671105062
+flagg0=1207959552
+flagh0=20
+flagi0=4325380
+flagj0=128
+tflag0=6210
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Crimson Skies.dxw b/build/exports/Crimson Skies.dxw
index b617446..84b3e28 100644
--- a/build/exports/Crimson Skies.dxw
+++ b/build/exports/Crimson Skies.dxw
@@ -5,10 +5,10 @@ module0=
opengllib0=
ver0=7
coord0=0
-flag0=155205668
+flag0=140525606
flagg0=1207959568
flagh0=20
-flagi0=292
+flagi0=4194596
tflag0=258
initx0=0
inity0=0
@@ -22,3 +22,7 @@ sizx0=800
sizy0=600
maxfps0=0
initts0=0
+launchpath0=
+flagj0=128
+winver0=0
+maxres0=0
diff --git a/build/exports/Dark Colony.dxw b/build/exports/Dark Colony.dxw
index 30b3ee1..31fed2d 100644
--- a/build/exports/Dark Colony.dxw
+++ b/build/exports/Dark Colony.dxw
@@ -5,10 +5,10 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=136315424
+flag0=134218272
flagg0=1207959552
flagh0=20
-flagi0=4
+flagi0=4194308
tflag0=0
initx0=0
inity0=0
@@ -24,3 +24,5 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+launchpath0=
+flagj0=128
diff --git a/build/exports/Dark Vengeance.dxw b/build/exports/Dark Vengeance.dxw
index 6cf30fa..5e8c151 100644
--- a/build/exports/Dark Vengeance.dxw
+++ b/build/exports/Dark Vengeance.dxw
@@ -5,11 +5,11 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=136314915
+flag0=134217763
flagg0=1476395008
flagh0=65556
-flagi0=4
-tflag0=2049
+flagi0=4194308
+tflag0=0
initx0=0
inity0=0
minx0=0
@@ -24,3 +24,5 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+launchpath0=
+flagj0=128
diff --git a/build/exports/Deadlock II.dxw b/build/exports/Deadlock II.dxw
new file mode 100644
index 0000000..e5d7837
--- /dev/null
+++ b/build/exports/Deadlock II.dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Deadlock II
+path0=D:\Games\deadlock2\DEADLOCK.EXE
+launchpath0=
+module0=
+opengllib0=
+ver0=7
+coord0=0
+flag0=-2013265886
+flagg0=1209008128
+flagh0=20
+flagi0=138412036
+flagj0=128
+tflag0=0
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Die Hard Nakatomi Plaza.dxw b/build/exports/Die Hard Nakatomi Plaza.dxw
new file mode 100644
index 0000000..99a83be
--- /dev/null
+++ b/build/exports/Die Hard Nakatomi Plaza.dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Die Hard Nakatomi Plaza
+path0=D:\Games\die hard nakatomi plaza\Lithtech.exe
+launchpath0=D:\Games\die hard nakatomi plaza\Nakatomi.exe
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=671096866
+flagg0=1207959552
+flagh0=20
+flagi0=138412036
+flagj0=8328
+tflag0=6403
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Dungeon Keeper II.dxw b/build/exports/Dungeon Keeper II.dxw
index 8f1b938..b4850f5 100644
--- a/build/exports/Dungeon Keeper II.dxw
+++ b/build/exports/Dungeon Keeper II.dxw
@@ -5,11 +5,11 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=16418
-flagg0=708837376
+flag0=134234146
+flagg0=1782579200
flagh0=20
flagi0=4194304
-tflag0=263
+tflag0=0
initx0=0
inity0=0
minx0=0
@@ -25,3 +25,4 @@ initts0=0
launchpath0=
winver0=0
maxres0=0
+flagj0=128
diff --git a/build/exports/Flying Heroes.dxw b/build/exports/Flying Heroes.dxw
index 1ac1a59..89f2c1e 100644
--- a/build/exports/Flying Heroes.dxw
+++ b/build/exports/Flying Heroes.dxw
@@ -5,10 +5,10 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=151011364
+flag0=134234150
flagg0=1207959552
flagh0=20
-flagi0=4
+flagi0=4194436
tflag0=0
initx0=0
inity0=0
@@ -24,3 +24,5 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+launchpath0=
+flagj0=128
diff --git a/build/exports/Force 21.dxw b/build/exports/Force 21.dxw
new file mode 100644
index 0000000..7ecf597
--- /dev/null
+++ b/build/exports/Force 21.dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Force 21
+path0=D:\Games\Force 21\Force21.exe
+launchpath0=
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=136331298
+flagg0=1207959552
+flagh0=20
+flagi0=138412036
+flagj0=8320
+tflag0=0
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Hesperian Wars.dxw b/build/exports/Hesperian Wars.dxw
index 9b5668b..2e27640 100644
--- a/build/exports/Hesperian Wars.dxw
+++ b/build/exports/Hesperian Wars.dxw
@@ -5,11 +5,11 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=136314914
+flag0=134217762
flagg0=1207959552
flagh0=-2147483628
-flagi0=4
-tflag0=6227
+flagi0=4194308
+tflag0=64
initx0=0
inity0=0
minx0=0
@@ -24,3 +24,5 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+launchpath0=
+flagj0=128
diff --git a/build/exports/Icewind Dale II.dxw b/build/exports/Icewind Dale II.dxw
new file mode 100644
index 0000000..7e1dc70
--- /dev/null
+++ b/build/exports/Icewind Dale II.dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Icewind Dale II
+path0=D:\Games\DnDMC\Icewind Dale II\IWD2.exe
+launchpath0=
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=134217762
+flagg0=1207959552
+flagh0=20
+flagi0=138543108
+flagj0=8320
+tflag0=129
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Icewind Dale.dxw b/build/exports/Icewind Dale.dxw
new file mode 100644
index 0000000..2b6d5fb
--- /dev/null
+++ b/build/exports/Icewind Dale.dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Icewind Dale
+path0=D:\Games\DnDMC\Icewind Dale\IDMain.exe
+launchpath0=
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=134217762
+flagg0=1207959552
+flagh0=20
+flagi0=138543108
+flagj0=8320
+tflag0=0
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Incoming (GOG).dxw b/build/exports/Incoming (GOG).dxw
index 5d12196..04531e5 100644
--- a/build/exports/Incoming (GOG).dxw
+++ b/build/exports/Incoming (GOG).dxw
@@ -5,10 +5,10 @@ module0=
opengllib0=
ver0=7
coord0=0
-flag0=150994976
+flag0=134217762
flagg0=1207959552
flagh0=20
-flagi0=4
+flagi0=4194308
tflag0=1024
initx0=0
inity0=0
@@ -24,3 +24,5 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+launchpath0=
+flagj0=128
diff --git a/build/exports/Lords of Magic Special Edition.dxw b/build/exports/Lords of Magic Special Edition.dxw
index c5048f2..7ebbfc7 100644
--- a/build/exports/Lords of Magic Special Edition.dxw
+++ b/build/exports/Lords of Magic Special Edition.dxw
@@ -5,11 +5,11 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=404766753
+flag0=402669603
flagg0=1207959552
-flagh0=6291540
-flagi0=0
-tflag0=6419
+flagh0=6291476
+flagi0=4194304
+tflag0=0
initx0=0
inity0=0
minx0=0
@@ -22,3 +22,7 @@ sizx0=800
sizy0=600
maxfps0=0
initts0=0
+launchpath0=
+flagj0=128
+winver0=0
+maxres0=0
diff --git a/build/exports/Panzer General 3 Scorched Earth.dxw b/build/exports/Panzer General 3 Scorched Earth.dxw
new file mode 100644
index 0000000..8a17e47
--- /dev/null
+++ b/build/exports/Panzer General 3 Scorched Earth.dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Panzer General 3 Scorched Earth
+path0=D:\Games\Panzer_General_3\PG3.exe
+launchpath0=
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=671088674
+flagg0=1207975936
+flagh0=2097172
+flagi0=138412036
+flagj0=8328
+tflag0=0
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Requiem Avenging Angel (D3D).dxw b/build/exports/Requiem Avenging Angel (D3D).dxw
index 3caea75..7a7d73a 100644
--- a/build/exports/Requiem Avenging Angel (D3D).dxw
+++ b/build/exports/Requiem Avenging Angel (D3D).dxw
@@ -6,7 +6,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=-1468006112
+flag0=-1468006366
flagg0=1207959552
flagh0=20
flagi0=138412036
@@ -25,3 +25,4 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+flagj0=128
diff --git a/build/exports/Risk II (Hasbro).dxw b/build/exports/Risk II (Hasbro).dxw
new file mode 100644
index 0000000..3b21bfc
--- /dev/null
+++ b/build/exports/Risk II (Hasbro).dxw
@@ -0,0 +1,28 @@
+[target]
+title0=Risk II (Hasbro)
+path0=D:\Games\Risk 2\RISKII.EXE
+launchpath0=
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=134217762
+flagg0=1207959552
+flagh0=20
+flagi0=138412036
+flagj0=128
+tflag0=0
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/exports/Settlers 3, the.dxw b/build/exports/Settlers 3, the.dxw
index a972e51..bc1c9de 100644
--- a/build/exports/Settlers 3, the.dxw
+++ b/build/exports/Settlers 3, the.dxw
@@ -8,7 +8,7 @@ coord0=0
flag0=-1476394974
flagg0=1207959618
flagh0=20
-flagi0=4
+flagi0=4194308
tflag0=64
initx0=0
inity0=0
@@ -24,3 +24,5 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+launchpath0=
+flagj0=128
diff --git a/build/exports/Summoner, the.dxw b/build/exports/Summoner, the.dxw
index ccf4c60..fcff169 100644
--- a/build/exports/Summoner, the.dxw
+++ b/build/exports/Summoner, the.dxw
@@ -6,7 +6,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=150994976
+flag0=134217762
flagg0=1207959552
flagh0=20
flagi0=138412036
@@ -25,3 +25,4 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+flagj0=128
diff --git a/build/exports/dxwnd.ini b/build/exports/dxwnd.ini
index baaa080..49efe1f 100644
--- a/build/exports/dxwnd.ini
+++ b/build/exports/dxwnd.ini
@@ -1,5 +1,5 @@
[window]
-posx=1182
-posy=638
-sizx=320
-sizy=200
+posx=1122
+posy=297
+sizx=365
+sizy=298
diff --git a/build/exports/eXpendable.dxw b/build/exports/eXpendable.dxw
new file mode 100644
index 0000000..38c084d
--- /dev/null
+++ b/build/exports/eXpendable.dxw
@@ -0,0 +1,28 @@
+[target]
+title0=eXpendable
+path0=D:\Games\eXpendable\go.exe
+launchpath0=D:\Games\eXpendable\Expendable.exe
+module0=
+opengllib0=
+ver0=0
+coord0=0
+flag0=134217762
+flagg0=1207959552
+flagh0=20
+flagi0=134217732
+flagj0=8320
+tflag0=129
+initx0=0
+inity0=0
+minx0=0
+miny0=0
+maxx0=0
+maxy0=0
+posx0=50
+posy0=50
+sizx0=800
+sizy0=600
+maxfps0=0
+initts0=0
+winver0=0
+maxres0=-1
diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt
index a0fe1a0..57b8235 100644
--- a/build/readme-relnotes.txt
+++ b/build/readme-relnotes.txt
@@ -636,3 +636,10 @@ fix: revised FPS control to assure more stable fps when a FPS limit delay is set
v2.02.97
fix: mouse black trails in "Deadlock II"
fix: missing default value for filter mode
+
+v2.02.98
+fix: better ddraw surface handling - now "Darkened Skye" runs in emulated surface mode with perfect colors
+fix: fixed RDTSC opcode search loop - fixed time stretching for "Ubik"
+add: added "Peplace privileged opcodes" flag - makes unpatched "Ubik" run
+fix: revised ddsurface capabilities policy to allow D3D1-7 games to run in emulated mode and bilinear filtering
+
diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp
index deea278..01ac518 100644
--- a/dll/ddraw.cpp
+++ b/dll/ddraw.cpp
@@ -435,8 +435,10 @@ static void LogSurfaceAttributes(LPDDSURFACEDESC lpddsd, char *label, int line)
if (lpddsd->dwFlags & DDSD_ALPHABITDEPTH) OutTrace(" AlphaBitDepth=%d", lpddsd->dwAlphaBitDepth);
if (lpddsd->dwFlags & DDSD_REFRESHRATE) OutTrace(" RefreshRate=%d", lpddsd->dwRefreshRate);
if (lpddsd->dwFlags & DDSD_LINEARSIZE) OutTrace(" LinearSize=%d", lpddsd->dwLinearSize);
- //if (lpddsd->dwFlags & DDSD_TEXTURESTAGE) OutTrace(" TextureStage=%x", lpddsd->dwTextureStage);
- //if (lpddsd->dwFlags & DDSD_FVF) OutTrace(" FVF=%x", lpddsd->dwFVF);
+ if (lpddsd->dwSize == sizeof(DDSURFACEDESC2)){
+ if (lpddsd->dwFlags & DDSD_TEXTURESTAGE) OutTrace(" TextureStage=%x", ((LPDDSURFACEDESC2)lpddsd)->dwTextureStage);
+ if (lpddsd->dwFlags & DDSD_FVF) OutTrace(" FVF=%x", ((LPDDSURFACEDESC2)lpddsd)->dwFVF);
+ }
OutTrace("\n");
}
@@ -2050,339 +2052,54 @@ HRESULT WINAPI extSetCooperativeLevel(void *lpdd, HWND hwnd, DWORD dwflags)
return res;
}
-#ifdef DXWND_ANALYTICMODE
-#define FIX_FLAGSMASK (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_ZBUFFERBITDEPTH|DDSD_TEXTURESTAGE)
-
-void FixSurfaceCapsAnalytic(LPDDSURFACEDESC2 lpddsd, int dxversion)
-{
- switch (lpddsd->dwFlags & FIX_FLAGSMASK){
- //case 0:
- // switch (lpddsd->ddsCaps.dwCaps){
- // case 0:
- // // Star Force Deluxe
- // lpddsd->dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
- // lpddsd->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
- // lpddsd->dwHeight = dxw.GetScreenHeight();
- // lpddsd->dwWidth = dxw.GetScreenWidth();
- // GetPixFmt(lpddsd);
- // return;
- // break;
- // }
- // break;
- case DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE:
- // Ancient Evil:
- // dwFlags: DDSD_CAPS+HEIGHT+WIDTH+PIXELFORMAT+TEXTURESTAGE
- // dwCaps1: DDSCAPS_OFFSCREENPLAIN+SYSTEMMEMORY+TEXTURE
- // dwCaps2: DDSCAPS2_TEXTUREMANAGE
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_ZBUFFERBITDEPTH:
- switch (lpddsd->ddsCaps.dwCaps){
- case DDSCAPS_VIDEOMEMORY|DDSCAPS_ZBUFFER:
- // Dungeon Keeper II
- return;
- break;
- case DDSCAPS_SYSTEMMEMORY|DDSCAPS_ZBUFFER:
- // "Star Wars Shadows of the Empire" through d3d
- return;
- break;
- }
- break;
- case DDSD_CAPS|DDSD_WIDTH:
- switch (lpddsd->ddsCaps.dwCaps){
- case DDSCAPS_SYSTEMMEMORY:
- return;
- break;
- case DDSCAPS_VIDEOMEMORY:
- return;
- break;
- case DDSCAPS_SYSTEMMEMORY|DDSCAPS_RESERVED2:
- // Martian Gothic
- return;
- break;
- case DDSCAPS_VIDEOMEMORY|DDSCAPS_RESERVED2:
- // Martian Gothic
- return;
- break;
- case DDSCAPS_VIDEOMEMORY|DDSCAPS_WRITEONLY|DDSCAPS_RESERVED2:
- // Empire Earth
- return;
- break;
- }
- break;
- case DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH:
- switch (lpddsd->ddsCaps.dwCaps){
- case DDSCAPS_BACKBUFFER|DDSCAPS_SYSTEMMEMORY:
- // Vangers
- lpddsd->ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE|DDSCAPS_VIDEOMEMORY:
- // Bunnies must die
- lpddsd->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE|DDSCAPS_SYSTEMMEMORY; // NOT WORKING
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY:
- // Alien Nations, Heroes of Might & Magic IV --- troublesome!!!!
- lpddsd->dwFlags = (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT);
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY:
- // Cave Story, HoMM3
- lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_SYSTEMMEMORY:
- // Magic & Mayhem
- lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- lpddsd->ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN;
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN:
- // Cave Story, Magic & Mayhem
- lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- lpddsd->ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN;
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE:
- // Nightmare Ned
- lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_SYSTEMMEMORY|DDSCAPS_3DDEVICE:
- // Actua Soccer 3
- lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_VIDEOMEMORY|DDSCAPS_3DDEVICE:
- // Actua Soccer 3
- lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- lpddsd->ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_3DDEVICE;
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE|DDSCAPS_SYSTEMMEMORY:
- // Nightmare Ned, The Sims ???
- lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- GetPixFmt(lpddsd);
- return;
- break;
- }
- break;
- case DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH:
- switch (lpddsd->ddsCaps.dwCaps){
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY:
- // Airline Tycoon Evolution
- return;
- break;
- }
- break;
- case DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT:
- switch (lpddsd->ddsCaps.dwCaps){
- case DDSCAPS_COMPLEX|DDSCAPS_SYSTEMMEMORY|DDSCAPS_TEXTURE|DDSCAPS_MIPMAP: // Powerslide
- case DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_TEXTURE|DDSCAPS_MIPMAP: // Powerslide
- return;
- break;
- case DDSCAPS_SYSTEMMEMORY|DDSCAPS_TEXTURE|DDSCAPS_3DDEVICE:
- case DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM:
- case DDSCAPS_COMPLEX|DDSCAPS_FLIP|DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM:
- case DDSCAPS_COMPLEX|DDSCAPS_FLIP|DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY:
- // Zoo Tycoon
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM:
- // Empire Earth
- // tbd
- // try
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE|DDSCAPS_SYSTEMMEMORY);
- // eotry
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN:
- // Submarine titans (8BPP)
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN);
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY:
- // Duckman, HoM&M4, Beavis & Butthead do U.
- // unsetting the Pixel Format may cause the backbuffer to be created with DDPF_ALPHAPIXELS flag on
- // and some generic surface with DDPF_ALPHAPIXELS off, so that blitting is unsupported.
- // But it seems impossible to get HOMM4 to cope with Beavis & Butthead!!!
- if(!(dxw.dwFlags3 & NOPIXELFORMAT)) GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY:
- // Dungeon Keeper II GOG release (intro screen): doesn't like calling GetPixFmt!!!
- // it requests a DDPF_FOURCC surface with fourcc="YYYY" that should not be overridden?
- //
- // need not to be configurable until we get a different case.
- // it works both on VIDEOMEMORY or SYSTEMMEMORY. The latter should be more stable.
- // v2.02.41: don't alter FOURCC pixel formats
- if(lpddsd->ddpfPixelFormat.dwFlags & DDPF_FOURCC) return;
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN);
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM:
- // Empire Earth
- // Zoo Tycoon: better leave as it is....
- // lpddsd->ddsCaps.dwCaps = (DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN); ????
- return;
- break;
- case DDSCAPS_COMPLEX|DDSCAPS_TEXTURE|DDSCAPS_MIPMAP:
- // Empire Earth: flags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_MIPMAPCOUNT
- return;
- break;
- case DDSCAPS_SYSTEMMEMORY|DDSCAPS_ZBUFFER:
- // the Sims
- return;
- break;
- case DDSCAPS_SYSTEMMEMORY|DDSCAPS_TEXTURE:
- // Wargames Direct3D hw acceleration
- // Star Wars Shadows of the Empire in RGB HEL mode
- return;
- break;
- case DDSCAPS_TEXTURE:
- // Empire Earth
- return;
- break;
- case DDSCAPS_VIDEOMEMORY|DDSCAPS_ZBUFFER:
- // Martian Gothic
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_SYSTEMMEMORY|DDSCAPS_ZBUFFER); // working ????
- return;
- break;
- case DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM|DDSCAPS_ZBUFFER:
- // Rayman 2
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_SYSTEMMEMORY|DDSCAPS_ZBUFFER); // working ????
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY|DDSCAPS_3DDEVICE:
- // Premier Manager 98
- GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY: // NOT WORKING
- // Bunnies must die (not the horny ones!)
- lpddsd->ddsCaps.dwCaps = DDSCAPS_OVERLAY|DDSCAPS_SYSTEMMEMORY;
- return;
- break;
- case DDSCAPS_SYSTEMMEMORY:
- // Star Force Deluxe
- lpddsd->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
- // GetPixFmt(lpddsd);
- return;
- break;
- case DDSCAPS_TEXTURE|DDSCAPS_VIDEOMEMORY|DDSCAPS_ALLOCONLOAD:
- // Star Wars Shadows of the Empire
- // seems to work both with/without GetPixFmt, but doesn't like DDSCAPS_SYSTEMMEMORY textures.
- // Setting GetPixFmt makes bad alpha transparencies!
- // DDSCAPS_VIDEOMEMORY doesn't work with HEL only! Better switch to DDSCAPS_SYSTEMMEMORY.
- if (dxw.dwFlags3 & FORCESHEL) lpddsd->ddsCaps.dwCaps = (DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY|DDSCAPS_ALLOCONLOAD);
- return;
- break;
- }
- break;
- case DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_PIXELFORMAT:
- switch (lpddsd->ddsCaps.dwCaps){
- case DDSCAPS_SYSTEMMEMORY:
- // Wargames
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN);
- GetPixFmt(lpddsd);
- //lpddsd->dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH; // turn DDSD_PIXELFORMAT off
- return;
- break;
- case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY:
- // A10 Cuba
- lpddsd->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; // DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY working as well...
- return;
- break;
- }
- break;
-
- }
-
- if(dxw.dwFlags3 & SURFACEWARN){
- char sMsg[512];
- sprintf(sMsg, "Flags=%x(%s) Caps=%x(%s)", lpddsd->dwFlags, ExplainFlags(lpddsd->dwFlags), lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps));
- MessageBox(0, sMsg, "FixSurfaceCaps unmanaged setting", MB_OK | MB_ICONEXCLAMATION);
- }
-}
-#endif
static void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion)
{
- // To do: fix Dungeon Keeper II
-
// rules of thumb:
- // 1) always get rid of DDSCAPS_VIDEOMEMORY & DDSCAPS_LOCALVIDMEM caps
- // 2) always add DDSCAPS_SYSTEMMEMORY caps
- // 3) DDSCAPS_SYSTEMMEMORY is supported from dxversion 4
- // 4) if DDSD_CAPS is not set, ignore caps
- // 5) ignore DDSD_CKSRCBLT, ....
- // 6) setting a different pixel format in memory requires DDSCAPS_OFFSCREENPLAIN capability
- // 7) DDSD_TEXTURESTAGE surfaces may need to adjust pixel format (....???)
- // 8) Generic surfaces are mapped to SYSTEMMEMORY and set to primary surface PixelFormat
- // 9) When pixelformat is unspecified, be sure to pick the right one (with or without alphapixels?)
- // 10) Don't alter surfaces with a color depth different from primary surface (Lords of Magic Special Edition)
+ // 1) textures should be left untouched (switching to SYSTEMMEMORY when forcing HEL may even fail!)
+ // 2) if a pixel format is specified, if DDSCAPS_SYSTEMMEMORY add DDSCAPS_OFFSCREENPLAY (if pixel formats are different?), otherwise do not touch anything.
+ // 3) if the surface is used as a buffer (DDSD_WIDTH set, DDSD_HEIGHT unset) do not touch anything.
+ // 4) zbuffer surfaces (DDSCAPS_ZBUFFER set) must have DDSCAPS_SYSTEMMEMORY
+ // 5) DDSCAPS_3DDEVICE surfaces should have a defined pixel format
+ // 6) in all remaining cases, adjust the pixel format and ensure you have DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN
if(!(lpddsd->dwFlags & DDSD_CAPS)) lpddsd->ddsCaps.dwCaps = 0;
OutTraceDW("FixSurfaceCaps: Flags=%x(%s) Caps=%x(%s)\n",
lpddsd->dwFlags, ExplainFlags(lpddsd->dwFlags), lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps));
-#ifdef DXWND_ANALYTICMODE
- if(dxw.dwFlags3 & ANALYTICMODE) return FixSurfaceCapsAnalytic(lpddsd, dxversion);
-#endif
-
- if((lpddsd->dwFlags & (DDSD_WIDTH|DDSD_HEIGHT)) == DDSD_WIDTH) {
- // buffer surface - no changes
- return;
- }
- if((lpddsd->dwFlags & (DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE)) == (DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE)){
- // textures, set proper color depth and make no further changes
- GetPixFmt(lpddsd);
- return;
- }
- if((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) { // z-buffer surface - set to memory
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_SYSTEMMEMORY|DDSCAPS_ZBUFFER);
- return;
- }
- if((lpddsd->dwFlags & DDSD_CAPS) &&
- (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) &&
- !(lpddsd->ddsCaps.dwCaps & DDSCAPS_TEXTURE)) // v2.02.90: added for "Zoo Tycoon" textures
- { // 3DDEVICE no TEXTURE: enforce PIXELFORMAT on MEMORY
- lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY|DDSCAPS_3DDEVICE);
- GetPixFmt(lpddsd);
- return;
- }
// DDSCAPS_TEXTURE surfaces must be left untouched, unless you set FORCESHEL: in this case switch VIDEOMEMORY to SYSTEMMEMORY
if((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_TEXTURE)){
if (dxw.dwFlags3 & FORCESHEL) {
lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
}
- // no further changes...
return;
}
- if(lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH){
- lpddsd->dwFlags &= ~DDSD_PIXELFORMAT;
+ // this is valid just in case the above block eliminated TEXTURE surfaces....
+ if (lpddsd->dwFlags & DDSD_PIXELFORMAT){ // pixel format defined
+ if (lpddsd->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) lpddsd->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; // to allow for pixel format conversion (Quest for Glory 5 - GOG version)
+ return;
}
- // v2.02.41: don't alter FOURCC pixel formats
- if((lpddsd->dwFlags & DDSD_PIXELFORMAT) && (lpddsd->ddpfPixelFormat.dwFlags & DDPF_FOURCC)) return;
+ if ((lpddsd->dwFlags & (DDSD_WIDTH|DDSD_HEIGHT)) == DDSD_WIDTH) { // buffer surface
+ return;
+ }
- // v2.02.50: don't alter surfaces with different color depth
- if((lpddsd->dwFlags & DDSD_PIXELFORMAT) && (lpddsd->ddpfPixelFormat.dwRGBBitCount != dxw.VirtualPixelFormat.dwRGBBitCount)) return;
+ if((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) { // z-buffer surface - set to memory
+ lpddsd->ddsCaps.dwCaps = (DDSCAPS_SYSTEMMEMORY|DDSCAPS_ZBUFFER);
+ return;
+ }
+
+ if((lpddsd->dwFlags & DDSD_CAPS) &&
+ (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) // v2.02.90: added for "Zoo Tycoon" textures
+ { // 3DDEVICE no TEXTURE: enforce PIXELFORMAT on MEMORY
+ lpddsd->dwFlags |= DDSD_PIXELFORMAT;
+ lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY|DDSCAPS_3DDEVICE);
+ GetPixFmt(lpddsd);
+ return;
+ }
// default case: adjust pixel format
OutTraceB("FixSurfaceCaps: suppress DDSCAPS_VIDEOMEMORY case\n");
@@ -2406,6 +2123,9 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf
DDSURFACEDESC2 ddsd;
HRESULT res;
+ // save primary surface type for later use
+ bIs3DPrimarySurfaceDevice = (lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE);
+
// emulated primary surface
memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize);
@@ -2419,8 +2139,18 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf
ddsd.dwFlags &= ~(DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE);
ddsd.dwFlags |= (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT);
ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM);
+#if 0
// DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces
ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
+#else
+ // "problematic" situations:
+ // New Your Racer (intro movies & 3D part) Caps=DDSCAPS_COMPLEX+OVERLAY Pixel.Flags=DDPF_FOURCC
+ //ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
+ //if(lpddsd->ddsCaps.dwCaps & DDSCAPS_OVERLAY) ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_SYSTEMMEMORY);
+ //if(lpddsd->ddsCaps.dwCaps & DDSCAPS_OVERLAY) ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_OFFSCREENPLAIN);
+ ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
+ //ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+#endif
// on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it....
if(dxw.dwFlags5 & NOSYSTEMEMULATED) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = dxw.GetScreenWidth();
@@ -2488,7 +2218,12 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf
ClearSurfaceDesc((void *)&ddsd, dxversion);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
// DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces
+ // DDSCAPS_SYSTEMMEMORY makes operations faster, but it is not always good...
ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
+ // "problematic" situations that need no DDSCAPS_SYSTEMMEMORY:
+ // Flying Heroes (caps=DDSCAPS_3DDEVICE)
+ // Echelon (caps=DDSCAPS_COMPLEX+3DDEVICE)
+ if(bIs3DPrimarySurfaceDevice) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
// on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it....
if(dxw.dwFlags5 & NOSYSTEMEMULATED) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = dxw.GetScreenWidth();
@@ -2520,17 +2255,15 @@ static HRESULT BuildPrimaryDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf
DDSURFACEDESC2 ddsd;
HRESULT res;
+ bIs3DPrimarySurfaceDevice = (lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE);
+
// genuine primary surface
memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize);
ddsd.dwFlags &= ~(DDSD_WIDTH|DDSD_HEIGHT|DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE|DDSD_PIXELFORMAT);
ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_FLIP|DDSCAPS_COMPLEX);
// v2.02.93: don't move primary / backbuf surfaces on systemmemory when 3DDEVICE is requested
// this impact also on capabilities for temporary surfaces for AERO optimized handling
- bIs3DPrimarySurfaceDevice = FALSE;
- if(lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) {
- ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
- bIs3DPrimarySurfaceDevice = TRUE;
- }
+ if(bIs3DPrimarySurfaceDevice) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
// create Primary surface
DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__);
@@ -3067,31 +2800,47 @@ HRESULT WINAPI PrimaryFastBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDI
HRESULT WINAPI PrimaryStretchBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect)
{
HRESULT res;
- DDSURFACEDESC ddsd;
+ DDSURFACEDESC2 ddsd;
RECT TmpRect;
LPDIRECTDRAWSURFACE lpddsTmp;
LPDIRECTDRAWSURFACE lpddsBak;
DDSCAPS caps;
+ CreateSurface1_Type pCreateSurface;
+ int dwSize;
+
+ switch(iBakBufferVersion){
+ default:
+ case 1: pCreateSurface=pCreateSurface1; dwSize = sizeof(DDSURFACEDESC); break;
+ case 2: pCreateSurface=(CreateSurface1_Type)pCreateSurface2; dwSize = sizeof(DDSURFACEDESC); break;
+ case 3: pCreateSurface=(CreateSurface1_Type)pCreateSurface3; dwSize = sizeof(DDSURFACEDESC); break;
+ case 4: pCreateSurface=(CreateSurface1_Type)pCreateSurface4; dwSize = sizeof(DDSURFACEDESC2); break;
+ case 7: pCreateSurface=(CreateSurface1_Type)pCreateSurface7; dwSize = sizeof(DDSURFACEDESC2); break;
+ }
caps.dwCaps = DDSCAPS_BACKBUFFER;
memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwSize = dwSize;
if(lpddssrc==NULL){
// blit from backbuffer
- lpdds->GetAttachedSurface(&caps, &lpddsBak);
- if(lpddsBak) lpddsBak->GetSurfaceDesc(&ddsd);
+ lpdds->GetAttachedSurface(&caps, &(LPDIRECTDRAWSURFACE)lpddsBak);
+ lpddsBak->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
}
else{
// blit from surface
- lpddssrc->GetSurfaceDesc(&ddsd);
+ lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
}
TmpRect.left = TmpRect.top = 0;
TmpRect.bottom = ddsd.dwHeight = lpdestrect->bottom - lpdestrect->top;
TmpRect.right = ddsd.dwWidth = lpdestrect->right - lpdestrect->left;
+ if((TmpRect.bottom==0) || (TmpRect.right==0)) return DD_OK; // avoid blitting to null areas (Fifa 2000 D3D)
ddsd.dwFlags = (DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS);
// capabilities must cope with primary / backbuffer surface capabilities to get speedy operations
ddsd.ddsCaps.dwCaps = bIs3DPrimarySurfaceDevice ? DDSCAPS_OFFSCREENPLAIN : (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
- res=(*pCreateSurface1)(lpPrimaryDD, &ddsd, &lpddsTmp, NULL);
- if(res) OutTraceE("CreateSurface: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
+ res=(*pCreateSurface)(lpPrimaryDD, (LPDDSURFACEDESC)&ddsd, &lpddsTmp, NULL);
+ if(res) {
+ OutTraceE("CreateSurface: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
+ if(IsDebug) DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Gateway]" , __LINE__);
+ return res;
+ }
// stretch-blit to target size on OFFSCREENPLAIN temp surface
res= (*pBlt)(lpddsTmp, &TmpRect, lpddssrc, lpsrcrect, DDBLT_WAIT, 0);
if(res) OutTraceE("Blt: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
@@ -3108,7 +2857,7 @@ HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
HRESULT res;
extern void Resize_HQ_4ch( unsigned char*, RECT *, int, unsigned char*, RECT *, int);
/* to be implemented .... */
- DDSURFACEDESC ddsd;
+ DDSURFACEDESC2 ddsd;
RECT TmpRect, SrcRect;
LPDIRECTDRAWSURFACE lpddsTmp;
LPDIRECTDRAWSURFACE lpddsBak;
@@ -3117,17 +2866,28 @@ HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
BYTE *bSourceBuf, *bDestBuf;
LONG dwWidth, dwHeight;
int SrcPitch, DestPitch;
+ CreateSurface1_Type pCreateSurface;
+ int dwSize;
+
+ switch(iBakBufferVersion){
+ default:
+ case 1: pCreateSurface=pCreateSurface1; dwSize = sizeof(DDSURFACEDESC); break;
+ case 2: pCreateSurface=(CreateSurface1_Type)pCreateSurface2; dwSize = sizeof(DDSURFACEDESC); break;
+ case 3: pCreateSurface=(CreateSurface1_Type)pCreateSurface3; dwSize = sizeof(DDSURFACEDESC); break;
+ case 4: pCreateSurface=(CreateSurface1_Type)pCreateSurface4; dwSize = sizeof(DDSURFACEDESC2); break;
+ case 7: pCreateSurface=(CreateSurface1_Type)pCreateSurface7; dwSize = sizeof(DDSURFACEDESC2); break;
+ }
caps.dwCaps = DDSCAPS_BACKBUFFER;
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
+ ddsd.dwSize = dwSize;
if(lpddssrc==NULL){
// blit from backbuffer
lpdds->GetAttachedSurface(&caps, &lpddsBak);
- if(lpddsBak) lpddsBak->GetSurfaceDesc(&ddsd);
+ if(lpddsBak) lpddsBak->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
}
else{
// blit from surface
- lpddssrc->GetSurfaceDesc(&ddsd);
+ lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd);
}
// assign source RECT values anyway....
@@ -3146,19 +2906,19 @@ HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
ddsd.dwFlags = (DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS);
// capabilities must cope with primary / backbuffer surface capabilities to get speedy operations
ddsd.ddsCaps.dwCaps = bIs3DPrimarySurfaceDevice ? DDSCAPS_OFFSCREENPLAIN : (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
- res=(*pCreateSurface1)(lpPrimaryDD, (LPDDSURFACEDESC)&ddsd, &lpddsTmp, NULL);
+ res=(*pCreateSurface)(lpPrimaryDD, (LPDDSURFACEDESC)&ddsd, &lpddsTmp, NULL);
if(res) OutTraceE("CreateSurface: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
// get informations
- memset(&ddsd,0,sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
+ memset(&ddsd,0,dwSize);
+ ddsd.dwSize = dwSize;
ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
res=(*pLock)(lpddssrc, 0, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY, 0);
if(res) OutTraceE("Lock: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
bSourceBuf = (BYTE *)ddsd.lpSurface;
SrcPitch = ddsd.lPitch;
- memset(&ddsd,0,sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
+ memset(&ddsd,0,dwSize);
+ ddsd.dwSize = dwSize;
ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
res=(*pLock)(lpddsTmp, 0, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0);
if(res) OutTraceE("Lock: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
@@ -3171,10 +2931,8 @@ HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
bDestBuf, lpdestrect, DestPitch);
// fast-blit to primary
- if(lpddssrc==lpDDSEmu_Back) lpddssrc->Unlock(NULL); // this surface is unhooked!!!
- else (*pUnlock1)(lpddssrc, NULL);
- //(*pUnlock1)(lpddsTmp, NULL);
- lpddsTmp->Unlock(NULL); // this surface is unhooked!!!
+ (*pUnlockMethod(lpddssrc))(lpddssrc, NULL);
+ (*pUnlockMethod(lpddsTmp))(lpddsTmp, NULL);
res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT);
if(res) OutTraceE("BltFast: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
(*pReleaseS)(lpddsTmp);
@@ -3454,9 +3212,11 @@ HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
Dungeon Keeper II intro movies bug ....
it seems that you can't blit from compressed or different surfaces in memory,
while the operation COULD be supported to video. As a mater of fact, it DOES
- work on my PC.
+ work on my PC. The error code is DDERR_UNSUPPORTED.
+ v2.02.98 update....
+ The same thing happens with New York Racer, but with DDERR_EXCEPTION error code.
*/
- if(res==DDERR_UNSUPPORTED){
+ if((res==DDERR_UNSUPPORTED) || (res==DDERR_EXCEPTION)){
dxw.ShowOverlay(lpddssrc);
if (IsDebug) BlitTrace("UNSUPP", &emurect, &destrect, __LINE__);
res=(*pBlt)(lpDDSEmu_Prim, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
@@ -4006,15 +3766,14 @@ HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRAWSURFAC
if(res==DDERR_NOTLOCKED) res=DD_OK; // ignore not locked error
if (res) OutTraceE("Unlock ERROR res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__);
if (IsPrim && res==DD_OK) {
- sBlt("Unlock", lpdds, NULL, lpdds, NULL, NULL, 0, FALSE);
- // v2.02.97: set dirty rect to syncronize with gdi operations. See "Deadlock II" problems...
- RECT dirty;
- if(lprect){
- dirty = *lprect;
- dxw.MapClient(&dirty);
- lprect = &dirty;
+ if(dxversion == 1){
+ res=sBlt("Unlock", lpdds, NULL, lpdds, NULL, NULL, 0, FALSE);
+ if(IsPrim) (*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); // to fix "Deadlock II" mouse trails....
+ }
+ else {
+ res=sBlt("Unlock", lpdds, lprect, lpdds, lprect, NULL, 0, FALSE);
+ if(IsPrim) (*pInvalidateRect)(dxw.GethWnd(), lprect, FALSE);
}
- (*pInvalidateRect)(dxw.GethWnd(), lprect, FALSE);
}
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
@@ -4914,6 +4673,7 @@ HRESULT WINAPI extGetSurfaceDesc7(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 l
OutTraceDW("GetSurfaceDesc: ASSERT - bad dwSize=%d lpdds=%x at %d\n", lpddsd->dwSize, lpdds, __LINE__);
return DDERR_INVALIDOBJECT;
}
+
OutTraceDW("GetSurfaceDesc: ASSERT - missing hook lpdds=%x dwSize=%d(%s) at %d\n",
lpdds, lpddsd->dwSize, lpddsd->dwSize==sizeof(DDSURFACEDESC)?"DDSURFACEDESC":"DDSURFACEDESC2", __LINE__);
return DDERR_INVALIDOBJECT;
diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp
index befd72d..5e2b8d0 100644
--- a/dll/dxhook.cpp
+++ b/dll/dxhook.cpp
@@ -95,7 +95,7 @@ static char *Flag4Names[32]={
static char *Flag5Names[32]={
"DIABLOTWEAK", "CLEARTARGET", "NOWINPOSCHANGES", "NOSYSTEMMEMORY",
"NOBLT", "NOSYSTEMEMULATED", "DOFASTBLT", "AEROBOOST",
- "QUARTERBLT", "NOIMAGEHLP", "BILINEARFILTER", "",
+ "QUARTERBLT", "NOIMAGEHLP", "BILINEARFILTER", "REPLACEPRIVOPS",
"", "", "", "",
"", "", "", "",
"", "", "", "",
@@ -616,7 +616,7 @@ LRESULT CALLBACK extDialogWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPA
t = (*pGetTickCount)();
int tn = (*pGetTickCount)();
- OutTraceW("DEBUG: DialogWinMsg [0x%x]%s(%x,%x)\n", message, ExplainWinMessage(message), wparam, lparam);
+ OutTraceW("DEBUG: DialogWinMsg hwnd=%x msg=[0x%x]%s(%x,%x)\n", hwnd, message, ExplainWinMessage(message), wparam, lparam);
// optimization: don't invalidate too often!
// 200mSec seems a good compromise.
@@ -639,7 +639,7 @@ LRESULT CALLBACK extChildWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPAR
static WINDOWPOS *wp;
WNDPROC pWindowProc;
- OutTraceW("DEBUG: ChildWinMsg [0x%x]%s(%x,%x)\n", message, ExplainWinMessage(message), wparam, lparam);
+ OutTraceW("DEBUG: ChildWinMsg hwnd=%x msg=[0x%x]%s(%x,%x)\n", hwnd, message, ExplainWinMessage(message), wparam, lparam);
if(dxw.Windowize){
switch(message){
@@ -1447,19 +1447,25 @@ static void ReplaceRDTSC()
FreeLibrary(psapilib);
(*pPreparedisasm)();
- opcodes=(unsigned char *)GetModuleHandle(NULL);
+ opcodes = (unsigned char *)mi.lpBaseOfDll;
unsigned int offset = 0;
BOOL cont = TRUE;
OutTraceDW("DXWND: opcode starting at addr=%x size=%x\n", opcodes, dwSegSize);
- while (TRUE) {
- int cmdlen;
+ while (cont) {
+ int cmdlen = 0;
__try{
cmdlen=(*pDisasm)(opcodes+offset,20,offset,&da,0,NULL,NULL);
//OutTrace("offset=%x opcode=%x\n", offset, *(opcodes+offset));
}
__except (EXCEPTION_EXECUTE_HANDLER){
OutTrace("exception at offset=%x\n", offset);
- cont=FALSE;
+ if(opcodes+offset < mi.EntryPoint) {
+ offset = (unsigned char *)mi.EntryPoint - (unsigned char *)mi.lpBaseOfDll;
+ OutTraceDW("DXWND: opcode resuming at addr=%x\n", opcodes+offset);
+ continue;
+ }
+ else
+ cont=FALSE;
}
if (cmdlen==0) break;
// search for RDTSC opcode 0x0F31
@@ -1492,7 +1498,82 @@ static void ReplaceRDTSC()
}
}
offset+=cmdlen;
- if((offset+0x10) > dwSegSize) break;
+ if((offset+0x10) > (int)mi.lpBaseOfDll + dwSegSize) break; // skip last 16 bytes, just in case....
+ }
+
+ return;
+ (*pFinishdisasm)();
+ FreeLibrary(disasmlib);
+}
+
+static void ReplacePrivilegedOps()
+{
+ typedef BOOL (WINAPI *GetModuleInformation_Type)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
+ HMODULE disasmlib;
+ unsigned char *opcodes;
+ t_disasm da;
+ MODULEINFO mi;
+ HMODULE psapilib;
+ GetModuleInformation_Type pGetModuleInformation;
+ DWORD dwSegSize;
+ DWORD oldprot;
+
+ if (!(disasmlib=LoadDisasm())) return;
+
+ // getting segment size
+ psapilib=(*pLoadLibraryA)("psapi.dll");
+ if(!psapilib) {
+ OutTraceDW("DXWND: Load lib=\"%s\" failed err=%d\n", "psapi.dll", GetLastError());
+ return;
+ }
+ pGetModuleInformation=(GetModuleInformation_Type)(*pGetProcAddress)(psapilib, "GetModuleInformation");
+ (*pGetModuleInformation)(GetCurrentProcess(), GetModuleHandle(NULL), &mi, sizeof(mi));
+ dwSegSize = mi.SizeOfImage;
+ FreeLibrary(psapilib);
+
+ (*pPreparedisasm)();
+ opcodes = (unsigned char *)mi.lpBaseOfDll;
+ unsigned int offset = 0;
+ BOOL cont = TRUE;
+ OutTraceDW("DXWND: opcode starting at addr=%x size=%x\n", opcodes, dwSegSize);
+ while (cont) {
+ int cmdlen = 0;
+ __try{
+ cmdlen=(*pDisasm)(opcodes+offset,20,offset,&da,0,NULL,NULL);
+ //OutTrace("offset=%x opcode=%x\n", offset, *(opcodes+offset));
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER){
+ OutTrace("exception at offset=%x\n", offset);
+ if(opcodes+offset < mi.EntryPoint) {
+ offset = (unsigned char *)mi.EntryPoint - (unsigned char *)mi.lpBaseOfDll;
+ OutTraceDW("DXWND: opcode resuming at addr=%x\n", opcodes+offset);
+ continue;
+ }
+ else
+ cont=FALSE;
+ }
+ if (cmdlen==0) break;
+ // search for IN opcode 0xEC (IN AL, DX)
+ if(*(opcodes+offset) == 0xEC){
+ OutTraceDW("DXWND: IN opcode found at addr=%x\n", (opcodes+offset));
+ if(!VirtualProtect((LPVOID)(opcodes+offset), 8, PAGE_READWRITE, &oldprot)) {
+ OutTrace("VirtualProtect ERROR: target=%x err=%d at %d\n", opcodes+offset, GetLastError(), __LINE__);
+ return; // error condition
+ }
+ *(opcodes+offset) = 0x90; // __asm NOP
+ if((*(opcodes+offset+1) == 0xA8) &&
+ ((*(opcodes+offset+3) == 0x75) || (*(opcodes+offset+3) == 0x74))) { // both JNZ and JZ
+ OutTraceDW("DXWND: IN loop found at addr=%x\n", (opcodes+offset));
+ memset((opcodes+offset+1), 0x90, 4); // Ubik I/O loop
+ offset+=4;
+ }
+ if(!VirtualProtect((LPVOID)(opcodes+offset), 8, oldprot, &oldprot)){
+ OutTrace("VirtualProtect ERROR; target=%x, err=%d at %d\n", opcodes+offset, GetLastError(), __LINE__);
+ return; // error condition
+ }
+ }
+ offset+=cmdlen;
+ if((offset+0x10) > (int)mi.lpBaseOfDll + dwSegSize) break; // skip last 16 bytes, just in case....
}
return;
@@ -1638,6 +1719,7 @@ void HookInit(TARGETMAP *target, HWND hwnd)
//if ((hwnd==0) && (dxw.dwFlags4 & INTERCEPTRDTSC)) ReplaceRDTSC();
if (dxw.dwFlags4 & INTERCEPTRDTSC) ReplaceRDTSC();
+ if (dxw.dwFlags5 & REPLACEPRIVOPS) ReplacePrivilegedOps();
if (dxw.dwTFlags & DXPROXED){
HookDDProxy(base, dxw.dwTargetDDVersion);
diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp
index 6b2252a..08dda9e 100644
--- a/dll/dxwnd.cpp
+++ b/dll/dxwnd.cpp
@@ -24,7 +24,7 @@ along with this program. If not, see .
#include "dxwnd.h"
#include "dxwcore.hpp"
-#define VERSION "2.02.97"
+#define VERSION "2.02.98"
#define DXWACTIVATESINGLETASK 1 // comment to allow multiple task activations
#define DDTHREADLOCK 1
diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo
index 4fa8bd3..b4a8eab 100644
Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ
diff --git a/dll/user32.cpp b/dll/user32.cpp
index 46141d7..84dad77 100644
--- a/dll/user32.cpp
+++ b/dll/user32.cpp
@@ -57,7 +57,7 @@ static HookEntry_Type Hooks[]={
{HOOK_IAT_CANDIDATE, "SystemParametersInfoA", (FARPROC)SystemParametersInfoA, (FARPROC *)&pSystemParametersInfoA, (FARPROC)extSystemParametersInfoA},
{HOOK_IAT_CANDIDATE, "SystemParametersInfoW", (FARPROC)SystemParametersInfoW, (FARPROC *)&pSystemParametersInfoW, (FARPROC)extSystemParametersInfoW},
//{HOOK_HOT_CANDIDATE, "GetActiveWindow", (FARPROC)NULL, (FARPROC *)&pGetActiveWindow, (FARPROC)extGetActiveWindow},
- //{HOOK_HOT_CANDIDATE, "GetForegroundWindow", (FARPROC)NULL, (FARPROC *)&pGetForegroundWindow, (FARPROC)extGetForegroundWindow},
+ //{HOOK_HOT_CANDIDATE, "GetForegroundWindow", (FARPROC)GetForegroundWindow, (FARPROC *)&pGetForegroundWindow, (FARPROC)extGetForegroundWindow},
//{HOOK_IAT_CANDIDATE, "GetWindowTextA", (FARPROC)GetWindowTextA, (FARPROC *)&pGetWindowTextA, (FARPROC)extGetWindowTextA},
{HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator
};
diff --git a/host/Resource.h b/host/Resource.h
index 6b79b21..b9405c4 100644
Binary files a/host/Resource.h and b/host/Resource.h differ
diff --git a/host/TabCompat.cpp b/host/TabCompat.cpp
index 485b3a1..57ee6c4 100644
--- a/host/TabCompat.cpp
+++ b/host/TabCompat.cpp
@@ -33,7 +33,6 @@ void CTabCompat::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_HANDLEEXCEPTIONS, cTarget->m_HandleExceptions);
DDX_Check(pDX, IDC_LIMITRESOURCES, cTarget->m_LimitResources);
DDX_Check(pDX, IDC_SUPPRESSIME, cTarget->m_SuppressIME);
- DDX_Check(pDX, IDC_SUPPRESSD3DEXT, cTarget->m_SuppressD3DExt);
DDX_Check(pDX, IDC_CDROMDRIVETYPE, cTarget->m_CDROMDriveType);
DDX_Check(pDX, IDC_FONTBYPASS, cTarget->m_FontBypass);
DDX_Check(pDX, IDC_BUFFEREDIOFIX, cTarget->m_BufferedIOFix);
@@ -44,6 +43,7 @@ void CTabCompat::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_HIDECDROMEMPTY, cTarget->m_HideCDROMEmpty);
DDX_Check(pDX, IDC_DIABLOTWEAK, cTarget->m_DiabloTweak);
DDX_Check(pDX, IDC_NOIMAGEHLP, cTarget->m_NoImagehlp);
+ DDX_Check(pDX, IDC_REPLACEPRIVOPS, cTarget->m_ReplacePrivOps);
// 3D management
DDX_Check(pDX, IDC_NOTEXTURES, cTarget->m_NoTextures);
@@ -51,6 +51,7 @@ void CTabCompat::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_DISABLEFOGGING, cTarget->m_DisableFogging);
DDX_Check(pDX, IDC_CLEARTARGET, cTarget->m_ClearTarget);
DDX_Check(pDX, IDC_NOD3DRESET, cTarget->m_NoD3DReset);
+ DDX_Check(pDX, IDC_SUPPRESSD3DEXT, cTarget->m_SuppressD3DExt);
// Registry management
DDX_Check(pDX, IDC_EMULATEREGISTRY, cTarget->m_EmulateRegistry);
diff --git a/host/TabInput.cpp b/host/TabInput.cpp
index 89dde5d..49e7246 100644
--- a/host/TabInput.cpp
+++ b/host/TabInput.cpp
@@ -27,9 +27,10 @@ void CTabInput::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent()));
+ // Cursor Visibility
+ DDX_Radio(pDX, IDC_CURSORAUTOMATIC, cTarget->m_MouseVisibility);
+ // Cursor Handling
DDX_Check(pDX, IDC_MODIFYMOUSE, cTarget->m_ModifyMouse);
- DDX_Check(pDX, IDC_HIDEHWCURSOR, cTarget->m_HideHwCursor);
- DDX_Check(pDX, IDC_SHOWHWCURSOR, cTarget->m_ShowHwCursor);
DDX_Check(pDX, IDC_ENABLECLIPPING, cTarget->m_EnableClipping);
DDX_Check(pDX, IDC_CLIPCURSOR, cTarget->m_CursorClipping);
DDX_Check(pDX, IDC_KEEPCURSORWITHIN, cTarget->m_KeepCursorWithin);
diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp
index 55f7971..806cae9 100644
--- a/host/TargetDlg.cpp
+++ b/host/TargetDlg.cpp
@@ -25,6 +25,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_DxEmulationMode = 4; // default: AUTOMATIC
m_DxFilterMode = 0; // default: ddraw filtering
m_DCEmulationMode = 0; // default: no emulation
+ m_MouseVisibility = 0;
m_HookDI = FALSE;
m_ModifyMouse = TRUE; // default true !!
m_OutProxyTrace = FALSE;
@@ -43,6 +44,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_AEROBoost = TRUE; // default true !!
m_DiabloTweak = FALSE;
m_NoImagehlp = FALSE;
+ m_ReplacePrivOps = FALSE;
m_DisableHAL = FALSE;
m_ForcesHEL = FALSE;
m_ColorFix = FALSE;
@@ -94,8 +96,6 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_DisableGammaRamp = FALSE;
m_AutoRefresh = FALSE;
m_FixWinFrame = FALSE;
- m_HideHwCursor = FALSE;
- m_ShowHwCursor = FALSE;
m_EnableClipping = FALSE;
m_CursorClipping = FALSE;
m_VideoToSystemMem = FALSE;
diff --git a/host/TargetDlg.h b/host/TargetDlg.h
index 9427847..ed73873 100644
--- a/host/TargetDlg.h
+++ b/host/TargetDlg.h
@@ -29,6 +29,7 @@ public:
int m_DxEmulationMode;
int m_DxFilterMode;
int m_DCEmulationMode;
+ int m_MouseVisibility;
BOOL m_HookDI;
BOOL m_ModifyMouse;
BOOL m_OutProxyTrace;
@@ -58,6 +59,7 @@ public:
BOOL m_NoBanner;
BOOL m_StartDebug;
BOOL m_HookEnabled;
+ BOOL m_ReplacePrivOps;
CString m_FilePath;
CString m_LaunchPath;
CString m_Module;
@@ -71,8 +73,6 @@ public:
BOOL m_DisableGammaRamp;
BOOL m_AutoRefresh;
BOOL m_FixWinFrame;
- BOOL m_HideHwCursor;
- BOOL m_ShowHwCursor;
BOOL m_EnableClipping;
BOOL m_CursorClipping;
BOOL m_VideoToSystemMem;
diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps
index 97192aa..a743b03 100644
Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ
diff --git a/host/dxwndhost.cpp b/host/dxwndhost.cpp
index fe7e6ff..a3150ca 100644
--- a/host/dxwndhost.cpp
+++ b/host/dxwndhost.cpp
@@ -163,6 +163,11 @@ BOOL CDxwndhostApp::InitInstance()
if(ResLib) AfxSetResourceHandle(ResLib);
else MessageBoxEx(NULL, "Missing language \"IT\"\nUsing default language \"en\"", "Warning", MB_OK, NULL);
break;
+ case 0x19: // 419 - russian
+ ResLib=LoadLibrary("Resources_RU.dll");
+ if(ResLib) AfxSetResourceHandle(ResLib);
+ else MessageBoxEx(NULL, "Missing language \"RU\"\nUsing default language \"en\"", "Warning", MB_OK, NULL);
+ break;
default:
//char sBuf[81];
//sprintf(sBuf, "Got Lang=%x(%x-%x)", LangId, LangId>>9, (LangId & 0x1FF));
diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc
index 9696eea..a6b9a84 100644
Binary files a/host/dxwndhost.rc and b/host/dxwndhost.rc differ
diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo
index cab0a08..70361bd 100644
Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ
diff --git a/host/dxwndhost.vs2008.vcproj b/host/dxwndhost.vs2008.vcproj
index 16cd2ed..e6836c9 100644
--- a/host/dxwndhost.vs2008.vcproj
+++ b/host/dxwndhost.vs2008.vcproj
@@ -491,7 +491,7 @@
>
-
-
m_PeekAllMessages) t->flags3 |= PEEKALLMESSAGES;
if(dlg->m_NoWinPosChanges) t->flags5 |= NOWINPOSCHANGES;
- t->flags &= ~EMULATEFLAGS;
switch(dlg->m_DxEmulationMode){
case 0: t->flags |= AUTOMATIC; break;
case 1: break;
@@ -135,28 +134,31 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
break;
}
- t->flags4 &= ~BILINEAR2XFILTER;
- t->flags5 &= ~BILINEARFILTER;
switch(dlg->m_DxFilterMode){
case 0: break;
case 1: t->flags4 |= BILINEAR2XFILTER; break;
case 2: t->flags5 |= BILINEARFILTER; break;
}
- t->flags2 &= ~GDISTRETCHED;
- t->flags &= ~MAPGDITOPRIMARY;
- t->flags3 &= ~GDIEMULATEDC;
switch(dlg->m_DCEmulationMode){
case 0: break;
case 1: t->flags2 |= GDISTRETCHED; break;
case 2: t->flags3 |= GDIEMULATEDC; break;
case 3: t->flags |= MAPGDITOPRIMARY; break;
}
+
switch(dlg->m_ResTypes){
case 0: t->flags4 |= SUPPORTSVGA; break;
case 1: t->flags4 |= SUPPORTHDTV; break;
case 2: t->flags4 |= NATIVERES; break;
}
+
+ switch(dlg->m_MouseVisibility){
+ case 0: break;
+ case 1: t->flags |= HIDEHWCURSOR; break;
+ case 2: t->flags2 |= SHOWHWCURSOR; break;
+ }
+
if(dlg->m_HookDI) t->flags |= HOOKDI;
if(dlg->m_ModifyMouse) t->flags |= MODIFYMOUSE;
if(dlg->m_OutProxyTrace) t->tflags |= OUTPROXYTRACE;
@@ -172,7 +174,6 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
if(dlg->m_ImportTable) t->tflags |= OUTIMPORTTABLE;
if(dlg->m_RegistryOp) t->tflags |= OUTREGISTRY;
if(dlg->m_TraceHooks) t->tflags |= TRACEHOOKS;
- //if(dlg->m_HandleDC) t->flags |= HANDLEDC;
if(dlg->m_HandleExceptions) t->flags |= HANDLEEXCEPTIONS;
if(dlg->m_LimitResources) t->flags2 |= LIMITRESOURCES;
if(dlg->m_CDROMDriveType) t->flags3 |= CDROMDRIVETYPE;
@@ -217,8 +218,6 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
if(dlg->m_DisableGammaRamp) t->flags2 |= DISABLEGAMMARAMP;
if(dlg->m_AutoRefresh) t->flags |= AUTOREFRESH;
if(dlg->m_FixWinFrame) t->flags |= FIXWINFRAME;
- if(dlg->m_HideHwCursor) t->flags |= HIDEHWCURSOR;
- if(dlg->m_ShowHwCursor) t->flags2 |= SHOWHWCURSOR;
if(dlg->m_EnableClipping) t->flags |= ENABLECLIPPING;
if(dlg->m_CursorClipping) t->flags |= CLIPCURSOR;
if(dlg->m_VideoToSystemMem) t->flags |= SWITCHVIDEOMEMORY;
@@ -233,7 +232,6 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
if(dlg->m_NoSystemMemory) t->flags5 |= NOSYSTEMMEMORY;
if(dlg->m_NoSystemEmulated) t->flags5 |= NOSYSTEMEMULATED;
if(dlg->m_NoBlt) t->flags5 |= NOBLT;
- //if(dlg->m_BilinearBlt) t->flags5 |= BILINEARFILTER;
if(dlg->m_FastBlt) t->flags5 |= DOFASTBLT;
if(dlg->m_PreventMaximize) t->flags |= PREVENTMAXIMIZE;
if(dlg->m_ClientRemapping) t->flags |= CLIENTREMAPPING;
@@ -285,6 +283,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
if(dlg->m_NoGDIBlt) t->flags3 |= NOGDIBLT;
if(dlg->m_NoFillRect) t->flags4 |= NOFILLRECT;
if(dlg->m_AnalyticMode) t->flags3 |= ANALYTICMODE;
+ if(dlg->m_ReplacePrivOps) t->flags5 |= REPLACEPRIVOPS;
t->initx = dlg->m_InitX;
t->inity = dlg->m_InitY;
t->minx = dlg->m_MinX;
@@ -345,6 +344,10 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
if(t->flags4 & SUPPORTHDTV) dlg->m_ResTypes = 1;
if(t->flags4 & NATIVERES) dlg->m_ResTypes = 2;
+ dlg->m_MouseVisibility = 0;
+ if(t->flags & HIDEHWCURSOR) dlg->m_MouseVisibility = 1;
+ if(t->flags2 & SHOWHWCURSOR) dlg->m_MouseVisibility = 2;
+
dlg->m_HookDI = t->flags & HOOKDI ? 1 : 0;
dlg->m_ModifyMouse = t->flags & MODIFYMOUSE ? 1 : 0;
dlg->m_OutProxyTrace = t->tflags & OUTPROXYTRACE ? 1 : 0;
@@ -405,8 +408,6 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
dlg->m_DisableGammaRamp = t->flags2 & DISABLEGAMMARAMP ? 1 : 0;
dlg->m_AutoRefresh = t->flags & AUTOREFRESH ? 1 : 0;
dlg->m_FixWinFrame = t->flags & FIXWINFRAME ? 1 : 0;
- dlg->m_HideHwCursor = t->flags & HIDEHWCURSOR ? 1 : 0;
- dlg->m_ShowHwCursor = t->flags2 & SHOWHWCURSOR ? 1 : 0;
dlg->m_EnableClipping = t->flags & ENABLECLIPPING ? 1 : 0;
dlg->m_CursorClipping = t->flags & CLIPCURSOR ? 1 : 0;
dlg->m_VideoToSystemMem = t->flags & SWITCHVIDEOMEMORY ? 1 : 0;
@@ -421,7 +422,6 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
dlg->m_NoSystemMemory = t->flags5 & NOSYSTEMMEMORY ? 1 : 0;
dlg->m_NoSystemEmulated = t->flags5 & NOSYSTEMEMULATED ? 1 : 0;
dlg->m_NoBlt = t->flags5 & NOBLT ? 1 : 0;
- //dlg->m_BilinearBlt = t->flags5 & BILINEARFILTER ? 1 : 0;
dlg->m_FastBlt = t->flags5 & DOFASTBLT ? 1 : 0;
dlg->m_PreventMaximize = t->flags & PREVENTMAXIMIZE ? 1 : 0;
dlg->m_ClientRemapping = t->flags & CLIENTREMAPPING ? 1 : 0;
@@ -473,6 +473,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
dlg->m_NoGDIBlt = t->flags3 & NOGDIBLT ? 1 : 0;
dlg->m_NoFillRect = t->flags4 & NOFILLRECT ? 1 : 0;
dlg->m_AnalyticMode = t->flags3 & ANALYTICMODE ? 1 : 0;
+ dlg->m_ReplacePrivOps = t->flags5 & REPLACEPRIVOPS ? 1 : 0;
dlg->m_InitX = t->initx;
dlg->m_InitY = t->inity;
dlg->m_MinX = t->minx;
diff --git a/host/host.aps b/host/host.aps
index 130bec5..d9b7ec6 100644
Binary files a/host/host.aps and b/host/host.aps differ
diff --git a/host/resource b/host/resource
deleted file mode 100644
index bca6966..0000000
Binary files a/host/resource and /dev/null differ
diff --git a/locale/cn/Resources_Cn.rc b/locale/cn/Resources_Cn.rc
index 17ed92c..9a86a9f 100644
Binary files a/locale/cn/Resources_Cn.rc and b/locale/cn/Resources_Cn.rc differ
diff --git a/locale/cn/Resources_Cn.suo b/locale/cn/Resources_Cn.suo
index a2b6943..b0f99b8 100644
Binary files a/locale/cn/Resources_Cn.suo and b/locale/cn/Resources_Cn.suo differ
diff --git a/locale/it/Resources_IT.rc b/locale/it/Resources_IT.rc
index 5209a87..8ecbd4f 100644
Binary files a/locale/it/Resources_IT.rc and b/locale/it/Resources_IT.rc differ
diff --git a/locale/it/Resources_It.suo b/locale/it/Resources_It.suo
index 8153fba..42389af 100644
Binary files a/locale/it/Resources_It.suo and b/locale/it/Resources_It.suo differ
diff --git a/locale/ru/Resources_RU.rc b/locale/ru/Resources_RU.rc
index d16af36..14fc747 100644
Binary files a/locale/ru/Resources_RU.rc and b/locale/ru/Resources_RU.rc differ
diff --git a/locale/ru/Resources_Ru.suo b/locale/ru/Resources_Ru.suo
index 30824f9..a658ad4 100644
Binary files a/locale/ru/Resources_Ru.suo and b/locale/ru/Resources_Ru.suo differ
diff --git a/locale/ru/Resources_Ru.vcproj b/locale/ru/Resources_Ru.vcproj
index ec1856d..c7c5216 100644
--- a/locale/ru/Resources_Ru.vcproj
+++ b/locale/ru/Resources_Ru.vcproj
@@ -253,6 +253,10 @@
>
+
+