From 568699f87b812719864bc0534b342fa0946ffcbd Mon Sep 17 00:00:00 2001 From: gho tik Date: Sun, 28 Dec 2014 11:40:12 -0500 Subject: [PATCH] v2_03_06_src Former-commit-id: ddafa6e48cf7d7c9e019e16ce37080d600443ce1 --- Disasm201/disasm.vs2008.suo | Bin 14848 -> 14848 bytes Include/dxwnd.h | 3 + build/Resources_CN.dll | 3 - build/Resources_EN.dll | 3 - build/Resources_IT.dll | 3 - build/Resources_RU.dll | 3 - build/dxwnd.dll | 4 +- build/dxwnd.exe | 2 +- build/dxwnd.ini | 6 +- build/exports/Age of Wonders.dxw | 3 +- build/exports/Beavis & Butthead Do U..dxw | 8 +- build/exports/Breath of Fire IV.dxw | 8 +- build/exports/Cyber Gladiators (3dfx).dxw | 28 ++++ build/exports/Hexplore.dxw | 28 ++++ .../Hoyle Casino Empire (fullscreen).dxw | 28 ++++ build/exports/Hoyle Casino Empire.dxw | 28 ++++ build/exports/M1 Tank Platoon 2.dxw | 28 ++++ ...ts of Sim City (2000 re-release, 3DFX).dxw | 28 ++++ build/exports/Taito Legends 2.dxw | 28 ++++ build/exports/Wind Fantasy SP.dxw | 2 +- build/exports/Wizardry 8 (3DfX).dxw | 28 ++++ build/exports/dxwnd.ini | 8 +- build/readme-relnotes.txt | 9 +- dll/d3dtexture.cpp | 2 - dll/ddraw.cpp | 135 +++++++++++++----- dll/dxemublt.cpp | 32 +++-- dll/dxhook.cpp | 33 ++++- dll/dxhook.h | 1 + dll/dxwcore.hpp | 5 +- dll/dxwnd.aps | Bin 37664 -> 37664 bytes dll/dxwnd.cpp | 2 +- dll/dxwnd.vs2008.suo | Bin 280576 -> 280576 bytes dll/kernel32.cpp | 33 ++++- dll/smack.cpp | 32 ++++- host/DesktopDialog.cpp | 16 ++- host/Resource.h | Bin 31048 -> 31298 bytes host/TabDebug.cpp | 1 + host/TabTiming.cpp | 1 + host/TargetDlg.cpp | 2 + host/TargetDlg.h | 2 + host/dxwndhost.aps | Bin 151536 -> 126128 bytes host/dxwndhost.rc | Bin 91182 -> 91912 bytes host/dxwndhost.vs2008.suo | Bin 128512 -> 26624 bytes host/dxwndhostView.cpp | 22 +-- host/resource | Bin 31174 -> 31424 bytes 45 files changed, 512 insertions(+), 96 deletions(-) delete mode 100644 build/Resources_CN.dll delete mode 100644 build/Resources_EN.dll delete mode 100644 build/Resources_IT.dll delete mode 100644 build/Resources_RU.dll create mode 100644 build/exports/Cyber Gladiators (3dfx).dxw create mode 100644 build/exports/Hexplore.dxw create mode 100644 build/exports/Hoyle Casino Empire (fullscreen).dxw create mode 100644 build/exports/Hoyle Casino Empire.dxw create mode 100644 build/exports/M1 Tank Platoon 2.dxw create mode 100644 build/exports/Streets of Sim City (2000 re-release, 3DFX).dxw create mode 100644 build/exports/Taito Legends 2.dxw create mode 100644 build/exports/Wizardry 8 (3DfX).dxw diff --git a/Disasm201/disasm.vs2008.suo b/Disasm201/disasm.vs2008.suo index 9d8f6ce8ec649154ec773284dcf49fb21383052b..0a849f69ed56b68e9f2256858f068859a73c6d87 100644 GIT binary patch delta 1739 zcmZuxUrd`-6hGfbzpot>MnR-NX}`5dOWOfLh2mfo2LstgFh<=2=!QDx-?-Q&V*??3 z@xd4AdE1idd|0;m;6|e{{u_ylW=7*?qVdHC9*ol%wnZLrk=5V%dbf1Z)BNuF-QPL) z^xpg3dl%9R>GLl;oT&>pc&_#ezwY=^FDHJjC&~*h2Ol=Z^{PTQh3>j>&|61D^*{sQ z18(Q@c>y0bo0^2QK#ZzD9DXa%3bZMWmrdVfQg!Z(?nS>3*bejqDPRD21lR!#0z<$~ zU<8nHkHU`vyMW!m9$*ZZ;2vjp%Ou#-z%#%;U_USgJPSMrJP#ZIrrFaK;E$cXi~HP5 zu0h>wglMQOaAONf$9cqv^IGW@*CvGU$N6kWgxAViot>!OPF=j>3FJoH|7d*4(a!0L zanpswQoBZOt>Rm~-y}_gbgcvp)zGqWS}&DSdvy|BEIB#pC@>;xLb!gn&v{SAkR=n( zRP8cFciYv?TF_~YZ&i)D%0SiR3|WJZXR42yey|sH{;B3v@oagc`2fEitn*=F_SE(` ziLRPNQu@316IIu5ujYB8rfI3JL+3LMz7DBAh)tWK3{BH4Jw-3jtJFyyw2f@qik+Rs z?RuACO^*D%+5 zJ|6b+a?p3rppE8AOxa2NMl_lArL_oWeBYa1Ot#kEAT7q3#<%!P(qhYRaViw4+D*UR z_rMPyghIm~{kk$2o_Zz0M?yQZ?f)rULG<%WhYq2Z{gK#;So5E$jt(z;GqA3-Zuq|e zu@ZdNJ73lTBHQOunw;THD(F?3jHv@p!8a&v0Ne*I7AqJ06{RN}PK zB<~>j0DM|$VcrM~+b5#3aK6*lg4vD)OXpkG5v_+aTju8CA!DP7GD2YIl_vZGxGZ(4C@%*t_DNCRr{HqMzbI()BoD|%mH1Ur;@9BAh+S4% z7x*_S?{}ri`Mm*d!QU*>8gcXFT?xR;TxEgH;P=BvlqL_m3N(Vto9S1YpMQylG>x@b7;TH)K4!Nwc6%yT4gJGdxJF9LZmeUZm}%he z_@*5<;)S@p&p^{eZq{Vo3pOlx0>3C4YHp7e7 z0eF-aDAKkltxdGtO8iYdcWtZJnKgV`H(zyxIF(44cxLFdlNUpyJor#=xx93DEmz+4 GSINJ1n>acE delta 1503 zcmb_c&uLfp7tSNWaUnz) zhyYO_2DAaRpm%n5f$Ra^1G<6DMx&9&*bDRl8GzRG=trz5VX_}!-jDHJU;r4jWkVQ; zfdjw@Fb%NnR!l%P2^<8bfb+mIm0bHMSQw|lQ~ z=QTQGOiBZn2E0- z^*NEliX2ul&i`;c`ZKVHR$HSEAJX`A zS44S-I<#0VT2YELAHA>hJ=J9KK{Fq_R0}TCm)-$d3&vk%oPIXL)EnCU+WcB5MJu6B z>TNM-vwcjK_ICLns>Ch5jNjf>Xd`}B8KwD-CEpkXe2=)f>PmP}p>kUnCA1(}ZDqPr zD&Oo>X*CsX?-wV;No3$SGJtCTNA)-S-$_q?2yaJj4*y4PBBpN|rLbRoh<-u5Pp2X= zd%02H+4Wde1PvvU=;vhrmF(}x{*Qzo^5=(+d(1(;!{+T4;5zRT%U8c#+4tukg(A7vil?c>n+a diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 9e00921..ddeacf0 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -163,6 +163,9 @@ #define TEXTUREDUMP 0x00004000 // dump textures to file system as bmp files #define TEXTUREHACK 0x00008000 // load (replace) hacked textures from file system (bmp files) #define TEXTURETRANSP 0x00010000 // transparent textures (unimplemented) +#define NORMALIZEPERFCOUNT 0x00020000 // Normalize Performance Counter to a Performance Frequency of 1MHz +#define HYBRIDMODE 0x00040000 // ????? +#define GDICOLORCONV 0x00080000 // do color conversion using GDI // 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 deleted file mode 100644 index aec1a83..0000000 --- a/build/Resources_CN.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7bebe395edfd439cfe09e4875e481f37506e0a980a3c589958dd9781c7dc4e65 -size 105472 diff --git a/build/Resources_EN.dll b/build/Resources_EN.dll deleted file mode 100644 index e87acca..0000000 --- a/build/Resources_EN.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0612ced9b9f9b7805a31213cba47f847cc10eb0d6a95e2d47adff97484edf5f5 -size 89600 diff --git a/build/Resources_IT.dll b/build/Resources_IT.dll deleted file mode 100644 index a8a9f92..0000000 --- a/build/Resources_IT.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ceacbf8f568d53efcb0982da28698e26923abb941312acaa6d6d0a743a91870b -size 112128 diff --git a/build/Resources_RU.dll b/build/Resources_RU.dll deleted file mode 100644 index 9382396..0000000 --- a/build/Resources_RU.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f2673e4533d1eeb79eb96ba29f360d844b64b06cdf3000271441a9f6b026d7e5 -size 114176 diff --git a/build/dxwnd.dll b/build/dxwnd.dll index dbf1421..28e192b 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dbfe732ec7cba24e2a540fa0a0275293d8f65b1922afeb0a190e5c7c5678e53f -size 535552 +oid sha256:dbb593dd74acbc13c129c32d28ba3808deabc13a62e2163696e371d06a5cdee5 +size 537600 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 6b38334..08c7dac 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef09812ea8000eca947a595d2c89257576af411f35834a2aecec9256e1c3a385 +oid sha256:8fb3df5a4f77d45fa4e102e1b37ab739fdee0eefc74edd8f3574f58c43166ee2 size 532992 diff --git a/build/dxwnd.ini b/build/dxwnd.ini index 6ab9251..4d43d17 100644 --- a/build/dxwnd.ini +++ b/build/dxwnd.ini @@ -1,9 +1,9 @@ [window] -posx=1486 -posy=523 +posx=50 +posy=50 sizx=320 sizy=200 -lang=automatic +lang=default [texture] MinTexX=16 MaxTexX=0 diff --git a/build/exports/Age of Wonders.dxw b/build/exports/Age of Wonders.dxw index 8caa0f2..9468df5 100644 --- a/build/exports/Age of Wonders.dxw +++ b/build/exports/Age of Wonders.dxw @@ -9,7 +9,7 @@ coord0=0 flag0=679477792 flagg0=1207959552 flagh0=20 -flagi0=201326596 +flagi0=205520900 tflag0=0 initx0=0 inity0=0 @@ -25,3 +25,4 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 +flagj0=128 diff --git a/build/exports/Beavis & Butthead Do U..dxw b/build/exports/Beavis & Butthead Do U..dxw index ea24f57..8189d23 100644 --- a/build/exports/Beavis & Butthead Do U..dxw +++ b/build/exports/Beavis & Butthead Do U..dxw @@ -5,10 +5,10 @@ module0= opengllib0= ver0=0 coord0=0 -flag0=671090722 +flag0=673187874 flagg0=1207959552 flagh0=32788 -flagi0=0 +flagi0=4194304 tflag0=3 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/Breath of Fire IV.dxw b/build/exports/Breath of Fire IV.dxw index ef8dcb8..1789bab 100644 --- a/build/exports/Breath of Fire IV.dxw +++ b/build/exports/Breath of Fire IV.dxw @@ -7,11 +7,11 @@ opengllib0= ver0=0 coord0=0 flag0=134217762 -flagg0=1476395024 -flagh0=4116 -flagi0=-2011168764 +flagg0=1476395008 +flagh0=20 +flagi0=138412036 flagj0=4224 -tflag0=6402 +tflag0=0 initx0=0 inity0=0 minx0=0 diff --git a/build/exports/Cyber Gladiators (3dfx).dxw b/build/exports/Cyber Gladiators (3dfx).dxw new file mode 100644 index 0000000..d8aeaf7 --- /dev/null +++ b/build/exports/Cyber Gladiators (3dfx).dxw @@ -0,0 +1,28 @@ +[target] +title0=Cyber Gladiators (3dfx) +path0=D:\Games\Cyber Gladiators\cyber.exe +launchpath0= +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=671088802 +flagg0=1744896000 +flagh0=20 +flagi0=-2009071612 +flagj0=4224 +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/Hexplore.dxw b/build/exports/Hexplore.dxw new file mode 100644 index 0000000..eb0303f --- /dev/null +++ b/build/exports/Hexplore.dxw @@ -0,0 +1,28 @@ +[target] +title0=Hexplore +path0=D:\Games\Hexplore\hexplore.exe +launchpath0= +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=134234146 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +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/Hoyle Casino Empire (fullscreen).dxw b/build/exports/Hoyle Casino Empire (fullscreen).dxw new file mode 100644 index 0000000..26b2195 --- /dev/null +++ b/build/exports/Hoyle Casino Empire (fullscreen).dxw @@ -0,0 +1,28 @@ +[target] +title0=Hoyle Casino Empire (fullscreen) +path0=D:\Games\Hoyle Casino Empire\CasinoEmpire.exe +launchpath0= +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=134217762 +flagg0=1073741824 +flagh0=20 +flagi0=138412036 +flagj0=4224 +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/Hoyle Casino Empire.dxw b/build/exports/Hoyle Casino Empire.dxw new file mode 100644 index 0000000..d8254c1 --- /dev/null +++ b/build/exports/Hoyle Casino Empire.dxw @@ -0,0 +1,28 @@ +[target] +title0=Hoyle Casino Empire +path0=D:\Games\Hoyle Casino Empire\CasinoEmpire.exe +launchpath0= +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=134217762 +flagg0=1242562560 +flagh0=20 +flagi0=138413060 +flagj0=4224 +tflag0=6151 +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/M1 Tank Platoon 2.dxw b/build/exports/M1 Tank Platoon 2.dxw new file mode 100644 index 0000000..9421797 --- /dev/null +++ b/build/exports/M1 Tank Platoon 2.dxw @@ -0,0 +1,28 @@ +[target] +title0=M1 Tank Platoon 2 +path0=D:\Games\M1 Tank Platoon 2\M1TP2.exe +launchpath0= +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=134238242 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +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=8 +winver0=0 +maxres0=-1 diff --git a/build/exports/Streets of Sim City (2000 re-release, 3DFX).dxw b/build/exports/Streets of Sim City (2000 re-release, 3DFX).dxw new file mode 100644 index 0000000..c469c45 --- /dev/null +++ b/build/exports/Streets of Sim City (2000 re-release, 3DFX).dxw @@ -0,0 +1,28 @@ +[target] +title0=Streets of Sim City +path0=D:\Games\Streets of Sim City\STREETS.EXE +launchpath0= +module0= +opengllib0= +ver0=1 +coord0=0 +flag0=671088674 +flagg0=1224736768 +flagh0=20 +flagi0=138412036 +flagj0=4224 +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/Taito Legends 2.dxw b/build/exports/Taito Legends 2.dxw new file mode 100644 index 0000000..8941389 --- /dev/null +++ b/build/exports/Taito Legends 2.dxw @@ -0,0 +1,28 @@ +[target] +title0=Taito Legends 2 +path0=D:\Games\Taito Legends 2\Taito.exe +launchpath0= +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=134217762 +flagg0=1207959552 +flagh0=20 +flagi0=205520900 +flagj0=4224 +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/Wind Fantasy SP.dxw b/build/exports/Wind Fantasy SP.dxw index 41bd5f3..b423bd3 100644 --- a/build/exports/Wind Fantasy SP.dxw +++ b/build/exports/Wind Fantasy SP.dxw @@ -25,4 +25,4 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 -flagj0=128 +flagj0=4224 diff --git a/build/exports/Wizardry 8 (3DfX).dxw b/build/exports/Wizardry 8 (3DfX).dxw new file mode 100644 index 0000000..2195b3a --- /dev/null +++ b/build/exports/Wizardry 8 (3DfX).dxw @@ -0,0 +1,28 @@ +[target] +title0=Wizardry 8 (3DfX) +path0=D:\Games\Wizardry 8\Wiz8.exe +launchpath0= +module0= +opengllib0= +ver0=9 +coord0=0 +flag0=134217730 +flagg0=1207959552 +flagh0=20 +flagi0=205520900 +flagj0=4224 +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/dxwnd.ini b/build/exports/dxwnd.ini index 4e7b98e..06104c1 100644 --- a/build/exports/dxwnd.ini +++ b/build/exports/dxwnd.ini @@ -1,5 +1,5 @@ [window] -posx=1392 -posy=53 -sizx=320 -sizy=841 +posx=1189 +posy=594 +sizx=497 +sizy=464 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 34a3b4c..1faa15b 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -673,4 +673,11 @@ fix: changed surface capability policy so that "Risk II" works with identical su v2.03.05 add: texture dump for d3d8 & d3d9. Note: highlight & hack yet to be implemented. d3d10 & d3d11 yet to be implemented. Texture types not complete. -fix: handling of d3d10 (Assassin's Creed) \ No newline at end of file +fix: handling of d3d10 (Assassin's Creed) + +v2.03.06 +fix: do not try to set vsync delays on ddraw surface when not created yet +fix: catched several sporadic errors before they could crash the application +fix: GetAttachedSurface() now retrieves a backbuffer from the list, instead of referencing the last one - this fixes "Tomb Raider III" GOG release in non emulated mode. +add: "Normalize performance counter" flag to fix an improper use of QueryPerformanceCounter() made by "Cyber Gladiators" +add: "GDI Color conversion" debug flag diff --git a/dll/d3dtexture.cpp b/dll/d3dtexture.cpp index 9e3006c..c41c305 100644 --- a/dll/d3dtexture.cpp +++ b/dll/d3dtexture.cpp @@ -233,8 +233,6 @@ void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) break; // almost certainly, an empty black surface! } - dxw.dwTFlags = (hash == 0xEC2EE7CE) ? 0xFFFFFFFF : 0x00000000; - // Create the .BMP file. extern char *GetDxWndPath(); sprintf_s(pszFile, MAX_PATH, "%s\\texture.out\\texture.%03d.%03d.%s.%08X.bmp", diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index e06536d..8e12d72 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -21,6 +21,7 @@ extern BOOL IsChangeDisplaySettingsHotPatched; BOOL bDontReleaseBackBuffer = FALSE; DWORD dwBackBufferCaps; extern void TextureHandling(LPDIRECTDRAWSURFACE); +ColorConversion_Type pColorConversion = NULL; // DirectDraw API HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); @@ -1516,10 +1517,7 @@ HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2) c2=&swcaps; res=(*pGetCapsD)(lpdd, NULL, c2); } - //DWORD AlphaCaps; - //AlphaCaps=c1->dwFXAlphaCaps; memcpy((void *)c1, (void *)c2, size); - //c1->dwFXAlphaCaps=AlphaCaps; } if(dxw.dwFlags3 & CAPMASK) MaskCapsD(c1, c2); @@ -2743,8 +2741,11 @@ HRESULT WINAPI extGetAttachedSurface(int dxversion, GetAttachedSurface_Type pGet // AddAttachedSurface, or a primary complex surface creation otherwise.... if(IsPrim && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_FLIP))) { // v2.02.42 added DDSCAPS_FLIP for Empire Earth - if (lpDDSBack) { - *lplpddas = lpDDSBack; + // in "Tomb Raider III" GOG release, the primary surface is queryed and has no attached + // backbuffer, but a backbuffer does exist and has to be retrieved by GetBackBufferSurface. + LPDIRECTDRAWSURFACE lpddsback = dxw.GetBackBufferSurface(); + if (lpddsback) { + *lplpddas = lpddsback; OutTraceDW("GetAttachedSurface(%d): BACKBUFFER attached=%x\n", dxversion, *lplpddas); return DD_OK; } @@ -2829,7 +2830,12 @@ HRESULT WINAPI PrimaryBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECT HRESULT WINAPI PrimaryFastBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect) { - return (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddssrc, lpsrcrect, DDBLTFAST_WAIT); + RECT client; + int iXOffset, iYOffset; // offsets to center surface area to window + (*pGetClientRect)(dxw.GethWnd(), &client); + iXOffset = (client.right - dxw.GetScreenWidth()) >> 1; + iYOffset = (client.bottom - dxw.GetScreenHeight()) >> 1; + return (*pBltFast)(lpdds, iXOffset + lpdestrect->left, iYOffset + lpdestrect->top, lpddssrc, lpsrcrect, DDBLTFAST_WAIT); } HRESULT WINAPI PrimaryStretchBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect) @@ -2857,6 +2863,10 @@ HRESULT WINAPI PrimaryStretchBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, L if(lpddssrc==NULL){ // blit from backbuffer lpdds->GetAttachedSurface(&caps, &(LPDIRECTDRAWSURFACE)lpddsBak); + if(lpddsBak == NULL) { + OutTraceE("PrimaryStretchBlt: skip - lpddsBak=%x at %d\n", lpddsBak, __LINE__); + return DD_OK; // fake a success ... + } lpddsBak->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd); } else{ @@ -2878,11 +2888,14 @@ HRESULT WINAPI PrimaryStretchBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, L } // 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__); - // fast-blit to primary - res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT); - if(res) OutTraceE("Blt: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - if (res) BlitError(res, lpsrcrect, lpdestrect, __LINE__); + if(res) { + OutTraceE("Blt: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + } + else { + // fast-blit to primary + res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT); + if(res) OutTraceE("Blt: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + } (*pReleaseS)(lpddsTmp); return res; } @@ -2976,14 +2989,20 @@ HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, 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__); + if(res) { + OutTraceE("Lock: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return DD_OK; + } bSourceBuf = (BYTE *)ddsd.lpSurface; SrcPitch = ddsd.lPitch; 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__); + if(res) { + OutTraceE("Lock: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return DD_OK; + } bDestBuf = (BYTE *)ddsd.lpSurface; DestPitch = ddsd.lPitch; @@ -3039,6 +3058,66 @@ HRESULT WINAPI PrimaryNoBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRE return DD_OK; } +typedef HRESULT (WINAPI *ColorConversion_Type)(LPDIRECTDRAWSURFACE, RECT, LPDIRECTDRAWSURFACE *); + +HRESULT WINAPI ColorConversionEmulated(LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPDIRECTDRAWSURFACE *lpddssource) +{ + HRESULT res; + res=(*pEmuBlt)(lpDDSEmu_Back, &emurect, lpdds, &emurect, DDBLT_WAIT, 0); + if(res==DDERR_SURFACEBUSY){ + (*pUnlockMethod(lpdds))(lpdds, NULL); + (*pUnlockMethod(lpDDSEmu_Back))(lpDDSEmu_Back, NULL); + res=(*pEmuBlt)(lpDDSEmu_Back, &emurect, lpdds, &emurect, DDBLT_WAIT, 0); + } + if(res) { + BlitError(res, &emurect, &emurect, __LINE__); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + } + *lpddssource = lpDDSEmu_Back; + return res; +} + +HRESULT WINAPI ColorConversionGDI(LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPDIRECTDRAWSURFACE *lpddssource) +{ + // GDICOLORCONV: use GDI capabilities to convert color depth by BitBlt-ting between different hdc + HRESULT res; + OutTrace("STEP: GDI Color Conversion\n"); + do { + HDC hdc_source, hdc_dest; + res=(*pGetDC)(lpdds, &hdc_source); + if(res) { + OutTraceE("GetDC ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + break; + } + res=(*pGetDC)(lpDDSEmu_Back, &hdc_dest); + if(res) { + OutTraceE("GetDC ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + break; + } + if(!BitBlt(hdc_dest, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), hdc_source, 0, 0, SRCCOPY)){ + OutTraceE("BitBlt ERROR: err=%d at %d\n", GetLastError(), __LINE__); + } + res=(*pReleaseDC)(lpdds, hdc_source); + if(res) { + OutTraceE("ReleaseDC ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + break; + } + res=(*pReleaseDC)(lpDDSEmu_Back, hdc_dest); + if(res) { + OutTraceE("ReleaseDC ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + break; + } + } while(FALSE); + *lpddssource = lpDDSEmu_Back; + return res; +} + +HRESULT WINAPI ColorConversionDDRAW(LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPDIRECTDRAWSURFACE *lpddssource) +{ + *lpddssource = lpdds; + return DD_OK; +} + HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping) { @@ -3332,23 +3411,10 @@ HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, } LPDIRECTDRAWSURFACE lpDDSSource; - - if(dxw.dwFlags1 & EMULATESURFACE){ - res=(*pEmuBlt)(lpDDSEmu_Back, &emurect, lpdds, &emurect, DDBLT_WAIT, 0); - if(res==DDERR_SURFACEBUSY){ - (*pUnlockMethod(lpdds))(lpdds, NULL); - (*pUnlockMethod(lpDDSEmu_Back))(lpDDSEmu_Back, NULL); - res=(*pEmuBlt)(lpDDSEmu_Back, &emurect, lpdds, &emurect, DDBLT_WAIT, 0); - } - if(res) { - BlitError(res, &emurect, &emurect, __LINE__); - if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; - return res; - } - lpDDSSource = lpDDSEmu_Back; - } - else{ - lpDDSSource = lpdds; + if (res=(*pColorConversion)(lpdds, emurect, &lpDDSSource)) { + OutTraceE("sBlt ERROR: Color conversion failed res=%d(%s)\n", res, ExplainDDError(res)); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + return res; } dxw.ShowOverlay(lpDDSSource); @@ -4332,8 +4398,13 @@ HRESULT WINAPI extReleaseS(LPDIRECTDRAWSURFACE lpdds) OutTraceDDRAW("Release(S): lpdds=%x%s refcount=%d\n", lpdds, IsPrim?"(PRIM)":(IsBack?"(BACK)":""), res); if (res==0) { // common precondition + // erase surface from primary or backbuffer list + if(IsPrim || IsBack) dxw.MarkRegularSurface(lpdds); + // when releasing primary surface, erase clipping region if(IsPrim && (dxw.dwFlags1 & CLIPCURSOR)) dxw.EraseClipCursor(); + + // clear service surface pointers if (dxw.dwFlags1 & EMULATESURFACE) { if(lpdds==lpDDSEmu_Prim) { OutTraceDW("Release(S): Clearing lpDDSEmu_Prim pointer\n"); @@ -4875,7 +4946,7 @@ HRESULT WINAPI extDDGetGammaRamp(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPDDG return ret; } - HRESULT WINAPI extDDSetGammaRamp(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPDDGAMMARAMP lpgr) +HRESULT WINAPI extDDSetGammaRamp(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPDDGAMMARAMP lpgr) { HRESULT ret; OutTraceDDRAW("SetGammaRamp: dds=%x dwFlags=%x\n", lpdds, dwFlags); @@ -4891,7 +4962,7 @@ HRESULT WINAPI extDDGetGammaRamp(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPDDG return ret; } - HRESULT WINAPI extGetAvailableVidMem(LPDIRECTDRAW lpdd, LPDDSCAPS lpDDSCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree, GetAvailableVidMem_Type pGetAvailableVidMem) +HRESULT WINAPI extGetAvailableVidMem(LPDIRECTDRAW lpdd, LPDDSCAPS lpDDSCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree, GetAvailableVidMem_Type pGetAvailableVidMem) { HRESULT res; //const DWORD dwMaxMem = 0x7FFFF000; diff --git a/dll/dxemublt.cpp b/dll/dxemublt.cpp index c84393b..a5ad9d2 100644 --- a/dll/dxemublt.cpp +++ b/dll/dxemublt.cpp @@ -1268,8 +1268,29 @@ static HRESULT WINAPI EmuBlt_Null(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrec void SetBltTransformations() { - OutTraceDW("SetBltTransformations: color transformation %d->%d\n", - dxw.VirtualPixelFormat.dwRGBBitCount, dxw.ActualPixelFormat.dwRGBBitCount); + pPrimaryBlt = PrimaryBlt; + if(dxw.dwFlags5 & AEROBOOST) pPrimaryBlt = PrimaryStretchBlt; + if(dxw.dwFlags5 & BILINEARFILTER) pPrimaryBlt = PrimaryBilinearBlt; + if(dxw.dwFlags5 & DOFASTBLT) pPrimaryBlt = PrimaryFastBlt; // debug opt + if(dxw.dwFlags5 & NOBLT) pPrimaryBlt = PrimaryNoBlt; // debug opt + + extern HRESULT WINAPI ColorConversionDDRAW(LPDIRECTDRAWSURFACE, RECT, LPDIRECTDRAWSURFACE *); + extern HRESULT WINAPI ColorConversionGDI(LPDIRECTDRAWSURFACE, RECT, LPDIRECTDRAWSURFACE *); + extern HRESULT WINAPI ColorConversionEmulated(LPDIRECTDRAWSURFACE, RECT, LPDIRECTDRAWSURFACE *); + pColorConversion = ColorConversionDDRAW; // default for no emulation mode + if(dxw.dwFlags1 & EMULATESURFACE) { + pColorConversion = ColorConversionEmulated; // default for emulation mode + if(dxw.dwFlags5 & HYBRIDMODE) pColorConversion = ColorConversionDDRAW; + if(dxw.dwFlags5 & GDICOLORCONV) pColorConversion = ColorConversionGDI; + } + char *s = "???"; + if(pColorConversion == ColorConversionDDRAW) s="DDRAW"; + if(pColorConversion == ColorConversionGDI) s="GDI"; + if(pColorConversion == ColorConversionEmulated) s="EMULATED"; + OutTraceDW("SetBltTransformations: color conversion %s BPP %d->%d\n", + s, dxw.VirtualPixelFormat.dwRGBBitCount, dxw.ActualPixelFormat.dwRGBBitCount); + + if(pColorConversion != ColorConversionEmulated) return; /* default (bad) setting */ pEmuBlt=EmuBlt_Null; @@ -1331,11 +1352,4 @@ void SetBltTransformations() dxw.ActualPixelFormat.dwRGBBitCount); break; } - - pPrimaryBlt = PrimaryBlt; - if(dxw.dwFlags5 & AEROBOOST) pPrimaryBlt = PrimaryStretchBlt; - if(dxw.dwFlags5 & BILINEARFILTER) pPrimaryBlt = PrimaryBilinearBlt; - if(dxw.dwFlags5 & DOFASTBLT) pPrimaryBlt = PrimaryFastBlt; // debug opt - if(dxw.dwFlags5 & NOBLT) pPrimaryBlt = PrimaryNoBlt; // debug opt - return; } diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 742dfaf..c2e45de 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -794,7 +794,7 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp extern void SetVSyncDelays(LPDIRECTDRAW); extern LPDIRECTDRAW lpPrimaryDD; if(dxw.dwFlags4 & STRETCHTIMERS) dxw.RenewTimers(); - SetVSyncDelays(lpPrimaryDD); + if(lpPrimaryDD) SetVSyncDelays(lpPrimaryDD); LastTimeShift=dxw.TimeShift; } @@ -1302,6 +1302,7 @@ void HookModule(HMODULE base, int dxversion) (dxw.dwFlags4 & OVERRIDEREGISTRY) || (dxw.dwTFlags & OUTREGISTRY)) HookAdvApi32(base); HookMSV4WLibs(base); // -- used by Aliens & Amazons demo: what for? + //HookSmackW32(base); } #define USEWINNLSENABLE @@ -1576,6 +1577,18 @@ static void ReplacePrivilegedOps() HWND hDesktopWindow = NULL; #endif +// Message poller: its only purpose is to keep sending messages to the main window +// so that the message loop is kept running. It is a trick necessary to play +// smack videos with smackw32.dll and AUTOREFRESH mode set +DWORD WINAPI MessagePoller(LPVOID lpParameter) +{ + #define DXWREFRESHINTERVAL 20 + while(TRUE){ + Sleep(DXWREFRESHINTERVAL); + SendMessage(dxw.GethWnd(), WM_NCHITTEST, 0, 0); + } +} + void HookInit(TARGETMAP *target, HWND hwnd) { HMODULE base; @@ -1604,6 +1617,13 @@ void HookInit(TARGETMAP *target, HWND hwnd) SetDllDirectory(sSourcePath); if(dxw.dwFlags1 & AUTOMATIC) dxw.dwFlags1 |= EMULATESURFACE; // if AUTOMATIC, try this first! + if(dxw.dwFlags5 & HYBRIDMODE) { + // special mode settings .... + dxw.dwFlags1 |= EMULATESURFACE; + dxw.dwFlags5 |= NOSYSTEMEMULATED; + dxw.dwFlags2 |= SETCOMPATIBILITY; + dxw.dwFlags5 &= ~(BILINEARFILTER | AEROBOOST); + } if(hwnd){ // v2.02.32: skip this when in code injection mode. // v2.1.75: is it correct to set hWnd here? @@ -1662,6 +1682,14 @@ void HookInit(TARGETMAP *target, HWND hwnd) if (dxw.dwFlags4 & LIMITSCREENRES) OutTrace("HookInit: max resolution=%s\n", (dxw.MaxScreenRes<6)?Resolutions[dxw.MaxScreenRes]:"unknown"); } + { + // Beware: for some strange & mysterious reason, this call makes Warcraft II and other games + // work better, avoiding something that resembles a black palette (no blit errors, but the + // whole screen black!!) and an AERO rupture. + PIXELFORMATDESCRIPTOR pfd; + DescribePixelFormat(GetDC(GetDesktopWindow()), 1, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + } + if (hwnd && IsDebug){ DWORD dwStyle, dwExStyle; char ClassName[81]; @@ -1786,6 +1814,9 @@ void HookInit(TARGETMAP *target, HWND hwnd) AdjustWindowPos(dxw.hParentWnd, target->sizx, target->sizy); } } + + if (dxw.dwFlags1 & AUTOREFRESH) + CreateThread(NULL, 0, MessagePoller, NULL, 0, NULL); } LPCSTR ProcToString(LPCSTR proc) diff --git a/dll/dxhook.h b/dll/dxhook.h index 4b2726e..a2c77d9 100644 --- a/dll/dxhook.h +++ b/dll/dxhook.h @@ -11,6 +11,7 @@ extern void HookUser32(HMODULE); extern void HookWinMM(HMODULE); extern void HookAdvApi32(HMODULE); extern void HookImagehlp(HMODULE); +extern void HookSmackW32(HMODULE); extern void InitPosition(int, int, int, int, int, int); //void InitWindowPos(int, int, int, int); diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index e79b926..a0f9c93 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -240,4 +240,7 @@ typedef enum { DXVK_TIMETOGGLE, DXVK_ALTF4, DXVK_SIZE -}; \ No newline at end of file +}; + +typedef HRESULT (WINAPI *ColorConversion_Type)(LPDIRECTDRAWSURFACE, RECT, LPDIRECTDRAWSURFACE *); +extern ColorConversion_Type pColorConversion; diff --git a/dll/dxwnd.aps b/dll/dxwnd.aps index fbcc6dc3a51dd6d9842377edb724a415fc597c10..be1bf616a727e51e670edda5895cfca4fb0cd760 100644 GIT binary patch delta 40 tcmZ3mjA_9#rU{`e#_. #include "dxwnd.h" #include "dxwcore.hpp" -#define VERSION "2.03.05" +#define VERSION "2.03.06" #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 d6281e057caadb2bfed0aa0e947df4b998a29b05..b65a310e9a82a14b138f7def0ddeb1cf12fb5243 100644 GIT binary patch delta 15018 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 diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index 9340914..e1b9ed7 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -357,6 +357,13 @@ BOOL WINAPI extQueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) else{ LARGE_INTEGER CurrentInCount; ret=(*pQueryPerformanceCounter)(&CurrentInCount); + if(dxw.dwFlags5 & NORMALIZEPERFCOUNT) { + LARGE_INTEGER PerfFrequency; + static LARGE_INTEGER StartCounter = {0LL}; + if (StartCounter.QuadPart == 0LL) StartCounter.QuadPart = CurrentInCount.QuadPart; + (*pQueryPerformanceFrequency)(&PerfFrequency); + CurrentInCount.QuadPart = ((CurrentInCount.QuadPart - StartCounter.QuadPart) * 1000000LL) / PerfFrequency.QuadPart; + } *lpPerformanceCount = dxw.StretchLargeCounter(CurrentInCount); } @@ -374,8 +381,15 @@ BOOL WINAPI extQueryPerformanceFrequency(LARGE_INTEGER *lpPerformanceFrequency) *lpPerformanceFrequency=myPerfFrequency; ret = 0; } - else - ret=(*pQueryPerformanceFrequency)(lpPerformanceFrequency); + else{ + if(dxw.dwFlags5 & NORMALIZEPERFCOUNT){ + lpPerformanceFrequency->QuadPart = 1000000LL; + ret = TRUE; + } + else{ + ret = (*pQueryPerformanceFrequency)(lpPerformanceFrequency); + } + } OutTraceDW("QueryPerformanceFrequency: ret=%x Frequency=%x-%x\n", ret, lpPerformanceFrequency->HighPart, lpPerformanceFrequency->LowPart); return ret; } @@ -726,6 +740,21 @@ BOOL WINAPI extCreateProcessA( OutTraceDW("CreateProcess: SUPPRESS\n"); return TRUE; } + +#if 0 + // useless: DxWnd should hook to two processes contemporarily .... + // problem: binkplay seems to detect the screen actual size + if(TRUE){ + // get rid of /R option from binkplay argument line + if(!strncmp(lpCommandLine, "binkplay.exe ", strlen("binkplay.exe "))){ + char *rCommand; + rCommand = strstr(lpCommandLine, "/R "); + if(rCommand) memset(rCommand, ' ', strlen("/R ")); + OutTraceDW("CreateProcess: ApplicationName=\"%s\" CommandLine=\"%s\"\n", lpApplicationName, lpCommandLine); + } + } +#endif + //#define RELEASEHOOKTOSONPROCESS TRUE // extern void UnhookProc(); // if(RELEASEHOOKTOSONPROCESS) UnhookProc(); diff --git a/dll/smack.cpp b/dll/smack.cpp index 7215425..414bb1f 100644 --- a/dll/smack.cpp +++ b/dll/smack.cpp @@ -22,17 +22,37 @@ SmackOpen_Type pSmackOpen = NULL; SmackStruct * WINAPI extSmackOpen(HANDLE, UINT32, INT32); +static HookEntry_Type Hooks[]={ + {HOOK_IAT_CANDIDATE, "_SmackOpen@12", (FARPROC)NULL, (FARPROC *)&pSmackOpen, (FARPROC)extSmackOpen}, + {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator +}; + FARPROC Remap_smack_ProcAddress(LPCSTR proc, HMODULE hModule) { - if (!strcmp(proc,"_SmackOpen@12") && !pSmackOpen){ - pSmackOpen=(SmackOpen_Type)(*pGetProcAddress)(hModule, proc); - OutTraceDW("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), pSmackOpen); - return (FARPROC)extSmackOpen; - } + FARPROC addr; + if (addr=RemapLibrary(proc, hModule, Hooks)) return addr; // NULL -> keep the original call address return NULL; } +static char *libname = "smackw32.dll"; + +void HookSmackW32(HMODULE hModule) +{ + HookLibrary(hModule, Hooks, libname); + return; +} + +DWORD ThreadId = 0; + +DWORD WINAPI DoScreenRefresh(LPVOID lpParameter) +{ + while(TRUE){ + Sleep(20); + dxw.ScreenRefresh(); + } +} + SmackStruct * WINAPI extSmackOpen(HANDLE SmackFile, UINT32 flags, INT32 unknown) { SmackStruct *ret; @@ -43,8 +63,6 @@ SmackStruct * WINAPI extSmackOpen(HANDLE SmackFile, UINT32 flags, INT32 unknown) if (ret) { OutTraceDW("SmackOpen: version=%x screen=(%dx%d) frame_count=%d frame_number=%d\n", ret->version, ret->width, ret->height, ret->frame_count, ret->frame_number); - //ret->width=800; - //ret->height=600; } return ret; } diff --git a/host/DesktopDialog.cpp b/host/DesktopDialog.cpp index 88aa340..643af85 100644 --- a/host/DesktopDialog.cpp +++ b/host/DesktopDialog.cpp @@ -52,7 +52,20 @@ void CDesktopDialog::OnTimer(UINT_PTR nIDEvent) PIXELFORMATDESCRIPTOR pfd; int iPixelFormat; - // get the current pixel format index + // get the current pixel format index +#if 0 + ::DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + HMODULE ogl; + //ogl=LoadLibrary("opengl32"); + ogl=LoadLibrary("gdi32"); + typedef BOOL (WINAPI *wglGetPixelFormat_Type)(HDC); + wglGetPixelFormat_Type pwglGetPixelFormat; + //pwglGetPixelFormat = (wglGetPixelFormat_Type)GetProcAddress(ogl, "wglGetPixelFormat"); + pwglGetPixelFormat = (wglGetPixelFormat_Type)GetProcAddress(ogl, "GetPixelFormat"); + iPixelFormat = (*pwglGetPixelFormat)(hDC); + iPixelFormat = (*pwglGetPixelFormat)(NULL); + //iPixelFormat = ::GetPixelFormat(NULL); +#endif iPixelFormat = ::GetPixelFormat(hDC); if(!iPixelFormat) iPixelFormat=1; // why returns 0??? if(iPixelFormat){ @@ -76,7 +89,6 @@ void CDesktopDialog::OnTimer(UINT_PTR nIDEvent) sprintf_s(sMsg, 1024, "error %d", GetLastError()); } - this->SetDlgItemTextA(IDC_DESKTOPINFO, sMsg); } diff --git a/host/Resource.h b/host/Resource.h index 42d887fb1ce271f4dbf18cdc71bce6b1fe5ed66e..7945a0e131425471f43dfe98e19c18db75e7fdf7 100644 GIT binary patch delta 130 zcmX@{iSf`E#tnzUCV${#5%gp5X9!~OWpHHhVen*#VsM?D=qx@$&G@_lP83-OfC_YQ}kenWN-qSm_MarkBlit); DDX_Check(pDX, IDC_NOBLT, cTarget->m_NoBlt); DDX_Check(pDX, IDC_FASTBLT, cTarget->m_FastBlt); + DDX_Check(pDX, IDC_GDICOLORCONV, cTarget->m_GDIColorConv); DDX_Check(pDX, IDC_ANALYTICMODE, cTarget->m_AnalyticMode); DDX_Check(pDX, IDC_SURFACEWARN, cTarget->m_SurfaceWarn); DDX_Check(pDX, IDC_CAPMASK, cTarget->m_CapMask); diff --git a/host/TabTiming.cpp b/host/TabTiming.cpp index d5905d6..72112d6 100644 --- a/host/TabTiming.cpp +++ b/host/TabTiming.cpp @@ -36,6 +36,7 @@ void CTabTiming::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_TIMESTRETCH, cTarget->m_TimeStretch); DDX_Check(pDX, IDC_INTERCEPTRDTSC, cTarget->m_InterceptRDTSC); DDX_Check(pDX, IDC_STRETCHTIMERS, cTarget->m_StretchTimers); + DDX_Check(pDX, IDC_NORMALIZEPERFCOUNT, cTarget->m_NormalizePerfCount); DDX_Check(pDX, IDC_QUARTERBLT, cTarget->m_QuarterBlt); DDX_Check(pDX, IDC_FINETIMING, cTarget->m_FineTiming); DDX_Text(pDX, IDC_MAXFPS, cTarget->m_MaxFPS); diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 19cd0e4..1b2a563 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -110,6 +110,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_NoBlt = FALSE; m_BilinearBlt = FALSE; m_FastBlt = FALSE; + m_GDIColorConv = FALSE; m_PreventMaximize = FALSE; m_ClientRemapping = TRUE; // default true !! m_LockWinPos = FALSE; @@ -139,6 +140,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_ShowTimeStretch = FALSE; m_TimeStretch = FALSE; m_StretchTimers = FALSE; + m_NormalizePerfCount = FALSE; m_QuarterBlt = FALSE; m_FineTiming = FALSE; m_ReleaseMouse = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 11322b9..58bd0ae 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -90,6 +90,7 @@ public: BOOL m_NoBlt; BOOL m_BilinearBlt; BOOL m_FastBlt; + BOOL m_GDIColorConv; BOOL m_PreventMaximize; BOOL m_ClientRemapping; BOOL m_LockWinPos; @@ -119,6 +120,7 @@ public: BOOL m_ShowTimeStretch; BOOL m_TimeStretch; BOOL m_StretchTimers; + BOOL m_NormalizePerfCount; BOOL m_QuarterBlt; BOOL m_FineTiming; BOOL m_ReleaseMouse; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 3628ef406bd75b3f494e738760a783dd0d3ba8e8..a7c5aefbdd92cc70ce51ccf5db784ef613f6191d 100644 GIT binary patch delta 6649 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 delta 23587 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 diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 52ac7d8667f391c70bf807954a2ec9c6f179a5c3..8a8492112c54330a2c47ba9e264fbec97590ab0d 100644 GIT binary patch delta 363 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 HiRS(b7KhcY literal 128512 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

-^`6Fba`ic*Lqz}0*bbuX#1ZyaOy^{b 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 diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp index 8ca11e7..e8dc9ce 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -131,6 +131,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) case 2: t->flags |= EMULATEBUFFER; break; case 3: t->flags |= LOCKEDSURFACE; break; case 4: t->flags |= EMULATESURFACE; break; + case 5: t->flags5 |= HYBRIDMODE; break; break; } @@ -238,6 +239,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_NoSystemEmulated) t->flags5 |= NOSYSTEMEMULATED; if(dlg->m_NoBlt) t->flags5 |= NOBLT; if(dlg->m_FastBlt) t->flags5 |= DOFASTBLT; + if(dlg->m_GDIColorConv) t->flags5 |= GDICOLORCONV; if(dlg->m_PreventMaximize) t->flags |= PREVENTMAXIMIZE; if(dlg->m_ClientRemapping) t->flags |= CLIENTREMAPPING; if(dlg->m_LockWinPos) t->flags |= LOCKWINPOS; @@ -267,6 +269,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_ShowTimeStretch) t->flags4 |= SHOWTIMESTRETCH; if(dlg->m_TimeStretch) t->flags2 |= TIMESTRETCH; if(dlg->m_StretchTimers) t->flags4 |= STRETCHTIMERS; + if(dlg->m_NormalizePerfCount) t->flags5 |= NORMALIZEPERFCOUNT; if(dlg->m_QuarterBlt) t->flags5 |= QUARTERBLT; if(dlg->m_FineTiming) t->flags4 |= FINETIMING; if(dlg->m_ReleaseMouse) t->flags4 |= RELEASEMOUSE; @@ -334,6 +337,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) if(t->flags & EMULATEBUFFER) dlg->m_DxEmulationMode = 2; if(t->flags & LOCKEDSURFACE) dlg->m_DxEmulationMode = 3; if(t->flags & EMULATESURFACE) dlg->m_DxEmulationMode = 4; + if(t->flags5 & HYBRIDMODE) dlg->m_DxEmulationMode = 5; dlg->m_DxFilterMode = 0; if(t->flags4 & BILINEAR2XFILTER) dlg->m_DxFilterMode = 1; @@ -431,6 +435,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_NoSystemEmulated = t->flags5 & NOSYSTEMEMULATED ? 1 : 0; dlg->m_NoBlt = t->flags5 & NOBLT ? 1 : 0; dlg->m_FastBlt = t->flags5 & DOFASTBLT ? 1 : 0; + dlg->m_GDIColorConv = t->flags5 & GDICOLORCONV ? 1 : 0; dlg->m_PreventMaximize = t->flags & PREVENTMAXIMIZE ? 1 : 0; dlg->m_ClientRemapping = t->flags & CLIENTREMAPPING ? 1 : 0; dlg->m_LockWinPos = t->flags & LOCKWINPOS ? 1 : 0; @@ -460,6 +465,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_ShowTimeStretch = t->flags4 & SHOWTIMESTRETCH ? 1 : 0; dlg->m_TimeStretch = t->flags2 & TIMESTRETCH ? 1 : 0; dlg->m_StretchTimers = t->flags4 & STRETCHTIMERS ? 1 : 0; + dlg->m_NormalizePerfCount = t->flags5 & NORMALIZEPERFCOUNT ? 1 : 0; dlg->m_QuarterBlt = t->flags5 & QUARTERBLT ? 1 : 0; dlg->m_FineTiming = t->flags4 & FINETIMING ? 1 : 0; dlg->m_ReleaseMouse = t->flags4 & RELEASEMOUSE ? 1 : 0; @@ -655,16 +661,16 @@ static int LoadConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, c sprintf_s(key, sizeof(key), "coord%i", i); TargetMap->coordinates = GetPrivateProfileInt("target", key, 0, InitPath); - // be sure just one of the emulation flags is set sprintf_s(key, sizeof(key), "flag%i", i); TargetMap->flags = GetPrivateProfileInt("target", key, 0, InitPath); - flags = TargetMap->flags; - TargetMap->flags &= ~EMULATEFLAGS; - do{ - if(flags & EMULATESURFACE) {TargetMap->flags |= EMULATESURFACE; break;} - if(flags & EMULATEBUFFER) {TargetMap->flags |= EMULATEBUFFER; break;} - if(flags & LOCKEDSURFACE) {TargetMap->flags |= LOCKEDSURFACE; break;} - } while (0); + //// be sure just one of the emulation flags is set + //flags = TargetMap->flags; + //TargetMap->flags &= ~EMULATEFLAGS; + //do{ + // if(flags & EMULATESURFACE) {TargetMap->flags |= EMULATESURFACE; break;} + // if(flags & EMULATEBUFFER) {TargetMap->flags |= EMULATEBUFFER; break;} + // if(flags & LOCKEDSURFACE) {TargetMap->flags |= LOCKEDSURFACE; break;} + //} while (0); sprintf_s(key, sizeof(key), "flagg%i", i); TargetMap->flags2 = GetPrivateProfileInt("target", key, 0, InitPath); diff --git a/host/resource b/host/resource index ac83293ab1add3fd6fa67da2e786ef3ce14897e1..ae55ba36406fd09b857f1455207d86133f7a6d11 100644 GIT binary patch delta 136 zcmX^1neo6^#tkarlO6OqWP=!d85|jW7(5xG7+e_wfH;W3jlr40pCOdNZ*n8I_~Z|v zY?D7p%1w5#U=sw1`v7qeScM-$*yKVMMX-t|{8E!QNU|wLGB^QcJsDhp=K2FkR|ZZv TG-NPhFqm8zExTDQe1Q@GMf@Mv delta 14 WcmX@`mGRhT#tkaro8=-FDFFaC{|1Qw