From 6762295239da357cd3b48163e9703fde924ed272 Mon Sep 17 00:00:00 2001 From: gho tik Date: Sun, 21 Jul 2013 12:38:09 -0400 Subject: [PATCH] v2_02_27_src Former-commit-id: 13f45f31d8d226c1f07c92f4e2dc65f9ab7d5400 --- build/dxwnd.dll | 4 +- build/dxwnd.exe | 4 +- build/{dxwnd.ini => dxwnd.my.ini} | 1920 ++++++++------- build/readme-relnotes.txt | 17 + dll/ddraw.cpp | 3797 +++++++++++++++++++++++++++++ dll/dinput.cpp | 304 +++ dll/dxemublt.cpp | 32 +- dll/dxhook.cpp | 341 +-- dll/dxhook.h | 3 + dll/dxwcore.cpp | 18 +- dll/dxwnd.aps | Bin 37660 -> 37664 bytes dll/dxwnd.cpp | 2 +- dll/dxwnd.vs2008.suo | Bin 96256 -> 157184 bytes dll/dxwnd.vs2008.vcproj | 112 +- dll/gdi32.cpp | 845 +++++++ dll/hddraw.cpp | 4 +- dll/kernel32.cpp | 486 ++++ dll/{msvfwhook.cpp => msvfw.cpp} | 0 dll/ole32.cpp | 97 + dll/{glhook.cpp => opengl.cpp} | 0 dll/resource.h | 1 - dll/syslibs.h | 9 + dll/{syslibs.cpp => user32.cpp} | 2690 ++++++++------------ dll/wndproc.cpp | 9 +- host/TabLogs.cpp | 16 +- host/TabLogs.h | 1 + host/TabProgram.cpp | 3 +- host/TabWindow.cpp | 1 - host/dxwnd.ini | 28 + host/dxwndhost.aps | Bin 161336 -> 161516 bytes host/dxwndhost.cpp | 5 + host/dxwndhost.rc | 41 +- host/dxwndhost.vs2008.suo | Bin 265728 -> 286208 bytes host/dxwndhostView.cpp | 578 ++--- 34 files changed, 8116 insertions(+), 3252 deletions(-) rename build/{dxwnd.ini => dxwnd.my.ini} (74%) create mode 100644 dll/ddraw.cpp create mode 100644 dll/dinput.cpp create mode 100644 dll/gdi32.cpp create mode 100644 dll/kernel32.cpp rename dll/{msvfwhook.cpp => msvfw.cpp} (100%) create mode 100644 dll/ole32.cpp rename dll/{glhook.cpp => opengl.cpp} (100%) rename dll/{syslibs.cpp => user32.cpp} (59%) create mode 100644 host/dxwnd.ini diff --git a/build/dxwnd.dll b/build/dxwnd.dll index c1a51bc..c0e379f 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89c569d050fd740aedc07bce2d7c3708b13aa127300a83332e8a0d1dde02fdb1 -size 344064 +oid sha256:cebe66cab28374f902eeeecc7aa8db65b794c728a3857488cdb26860ef3976c8 +size 342528 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index e11abce..c87523a 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62dacd099414e7a8a4cfa4a1623aa5d55f7728bab0c61ea2a5ab5dfe1c7a43c2 -size 524800 +oid sha256:445871f8075154ab63a9ef75f3b7ffcfe0b96ffec47887290a22d037b0dc50e8 +size 523264 diff --git a/build/dxwnd.ini b/build/dxwnd.my.ini similarity index 74% rename from build/dxwnd.ini rename to build/dxwnd.my.ini index 7525d57..a38fb15 100644 --- a/build/dxwnd.ini +++ b/build/dxwnd.my.ini @@ -4,8 +4,8 @@ path0=D:\Games\007_NightFire\Bond.exe module0= ver0=0 flag0=134217730 -flagg0=138412032 -tflag0=3 +flagg0=134348800 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -37,9 +37,9 @@ title2=688I Hunter Killer path2=D:\Games\688\688I_HK.EXE module2= ver2=0 -flag2=134479906 -flagg2=134217728 -tflag2=2 +flag2=1744830626 +flagg2=135266304 +tflag2=3 initx2=0 inity2=0 minx2=0 @@ -48,15 +48,15 @@ maxx2=0 maxy2=0 posx2=50 posy2=50 -sizx2=640 -sizy2=480 +sizx2=0 +sizy2=0 title3=7th Legion path3=D:\Games\7th_Legion\LEGION.EXE module3= ver3=0 flag3=402669607 flagg3=539056144 -tflag3=12 +tflag3=64 initx3=0 inity3=0 minx3=0 @@ -72,8 +72,8 @@ path4=D:\Games\A10\A10Cuba.exe module4= ver4=0 flag4=162 -flagg4=1073741824 -tflag4=258 +flagg4=1073741840 +tflag4=0 initx4=0 inity4=0 minx4=0 @@ -124,7 +124,7 @@ module7= ver7=1 flag7=142606370 flagg7=1048736 -tflag7=258 +tflag7=0 initx7=0 inity7=0 minx7=0 @@ -140,8 +140,8 @@ path8=D:\Games\Age of Empires\EMPIRES.EXE module8= ver8=0 flag8=402655267 -flagg8=536940544 -tflag8=2 +flagg8=69632 +tflag8=3 initx8=0 inity8=0 minx8=0 @@ -158,7 +158,7 @@ module9= ver9=0 flag9=134217762 flagg9=1073762320 -tflag9=2 +tflag9=0 initx9=0 inity9=0 minx9=0 @@ -205,11 +205,11 @@ sizx11=800 sizy11=600 title12=Age of Wonders path12=D:\Games\Age of Wonders\AoW.exe -module12=VideoP.dpl vcl30.dpl -ver12=0 -flag12=813826050 -flagg12=537919505 -tflag12=2 +module12= +ver12=7 +flag12=268435458 +flagg12=1048576 +tflag12=259 initx12=0 inity12=0 minx12=0 @@ -224,8 +224,8 @@ title13=Airline Tycoon Evolution path13=D:\Games\Airline.Tycoon.Evolution\AT.EXE module13= ver13=0 -flag13=402653219 -flagg13=0 +flag13=1476395043 +flagg13=1048576 tflag13=323 initx13=0 inity13=0 @@ -241,17 +241,17 @@ title14=Alien Cabal 95 path14=D:\Games\Alien_cabal\ACabal95.exe module14= ver14=0 -flag14=32 +flag14=67108896 flagg14=0 -tflag14=259 +tflag14=0 initx14=0 inity14=0 minx14=0 miny14=0 maxx14=0 maxy14=0 -posx14=50 -posy14=50 +posx14=0 +posy14=0 sizx14=800 sizy14=600 title15=Alien vs. Predator @@ -530,8 +530,8 @@ title31=Beyond Divinity path31=D:\Games\Beyond Divinity\Div.exe module31= ver31=0 -flag31=0 -flagg31=134218240 +flag31=134217728 +flagg31=671088640 tflag31=3 initx31=0 inity31=0 @@ -541,8 +541,8 @@ maxx31=0 maxy31=0 posx31=50 posy31=50 -sizx31=800 -sizy31=600 +sizx31=0 +sizy31=0 title32=Beyond Good & Evil Demo path32=C:\Games\Beyond Good & Evil\BGE.exe module32= @@ -799,10 +799,10 @@ posy46=50 sizx46=800 sizy46=600 title47=Commandos II: Men of Courage -path47=C:\Games\Commandos II\comm2.exe +path47=D:\Games\Commandos II\comm2.exe module47= -ver47=0 -flag47=-1207951008 +ver47=7 +flag47=2013276256 flagg47=0 tflag47=0 initx47=0 @@ -870,8 +870,8 @@ title51=Daikatana path51=D:\Games\Daikatana\daikatana.exe module51= ver51=12 -flag51=806429218 -flagg51=537002496 +flag51=269492738 +flagg51=537002497 tflag51=2 initx51=0 inity51=0 @@ -1075,8 +1075,8 @@ path63=D:\Games\Diablo\Diablo.exe module63= ver63=1 flag63=138428450 -flagg63=1108344832 -tflag63=258 +flagg63=1108344848 +tflag63=0 initx63=0 inity63=0 minx63=0 @@ -1193,9 +1193,9 @@ title70=Dungeon Keeper 95 path70=D:\Games\Keeper95\KEEPER95.EXE module70= ver70=0 -flag70=134234150 +flag70=134299686 flagg70=0 -tflag70=64 +tflag70=0 initx70=0 inity70=0 minx70=0 @@ -1229,7 +1229,7 @@ module72= ver72=0 flag72=34 flagg72=574619648 -tflag72=262 +tflag72=263 initx72=0 inity72=0 minx72=0 @@ -1278,9 +1278,9 @@ title75=Evany La chiave per mondi sconosciuti path75=D:\Games\Evany La chiave per mondi sconosciuti\Evany.exe module75= ver75=0 -flag75=134348866 +flag75=134348864 flagg75=0 -tflag75=259 +tflag75=0 initx75=0 inity75=0 minx75=0 @@ -1601,17 +1601,17 @@ title94=Grand Prix Legends path94=D:\Games\Grand Prix Legends\gpl\gpl.exe module94= ver94=0 -flag94=-1979678687 -flagg94=4 -tflag94=270 +flag94=-2013233119 +flagg94=8 +tflag94=3 initx94=0 inity94=0 minx94=0 miny94=0 maxx94=0 maxy94=0 -posx94=50 -posy94=50 +posx94=0 +posy94=0 sizx94=640 sizy94=480 title95=Grand Prix Legends MAX @@ -1635,9 +1635,9 @@ title96=Grand Prix World path96=D:\Games\Grand Prix World\gpwxp2.exe module96= ver96=0 -flag96=-2011037534 -flagg96=134217864 -tflag96=259 +flag96=2097314 +flagg96=134217856 +tflag96=35 initx96=0 inity96=0 minx96=0 @@ -1818,13 +1818,13 @@ posx106=50 posy106=50 sizx106=800 sizy106=600 -title107=Heavy Metal FAKK 2 -path107=C:\Games\Heavy Metal - FAKK2\fakk2.exe +title107=Heavy Metal - FAKK2 Demo +path107=D:\Games\Heavy Metal - FAKK2 Demo\fakk2.exe module107= ver107=0 -flag107=33554464 -flagg107=64 -tflag107=2 +flag107=4 +flagg107=134348800 +tflag107=0 initx107=0 inity107=0 minx107=0 @@ -1835,13 +1835,13 @@ posx107=50 posy107=50 sizx107=800 sizy107=600 -title108=HellCopter -path108=C:\Games\hellcop\HCopter.exe +title108=Heavy Metal FAKK 2 +path108=C:\Games\Heavy Metal - FAKK2\fakk2.exe module108= ver108=0 -flag108=-2013249500 -flagg108=256 -tflag108=0 +flag108=33554464 +flagg108=64 +tflag108=2 initx108=0 inity108=0 minx108=0 @@ -1852,13 +1852,13 @@ posx108=50 posy108=50 sizx108=800 sizy108=600 -title109=Heretic 2 -path109=D:\Games\Heretic 2\Heretic2.exe +title109=HellCopter +path109=C:\Games\hellcop\HCopter.exe module109= ver109=0 -flag109=0 -flagg109=134348800 -tflag109=258 +flag109=-2013249500 +flagg109=256 +tflag109=0 initx109=0 inity109=0 minx109=0 @@ -1869,13 +1869,13 @@ posx109=50 posy109=50 sizx109=800 sizy109=600 -title110=Heroes of Might & Magic III Demo -path110=C:\Games\Heroes III Demo\h3demo.exe +title110=Heretic 2 +path110=D:\Games\Heretic 2\Heretic2.exe module110= -ver110=1 -flag110=134234146 -flagg110=0 -tflag110=2 +ver110=0 +flag110=0 +flagg110=134348800 +tflag110=258 initx110=0 inity110=0 minx110=0 @@ -1886,13 +1886,13 @@ posx110=50 posy110=50 sizx110=800 sizy110=600 -title111=Hexen II (opengl) -path111=D:\Games\Hexen II\glh2.exe +title111=Heroes of Might & Magic III Demo +path111=C:\Games\Heroes III Demo\h3demo.exe module111= -ver111=10 -flag111=3 -flagg111=212993 -tflag111=386 +ver111=1 +flag111=134234146 +flagg111=0 +tflag111=2 initx111=0 inity111=0 minx111=0 @@ -1903,13 +1903,13 @@ posx111=50 posy111=50 sizx111=800 sizy111=600 -title112=Hexen II (software) -path112=D:\Games\Hexen II\h2.exe +title112=Hexen II (opengl) +path112=D:\Games\Hexen II\glh2.exe module112= -ver112=0 -flag112=671088642 -flagg112=1130496 -tflag112=0 +ver112=10 +flag112=3 +flagg112=212993 +tflag112=386 initx112=0 inity112=0 minx112=0 @@ -1920,13 +1920,13 @@ posx112=50 posy112=50 sizx112=800 sizy112=600 -title113=Hitman - Codename 47 -path113=D:\Games\Hitman - Codename 47\Hitman.Exe +title113=Hexen II (software) +path113=D:\Games\Hexen II\h2.exe module113= ver113=0 -flag113=134217728 -flagg113=671088640 -tflag113=3 +flag113=671088642 +flagg113=1130496 +tflag113=0 initx113=0 inity113=0 minx113=0 @@ -1937,13 +1937,13 @@ posx113=50 posy113=50 sizx113=800 sizy113=600 -title114=Homeworld 2 -path114=D:\Games\Homeworld2\Bin\Release\Homeworld2.exe +title114=Hitman - Codename 47 +path114=D:\Games\Hitman - Codename 47\Hitman.Exe module114= ver114=0 -flag114=671088642 -flagg114=134217728 -tflag114=0 +flag114=134217728 +flagg114=671088640 +tflag114=3 initx114=0 inity114=0 minx114=0 @@ -1954,12 +1954,12 @@ posx114=50 posy114=50 sizx114=800 sizy114=600 -title115=hover -path115=C:\Games\hover\hoverX.exe +title115=Homeworld 2 +path115=D:\Games\Homeworld2\Bin\Release\Homeworld2.exe module115= ver115=0 -flag115=8224 -flagg115=0 +flag115=671088642 +flagg115=134217728 tflag115=0 initx115=0 inity115=0 @@ -1971,13 +1971,13 @@ posx115=50 posy115=50 sizx115=800 sizy115=600 -title116=Hyperblade -path116=D:\Games\Hyperblade\HYPERX.EXE +title116=hover +path116=C:\Games\hover\hoverX.exe module116= ver116=0 -flag116=134217891 -flagg116=3231762 -tflag116=2 +flag116=8224 +flagg116=0 +tflag116=0 initx116=0 inity116=0 minx116=0 @@ -1988,13 +1988,13 @@ posx116=50 posy116=50 sizx116=800 sizy116=600 -title117=Idinaloq -path117=C:\Games\idina101\idinaloq.exe +title117=Hyperblade +path117=D:\Games\Hyperblade\HYPERX.EXE module117= ver117=0 -flag117=32 -flagg117=0 -tflag117=0 +flag117=134217891 +flagg117=3231762 +tflag117=2 initx117=0 inity117=0 minx117=0 @@ -2005,11 +2005,11 @@ posx117=50 posy117=50 sizx117=800 sizy117=600 -title118=Immanis -path118=C:\Games\Immanis CD release\immanis.exe +title118=Idinaloq +path118=C:\Games\idina101\idinaloq.exe module118= ver118=0 -flag118=24611 +flag118=32 flagg118=0 tflag118=0 initx118=0 @@ -2022,11 +2022,11 @@ posx118=50 posy118=50 sizx118=800 sizy118=600 -title119=Immanis (v2) -path119=C:\Games\Immanis CD release\immanis_v2.exe +title119=Immanis +path119=C:\Games\Immanis CD release\immanis.exe module119= ver119=0 -flag119=268460067 +flag119=24611 flagg119=0 tflag119=0 initx119=0 @@ -2039,11 +2039,11 @@ posx119=50 posy119=50 sizx119=800 sizy119=600 -title120=In the Hunt -path120=C:\Games\In The Hunt\e8.exe +title120=Immanis (v2) +path120=C:\Games\Immanis CD release\immanis_v2.exe module120= ver120=0 -flag120=2 +flag120=268460067 flagg120=0 tflag120=0 initx120=0 @@ -2056,13 +2056,13 @@ posx120=50 posy120=50 sizx120=800 sizy120=600 -title121=Incoming Forces -path121=D:\Games\Incoming Forces\forces.exe +title121=In the Hunt +path121=C:\Games\In The Hunt\e8.exe module121= -ver121=8 -flag121=134217760 +ver121=0 +flag121=2 flagg121=0 -tflag121=2 +tflag121=0 initx121=0 inity121=0 minx121=0 @@ -2073,13 +2073,13 @@ posx121=50 posy121=50 sizx121=800 sizy121=600 -title122=International Superstar Soccer 3 -path122=C:\Games\ISS_3\iss3.exe +title122=Incoming Forces +path122=D:\Games\Incoming Forces\forces.exe module122= ver122=8 -flag122=545267715 +flag122=134217760 flagg122=0 -tflag122=0 +tflag122=2 initx122=0 inity122=0 minx122=0 @@ -2090,13 +2090,13 @@ posx122=50 posy122=50 sizx122=800 sizy122=600 -title123=Jacked -path123=D:\Games\Jacked\Jacked.exe -module123=winmm -ver123=9 -flag123=537010208 -flagg123=196608 -tflag123=258 +title123=International Superstar Soccer 3 +path123=C:\Games\ISS_3\iss3.exe +module123= +ver123=8 +flag123=545267715 +flagg123=0 +tflag123=0 initx123=0 inity123=0 minx123=0 @@ -2107,13 +2107,13 @@ posx123=50 posy123=50 sizx123=800 sizy123=600 -title124=Jedi Knight II Jedi Outcast -path124=D:\Games\Jedi Knight II Jedi Outcast\GameData\jk2sp.exe -module124= -ver124=0 -flag124=2 -flagg124=1180161 -tflag124=2 +title124=Jacked +path124=D:\Games\Jacked\Jacked.exe +module124=winmm +ver124=9 +flag124=537010208 +flagg124=196608 +tflag124=258 initx124=0 inity124=0 minx124=0 @@ -2124,13 +2124,13 @@ posx124=50 posy124=50 sizx124=800 sizy124=600 -title125=Jet Moto -path125=M:\JETMOTO.EXE +title125=Jedi Knight II Jedi Outcast +path125=D:\Games\Jedi Knight II Jedi Outcast\GameData\jk2sp.exe module125= ver125=0 -flag125=139298 -flagg125=0 -tflag125=0 +flag125=2 +flagg125=1180161 +tflag125=2 initx125=0 inity125=0 minx125=0 @@ -2141,11 +2141,11 @@ posx125=50 posy125=50 sizx125=800 sizy125=600 -title126=Kiss Psyco Cyrcus -path126=C:\Games\Psycho\client.exe -module126=d3d.ren -ver126=7 -flag126=537018404 +title126=Jet Moto +path126=M:\JETMOTO.EXE +module126= +ver126=0 +flag126=139298 flagg126=0 tflag126=0 initx126=0 @@ -2158,12 +2158,12 @@ posx126=50 posy126=50 sizx126=800 sizy126=600 -title127=Kohan II Kings of War -path127=D:\Games\Kohan II Kings of War\k2.exe -module127= -ver127=0 -flag127=134217728 -flagg127=134217728 +title127=Kiss Psyco Cyrcus +path127=C:\Games\Psycho\client.exe +module127=d3d.ren +ver127=7 +flag127=537018404 +flagg127=0 tflag127=0 initx127=0 inity127=0 @@ -2175,12 +2175,12 @@ posx127=50 posy127=50 sizx127=800 sizy127=600 -title128=Koplio -path128=D:\Games\Koplio\KOPLIO.exe +title128=Kohan II Kings of War +path128=D:\Games\Kohan II Kings of War\k2.exe module128= ver128=0 -flag128=545259520 -flagg128=134217729 +flag128=134217728 +flagg128=134217728 tflag128=0 initx128=0 inity128=0 @@ -2192,13 +2192,13 @@ posx128=50 posy128=50 sizx128=800 sizy128=600 -title129=Krazy Ivan -path129=C:\Games\Krazy Ivan\KRAZY.EXE +title129=Koplio +path129=D:\Games\Koplio\KOPLIO.exe module129= -ver129=0 -flag129=536870914 -flagg129=0 -tflag129=0 +ver129=1 +flag129=545390720 +flagg129=134217729 +tflag129=3 initx129=0 inity129=0 minx129=0 @@ -2209,13 +2209,13 @@ posx129=50 posy129=50 sizx129=800 sizy129=600 -title130=Last Bronx -path130=C:\Games\Last_Bronx\LB.EXE +title130=Krazy Ivan +path130=C:\Games\Krazy Ivan\KRAZY.EXE module130= ver130=0 -flag130=40994 +flag130=536870914 flagg130=0 -tflag130=64 +tflag130=0 initx130=0 inity130=0 minx130=0 @@ -2226,13 +2226,13 @@ posx130=50 posy130=50 sizx130=800 sizy130=600 -title131=Lionheart -path131=C:\Games\Lionheart Demo\Lionheart.exe +title131=Last Bronx +path131=C:\Games\Last_Bronx\LB.EXE module131= ver131=0 -flag131=-2147483612 +flag131=40994 flagg131=0 -tflag131=0 +tflag131=64 initx131=0 inity131=0 minx131=0 @@ -2243,13 +2243,13 @@ posx131=50 posy131=50 sizx131=800 sizy131=600 -title132=lithtech.exe -path132=D:\Games\NOLF Technology Demo\lithtech.exe +title132=Lionheart +path132=C:\Games\Lionheart Demo\Lionheart.exe module132= -ver132=7 -flag132=0 -flagg132=512 -tflag132=258 +ver132=0 +flag132=-2147483612 +flagg132=0 +tflag132=0 initx132=0 inity132=0 minx132=0 @@ -2260,13 +2260,13 @@ posx132=50 posy132=50 sizx132=800 sizy132=600 -title133=Lords of the Realm 2 -path133=D:\Games\L2SIEGE\LORDS2.EXE +title133=lithtech.exe +path133=D:\Games\NOLF Technology Demo\lithtech.exe module133= -ver133=0 -flag133=38 -flagg133=65536 -tflag133=8 +ver133=7 +flag133=0 +flagg133=512 +tflag133=258 initx133=0 inity133=0 minx133=0 @@ -2277,13 +2277,13 @@ posx133=50 posy133=50 sizx133=800 sizy133=600 -title134=M.A.X. 2 -path134=C:\Games\MAX 2\MAX_2\MAX2\MAX2.EXE +title134=Lords of the Realm 2 +path134=D:\Games\L2SIEGE\LORDS2.EXE module134= ver134=0 -flag134=34 -flagg134=0 -tflag134=0 +flag134=38 +flagg134=65536 +tflag134=8 initx134=0 inity134=0 minx134=0 @@ -2294,10 +2294,10 @@ posx134=50 posy134=50 sizx134=800 sizy134=600 -title135=M1 Tank Platoon 2 -path135=C:\Games\M1 Tank Platoon 2\M1TP2.exe +title135=M.A.X. 2 +path135=C:\Games\MAX 2\MAX_2\MAX2\MAX2.EXE module135= -ver135=8 +ver135=0 flag135=34 flagg135=0 tflag135=0 @@ -2311,13 +2311,13 @@ posx135=50 posy135=50 sizx135=800 sizy135=600 -title136=Mario Worlds (stripped PE) -path136=C:\Games\Mario Worlds\Mario Worlds.exe +title136=M1 Tank Platoon 2 +path136=C:\Games\M1 Tank Platoon 2\M1TP2.exe module136= -ver136=1 -flag136=2 -flagg136=1 -tflag136=386 +ver136=8 +flag136=34 +flagg136=0 +tflag136=0 initx136=0 inity136=0 minx136=0 @@ -2328,13 +2328,13 @@ posx136=50 posy136=50 sizx136=800 sizy136=600 -title137=Masters of Orion 2 -path137=C:\Games\Orion2\Orion95.exe +title137=Mario Worlds (stripped PE) +path137=C:\Games\Mario Worlds\Mario Worlds.exe module137= -ver137=0 -flag137=34 -flagg137=0 -tflag137=0 +ver137=1 +flag137=2 +flagg137=1 +tflag137=386 initx137=0 inity137=0 minx137=0 @@ -2345,11 +2345,11 @@ posx137=50 posy137=50 sizx137=800 sizy137=600 -title138=Microsoft Flight Simulator 98 -path138=C:\Games\Flight Simulator 98\FLTSIM98.EXE +title138=Masters of Orion 2 +path138=C:\Games\Orion2\Orion95.exe module138= ver138=0 -flag138=288 +flag138=34 flagg138=0 tflag138=0 initx138=0 @@ -2362,13 +2362,13 @@ posx138=50 posy138=50 sizx138=800 sizy138=600 -title139=Microsoft Midtown Madness -path139=C:\Games\Midtown Madness\midtown.exe +title139=Microsoft Flight Simulator 98 +path139=C:\Games\Flight Simulator 98\FLTSIM98.EXE module139= ver139=0 -flag139=8192 +flag139=288 flagg139=0 -tflag139=2 +tflag139=0 initx139=0 inity139=0 minx139=0 @@ -2379,47 +2379,47 @@ posx139=50 posy139=50 sizx139=800 sizy139=600 -title140=Microsoft Midtown Madness Trial (BAD) -path140=C:\Games\Midtown Madness Trial\midtrial.exe +title140=Microsoft Midtown Madness +path140=C:\Games\Midtown Madness\midtown.exe module140= ver140=0 -flag140=2 +flag140=8192 flagg140=0 -tflag140=0 +tflag140=2 initx140=0 inity140=0 minx140=0 miny140=0 maxx140=0 maxy140=0 -posx140=0 -posy140=0 +posx140=50 +posy140=50 sizx140=800 sizy140=600 -title141=Microsoft Motocross Madness 2 (BAD!!) -path141=C:\Games\Motocross Madness 2\MCM2.cracked.EXE +title141=Microsoft Midtown Madness Trial (BAD) +path141=C:\Games\Midtown Madness Trial\midtrial.exe module141= -ver141=7 -flag141=201326664 -flagg141=1 -tflag141=82 +ver141=0 +flag141=2 +flagg141=0 +tflag141=0 initx141=0 inity141=0 minx141=0 miny141=0 maxx141=0 maxy141=0 -posx141=50 -posy141=50 +posx141=0 +posy141=0 sizx141=800 sizy141=600 -title142=Microsoft Motocross Madness Trial (BAD) -path142=C:\Games\Motocross Madness Trial\mcm.exe +title142=Microsoft Motocross Madness 2 (BAD!!) +path142=C:\Games\Motocross Madness 2\MCM2.cracked.EXE module142= -ver142=1 -flag142=134225952 -flagg142=0 -tflag142=130 +ver142=7 +flag142=201326664 +flagg142=1 +tflag142=82 initx142=0 inity142=0 minx142=0 @@ -2428,15 +2428,15 @@ maxx142=0 maxy142=0 posx142=50 posy142=50 -sizx142=0 -sizy142=0 -title143=Mission Force Cyberstorm (BAD ?) -path143=C:\Games\SIERRA\CSTORM\CSTORM.EXE +sizx142=800 +sizy142=600 +title143=Microsoft Motocross Madness Trial (BAD) +path143=C:\Games\Motocross Madness Trial\mcm.exe module143= -ver143=0 -flag143=33562658 +ver143=1 +flag143=134225952 flagg143=0 -tflag143=0 +tflag143=130 initx143=0 inity143=0 minx143=0 @@ -2447,13 +2447,13 @@ posx143=50 posy143=50 sizx143=0 sizy143=0 -title144=Monopoly 3D -path144=C:\Games\Monopoly (Edition 3D)\Monopoly.exe +title144=Mission Force Cyberstorm (BAD ?) +path144=C:\Games\SIERRA\CSTORM\CSTORM.EXE module144= ver144=0 -flag144=134244388 +flag144=33562658 flagg144=0 -tflag144=2 +tflag144=0 initx144=0 inity144=0 minx144=0 @@ -2462,15 +2462,15 @@ maxx144=0 maxy144=0 posx144=50 posy144=50 -sizx144=800 -sizy144=600 -title145=Monster Truck Madness 2 -path145=C:\Games\Monster Truck Madness 2\Monster.EXE +sizx144=0 +sizy144=0 +title145=Monopoly 3D +path145=C:\Games\Monopoly (Edition 3D)\Monopoly.exe module145= -ver145=1 -flag145=34 -flagg145=1 -tflag145=0 +ver145=0 +flag145=134244388 +flagg145=0 +tflag145=2 initx145=0 inity145=0 minx145=0 @@ -2481,13 +2481,13 @@ posx145=50 posy145=50 sizx145=800 sizy145=600 -title146=Moto Racer Demo -path146=D:\Games\Moto Racer Demo\PlayDemo.exe +title146=Monster Truck Madness 2 +path146=C:\Games\Monster Truck Madness 2\Monster.EXE module146= -ver146=0 -flag146=167903267 -flagg146=192 -tflag146=14 +ver146=1 +flag146=34 +flagg146=1 +tflag146=0 initx146=0 inity146=0 minx146=0 @@ -2498,13 +2498,13 @@ posx146=50 posy146=50 sizx146=800 sizy146=600 -title147=MTV Music Generator -path147=D:\games\MTV Music Generator\mtvmusic.exe +title147=Moto Racer Demo +path147=D:\Games\Moto Racer Demo\PlayDemo.exe module147= ver147=0 -flag147=0 -flagg147=671088640 -tflag147=0 +flag147=167903267 +flagg147=192 +tflag147=14 initx147=0 inity147=0 minx147=0 @@ -2515,13 +2515,13 @@ posx147=50 posy147=50 sizx147=800 sizy147=600 -title148=Necrodrome -path148=C:\Games\Necrodome\NECRO95.EXE +title148=MTV Music Generator +path148=D:\games\MTV Music Generator\mtvmusic.exe module148= ver148=0 -flag148=268435495 -flagg148=256 -tflag148=0 +flag148=136314914 +flagg148=1209008128 +tflag148=3 initx148=0 inity148=0 minx148=0 @@ -2532,13 +2532,13 @@ posx148=50 posy148=50 sizx148=800 sizy148=600 -title149=Need For Speed - Porsche 2000 -path149=C:\Games\Need For Speed - Porsche 2000\Porsche.exe +title149=Necrodrome +path149=C:\Games\Necrodome\NECRO95.EXE module149= -ver149=7 -flag149=0 -flagg149=0 -tflag149=258 +ver149=0 +flag149=268435495 +flagg149=256 +tflag149=0 initx149=0 inity149=0 minx149=0 @@ -2549,13 +2549,13 @@ posx149=50 posy149=50 sizx149=800 sizy149=600 -title150=Need For Speed Underground -path150=D:\Games\Need For Speed Underground\speed.exe +title150=Need For Speed - Porsche 2000 +path150=C:\Games\Need For Speed - Porsche 2000\Porsche.exe module150= -ver150=0 -flag150=671088674 -flagg150=1815101441 -tflag150=322 +ver150=7 +flag150=0 +flagg150=0 +tflag150=258 initx150=0 inity150=0 minx150=0 @@ -2566,13 +2566,13 @@ posx150=50 posy150=50 sizx150=800 sizy150=600 -title151=Need for Speed Underground 2 -path151=D:\Games\Need for Speed Underground 2\SPEED2.EXE +title151=Need For Speed Underground +path151=D:\Games\Need For Speed Underground\speed.exe module151= ver151=0 -flag151=671105026 -flagg151=136331264 -tflag151=6 +flag151=671088674 +flagg151=1815101441 +tflag151=322 initx151=0 inity151=0 minx151=0 @@ -2583,13 +2583,13 @@ posx151=50 posy151=50 sizx151=800 sizy151=600 -title152=Need For Speed Underground Demo -path152=D:\Games\Need For Speed Underground Demo\speeddemo.exe +title152=Need for Speed Underground 2 +path152=D:\Games\Need for Speed Underground 2\SPEED2.EXE module152= -ver152=9 -flag152=0 -flagg152=673202192 -tflag152=2 +ver152=0 +flag152=671105026 +flagg152=136331264 +tflag152=6 initx152=0 inity152=0 minx152=0 @@ -2600,13 +2600,13 @@ posx152=50 posy152=50 sizx152=800 sizy152=600 -title153=Netstorm Islands at War -path153=C:\Games\Netstorm\Netstorm.exe +title153=Need For Speed Underground Demo +path153=D:\Games\Need For Speed Underground Demo\speeddemo.exe module153= -ver153=0 -flag153=2 -flagg153=0 -tflag153=0 +ver153=9 +flag153=0 +flagg153=673202192 +tflag153=2 initx153=0 inity153=0 minx153=0 @@ -2617,12 +2617,12 @@ posx153=50 posy153=50 sizx153=800 sizy153=600 -title154=Nightmare Ned -path154=D:\Games\Ned\NITENED.EXE +title154=Netstorm Islands at War +path154=C:\Games\Netstorm\Netstorm.exe module154= ver154=0 -flag154=537395202 -flagg154=135266305 +flag154=2 +flagg154=0 tflag154=0 initx154=0 inity154=0 @@ -2630,34 +2630,34 @@ minx154=0 miny154=0 maxx154=0 maxy154=0 -posx154=0 -posy154=0 +posx154=50 +posy154=50 sizx154=800 sizy154=600 -title155=Nocturne -path155=D:\Games\Nocturne\nocturne.exe +title155=Nightmare Ned +path155=D:\Games\Ned\NITENED.EXE module155= ver155=0 -flag155=134217730 -flagg155=402653264 -tflag155=3 +flag155=537395202 +flagg155=135266305 +tflag155=0 initx155=0 inity155=0 minx155=0 miny155=0 maxx155=0 maxy155=0 -posx155=50 -posy155=50 +posx155=0 +posy155=0 sizx155=800 sizy155=600 -title156=Nox -path156=d:\Games\Nox\Game.exe +title156=Nocturne +path156=D:\Games\Nocturne\nocturne.exe module156= ver156=0 -flag156=939540515 -flagg156=0 -tflag156=386 +flag156=134217730 +flagg156=402653264 +tflag156=3 initx156=0 inity156=0 minx156=0 @@ -2668,13 +2668,13 @@ posx156=50 posy156=50 sizx156=800 sizy156=600 -title157=Pacific General -path157=C:\Games\Pacific General\PACGEN.EXE +title157=Nox +path157=d:\Games\Nox\Game.exe module157= ver157=0 -flag157=8226 +flag157=939540515 flagg157=0 -tflag157=2 +tflag157=386 initx157=0 inity157=0 minx157=0 @@ -2685,13 +2685,13 @@ posx157=50 posy157=50 sizx157=800 sizy157=600 -title158=Pandemonium 2 -path158=D:\Games\Pandemonium 2\pandy.exe +title158=Pacific General +path158=C:\Games\Pacific General\PACGEN.EXE module158= ver158=0 -flag158=134217728 -flagg158=1 -tflag158=3 +flag158=8226 +flagg158=0 +tflag158=2 initx158=0 inity158=0 minx158=0 @@ -2702,12 +2702,12 @@ posx158=50 posy158=50 sizx158=800 sizy158=600 -title159=Pharaoh -path159=D:\Games\Pharaoh\Pharaoh.exe +title159=Pandemonium 2 +path159=D:\Games\Pandemonium 2\pandy.exe module159= ver159=0 -flag159=1208483874 -flagg159=1048576 +flag159=201326594 +flagg159=1 tflag159=0 initx159=0 inity159=0 @@ -2719,13 +2719,13 @@ posx159=50 posy159=50 sizx159=800 sizy159=600 -title160=Postal -path160=D:\Games\Postal\POSTAL.EXE +title160=Pharaoh +path160=D:\Games\Pharaoh\Pharaoh.exe module160= -ver160=1 -flag160=537133059 -flagg160=65536 -tflag160=266 +ver160=0 +flag160=1207959586 +flagg160=1048576 +tflag160=3 initx160=0 inity160=0 minx160=0 @@ -2736,12 +2736,12 @@ posx160=50 posy160=50 sizx160=800 sizy160=600 -title161=Premier Manager 98 -path161=D:\Games\Premier Manager 98\MANAGER.EXE +title161=Postal +path161=D:\Games\Postal\POSTAL.EXE module161= -ver161=0 -flag161=671088674 -flagg161=1207959552 +ver161=1 +flag161=537133059 +flagg161=65536 tflag161=0 initx161=0 inity161=0 @@ -2753,13 +2753,13 @@ posx161=50 posy161=50 sizx161=800 sizy161=600 -title162=Project Nomads Demo (BAD) -path162=C:\Games\Project Nomads Demo\bin\win32\nomads.exe +title162=Premier Manager 98 +path162=D:\Games\Premier Manager 98\MANAGER.EXE module162= -ver162=8 -flag162=-1476394912 -flagg162=256 -tflag162=258 +ver162=0 +flag162=671088674 +flagg162=1207959552 +tflag162=0 initx162=0 inity162=0 minx162=0 @@ -2770,13 +2770,13 @@ posx162=50 posy162=50 sizx162=800 sizy162=600 -title163=Puzzle Bubble -path163=C:\Games\Puzzle Bubble\PB.EXE +title163=Project Nomads Demo (BAD) +path163=C:\Games\Project Nomads Demo\bin\win32\nomads.exe module163= -ver163=0 -flag163=34 -flagg163=0 -tflag163=0 +ver163=8 +flag163=-1476394912 +flagg163=256 +tflag163=258 initx163=0 inity163=0 minx163=0 @@ -2787,13 +2787,13 @@ posx163=50 posy163=50 sizx163=800 sizy163=600 -title164=Quake 2 -path164=D:\Games\QUAKE2\quake2.exe +title164=Puzzle Bubble +path164=C:\Games\Puzzle Bubble\PB.EXE module164= -ver164=10 -flag164=671089154 -flagg164=671220289 -tflag164=258 +ver164=0 +flag164=34 +flagg164=0 +tflag164=0 initx164=0 inity164=0 minx164=0 @@ -2804,13 +2804,13 @@ posx164=50 posy164=50 sizx164=800 sizy164=600 -title165=Quake 3 Arena -path165=D:\Games\Q3A\quake3.exe +title165=Quake 2 +path165=D:\Games\QUAKE2\quake2.exe module165= -ver165=0 -flag165=536870914 -flagg165=1180161 -tflag165=2 +ver165=10 +flag165=671089154 +flagg165=671220289 +tflag165=258 initx165=0 inity165=0 minx165=0 @@ -2821,13 +2821,13 @@ posx165=50 posy165=50 sizx165=800 sizy165=600 -title166=Raiden II -path166=C:\Games\Raiden II\Raiden II\RAIDENII.EXE +title166=Quake 3 Arena +path166=D:\Games\Q3A\quake3.exe module166= ver166=0 -flag166=34 -flagg166=0 -tflag166=0 +flag166=536870914 +flagg166=1180161 +tflag166=2 initx166=0 inity166=0 minx166=0 @@ -2838,11 +2838,11 @@ posx166=50 posy166=50 sizx166=800 sizy166=600 -title167=Railroad Tycoon II -path167=C:\Games\Railroad.Tycoon.II\RT2.EXE +title167=Raiden II +path167=C:\Games\Raiden II\Raiden II\RAIDENII.EXE module167= -ver167=1 -flag167=134225954 +ver167=0 +flag167=34 flagg167=0 tflag167=0 initx167=0 @@ -2855,13 +2855,13 @@ posx167=50 posy167=50 sizx167=800 sizy167=600 -title168=Rally Championship 2000 -path168=C:\Games\Rally Championship 2000\RAL.EXE +title168=Railroad Tycoon II +path168=C:\Games\Railroad.Tycoon.II\RT2.EXE module168= -ver168=0 -flag168=67108864 +ver168=1 +flag168=134225954 flagg168=0 -tflag168=2 +tflag168=0 initx168=0 inity168=0 minx168=0 @@ -2872,13 +2872,13 @@ posx168=50 posy168=50 sizx168=800 sizy168=600 -title169=Rebel Moon Rising -path169=C:\Games\Rebel Moon Rising\Rmr.exe +title169=Rally Championship 2000 +path169=C:\Games\Rally Championship 2000\RAL.EXE module169= ver169=0 -flag169=0 +flag169=67108864 flagg169=0 -tflag169=0 +tflag169=2 initx169=0 inity169=0 minx169=0 @@ -2889,13 +2889,13 @@ posx169=50 posy169=50 sizx169=800 sizy169=600 -title170=Redline - Gang Warfare 2066 -path170=C:\Games\Redline - Gang Warfare 2066\redline.exe +title170=Rebel Moon Rising +path170=C:\Games\Rebel Moon Rising\Rmr.exe module170= ver170=0 -flag170=32 +flag170=0 flagg170=0 -tflag170=386 +tflag170=0 initx170=0 inity170=0 minx170=0 @@ -2906,13 +2906,13 @@ posx170=50 posy170=50 sizx170=800 sizy170=600 -title171=Resident Evil -path171=D:\Games\Resident Evil\residentevil.patched.exe +title171=Redline - Gang Warfare 2066 +path171=C:\Games\Redline - Gang Warfare 2066\redline.exe module171= -ver171=1 -flag171=134217827 -flagg171=128 -tflag171=2 +ver171=0 +flag171=32 +flagg171=0 +tflag171=386 initx171=0 inity171=0 minx171=0 @@ -2923,13 +2923,13 @@ posx171=50 posy171=50 sizx171=800 sizy171=600 -title172=Resurrection -path172=D:\Games\Resurrection Il Ritorno del Drago Nero\Resurrection.exe +title172=Resident Evil +path172=D:\Games\Resident Evil\residentevil.patched.exe module172= -ver172=7 -flag172=136314882 -flagg172=134217728 -tflag172=3 +ver172=1 +flag172=134217827 +flagg172=128 +tflag172=2 initx172=0 inity172=0 minx172=0 @@ -2940,13 +2940,13 @@ posx172=50 posy172=50 sizx172=800 sizy172=600 -title173=Return to Castle Wolfenstein -path173=D:\Games\Return to Castle Wolfenstein (2001)\Return to Castle Wolfenstein\WolfSP.exe +title173=Resurrection +path173=D:\Games\Resurrection Il Ritorno del Drago Nero\Resurrection.exe module173= -ver173=0 -flag173=134234114 -flagg173=-2147270656 -tflag173=256 +ver173=7 +flag173=136314882 +flagg173=134217728 +tflag173=3 initx173=0 inity173=0 minx173=0 @@ -2957,13 +2957,13 @@ posx173=50 posy173=50 sizx173=800 sizy173=600 -title174=Re-Volt -path174=C:\Games\Re-Volt\REVOLT.EXE +title174=Return to Castle Wolfenstein +path174=D:\Games\Return to Castle Wolfenstein (2001)\Return to Castle Wolfenstein\WolfSP.exe module174= ver174=0 -flag174=134217792 -flagg174=0 -tflag174=0 +flag174=134234114 +flagg174=-2147270656 +tflag174=256 initx174=0 inity174=0 minx174=0 @@ -2974,13 +2974,13 @@ posx174=50 posy174=50 sizx174=800 sizy174=600 -title175=Road Rash -path175=D:\Games\Road Rash\ROADRASH\ROADRASH.EXE +title175=Re-Volt +path175=C:\Games\Re-Volt\REVOLT.EXE module175= ver175=0 -flag175=134217730 +flag175=134217792 flagg175=0 -tflag175=386 +tflag175=0 initx175=0 inity175=0 minx175=0 @@ -2991,13 +2991,13 @@ posx175=50 posy175=50 sizx175=800 sizy175=600 -title176=Road Rash Demo -path176=D:\Games\RoadRash DEMO\DEMORASH.EXE +title176=Road Rash +path176=D:\Games\Road Rash\ROADRASH\ROADRASH.EXE module176= ver176=0 -flag176=134218242 +flag176=134217730 flagg176=0 -tflag176=258 +tflag176=386 initx176=0 inity176=0 minx176=0 @@ -3008,13 +3008,13 @@ posx176=50 posy176=50 sizx176=800 sizy176=600 -title177=Rogue Spear (BAD) -path177=D:\Games\Rogue Spear\RogueSpear.exe +title177=Road Rash Demo +path177=D:\Games\RoadRash DEMO\DEMORASH.EXE module177= -ver177=1 -flag177=134234116 -flagg177=134217984 -tflag177=2 +ver177=0 +flag177=134218242 +flagg177=0 +tflag177=258 initx177=0 inity177=0 minx177=0 @@ -3025,13 +3025,13 @@ posx177=50 posy177=50 sizx177=800 sizy177=600 -title178=Rollcage -path178=D:\Games\Rollcage\Direct3D\Rollcage.exe +title178=Rogue Spear (BAD) +path178=D:\Games\Rogue Spear\RogueSpear.exe module178= -ver178=0 -flag178=339739138 -flagg178=135331844 -tflag178=258 +ver178=1 +flag178=134234116 +flagg178=134217984 +tflag178=2 initx178=0 inity178=0 minx178=0 @@ -3042,29 +3042,29 @@ posx178=50 posy178=50 sizx178=800 sizy178=600 -title179=RollerCoaster Tycoon 2 Mini Game -path179=C:\Games\RollerCoaster Tycoon 2 Mini Game\rct2.exe +title179=Rollcage +path179=D:\Games\Rollcage\Direct3D\Rollcage.exe module179= -ver179=1 -flag179=536870946 -flagg179=0 -tflag179=0 +ver179=0 +flag179=339739138 +flagg179=135331844 +tflag179=258 initx179=0 inity179=0 minx179=0 miny179=0 maxx179=0 maxy179=0 -posx179=0 -posy179=0 +posx179=50 +posy179=50 sizx179=800 sizy179=600 -title180=Sega Rally 2 Championship -path180=C:\Games\Sega Rally 2 Championship\SEGA RALLY 2.exe +title180=RollerCoaster Tycoon 2 Mini Game +path180=C:\Games\RollerCoaster Tycoon 2 Mini Game\rct2.exe module180= ver180=1 -flag180=268435488 -flagg180=2 +flag180=536870946 +flagg180=0 tflag180=0 initx180=0 inity180=0 @@ -3076,12 +3076,12 @@ posx180=0 posy180=0 sizx180=800 sizy180=600 -title181=Sentinel Returns -path181=D:\Games\Sentinel Returns\Sentinel.exe +title181=Sega Rally 2 Championship +path181=C:\Games\Sega Rally 2 Championship\SEGA RALLY 2.exe module181= ver181=1 -flag181=3 -flagg181=-2147483648 +flag181=268435488 +flagg181=2 tflag181=0 initx181=0 inity181=0 @@ -3089,17 +3089,17 @@ minx181=0 miny181=0 maxx181=0 maxy181=0 -posx181=50 -posy181=50 +posx181=0 +posy181=0 sizx181=800 sizy181=600 -title182=Shadow Master (TBD) -path182=C:\Games\Shadow Master\rmg.exe +title182=Sentinel Returns +path182=D:\Games\Sentinel Returns\Sentinel.exe module182= ver182=1 -flag182=32 -flagg182=256 -tflag182=450 +flag182=3 +flagg182=-2147483648 +tflag182=0 initx182=0 inity182=0 minx182=0 @@ -3110,13 +3110,13 @@ posx182=50 posy182=50 sizx182=800 sizy182=600 -title183=Sid Meier's SimGolf Demo -path183=C:\Games\Sid Meier's SimGolf Demo\golf.exe -module183=jgl.dll -ver183=0 -flag183=33554434 -flagg183=0 -tflag183=2 +title183=Shadow Master (TBD) +path183=C:\Games\Shadow Master\rmg.exe +module183= +ver183=1 +flag183=32 +flagg183=256 +tflag183=450 initx183=0 inity183=0 minx183=0 @@ -3127,12 +3127,12 @@ posx183=50 posy183=50 sizx183=800 sizy183=600 -title184=Silent Storm Demo -path184=D:\Games\Silent Storm Demo\SilentStormDemo.exe -module184= +title184=Sid Meier's SimGolf Demo +path184=C:\Games\Sid Meier's SimGolf Demo\golf.exe +module184=jgl.dll ver184=0 -flag184=536870913 -flagg184=-2013265664 +flag184=33554434 +flagg184=0 tflag184=2 initx184=0 inity184=0 @@ -3144,13 +3144,13 @@ posx184=50 posy184=50 sizx184=800 sizy184=600 -title185=Sin, Wages of (sw renderer) -path185=D:\Games\sin\sin.exe -module185=ref_gl.dll ref_soft.dll -ver185=10 -flag185=402670082 -flagg185=513 -tflag185=386 +title185=Silent Storm Demo +path185=D:\Games\Silent Storm Demo\SilentStormDemo.exe +module185= +ver185=0 +flag185=536870913 +flagg185=-2013265664 +tflag185=2 initx185=0 inity185=0 minx185=0 @@ -3161,13 +3161,13 @@ posx185=50 posy185=50 sizx185=800 sizy185=600 -title186=SleepWalker -path186=C:\Games\SleepWalker\Sleepy.exe +title186=Sin, Wages of (sw renderer) +path186=D:\Games\sin\sin.exe module186= -ver186=0 -flag186=301989954 -flagg186=0 -tflag186=198 +ver186=10 +flag186=402670082 +flagg186=131585 +tflag186=386 initx186=0 inity186=0 minx186=0 @@ -3178,13 +3178,13 @@ posx186=50 posy186=50 sizx186=800 sizy186=600 -title187=SnowBoard Racer -path187=C:\Games\Snowboard Racer\SnowBoard.exe +title187=SleepWalker +path187=C:\Games\SleepWalker\Sleepy.exe module187= ver187=0 -flag187=268443681 +flag187=301989954 flagg187=0 -tflag187=0 +tflag187=198 initx187=0 inity187=0 minx187=0 @@ -3306,20 +3306,20 @@ maxfps107=0 maxfps108=0 maxfps109=0 maxfps110=0 -maxfps111=50 -maxfps112=0 +maxfps111=0 +maxfps112=50 maxfps113=0 maxfps114=0 maxfps115=0 -maxfps116=25 -maxfps117=0 +maxfps116=0 +maxfps117=25 maxfps118=0 maxfps119=0 maxfps120=0 maxfps121=0 maxfps122=0 -maxfps123=100 -maxfps124=0 +maxfps123=0 +maxfps124=100 maxfps125=0 maxfps126=0 maxfps127=0 @@ -3368,8 +3368,8 @@ maxfps169=0 maxfps170=0 maxfps171=0 maxfps172=0 -maxfps173=50 -maxfps174=0 +maxfps173=0 +maxfps174=50 maxfps175=0 maxfps176=0 maxfps177=0 @@ -3383,13 +3383,13 @@ maxfps184=0 maxfps185=0 maxfps186=0 maxfps187=0 -title188=Solaris (~BAD) -path188=c:\Games\Solaris\solaris.exe +title188=SnowBoard Racer +path188=C:\Games\Snowboard Racer\SnowBoard.exe module188= -ver188=7 -flag188=973078627 -flagg188=1 -tflag188=2 +ver188=0 +flag188=268443681 +flagg188=0 +tflag188=0 initx188=0 inity188=0 minx188=0 @@ -3623,19 +3623,19 @@ initts109=0 opengllib110= initts110=0 opengllib111= -initts111=8 +initts111=0 opengllib112= initts112=8 opengllib113= -initts113=0 +initts113=8 opengllib114= initts114=0 opengllib115= initts115=0 opengllib116= -initts116=1 +initts116=0 opengllib117= -initts117=0 +initts117=1 opengllib118= initts118=0 opengllib119= @@ -3647,9 +3647,9 @@ initts121=0 opengllib122= initts122=0 opengllib123= -initts123=3 +initts123=0 opengllib124= -initts124=0 +initts124=3 opengllib125= initts125=0 opengllib126= @@ -3701,9 +3701,9 @@ initts148=0 opengllib149= initts149=0 opengllib150= -initts150=6 +initts150=0 opengllib151= -initts151=0 +initts151=6 opengllib152= initts152=0 opengllib153= @@ -3721,9 +3721,9 @@ initts158=0 opengllib159= initts159=0 opengllib160= -initts160=-3 +initts160=0 opengllib161= -initts161=0 +initts161=-3 opengllib162= initts162=0 opengllib163= @@ -3747,9 +3747,9 @@ initts171=0 opengllib172= initts172=0 opengllib173= -initts173=-4 +initts173=0 opengllib174= -initts174=0 +initts174=-4 opengllib175= initts175=0 opengllib176= @@ -3757,9 +3757,9 @@ initts176=0 opengllib177= initts177=0 opengllib178= -initts178=3 +initts178=0 opengllib179= -initts179=0 +initts179=3 opengllib180= initts180=0 opengllib181= @@ -3779,14 +3779,14 @@ initts187=0 opengllib188= sizy188=600 initts188=0 -title189=Soldiers at War -path189=D:\Games\Soldiers at War\SAW_Game.exe +title189=Solaris (~BAD) +path189=c:\Games\Solaris\solaris.exe module189= opengllib189= -ver189=0 -flag189=671359010 -flagg189=64 -tflag189=0 +ver189=7 +flag189=973078627 +flagg189=1 +tflag189=2 initx189=0 inity189=0 minx189=0 @@ -3795,17 +3795,17 @@ maxx189=0 maxy189=0 posx189=50 posy189=50 -sizx189=640 -sizy189=480 +sizx189=800 +sizy189=600 maxfps189=0 initts189=0 -title190=Sonic 3 +title190=Soldiers at War module190= opengllib190= -path190=C:\Games\Sonic 3 + Sonic et Knuckles\Sonic 3\SONIC3K.EXE -ver190=1 -flag190=546 -flagg190=0 +path190=D:\Games\Soldiers at War\SAW_Game.exe +ver190=0 +flag190=671359010 +flagg190=64 tflag190=0 initx190=0 inity190=0 @@ -3815,16 +3815,16 @@ maxx190=0 maxy190=0 posx190=50 posy190=50 -sizx190=800 -sizy190=600 +sizx190=640 +sizy190=480 maxfps190=0 initts190=0 -title191=Sonic 3D Blast -path191=C:\Games\Sonic3D\pcsonic.exe +title191=Sonic 3 +path191=C:\Games\Sonic 3 + Sonic et Knuckles\Sonic 3\SONIC3K.EXE module191= opengllib191= -ver191=0 -flag191=134217762 +ver191=1 +flag191=546 flagg191=0 tflag191=0 initx191=0 @@ -3839,12 +3839,12 @@ sizx191=800 sizy191=600 maxfps191=0 initts191=0 -title192=Sonic R -path192=C:\Games\SonicR\sonicr.exe +title192=Sonic 3D Blast +path192=C:\Games\Sonic3D\pcsonic.exe module192= opengllib192= ver192=0 -flag192=8288 +flag192=134217762 flagg192=0 tflag192=0 initx192=0 @@ -3859,12 +3859,12 @@ sizx192=800 sizy192=600 maxfps192=0 initts192=0 -title193=Soulbringer -path193=C:\Games\SoulBringer\SoulbringeVCnoeax.exe +title193=Sonic R +path193=C:\Games\SonicR\sonicr.exe module193= opengllib193= ver193=0 -flag193=143024174 +flag193=8288 flagg193=0 tflag193=0 initx193=0 @@ -3879,14 +3879,14 @@ sizx193=800 sizy193=600 maxfps193=0 initts193=0 -title194=Speedboat Attack (BAD) -path194=C:\Games\Speedboat Attack\SBOAT.EXE +title194=Soulbringer +path194=C:\Games\SoulBringer\SoulbringeVCnoeax.exe module194= opengllib194= ver194=0 -flag194=541073954 +flag194=143024174 flagg194=0 -tflag194=2 +tflag194=0 initx194=0 inity194=0 minx194=0 @@ -3899,14 +3899,14 @@ sizx194=800 sizy194=600 maxfps194=0 initts194=0 -title195=Star trek Klingon Honor Guard -path195=D:\Games\Star trek Klingon Honor Guard\System\Khg.exe -module195=OGIDrv.dll +title195=Speedboat Attack (BAD) +path195=C:\Games\Speedboat Attack\SBOAT.EXE +module195= opengllib195= -ver195=10 -flag195=0 -flagg195=537002497 -tflag195=386 +ver195=0 +flag195=541073954 +flagg195=0 +tflag195=2 initx195=0 inity195=0 minx195=0 @@ -3919,14 +3919,14 @@ sizx195=800 sizy195=600 maxfps195=0 initts195=0 -title196=Star Wars Episode 1 Racer -path196=C:\Games\sw racer\SWEP1RCR.EXE -module196= +title196=Star trek Klingon Honor Guard +path196=D:\Games\Star trek Klingon Honor Guard\System\Khg.exe +module196=OGIDrv.dll opengllib196= -ver196=0 -flag196=142606368 -flagg196=0 -tflag196=0 +ver196=10 +flag196=0 +flagg196=537002497 +tflag196=386 initx196=0 inity196=0 minx196=0 @@ -3940,14 +3940,14 @@ sizy196=600 maxfps196=0 initts196=0 -title197=Star Wars Jedi Knight Jedi Academy -path197=D:\Games\Star_Wars_Jedi_Knight_Jedi_Academy\GameData\jasp.exe +title197=Star Wars Episode 1 Racer +path197=C:\Games\sw racer\SWEP1RCR.EXE module197= opengllib197= ver197=0 -flag197=2 -flagg197=196608 -tflag197=2 +flag197=142606368 +flagg197=0 +tflag197=0 initx197=0 inity197=0 minx197=0 @@ -3960,14 +3960,14 @@ sizx197=800 sizy197=600 maxfps197=0 initts197=0 -title198=Star Wars: Jedi Knight -path198=C:\Games\Jedi Knight\Jedi Knight\JK.EXE +title198=Star Wars Jedi Knight Jedi Academy +path198=D:\Games\Star_Wars_Jedi_Knight_Jedi_Academy\GameData\jasp.exe module198= opengllib198= ver198=0 -flag198=8226 -flagg198=0 -tflag198=0 +flag198=2 +flagg198=196608 +tflag198=2 initx198=0 inity198=0 minx198=0 @@ -3980,13 +3980,13 @@ sizx198=800 sizy198=600 maxfps198=0 initts198=0 -title199=Star Wars: the Gungan Frontier -path199=C:\Games\sw the gungan frontier\Gungan Frontier.exe +title199=Star Wars: Jedi Knight +path199=C:\Games\Jedi Knight\Jedi Knight\JK.EXE module199= opengllib199= -ver199=1 -flag199=402915362 -flagg199=512 +ver199=0 +flag199=8226 +flagg199=0 tflag199=0 initx199=0 inity199=0 @@ -3994,40 +3994,40 @@ minx199=0 miny199=0 maxx199=0 maxy199=0 -posx199=0 -posy199=0 +posx199=50 +posy199=50 sizx199=800 sizy199=600 maxfps199=0 initts199=0 -title200=Starcraft -path200=D:\Games\Starcraft\StarCraft.exe +title200=Star Wars: the Gungan Frontier +path200=C:\Games\sw the gungan frontier\Gungan Frontier.exe module200= opengllib200= -ver200=0 -flag200=134234115 -flagg200=2179088 -tflag200=258 +ver200=1 +flag200=402915362 +flagg200=512 +tflag200=0 initx200=0 inity200=0 minx200=0 miny200=0 maxx200=0 maxy200=0 -posx200=50 -posy200=50 +posx200=0 +posy200=0 sizx200=800 sizy200=600 maxfps200=0 initts200=0 -title201=Starship Troopers -path201=C:\Games\Starship Troopers - Terran Ascendancy\stta\StarshipTroopers.exe +title201=Starcraft +path201=D:\Games\Starcraft\StarCraft.exe module201= opengllib201= -ver201=1 -flag201=32 -flagg201=0 -tflag201=0 +ver201=0 +flag201=134234115 +flagg201=2179088 +tflag201=258 initx201=0 inity201=0 minx201=0 @@ -4040,12 +4040,12 @@ sizx201=800 sizy201=600 maxfps201=0 initts201=0 -title202=Starshot Space Circus -path202=D:\SpaceCircus.exe +title202=Starship Troopers +path202=C:\Games\Starship Troopers - Terran Ascendancy\stta\StarshipTroopers.exe module202= opengllib202= -ver202=0 -flag202=66 +ver202=1 +flag202=32 flagg202=0 tflag202=0 initx202=0 @@ -4060,12 +4060,12 @@ sizx202=800 sizy202=600 maxfps202=0 initts202=0 -title203=Stronghold Demo -path203=C:\Games\Firefly Studios' Stronghold - Demo\Stronghold Demo.exe +title203=Starshot Space Circus +path203=D:\SpaceCircus.exe module203= opengllib203= ver203=0 -flag203=98 +flag203=66 flagg203=0 tflag203=0 initx203=0 @@ -4080,51 +4080,51 @@ sizx203=800 sizy203=600 maxfps203=0 initts203=0 -title204=Sub Culture -path204=C:\Games\Sub Culture\sc.exe +title204=Stronghold Demo +path204=C:\Games\Firefly Studios' Stronghold - Demo\Stronghold Demo.exe module204= opengllib204= ver204=0 -flag204=66 -flagg204=256 -tflag204=10 -initx204=50 -inity204=50 -minx204=50 -miny204=50 -maxx204=800 -maxy204=600 +flag204=98 +flagg204=0 +tflag204=0 +initx204=0 +inity204=0 +minx204=0 +miny204=0 +maxx204=0 +maxy204=0 posx204=50 posy204=50 sizx204=800 sizy204=600 maxfps204=0 initts204=0 -title205=Superbike 2001 -path205=C:\Games\Superbike 2001\Sbk2001.exe +title205=Sub Culture +path205=C:\Games\Sub Culture\sc.exe module205= opengllib205= -ver205=1 -flag205=536887332 -flagg205=0 -tflag205=0 -initx205=0 -inity205=0 -minx205=0 -miny205=0 -maxx205=0 -maxy205=0 +ver205=0 +flag205=66 +flagg205=256 +tflag205=10 +initx205=50 +inity205=50 +minx205=50 +miny205=50 +maxx205=800 +maxy205=600 posx205=50 posy205=50 sizx205=800 sizy205=600 maxfps205=0 initts205=0 -title206=Syberia 2 Demo -path206=C:\Games\Syberia 2 Demo\Syberia2Demo.exe +title206=Superbike 2001 +path206=C:\Games\Superbike 2001\Sbk2001.exe module206= opengllib206= -ver206=8 +ver206=1 flag206=536887332 flagg206=0 tflag206=0 @@ -4140,11 +4140,11 @@ sizx206=800 sizy206=600 maxfps206=0 initts206=0 -title207=Syberia Demo -path207=C:\Games\SyberiaDemo\SyberiaDemo.exe +title207=Syberia 2 Demo +path207=C:\Games\Syberia 2 Demo\Syberia2Demo.exe module207= opengllib207= -ver207=1 +ver207=8 flag207=536887332 flagg207=0 tflag207=0 @@ -4160,13 +4160,13 @@ sizx207=800 sizy207=600 maxfps207=0 initts207=0 -title208=System Shock 2 (BAD!!!) -path208=C:\Games\Sys Shock II\Shock2.exe +title208=Syberia Demo +path208=C:\Games\SyberiaDemo\SyberiaDemo.exe module208= opengllib208= ver208=1 -flag208=0 -flagg208=64 +flag208=536887332 +flagg208=0 tflag208=0 initx208=0 inity208=0 @@ -4180,13 +4180,13 @@ sizx208=800 sizy208=600 maxfps208=0 initts208=0 -title209=Take no Prisoners +title209=System Shock 2 (BAD!!!) module209= opengllib209= -path209=D:\Games\Take no Prisoners\TNP.EXE -ver209=0 -flag209=2 -flagg209=16777248 +path209=C:\Games\Sys Shock II\Shock2.exe +ver209=1 +flag209=0 +flagg209=64 tflag209=0 initx209=0 inity209=0 @@ -4200,14 +4200,14 @@ sizx209=800 sizy209=600 maxfps209=0 initts209=0 -title210=Test Drive 4 -path210=D:\Games\Test Drive 4\td4.EXE +title210=Take no Prisoners +path210=D:\Games\Take no Prisoners\TNP.EXE module210= opengllib210= ver210=0 -flag210=-2013265885 -flagg210=-2147418094 -tflag210=2 +flag210=2 +flagg210=16777248 +tflag210=0 initx210=0 inity210=0 minx210=0 @@ -4219,15 +4219,15 @@ posy210=50 sizx210=800 sizy210=600 maxfps210=0 -initts210=-2 -title211=Test Drive 5 (D3D) -path211=D:\Games\Test Drive 5\TD5_D3D.exe +initts210=0 +title211=Test Drive 4 +path211=D:\Games\Test Drive 4\td4.EXE module211= opengllib211= ver211=0 -flag211=671088640 -flagg211=0 -tflag211=258 +flag211=-2013265885 +flagg211=-2147418094 +tflag211=2 initx211=0 inity211=0 minx211=0 @@ -4239,15 +4239,15 @@ posy211=50 sizx211=800 sizy211=600 maxfps211=0 -initts211=0 -title212=The Nations Demo -path212=C:\Games\The Nations Demo\bin\Game.exe +initts211=-2 +title212=Test Drive 5 (D3D) +path212=D:\Games\Test Drive 5\TD5_D3D.exe module212= opengllib212= -ver212=1 -flag212=402661920 -flagg212=256 -tflag212=0 +ver212=0 +flag212=671088640 +flagg212=0 +tflag212=258 initx212=0 inity212=0 minx212=0 @@ -4260,14 +4260,14 @@ sizx212=800 sizy212=600 maxfps212=0 initts212=0 -title213=The Sims -path213=D:\Games\sims\Sims.exe +title213=The Nations Demo +path213=C:\Games\The Nations Demo\bin\Game.exe module213= opengllib213= -ver213=0 -flag213=134226976 -flagg213=65536 -tflag213=2 +ver213=1 +flag213=402661920 +flagg213=256 +tflag213=0 initx213=0 inity213=0 minx213=0 @@ -4280,13 +4280,13 @@ sizx213=800 sizy213=600 maxfps213=0 initts213=0 -title214=Thief the Dark Project (FRE) -path214=C:\Games\thief\game\thieffixed.exe +title214=The Sims +path214=D:\Games\sims\Sims.exe module214= opengllib214= -ver214=1 -flag214=16390 -flagg214=0 +ver214=0 +flag214=134225954 +flagg214=65536 tflag214=0 initx214=0 inity214=0 @@ -4300,14 +4300,14 @@ sizx214=800 sizy214=600 maxfps214=0 initts214=0 -title215=TinTin: Prisoners of the Sun -path215=C:\Games\tintin\TINTINW.EXE +title215=Thief the Dark Project (FRE) +path215=C:\Games\thief\game\thieffixed.exe module215= opengllib215= -ver215=0 -flag215=34 +ver215=1 +flag215=16390 flagg215=0 -tflag215=2 +tflag215=0 initx215=0 inity215=0 minx215=0 @@ -4320,14 +4320,14 @@ sizx215=800 sizy215=600 maxfps215=0 initts215=0 -title216=Tintoy (BAD gfx) -path216=C:\Games\Tintoy\Tintoy.exe +title216=TinTin: Prisoners of the Sun +path216=C:\Games\tintin\TINTINW.EXE module216= opengllib216= ver216=0 -flag216=546 -flagg216=256 -tflag216=258 +flag216=34 +flagg216=0 +tflag216=2 initx216=0 inity216=0 minx216=0 @@ -4340,14 +4340,14 @@ sizx216=800 sizy216=600 maxfps216=0 initts216=0 -title217=Tomb Raider - Anniversary -path217=C:\Games\Tomb Raider - Anniversary\tra.exe +title217=Tintoy (BAD gfx) +path217=C:\Games\Tintoy\Tintoy.exe module217= opengllib217= -ver217=9 -flag217=0 +ver217=0 +flag217=546 flagg217=256 -tflag217=2 +tflag217=258 initx217=0 inity217=0 minx217=0 @@ -4359,15 +4359,15 @@ posy217=50 sizx217=800 sizy217=600 maxfps217=0 -initts217=8 -title218=Tomb Raider 2 the Golden Mask +initts217=0 +title218=Tomb Raider - Anniversary module218= opengllib218= -path218=D:\Games\TR2 Golden Mask\T2GOLD.EXE -ver218=0 -flag218=570425378 -flagg218=1064960 -tflag218=258 +path218=C:\Games\Tomb Raider - Anniversary\tra.exe +ver218=9 +flag218=0 +flagg218=256 +tflag218=2 initx218=0 inity218=0 minx218=0 @@ -4380,14 +4380,14 @@ sizx218=800 sizy218=600 maxfps218=0 initts218=8 -title219=Tomb Raider 3 Demo -path219=C:\Games\Tomb Raider 3 - The Lost Artifact Demo\tr3gold.exe +title219=Tomb Raider 2 the Golden Mask +path219=D:\Games\TR2 Golden Mask\T2GOLD.EXE module219= opengllib219= -ver219=1 -flag219=369098848 -flagg219=0 -tflag219=258 +ver219=0 +flag219=704643106 +flagg219=554713088 +tflag219=0 initx219=0 inity219=0 minx219=0 @@ -4399,14 +4399,14 @@ posy219=50 sizx219=800 sizy219=600 maxfps219=0 -initts219=0 -title220=Tomb Raider 4 Demo -path220=C:\Games\Tomb Raider 4 - The Last Revelation (Demo)\tomb4.patched.exe +initts219=8 +title220=Tomb Raider 3 Demo +path220=C:\Games\Tomb Raider 3 - The Lost Artifact Demo\tr3gold.exe module220= opengllib220= -ver220=0 -flag220=234881056 -flagg220=16 +ver220=1 +flag220=369098848 +flagg220=0 tflag220=258 initx220=0 inity220=0 @@ -4420,14 +4420,14 @@ sizx220=800 sizy220=600 maxfps220=0 initts220=0 -title221=Total Annihilation Kingdoms -path221=D:\Games\Total Annihilation Kingdoms\Kingdoms.exe +title221=Tomb Raider 4 Demo +path221=C:\Games\Tomb Raider 4 - The Last Revelation (Demo)\tomb4.patched.exe module221= opengllib221= ver221=0 -flag221=134234146 -flagg221=1073741824 -tflag221=0 +flag221=234881056 +flagg221=16 +tflag221=258 initx221=0 inity221=0 minx221=0 @@ -4440,13 +4440,13 @@ sizx221=800 sizy221=600 maxfps221=0 initts221=0 -title222=Total Soccer 2000 -path222=D:\Games\Total Soccer 2000\Total Soccer 2000\SOCCERDX.EXE +title222=Total Annihilation Kingdoms +path222=D:\Games\Total Annihilation Kingdoms\Kingdoms.exe module222= opengllib222= -ver222=1 -flag222=167772162 -flagg222=1069056 +ver222=0 +flag222=134234146 +flagg222=1073741840 tflag222=0 initx222=0 inity222=0 @@ -4458,13 +4458,13 @@ posx222=50 posy222=50 sizx222=800 sizy222=600 -maxfps222=200 +maxfps222=0 initts222=0 -flagh0=276 +flagh0=20 flagi0=0 flagh1=0 flagi1=0 -flagh2=0 +flagh2=20 flagi2=0 flagh3=0 flagi3=0 @@ -4476,9 +4476,9 @@ flagh6=0 flagi6=0 flagh7=16 flagi7=0 -flagh8=144 +flagh8=16 flagi8=0 -flagh9=176 +flagh9=48 flagi9=0 flagh10=56 flagi10=0 @@ -4486,7 +4486,7 @@ flagh11=16 flagi11=0 flagh12=20 flagi12=0 -flagh13=144 +flagh13=148 flagi13=0 flagh14=16 flagi14=0 @@ -4494,11 +4494,11 @@ flagh15=0 flagi15=0 flagh16=0 flagi16=0 -flagh17=20 +flagh17=148 flagi17=0 flagh18=16 flagi18=0 -flagh19=80 +flagh19=16 flagi19=0 flagh20=0 flagi20=0 @@ -4522,7 +4522,7 @@ flagh29=0 flagi29=0 flagh30=0 flagi30=0 -flagh31=29 +flagh31=61 flagi31=0 flagh32=0 flagi32=0 @@ -4554,7 +4554,7 @@ flagh45=0 flagi45=0 flagh46=0 flagi46=0 -flagh47=0 +flagh47=20 flagi47=0 flagh48=0 flagi48=0 @@ -4648,11 +4648,11 @@ flagh92=0 flagi92=0 flagh93=0 flagi93=0 -flagh94=0 +flagh94=20 flagi94=0 flagh95=0 flagi95=0 -flagh96=92 +flagh96=80 flagi96=0 flagh97=0 flagi97=0 @@ -4674,27 +4674,27 @@ flagh105=0 flagi105=0 flagh106=16 flagi106=0 -flagh107=0 +flagh107=284 flagi107=0 flagh108=0 flagi108=0 -flagh109=29 +flagh109=0 flagi109=0 -flagh110=0 +flagh110=29 flagi110=0 -flagh111=16 +flagh111=0 flagi111=0 flagh112=16 flagi112=0 -flagh113=28 +flagh113=16 flagi113=0 -flagh114=477 +flagh114=28 flagi114=0 -flagh115=0 +flagh115=477 flagi115=0 flagh116=0 flagi116=0 -flagh117=0 +flagh117=16 flagi117=0 flagh118=0 flagi118=0 @@ -4708,17 +4708,17 @@ flagh122=0 flagi122=0 flagh123=0 flagi123=0 -flagh124=16 +flagh124=0 flagi124=0 -flagh125=0 +flagh125=16 flagi125=0 flagh126=0 flagi126=0 -flagh127=-842150435 -flagi127=-842150451 -flagh128=0 -flagi128=0 -flagh129=0 +flagh127=0 +flagi127=0 +flagh128=-842150435 +flagi128=-842150451 +flagh129=20 flagi129=0 flagh130=0 flagi130=0 @@ -4726,9 +4726,9 @@ flagh131=0 flagi131=0 flagh132=0 flagi132=0 -flagh133=16 +flagh133=0 flagi133=0 -flagh134=0 +flagh134=16 flagi134=0 flagh135=0 flagi135=0 @@ -4752,47 +4752,47 @@ flagh144=0 flagi144=0 flagh145=0 flagi145=0 -flagh146=16 +flagh146=0 flagi146=0 -flagh147=285 +flagh147=16 flagi147=0 -flagh148=16 +flagh148=797 flagi148=0 -flagh149=0 +flagh149=16 flagi149=0 -flagh150=60 +flagh150=0 flagi150=0 -flagh151=61 +flagh151=60 flagi151=0 flagh152=61 flagi152=0 -flagh153=0 +flagh153=61 flagi153=0 flagh154=0 flagi154=0 -flagh155=144 +flagh155=0 flagi155=0 -flagh156=0 +flagh156=144 flagi156=0 flagh157=0 flagi157=0 -flagh158=20 +flagh158=0 flagi158=0 -flagh159=16 +flagh159=20 flagi159=0 -flagh160=20 +flagh160=16 flagi160=0 -flagh161=16 +flagh161=20 flagi161=0 -flagh162=0 +flagh162=16 flagi162=0 flagh163=0 flagi163=0 -flagh164=16 +flagh164=0 flagi164=0 flagh165=16 flagi165=0 -flagh166=0 +flagh166=16 flagi166=0 flagh167=0 flagi167=0 @@ -4802,11 +4802,11 @@ flagh169=0 flagi169=0 flagh170=0 flagi170=0 -flagh171=16 +flagh171=0 flagi171=0 -flagh172=29 +flagh172=16 flagi172=0 -flagh173=0 +flagh173=29 flagi173=0 flagh174=0 flagi174=0 @@ -4814,11 +4814,11 @@ flagh175=0 flagi175=0 flagh176=0 flagi176=0 -flagh177=20 +flagh177=0 flagi177=0 flagh178=20 flagi178=0 -flagh179=0 +flagh179=20 flagi179=0 flagh180=0 flagi180=0 @@ -4830,9 +4830,9 @@ flagh183=0 flagi183=0 flagh184=0 flagi184=0 -flagh185=16 +flagh185=0 flagi185=0 -flagh186=0 +flagh186=20 flagi186=0 flagh187=0 flagi187=0 @@ -4850,19 +4850,19 @@ flagh193=0 flagi193=0 flagh194=0 flagi194=0 -flagh195=16 +flagh195=0 flagi195=0 -flagh196=0 +flagh196=16 flagi196=0 -flagh197=20 +flagh197=0 flagi197=0 -flagh198=0 +flagh198=20 flagi198=0 flagh199=0 flagi199=0 flagh200=0 flagi200=0 -flagh201=0 +flagh201=16 flagi201=0 flagh202=0 flagi202=0 @@ -4880,15 +4880,15 @@ flagh208=0 flagi208=0 flagh209=0 flagi209=0 -flagh210=16 +flagh210=0 flagi210=0 -flagh211=20 +flagh211=16 flagi211=0 -flagh212=0 +flagh212=20 flagi212=0 -flagh213=144 +flagh213=0 flagi213=0 -flagh214=0 +flagh214=16 flagi214=0 flagh215=0 flagi215=0 @@ -4896,24 +4896,24 @@ flagh216=0 flagi216=0 flagh217=0 flagi217=0 -flagh218=16 +flagh218=0 flagi218=0 -flagh219=0 +flagh219=20 flagi219=0 flagh220=0 flagi220=0 -flagh221=16 +flagh221=0 flagi221=0 flagh222=16 flagi222=0 -title223=Ultim@te Race Pro -path223=C:\Games\Ultim@te race pro\Ultim@te Race Pro.exe +title223=Total Soccer 2000 +path223=D:\Games\Total Soccer 2000\Total Soccer 2000\SOCCERdx.EXE module223= opengllib223= -ver223=0 -flag223=570425440 -flagg223=256 -flagh223=0 +ver223=1 +flag223=167772226 +flagg223=1069056 +flagh223=20 flagi223=0 tflag223=0 initx223=0 @@ -4926,16 +4926,16 @@ posx223=50 posy223=50 sizx223=800 sizy223=600 -maxfps223=0 +maxfps223=200 initts223=0 -title224=Uprising - Join or Die -path224=D:\Games\Uprising\uprising.exe +title224=Ultim@te Race Pro +path224=C:\Games\Ultim@te race pro\Ultim@te Race Pro.exe module224= opengllib224= ver224=0 -flag224=-2013265882 -flagg224=18 -flagh224=16 +flag224=570425440 +flagg224=256 +flagh224=0 flagi224=0 tflag224=0 initx224=0 @@ -4950,16 +4950,16 @@ sizx224=800 sizy224=600 maxfps224=0 initts224=0 -title225=Urban Assault -path225=D:\Games\Urban Assault\UA.EXE +title225=Uprising - Join or Die +path225=D:\Games\Uprising\uprising.exe module225= opengllib225= ver225=0 -flag225=671236130 -flagg225=256 +flag225=-2013265882 +flagg225=18 flagh225=16 flagi225=0 -tflag225=258 +tflag225=0 initx225=0 inity225=0 minx225=0 @@ -4972,14 +4972,14 @@ sizx225=800 sizy225=600 maxfps225=0 initts225=0 -title226=Urban Assault CD -path226=D:\Games\Urban Assault CD\UA.EXE +title226=Urban Assault +path226=D:\Games\Urban Assault\UA.EXE module226= opengllib226= ver226=0 flag226=671236130 -flagg226=33024 -flagh226=0 +flagg226=256 +flagh226=16 flagi226=0 tflag226=258 initx226=0 @@ -4994,16 +4994,16 @@ sizx226=800 sizy226=600 maxfps226=0 initts226=0 -title227=wa[cracked].exe -path227=D:\Games\Worms 2 Armageddon\wa[cracked].exe +title227=Urban Assault CD +path227=D:\Games\Urban Assault CD\UA.EXE module227= opengllib227= ver227=0 -flag227=134217730 -flagg227=171966464 -flagh227=16 +flag227=671236130 +flagg227=33024 +flagh227=0 flagi227=0 -tflag227=0 +tflag227=258 initx227=0 inity227=0 minx227=0 @@ -5016,16 +5016,16 @@ sizx227=800 sizy227=600 maxfps227=0 initts227=0 -title228=Warcraft 2 Battlenet Edition -path228=D:\Games\Warcraft 2\Warcraft II BNE.exe +title228=wa[cracked].exe +path228=D:\Games\Worms 2 Armageddon\wa[cracked].exe module228= opengllib228= ver228=0 -flag228=268452003 -flagg228=16 +flag228=134217730 +flagg228=171966464 flagh228=16 flagi228=0 -tflag228=258 +tflag228=0 initx228=0 inity228=0 minx228=0 @@ -5036,18 +5036,18 @@ posx228=50 posy228=50 sizx228=800 sizy228=600 -maxfps228=40 +maxfps228=0 initts228=0 -title229=Wargames (demo) -path229=D:\Games\Wargames\wargames.exe +title229=Warcraft 2 Battlenet Edition +path229=D:\Games\Warcraft 2\Warcraft II BNE.exe module229= opengllib229= ver229=0 -flag229=268435618 -flagg229=1207959552 -flagh229=20 +flag229=268452003 +flagg229=16 +flagh229=16 flagi229=0 -tflag229=3 +tflag229=258 initx229=0 inity229=0 minx229=0 @@ -5058,21 +5058,21 @@ posx229=50 posy229=50 sizx229=800 sizy229=600 -maxfps229=0 +maxfps229=40 initts229=0 -title230=WarHammer Rites of War +title230=Wargames (demo) module230= opengllib230= -title231=Warlords 3 +title231=Warhammer 40K Final Liberation module231= opengllib231= -path230=C:\Games\Rites of War\RoW.exe +path230=D:\Games\Wargames\wargames.exe ver230=0 -flag230=134217760 -flagg230=128 -flagh230=0 +flag230=268435618 +flagg230=1207959552 +flagh230=20 flagi230=0 -tflag230=0 +tflag230=3 initx230=0 inity230=0 minx230=0 @@ -5085,13 +5085,13 @@ sizx230=800 sizy230=600 maxfps230=0 initts230=0 -path231=D:\Games\WARLORDS3\Darklord.exe -ver231=0 -flag231=-2013265886 -flagg231=1343225888 -flagh231=20 +path231=D:\Games\Warhammer 40K Final Liberation\EPIC40K.EXE +ver231=1 +flag231=134479874 +flagg231=135266304 +flagh231=31 flagi231=0 -tflag231=258 +tflag231=0 initx231=0 inity231=0 minx231=0 @@ -5100,17 +5100,17 @@ maxx231=0 maxy231=0 posx231=50 posy231=50 -sizx231=0 -sizy231=0 +sizx231=800 +sizy231=600 maxfps231=0 initts231=0 -title232=WarTorn -path232=C:\Games\WarTorn\W.exe +title232=WarHammer Rites of War +path232=C:\Games\Rites of War\RoW.exe module232= opengllib232= ver232=0 -flag232=32 -flagg232=0 +flag232=134217760 +flagg232=128 flagh232=0 flagi232=0 tflag232=0 @@ -5126,14 +5126,14 @@ sizx232=800 sizy232=600 maxfps232=0 initts232=0 -title233=WarWind -path233=C:\Games\WarWind\WW.EXE +title233=Warlords 3 +path233=D:\Games\WARLORDS3\Darklord.exe module233= opengllib233= ver233=0 -flag233=16418 -flagg233=81936 -flagh233=0 +flag233=-2147483102 +flagg233=269484064 +flagh233=532 flagi233=0 tflag233=0 initx233=0 @@ -5144,37 +5144,37 @@ maxx233=0 maxy233=0 posx233=50 posy233=50 -sizx233=800 -sizy233=600 +sizx233=0 +sizy233=0 maxfps233=0 initts233=0 -title234=Worms Armageddon Demo (BAD!!!) -path234=C:\Games\Worms Armageddon Demo\WaDemo.exe +title234=WarTorn +path234=C:\Games\WarTorn\W.exe module234= opengllib234= -ver234=1 -flag234=939524099 -flagg234=8 +ver234=0 +flag234=32 +flagg234=0 flagh234=0 flagi234=0 -tflag234=2 +tflag234=0 initx234=0 inity234=0 minx234=0 miny234=0 maxx234=0 maxy234=0 -posx234=0 -posy234=0 -sizx234=0 -sizy234=0 +posx234=50 +posy234=50 +sizx234=800 +sizy234=600 maxfps234=0 initts234=0 coord0=0 coord1=0 coord2=0 coord3=0 -coord4=0 +coord4=1 coord5=0 coord6=0 coord7=0 @@ -5370,8 +5370,8 @@ coord196=0 coord197=0 coord198=0 coord199=0 -coord200=1 -coord201=0 +coord200=0 +coord201=1 coord202=0 coord203=0 coord204=0 @@ -5391,7 +5391,7 @@ coord217=0 coord218=0 coord219=0 coord220=0 -coord221=1 +coord221=0 coord222=0 coord223=0 coord224=0 @@ -5405,14 +5405,14 @@ coord231=0 coord232=0 coord233=0 coord234=0 -title235=Worms World Party -path235=D:\Games\Worms World Party\wwp.exe +title235=WarWind +path235=C:\Games\WarWind\WW.EXE module235= opengllib235= -ver235=1 +ver235=0 coord235=0 -flag235=8388610 -flagg235=0 +flag235=16418 +flagg235=81936 flagh235=0 flagi235=0 tflag235=0 @@ -5428,13 +5428,13 @@ sizx235=800 sizy235=600 maxfps235=0 initts235=0 -title236=Worms World Party Demo (BAD) -path236=C:\Games\WWP Demo\wwp.exe -module236=MFC42.DLL ltkrn10N.dll +title236=Worms Armageddon Demo (BAD!!!) +path236=C:\Games\Worms Armageddon Demo\WaDemo.exe +module236= opengllib236= ver236=1 coord236=0 -flag236=406847491 +flag236=939524099 flagg236=8 flagh236=0 flagi236=0 @@ -5451,13 +5451,13 @@ sizx236=0 sizy236=0 maxfps236=0 initts236=0 -title237=X-Com Enforcer -path237=C:\Games\X-Com Enforcer\System\xcom.exe +title237=Worms World Party +path237=D:\Games\Worms World Party\wwp.exe module237= opengllib237= ver237=1 coord237=0 -flag237=32 +flag237=8388610 flagg237=0 flagh237=0 flagi237=0 @@ -5468,42 +5468,42 @@ minx237=0 miny237=0 maxx237=0 maxy237=0 -posx237=0 -posy237=0 +posx237=50 +posy237=50 sizx237=800 sizy237=600 maxfps237=0 initts237=0 -title238=X-Com Interceptor -path238=C:\Games\X-Com_Interceptor\X-COM Interceptor\Interceptor.exe -module238= +title238=Worms World Party Demo (BAD) +path238=C:\Games\WWP Demo\wwp.exe +module238=MFC42.DLL ltkrn10N.dll opengllib238= -ver238=0 +ver238=1 coord238=0 -flag238=16418 -flagg238=0 +flag238=406847491 +flagg238=8 flagh238=0 flagi238=0 -tflag238=0 +tflag238=2 initx238=0 inity238=0 minx238=0 miny238=0 maxx238=0 maxy238=0 -posx238=50 -posy238=50 -sizx238=800 -sizy238=600 +posx238=0 +posy238=0 +sizx238=0 +sizy238=0 maxfps238=0 initts238=0 -title239=Z Steel Soldiers -path239=C:\Games\ZSteelSoldiers\Bin\z2.exe +title239=X-Com Enforcer +path239=C:\Games\X-Com Enforcer\System\xcom.exe module239= opengllib239= -ver239=8 +ver239=1 coord239=0 -flag239=805462020 +flag239=32 flagg239=0 flagh239=0 flagi239=0 @@ -5514,19 +5514,19 @@ minx239=0 miny239=0 maxx239=0 maxy239=0 -posx239=50 -posy239=50 +posx239=0 +posy239=0 sizx239=800 sizy239=600 maxfps239=0 initts239=0 -title240=Zax Alien Hunter -path240=C:\Games\ZaxDemo\Zax.exe +title240=X-Com Interceptor +path240=C:\Games\X-Com_Interceptor\X-COM Interceptor\Interceptor.exe module240= opengllib240= ver240=0 coord240=0 -flag240=-1476386784 +flag240=16418 flagg240=0 flagh240=0 flagi240=0 @@ -5543,14 +5543,14 @@ sizx240=800 sizy240=600 maxfps240=0 initts240=0 -title241=Zero Critical (BAD) -path241=C:\Games\zero_critical_-_satin_rift\ZEROCR.EXE +title241=Z Steel Soldiers +path241=C:\Games\ZSteelSoldiers\Bin\z2.exe module241= opengllib241= -ver241=0 +ver241=8 coord241=0 -flag241=679477858 -flagg241=8 +flag241=805462020 +flagg241=0 flagh241=0 flagi241=0 tflag241=0 @@ -5560,19 +5560,19 @@ minx241=0 miny241=0 maxx241=0 maxy241=0 -posx241=0 -posy241=0 +posx241=50 +posy241=50 sizx241=800 sizy241=600 maxfps241=0 initts241=0 -title242=Zero Population Count -path242=C:\Games\ZPC\ZPC.EXE +title242=Zax Alien Hunter +path242=C:\Games\ZaxDemo\Zax.exe module242= opengllib242= ver242=0 coord242=0 -flag242=1073741859 +flag242=-1476386784 flagg242=0 flagh242=0 flagi242=0 @@ -5583,20 +5583,20 @@ minx242=0 miny242=0 maxx242=0 maxy242=0 -posx242=0 -posy242=0 +posx242=50 +posy242=50 sizx242=800 sizy242=600 maxfps242=0 initts242=0 -title243=Zero Zone -path243=D:\ZZone\ZeroZone.exe +title243=Zero Critical (BAD) +path243=C:\Games\zero_critical_-_satin_rift\ZEROCR.EXE module243= opengllib243= ver243=0 coord243=0 -flag243=34 -flagg243=0 +flag243=679477858 +flagg243=8 flagh243=0 flagi243=0 tflag243=0 @@ -5606,19 +5606,19 @@ minx243=0 miny243=0 maxx243=0 maxy243=0 -posx243=50 -posy243=50 +posx243=0 +posy243=0 sizx243=800 sizy243=600 maxfps243=0 initts243=0 -title244=Zeus Poseidon -path244=C:\Games\Zeus-Poseidon\Zeus.exe +title244=Zero Population Count +path244=C:\Games\ZPC\ZPC.EXE module244= opengllib244= ver244=0 coord244=0 -flag244=34 +flag244=1073741859 flagg244=0 flagh244=0 flagi244=0 @@ -5629,19 +5629,19 @@ minx244=0 miny244=0 maxx244=0 maxy244=0 -posx244=50 -posy244=50 +posx244=0 +posy244=0 sizx244=800 sizy244=600 maxfps244=0 initts244=0 -title245=Zoo Tycoon -path245=C:\Games\Zoo Tycoon\zoo.exe +title245=Zero Zone +path245=D:\ZZone\ZeroZone.exe module245= opengllib245= ver245=0 coord245=0 -flag245=-2013265886 +flag245=34 flagg245=0 flagh245=0 flagi245=0 @@ -5658,17 +5658,17 @@ sizx245=800 sizy245=600 maxfps245=0 initts245=0 -title246=Warhammer 40K Final Liberation -path246=D:\Games\Warhammer 40K Final Liberation\EPIC40K.EXE +title246=Zeus Poseidon +path246=C:\Games\Zeus-Poseidon\Zeus.exe module246= opengllib246= -ver246=1 +ver246=0 coord246=0 -flag246=134217730 -flagg246=1209008128 -flagh246=221 +flag246=34 +flagg246=0 +flagh246=0 flagi246=0 -tflag246=3 +tflag246=0 initx246=0 inity246=0 minx246=0 @@ -5681,8 +5681,100 @@ sizx246=800 sizy246=600 maxfps246=0 initts246=0 +title247=Zoo Tycoon +path247=C:\Games\Zoo Tycoon\zoo.exe +module247= +opengllib247= +ver247=0 +coord247=0 +flag247=-2013265886 +flagg247=0 +flagh247=0 +flagi247=0 +tflag247=0 +initx247=0 +inity247=0 +minx247=0 +miny247=0 +maxx247=0 +maxy247=0 +posx247=50 +posy247=50 +sizx247=800 +sizy247=600 +maxfps247=0 +initts247=0 +title248=Mortal Kombat 4 +path248=D:\Games\mk4\Mortal Kombat 4.exe +module248= +opengllib248= +ver248=0 +coord248=0 +flag248=536879107 +flagg248=135266308 +flagh248=276 +flagi248=0 +tflag248=3 +initx248=0 +inity248=0 +minx248=0 +miny248=0 +maxx248=0 +maxy248=0 +posx248=50 +posy248=50 +sizx248=800 +sizy248=600 +maxfps248=0 +initts248=0 +title249=Railroad Tycoon II +module249= +opengllib249= +path249=D:\Games\Railroad.Tycoon.II\RT2.EXE +ver249=0 +coord249=0 +flag249=2080 +flagg249=143654912 +flagh249=16 +flagi249=0 +tflag249=0 +initx249=0 +inity249=0 +minx249=0 +miny249=0 +maxx249=0 +maxy249=0 +posx249=50 +posy249=50 +sizx249=800 +sizy249=600 +maxfps249=0 +initts249=0 +title250=Space Hack +path250=D:\Games\Space Hack\main.exe +module250= +opengllib250= +ver250=0 +coord250=0 +flag250=134234144 +flagg250=134217728 +flagh250=20 +flagi250=0 +tflag250=3 +initx250=0 +inity250=0 +minx250=0 +miny250=0 +maxx250=0 +maxy250=0 +posx250=50 +posy250=50 +sizx250=800 +sizy250=600 +maxfps250=0 +initts250=0 [window] -posx=-32008 -posy=-32050 -sizx=16 -sizy=58 +posx=847 +posy=92 +sizx=400 +sizy=300 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 5ed2651..e200df1 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -151,3 +151,20 @@ Added Kill process by name functionality (right click menu on program's list) Fixed GUI initial position: now checks for desktop size to fit GUI within visible borders Added single cpu process affinity checkbox in compatibility tab +v2.02.26 +CORE: +Fixed Black&White mode for 16BPP color depth +Revised hooking code, now more compact and clear.... +Fixed DxWnd splash screen, for those who love it +Increased child win table - now 688 hunter killer works perfectly +GUI: +Added /debug flag to enable debugging options +Revised hooking code, now more compact and clear.... +Restored Hook child win option + +v2.02.27 +CORE: +fixed GetDC/ReleaseDC ddraw implementation to refresh GDI operation on primary surface. Warlords 3 text is now visible. +preliminary implementation of MapWindowPoints - to be tested +GUI: +Fixed log flags wrong initialization \ No newline at end of file diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp new file mode 100644 index 0000000..f856c1a --- /dev/null +++ b/dll/ddraw.cpp @@ -0,0 +1,3797 @@ +// to do: duplicate EnumSurfaces(D) handling +// fix Unlock duplicate hook in Judge Dredd Pinball + +#define INITGUID + +#include +#include +#include "dxwnd.h" +#include "dxhook.h" +#include "dxwcore.hpp" +#include "stdio.h" +#include "hddraw.h" +#include "hddproxy.h" +#include "dxhelper.h" +#include "syslibs.h" + + +// DirectDraw API +HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); +HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *); +HRESULT WINAPI extDirectDrawEnumerate(LPDDENUMCALLBACK, LPVOID); +HRESULT WINAPI extDirectDrawEnumerateEx(LPDDENUMCALLBACKEX, LPVOID, DWORD); + +// DirectDraw +HRESULT WINAPI extQueryInterfaceD(void *, REFIID, LPVOID *); +ULONG WINAPI extReleaseD(LPDIRECTDRAW); + /*** IDirectDraw methods ***/ +HRESULT WINAPI extCreateClipper(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*); +HRESULT WINAPI extCreatePalette(LPDIRECTDRAW, DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *, IUnknown *); +HRESULT WINAPI extCreateSurface1(LPDIRECTDRAW, DDSURFACEDESC *, LPDIRECTDRAWSURFACE *, void *); +HRESULT WINAPI extCreateSurface2(LPDIRECTDRAW, DDSURFACEDESC *, LPDIRECTDRAWSURFACE *, void *); +HRESULT WINAPI extCreateSurface4(LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *); +HRESULT WINAPI extCreateSurface7(LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *); +HRESULT WINAPI extDuplicateSurface(LPDIRECTDRAW, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE *); +HRESULT WINAPI extFlipToGDISurface(LPDIRECTDRAW); +HRESULT WINAPI extGetDisplayMode(LPDIRECTDRAW, LPDDSURFACEDESC); +HRESULT WINAPI extGetGDISurface(LPDIRECTDRAW, LPDIRECTDRAWSURFACE *); +HRESULT WINAPI extEnumDisplayModes1(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK); +HRESULT WINAPI extEnumDisplayModes4(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC2, LPVOID, LPDDENUMMODESCALLBACK2); +// STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; +HRESULT WINAPI extSetCooperativeLevel(void *, HWND, DWORD); +HRESULT WINAPI extSetDisplayMode1(LPDIRECTDRAW, DWORD, DWORD, DWORD); +HRESULT WINAPI extSetDisplayMode2(LPDIRECTDRAW, DWORD, DWORD, DWORD, DWORD, DWORD); +HRESULT WINAPI extWaitForVerticalBlank(LPDIRECTDRAW, DWORD, HANDLE); + /*** Added in the V4 Interface ***/ +HRESULT WINAPI extTestCooperativeLevel(LPDIRECTDRAW); +// STDMETHOD(StartModeTest)(THIS_ LPSIZE, DWORD, DWORD ) PURE; +// STDMETHOD(EvaluateMode)(THIS_ DWORD, DWORD * ) PURE; +HRESULT WINAPI extGetCapsD(LPDIRECTDRAW, LPDDCAPS, LPDDCAPS); + + +// DirectDrawSurface +HRESULT WINAPI extQueryInterfaceS(void *, REFIID, LPVOID *); +HRESULT WINAPI extReleaseS(LPDIRECTDRAWSURFACE); + + /*** IDirectDrawSurface methods ***/ +HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE); +HRESULT WINAPI extBlt(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX); +HRESULT WINAPI extBltFast(LPDIRECTDRAWSURFACE, DWORD, DWORD, LPDIRECTDRAWSURFACE, LPRECT, DWORD); +HRESULT WINAPI extDeleteAttachedSurface(LPDIRECTDRAWSURFACE, DWORD, LPDIRECTDRAWSURFACE); +HRESULT WINAPI extEnumAttachedSurfaces(LPDIRECTDRAWSURFACE, LPVOID, LPDDENUMSURFACESCALLBACK); +HRESULT WINAPI extFlip(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE, DWORD); +HRESULT WINAPI extGetAttachedSurface1(LPDIRECTDRAWSURFACE, DDSCAPS *, LPDIRECTDRAWSURFACE *); +HRESULT WINAPI extGetAttachedSurface3(LPDIRECTDRAWSURFACE, DDSCAPS *, LPDIRECTDRAWSURFACE *); +HRESULT WINAPI extGetAttachedSurface4(LPDIRECTDRAWSURFACE, DDSCAPS *, LPDIRECTDRAWSURFACE *); +HRESULT WINAPI extGetAttachedSurface7(LPDIRECTDRAWSURFACE, DDSCAPS *, LPDIRECTDRAWSURFACE *); +HRESULT WINAPI extGetCaps1S(LPDIRECTDRAWSURFACE, LPDDSCAPS); +HRESULT WINAPI extGetCaps2S(LPDIRECTDRAWSURFACE, LPDDSCAPS); +HRESULT WINAPI extGetCaps3S(LPDIRECTDRAWSURFACE, LPDDSCAPS); +HRESULT WINAPI extGetCaps4S(LPDIRECTDRAWSURFACE, LPDDSCAPS2); +HRESULT WINAPI extGetCaps7S(LPDIRECTDRAWSURFACE, LPDDSCAPS2); +HRESULT WINAPI extGetColorKey(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY); +HRESULT WINAPI extGetDC(LPDIRECTDRAWSURFACE, HDC FAR *); +HRESULT WINAPI extGetPalette(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE *); +HRESULT WINAPI extGetPixelFormat(LPDIRECTDRAWSURFACE, LPDDPIXELFORMAT); +HRESULT WINAPI extGetSurfaceDesc1(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd); +HRESULT WINAPI extGetSurfaceDesc2(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 lpddsd); +// STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC2) PURE; +HRESULT WINAPI extLock(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, DWORD, HANDLE); +HRESULT WINAPI extReleaseDC(LPDIRECTDRAWSURFACE, HDC); +HRESULT WINAPI extSetClipper(LPDIRECTDRAWSURFACE, LPDIRECTDRAWCLIPPER); +HRESULT WINAPI extSetColorKey(LPDIRECTDRAWSURFACE, DWORD, LPDDCOLORKEY); +HRESULT WINAPI extSetPalette(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE); +HRESULT WINAPI extUnlock4(LPDIRECTDRAWSURFACE, LPRECT); +HRESULT WINAPI extUnlock1(LPDIRECTDRAWSURFACE, LPVOID); + +HRESULT WINAPI extCreateSurface(int, CreateSurface_Type, LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *); + +// DirectDrawClipper +HRESULT WINAPI extReleaseC(LPDIRECTDRAWCLIPPER); + +// DirectDrawPalette +HRESULT WINAPI extReleaseP(LPDIRECTDRAWPALETTE); +// STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE; +HRESULT WINAPI extSetEntries(LPDIRECTDRAWPALETTE, DWORD, DWORD, DWORD, LPPALETTEENTRY); + +HDC WINAPI extGDIGetDC(HWND); +HDC WINAPI extGDIGetWindowDC(HWND); +int WINAPI extGDIReleaseDC(HWND, HDC); + +/* DirectDraw APIs */ +DirectDrawCreate_Type pDirectDrawCreate; +DirectDrawCreateEx_Type pDirectDrawCreateEx; +DirectDrawEnumerate_Type pDirectDrawEnumerate; +DirectDrawEnumerateEx_Type pDirectDrawEnumerateEx; + +/* DirectDraw hook pointers */ +QueryInterface_Type pQueryInterfaceD; +AddRefD_Type pAddRefD; +ReleaseD_Type pReleaseD; +Compact_Type pCompact; +CreateClipper_Type pCreateClipper=NULL; +CreatePalette_Type pCreatePalette; +CreateSurface1_Type pCreateSurface1; +CreateSurface1_Type pCreateSurface2; +CreateSurface1_Type pCreateSurface3; +CreateSurface2_Type pCreateSurface4; +CreateSurface2_Type pCreateSurface7; +DuplicateSurface_Type pDuplicateSurface; +EnumDisplayModes1_Type pEnumDisplayModes1; +EnumDisplayModes4_Type pEnumDisplayModes4; +EnumSurfaces1_Type pEnumSurfaces1; +EnumSurfaces4_Type pEnumSurfaces4; +FlipToGDISurface_Type pFlipToGDISurface; +GetCapsD_Type pGetCapsD; +GetDisplayMode_Type pGetDisplayMode; +GetFourCCCodes_Type pGetFourCCCodes; +GetGDISurface_Type pGetGDISurface; +GetMonitorFrequency_Type pGetMonitorFrequency; +GetScanLine_Type pGetScanLine; +GetVerticalBlankStatus_Type pGetVerticalBlankStatus; +//Initialize +RestoreDisplayMode_Type pRestoreDisplayMode; +SetCooperativeLevel_Type pSetCooperativeLevel; +SetDisplayMode1_Type pSetDisplayMode1; +SetDisplayMode2_Type pSetDisplayMode2; +WaitForVerticalBlank_Type pWaitForVerticalBlank; +GetSurfaceFromDC_Type pGetSurfaceFromDC; +GetAvailableVidMem_Type pGetAvailableVidMem; +RestoreAllSurfaces_Type pRestoreAllSurfaces; +TestCooperativeLevel_Type pTestCooperativeLevel; +GetDeviceIdentifier_Type pGetDeviceIdentifier; + +/* DirectDrawSurface hook pointers */ +QueryInterface_Type pQueryInterfaceS; +AddRefS_Type pAddRefS; +ReleaseS_Type pReleaseS; +AddAttachedSurface_Type pAddAttachedSurface; +AddOverlayDirtyRect_Type pAddOverlayDirtyRect; +Blt_Type pBlt; +BltBatch_Type pBltBatch; +BltFast_Type pBltFast; +DeleteAttachedSurface_Type pDeleteAttachedSurface; +EnumAttachedSurfaces_Type pEnumAttachedSurfaces; +EnumOverlayZOrders_Type pEnumOverlayZOrders; +Flip_Type pFlip; +GetAttachedSurface_Type pGetAttachedSurface1; +GetAttachedSurface_Type pGetAttachedSurface3; +GetAttachedSurface_Type pGetAttachedSurface4; +GetAttachedSurface_Type pGetAttachedSurface7; +GetBltStatus_Type pGetBltStatus; +GetCapsS_Type pGetCaps1S; +GetCapsS_Type pGetCaps2S; +GetCapsS_Type pGetCaps3S; +GetCaps2S_Type pGetCaps4S; +GetCaps2S_Type pGetCaps7S; +GetClipper_Type pGetClipper; +GetColorKey_Type pGetColorKey; +GetDC_Type pGetDC; +GetFlipStatus_Type pGetFlipStatus; +GetOverlayPosition_Type pGetOverlayPosition; +GetPalette_Type pGetPalette; +GetPixelFormat_Type pGetPixelFormat; +GetSurfaceDesc_Type pGetSurfaceDesc1; +GetSurfaceDesc2_Type pGetSurfaceDesc4; +//Initialize +IsLost_Type pIsLost; +Lock_Type pLock; +ReleaseDC_Type pReleaseDC; +Restore_Type pRestore; +SetClipper_Type pSetClipper; +SetColorKey_Type pSetColorKey; +SetOverlayPosition_Type pSetOverlayPosition; +SetPalette_Type pSetPalette; +Unlock1_Type pUnlock1; +Unlock4_Type pUnlock4; +UpdateOverlay_Type pUpdateOverlay; +UpdateOverlayDisplay_Type pUpdateOverlayDisplay; +UpdateOverlayZOrder_Type pUpdateOverlayZOrder; + +/* DirectDrawClipper hook pointers */ +QueryInterface_Type pQueryInterfaceC; +AddRefC_Type pAddRefC; +ReleaseC_Type pReleaseC; +GetClipList_Type pGetClipList; +GetHWnd_Type pGetHWnd; +InitializeC_Type pInitializeC; +IsClipListChanged_Type pIsClipListChanged; +SetClipList_Type pSetClipList; +SetHWnd_Type pSetHWnd; + +/* DirectDrawPalette hook pointers */ +QueryInterfaceP_Type pQueryInterfaceP; +AddRefP_Type pAddRefP; +ReleaseP_Type pReleaseP; + /*** IDirectDrawPalette methods ***/ +GetCapsP_Type pGetCapsP; +GetEntries_Type pGetEntries; +// STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE; +SetEntries_Type pSetEntries; + +#define MAXBACKBUFFERS 4 + +LPDIRECTDRAWSURFACE lpDDSEmu_Prim=NULL, lpDDSEmu_Back=NULL; +LPDIRECTDRAWSURFACE lpDDSBack=NULL; +LPDIRECTDRAWCLIPPER lpDDC=NULL; +LPDIRECTDRAWPALETTE lpDDP=NULL; +LPDIRECTDRAW lpDD=NULL; +// v2.1.87: lpServiceDD is the DIRECTDRAW object to which the primary surface and all +// the service objects (emulated backbuffer, emulater primary, ....) are attached. +LPDIRECTDRAW lpServiceDD=NULL; +DWORD PaletteEntries[256]; +DWORD *Palette16BPP = NULL; +void *EmuScreenBuffer = NULL; // to implement pitch bug fix +DWORD rPitch = 0; +LPVOID rSurface = NULL; +static char *SetPixFmt(LPDDSURFACEDESC2); +int FlipChainLength=0; + +FARPROC Remap_ddraw_ProcAddress(LPCSTR proc, HMODULE hModule) +{ + if (!strcmp(proc,"DirectDrawCreate")){ + pDirectDrawCreate=(DirectDrawCreate_Type)(*pGetProcAddress)(hModule, proc); + OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), pDirectDrawCreate); + return (FARPROC)extDirectDrawCreate; + } + if (!strcmp(proc,"DirectDrawCreateEx")){ + pDirectDrawCreateEx=(DirectDrawCreateEx_Type)(*pGetProcAddress)(hModule, proc); + OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), pDirectDrawCreateEx); + return (FARPROC)extDirectDrawCreateEx; + } + if (!strcmp(proc,"DirectDrawEnumerateA")){ + pDirectDrawEnumerate=(DirectDrawEnumerate_Type)(*pGetProcAddress)(hModule, proc); + OutTraceP("GetProcAddress: hooking proc=%s at addr=%x\n", proc, pDirectDrawEnumerate); + return (FARPROC)extDirectDrawEnumerateProxy; + } + if (!strcmp(proc,"DirectDrawEnumerateExA")){ + pDirectDrawEnumerateEx=(DirectDrawEnumerateEx_Type)(*pGetProcAddress)(hModule, proc); + OutTraceP("GetProcAddress: hooking proc=%s at addr=%x\n", proc, pDirectDrawEnumerateEx); + return (FARPROC)extDirectDrawEnumerateExProxy; + } + // NULL -> keep the original call address + return NULL; +} + +/* ------------------------------------------------------------------------------ */ +// auxiliary (static) functions +/* ------------------------------------------------------------------------------ */ + +static void LogSurfaceAttributes(LPDDSURFACEDESC lpddsd, char *label, int line) +{ + OutTraceD("SurfaceDesc: %s Flags=%x(%s)", + label, + lpddsd->dwFlags, ExplainFlags(lpddsd->dwFlags)); + if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) OutTraceD(" BackBufferCount=%d", lpddsd->dwBackBufferCount); + if (lpddsd->dwFlags & DDSD_WIDTH) OutTraceD(" Width=%d", lpddsd->dwWidth); + if (lpddsd->dwFlags & DDSD_HEIGHT) OutTraceD(" Height=%d", lpddsd->dwHeight); + if (lpddsd->dwFlags & DDSD_CAPS) OutTraceD(" Caps=%x(%s)", lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps)); + if (lpddsd->dwFlags & DDSD_CKDESTBLT ) OutTraceD(" CKDestBlt=(%x,%x)", lpddsd->ddckCKDestBlt.dwColorSpaceLowValue, lpddsd->ddckCKDestBlt.dwColorSpaceHighValue); + if (lpddsd->dwFlags & DDSD_CKDESTOVERLAY ) OutTraceD(" CKDestOverlay=(%x,%x)", lpddsd->ddckCKDestOverlay.dwColorSpaceLowValue, lpddsd->ddckCKDestOverlay.dwColorSpaceHighValue); + if (lpddsd->dwFlags & DDSD_CKSRCBLT ) OutTraceD(" CKSrcBlt=(%x,%x)", lpddsd->ddckCKSrcBlt.dwColorSpaceLowValue, lpddsd->ddckCKSrcBlt.dwColorSpaceHighValue); + if (lpddsd->dwFlags & DDSD_CKSRCOVERLAY ) OutTraceD(" CKSrcOverlay=(%x,%x)", lpddsd->ddckCKSrcOverlay.dwColorSpaceLowValue, lpddsd->ddckCKSrcOverlay.dwColorSpaceHighValue); + if (lpddsd->dwFlags & DDSD_PIXELFORMAT ) OutTraceD(" PixelFormat BPP=%d RGBA=(%x,%x,%x,%x)", + lpddsd->ddpfPixelFormat.dwRGBBitCount, + lpddsd->ddpfPixelFormat.dwRBitMask, + lpddsd->ddpfPixelFormat.dwGBitMask, + lpddsd->ddpfPixelFormat.dwBBitMask, + lpddsd->ddpfPixelFormat.dwRGBAlphaBitMask); + if (lpddsd->dwFlags & DDSD_LPSURFACE) OutTraceD(" Surface=%x", lpddsd->lpSurface); + OutTraceD("\n"); +} + +static void DumpSurfaceAttributes(LPDDSURFACEDESC lpddsd, char *label, int line) +{ + if(!IsDebug) return; + LogSurfaceAttributes(lpddsd, label, line); +} + +#define CAPSHASHSIZE 113 + +typedef struct { + LPDIRECTDRAWSURFACE lpdds; + DWORD Flags; + DWORD Caps; + DDPIXELFORMAT PixelFormat; +} CapsHash_Type; +static CapsHash_Type *CapsHash; + +static void PushCaps(LPDDSURFACEDESC2 lpddsd, LPDIRECTDRAWSURFACE lpdds) +{ + static BOOL DoFirst = TRUE; + int i; + if (DoFirst) { // initialize + CapsHash=(CapsHash_Type *)malloc(CAPSHASHSIZE * sizeof(CapsHash_Type)); + memset(CapsHash, 0, CAPSHASHSIZE * sizeof(CapsHash_Type)); + DoFirst = FALSE; + } + if(IsDebug){ + OutTrace("PushCaps: lpdds=%x dwFlags=%x dwCaps=%x", lpdds, lpddsd->dwFlags, lpddsd->ddsCaps.dwCaps); + if (lpddsd->dwFlags & DDSD_PIXELFORMAT) OutTrace(" PF.dwFlags=%x PF.dwFourCC=%x PF.dwRGBBitCount=%x RGBA=(%x,%x,%x,%x)", + lpddsd->ddpfPixelFormat.dwFlags, lpddsd->ddpfPixelFormat.dwFourCC, lpddsd->ddpfPixelFormat.dwRGBBitCount, + lpddsd->ddpfPixelFormat.dwRBitMask, lpddsd->ddpfPixelFormat.dwGBitMask, lpddsd->ddpfPixelFormat.dwBBitMask, lpddsd->ddpfPixelFormat.dwRGBAlphaBitMask); + OutTrace("\n"); + } + i = ((DWORD)lpdds >> 3) % CAPSHASHSIZE; + if(CapsHash[i].lpdds && (CapsHash[i].lpdds != lpdds)) { + char sMsg[80]; + sprintf(sMsg, "PushCaps CONFLICT %x:%x\n", lpdds, CapsHash[i].lpdds); + OutTraceE(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "PushCaps", MB_OK | MB_ICONEXCLAMATION); + return; + } + CapsHash[i].lpdds = lpdds; + CapsHash[i].Flags = lpddsd->dwFlags; + CapsHash[i].Caps = lpddsd->ddsCaps.dwCaps; + memcpy((void *)&CapsHash[i].PixelFormat, &lpddsd->ddpfPixelFormat, sizeof(DDPIXELFORMAT)); + //CapsHash[i].PixelFormat.dwFlags = lpddsd->ddpfPixelFormat.dwFlags; +} + +static int PopCaps(LPDDSURFACEDESC2 lpddsd, LPDIRECTDRAWSURFACE lpdds) +{ + int i; + i = ((DWORD)lpdds >> 3) % CAPSHASHSIZE; + if(lpdds != CapsHash[i].lpdds){ + char sMsg[80]; + sprintf(sMsg, "PopCaps MISMATCH %x:%x\n", lpdds, CapsHash[i].lpdds); + OutTraceE(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "PopCaps", MB_OK | MB_ICONEXCLAMATION); + return FALSE; + } + if (lpddsd->dwSize > (DWORD)&((LPDDSURFACEDESC2)NULL)->dwFlags) lpddsd->dwFlags = CapsHash[i].Flags; + if (lpddsd->dwSize > (DWORD)&((LPDDSURFACEDESC2)NULL)->ddsCaps.dwCaps) lpddsd->ddsCaps.dwCaps = CapsHash[i].Caps; + if ((lpddsd->dwFlags & DDSD_PIXELFORMAT) && (lpddsd->dwSize > (DWORD)&((LPDDSURFACEDESC2)NULL)->ddpfPixelFormat)) + memcpy(&(lpddsd->ddpfPixelFormat), (void *)&CapsHash[i].PixelFormat, sizeof(DDPIXELFORMAT)); + + if(IsDebug){ + OutTrace("PopCaps: lpdds=%x dwFlags=%x dwCaps=%x", lpdds, lpddsd->dwFlags, lpddsd->ddsCaps.dwCaps); + if (lpddsd->dwFlags & DDSD_PIXELFORMAT) OutTrace(" PF.dwFlags=%x PF.dwFourCC=%x PF.dwRGBBitCount=%x RGBA=(%x,%x,%x,%x)", + lpddsd->ddpfPixelFormat.dwFlags, lpddsd->ddpfPixelFormat.dwFourCC, lpddsd->ddpfPixelFormat.dwRGBBitCount, + lpddsd->ddpfPixelFormat.dwRBitMask, lpddsd->ddpfPixelFormat.dwGBitMask, lpddsd->ddpfPixelFormat.dwBBitMask, lpddsd->ddpfPixelFormat.dwRGBAlphaBitMask); + OutTrace("\n"); + } + return TRUE; +} + +/* ------------------------------------------------------------------------------ */ +// auxiliary (static) functions for HDC service surfaces stack +/* ------------------------------------------------------------------------------ */ + +typedef struct { + LPDIRECTDRAWSURFACE lpdds; + HDC hdc; +} DCStackEntry_Type; + +DCStackEntry_Type DCStack[22]; + +static void InitDCStack() +{ + int i; + for(i=0; i<22; i++) { + DCStack[i].hdc=NULL; + DCStack[i].lpdds=NULL; + } +} + +static void PushDC(LPDIRECTDRAWSURFACE lpdds, HDC hdc) +{ + int i; + for(i=0; DCStack[i].hdc; i++); + if(i<20){ + DCStack[i].lpdds=lpdds; + DCStack[i].hdc=hdc; + } +} + +static LPDIRECTDRAWSURFACE PopDC(HDC hdc) +{ + int i; + LPDIRECTDRAWSURFACE ret; + for(i=0; DCStack[i].hdc && (DCStack[i].hdc!=hdc); i++); + ret=DCStack[i].lpdds; + for(; DCStack[i].hdc; i++) DCStack[i].hdc=NULL; + return ret; +} + +BOOL isPaletteUpdated; + +void mySetPalette(int dwstart, int dwcount, LPPALETTEENTRY lpentries) +{ + int i; + OutTraceD("mySetPalette DEBUG: BPP=%d GBitMask=%x count=%d\n", + dxw.ActualPixelFormat.dwRGBBitCount, dxw.ActualPixelFormat.dwGBitMask, dwcount); + + if(IsDebug){ + int idx; + OutTraceD("PaletteEntries: start=%d count=%d ", dwstart, dwcount); + for(idx=0; idx> 3) + : + (((DWORD)lpentries[i].peRed & 0xF8) << 8) + (((DWORD)lpentries[i].peGreen & 0xF8) << 3) + (((DWORD)lpentries[i].peBlue &0xF8) >> 3); + } + break; + default: + OutTraceD("ASSERT: unsupported Color BPP=%d\n", dxw.ActualPixelFormat.dwRGBBitCount); + break; + } + + isPaletteUpdated = TRUE; +} + +void InitDDScreenParameters(LPDIRECTDRAW lpdd) +{ + HRESULT res; + DDSURFACEDESC ddsd; + ddsd.dwSize=sizeof(DDSURFACEDESC); + if(res=(*pGetDisplayMode)(lpdd, &ddsd)){ + OutTraceE("GetDisplayMode: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return; + } + + OutTraceD("InitDDScreenParameters: Flags=%x FourCC=%x RGBBitCount=%d RGBA BitMask=(%x,%x,%x,%x)\n", + ddsd.ddpfPixelFormat.dwFlags, + ddsd.ddpfPixelFormat.dwFourCC, + ddsd.ddpfPixelFormat.dwRGBBitCount, + ddsd.ddpfPixelFormat.dwRBitMask, + ddsd.ddpfPixelFormat.dwGBitMask, + ddsd.ddpfPixelFormat.dwBBitMask, + ddsd.ddpfPixelFormat.dwRGBAlphaBitMask); + + dxw.ActualPixelFormat=ddsd.ddpfPixelFormat; + SetBltTransformations(); + + return; +} + +void InitDSScreenParameters(LPDIRECTDRAWSURFACE lpdds) +{ + HRESULT res; + DDPIXELFORMAT p; + p.dwSize=sizeof(DDPIXELFORMAT); + if(res=(*pGetPixelFormat)(lpdds, &p)){ + OutTraceE("GetPixelFormat: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return; + } + + OutTraceD("InitDSScreenParameters: Flags=%x FourCC=%x RGBBitCount=%d RGBA BitMask=(%x,%x,%x,%x)\n", + p.dwFlags, + p.dwFourCC, + p.dwRGBBitCount, + p.dwRBitMask, + p.dwGBitMask, + p.dwBBitMask, + p.dwRGBAlphaBitMask); + + dxw.ActualPixelFormat=p; + SetBltTransformations(); + + return; +} + +void InitScreenParameters() +{ + DEVMODE CurrDevMode; + static int DoOnce = FALSE; + + if(DoOnce) return; + DoOnce = TRUE; + + // set default VGA mode 800x600 + // should I make it configurable ? (640x480, 800x600, 1024x768) + dxw.SetScreenSize(); // 800 x 600 by default + GetHookInfo()->Height=(short)dxw.GetScreenHeight(); + GetHookInfo()->Width=(short)dxw.GetScreenWidth(); + GetHookInfo()->ColorDepth=0; // unknown + GetHookInfo()->DXVersion=0; // unknown + GetHookInfo()->isLogging=(dxw.dwTFlags & OUTTRACE); + + if(!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &CurrDevMode)){ + OutTraceE("EnumDisplaySettings: ERROR err=%d at %d\n", GetLastError(), __LINE__); + return; + } + memset(&dxw.ActualPixelFormat, 0, sizeof(DDPIXELFORMAT)); + // initialize to default null values, but dwRGBBitCount + dxw.ActualPixelFormat.dwRGBBitCount=CurrDevMode.dmBitsPerPel; + dxw.VirtualPixelFormat.dwRGBBitCount=CurrDevMode.dmBitsPerPel; // until set differently + //if(dxw.dwFlags2 & INIT8BPP) dxw.VirtualPixelFormat.dwRGBBitCount = 8; + OutTraceD("InitScreenParameters: RGBBitCount=%d\n", CurrDevMode.dmBitsPerPel); + SetBltTransformations(); + InitDCStack(); + + return; +} + +void FixPixelFormat(int ColorDepth, DDPIXELFORMAT *pf) +{ + pf->dwFlags = DDPF_RGB; + switch(ColorDepth){ + case 8: + pf->dwFlags |= DDPF_PALETTEINDEXED8; + pf->dwRGBBitCount = 8; + pf->dwRBitMask = 0; + pf->dwGBitMask = 0; + pf->dwBBitMask = 0; + pf->dwRGBAlphaBitMask = 0x0000; + break; + case 16: + pf->dwRGBBitCount = 16; + if (dxw.dwFlags1 & USERGB565){ + pf->dwRBitMask = 0xf800; + pf->dwGBitMask = 0x07e0; + pf->dwBBitMask = 0x001f; + } + else { + pf->dwRBitMask = 0x7c00; + pf->dwGBitMask = 0x03e0; + pf->dwBBitMask = 0x001f; + } + pf->dwRGBAlphaBitMask = 0x8000; + break; + case 24: + pf->dwRGBBitCount = 24; + pf->dwRBitMask = 0x00FF0000; + pf->dwGBitMask = 0x0000FF00; + pf->dwBBitMask = 0x000000FF; + pf->dwRGBAlphaBitMask = 0x00000000; + break; + case 32: + pf->dwRGBBitCount = 32; + pf->dwRBitMask = 0x00FF0000; + pf->dwGBitMask = 0x0000FF00; + pf->dwBBitMask = 0x000000FF; + pf->dwRGBAlphaBitMask = 0xFF000000; + break; + } +} + +int HookDirectDraw(HMODULE module, int version) +{ + HINSTANCE hinst; + void *tmp; + const GUID dd7 = {0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b}; + //static BOOL DoOnce = FALSE; + //if(DoOnce) return 0; + //DoOnce=TRUE; + + if(dxw.dwFlags2 & SETCOMPATIBILITY){ + typedef HRESULT (WINAPI *SetAppCompatData_Type)(DWORD, DWORD); + SetAppCompatData_Type pSetAppCompatData; + HRESULT res; + + hinst=LoadLibrary("ddraw.dll"); + pSetAppCompatData=(SetAppCompatData_Type)(*pGetProcAddress)(hinst, "SetAppCompatData"); + if(pSetAppCompatData) { + res=(*pSetAppCompatData)(2, 0); + OutTraceD("HookDirectDraw: SetAppCompatData(2,0) ret=%x(%s)\n", res, ExplainDDError(res)); + } + FreeLibrary(hinst); + } + + OutTraceB("HookDirectDraw version=%d\n", version); //GHO + switch(version){ + case 0: // automatic + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawCreate", extDirectDrawCreate); + if(tmp) pDirectDrawCreate = (DirectDrawCreate_Type)tmp; + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawCreateEx", extDirectDrawCreateEx); + if(tmp) pDirectDrawCreateEx = (DirectDrawCreateEx_Type)tmp; + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawEnumerateA", extDirectDrawEnumerate); + if(tmp) pDirectDrawEnumerate = (DirectDrawEnumerate_Type)tmp; + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawEnumerateExA", extDirectDrawEnumerateEx); + if(tmp) pDirectDrawEnumerateEx = (DirectDrawEnumerateEx_Type)tmp; + break; + case 1: + case 2: + case 3: + case 5: + case 6: + hinst = LoadLibrary("ddraw.dll"); + pDirectDrawEnumerate = + (DirectDrawEnumerate_Type)GetProcAddress(hinst, "DirectDrawEnumerateA"); + pDirectDrawCreate = + (DirectDrawCreate_Type)GetProcAddress(hinst, "DirectDrawCreate"); + if(pDirectDrawCreate){ + LPDIRECTDRAW lpdd; + BOOL res; + HookAPI(module, "ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreate); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerate); + res=extDirectDrawCreate(0, &lpdd, 0); + if (res){ + OutTraceE("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + } + lpdd->Release(); + } + break; + case 7: + hinst = LoadLibrary("ddraw.dll"); + pDirectDrawEnumerate = + (DirectDrawEnumerate_Type)GetProcAddress(hinst, "DirectDrawEnumerateA"); + pDirectDrawEnumerateEx = + (DirectDrawEnumerateEx_Type)GetProcAddress(hinst, "DirectDrawEnumerateExA"); + pDirectDrawCreate = + (DirectDrawCreate_Type)GetProcAddress(hinst, "DirectDrawCreate"); + if(pDirectDrawCreate){ + LPDIRECTDRAW lpdd; + BOOL res; + HookAPI(module, "ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreate); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerate); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerateEx, "DirectDrawEnumerateExA", extDirectDrawEnumerateEx); + res=extDirectDrawCreate(0, &lpdd, 0); + if (res) OutTraceE("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + lpdd->Release(); + } + pDirectDrawCreateEx = + (DirectDrawCreateEx_Type)GetProcAddress(hinst, "DirectDrawCreateEx"); + if(pDirectDrawCreateEx){ + LPDIRECTDRAW lpdd; + BOOL res; + HookAPI(module, "ddraw.dll", pDirectDrawCreateEx, "DirectDrawCreateEx", extDirectDrawCreateEx); + res=extDirectDrawCreateEx(0, &lpdd, dd7, 0); + if (res) OutTraceE("DirectDrawCreateEx: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + lpdd->Release(); + } + break; + } + + if(pDirectDrawCreate || pDirectDrawCreateEx) return 1; + return 0; +} + +Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE lpdds) +{ + char sMsg[81]; + void * extUnlock; + extUnlock=(void *)*(DWORD *)(*(DWORD *)lpdds + 128); + if(extUnlock==(void *)extUnlock1) return (Unlock4_Type)pUnlock1; + if(extUnlock==(void *)extUnlock4) return (Unlock4_Type)pUnlock4; + sprintf_s(sMsg, 80, "pUnlockMethod: pUnlock(%x) can't match %x\n", lpdds, extUnlock); + OutTraceD(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "pUnlockMethod", MB_OK | MB_ICONEXCLAMATION); + if (pUnlock4) return pUnlock4; + return (Unlock4_Type)pUnlock1; +} + +CreateSurface2_Type pCreateSurfaceMethod(LPDIRECTDRAWSURFACE lpdds) +{ + char sMsg[81]; + void * extUnlock; + extUnlock=(void *)*(DWORD *)(*(DWORD *)lpdds + 128); + if(extUnlock==(void *)extUnlock1) return (CreateSurface2_Type)pCreateSurface1; + if(extUnlock==(void *)extUnlock4) return (CreateSurface2_Type)pCreateSurface4; + sprintf_s(sMsg, 80, "pCreateSurfaceMethod: pUnlock(%x) can't match %x\n", lpdds, extUnlock); + OutTraceD(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "pCreateSurfaceMethod", MB_OK | MB_ICONEXCLAMATION); + if (pCreateSurface4) return pCreateSurface4; + return (CreateSurface2_Type)pCreateSurface1; +} + +int lpddsHookedVersion(LPDIRECTDRAWSURFACE lpdds) +{ + char sMsg[81]; + void * extGetCaps; + + __try{ + extGetCaps=(void *)*(DWORD *)(*(DWORD *)lpdds + 56); + } + __except (EXCEPTION_EXECUTE_HANDLER){ + extGetCaps=NULL; + }; + if(extGetCaps==(void *)extGetCaps1S) return 1; + if(extGetCaps==(void *)extGetCaps2S) return 2; + if(extGetCaps==(void *)extGetCaps3S) return 3; + if(extGetCaps==(void *)extGetCaps4S) return 4; + if(extGetCaps==(void *)extGetCaps7S) return 7; + sprintf_s(sMsg, 80, "lpddsHookedVersion(%x) can't match %x\n", lpdds, extGetCaps); + OutTraceD(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "lpddsHookedVersion", MB_OK | MB_ICONEXCLAMATION); + return 0; +} + +int lpddHookedVersion(LPDIRECTDRAW lpdd) +{ + char sMsg[81]; + void * extCreateSurface; + + __try{ + extCreateSurface=(void *)*(DWORD *)(*(DWORD *)lpdd + 24); + } + __except (EXCEPTION_EXECUTE_HANDLER){ + extCreateSurface=NULL; + }; + if(extCreateSurface==(void *)extCreateSurface1) return 1; + if(extCreateSurface==(void *)extCreateSurface2) return 2; + if(extCreateSurface==(void *)extCreateSurface4) return 4; + if(extCreateSurface==(void *)extCreateSurface7) return 7; + sprintf_s(sMsg, 80, "lpddHookedVersion(%x) can't match %x\n", lpdd, extCreateSurface); + OutTraceD(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "lpddHookedVersion", MB_OK | MB_ICONEXCLAMATION); + return 0; +} + +/* ------------------------------------------------------------------ */ + +static void DumpPixFmt(LPDDSURFACEDESC2 lpdd) +{ + OutTraceD("PixFmt: Size=%x Flags=%x(%s) FourCC=%x RGBBitCount=%d RGBA BitMask=(%x,%x,%x,%x)\n", + lpdd->ddpfPixelFormat.dwSize, + lpdd->ddpfPixelFormat.dwFlags, ExplainPixelFormatFlags(lpdd->ddpfPixelFormat.dwFlags), + lpdd->ddpfPixelFormat.dwFourCC, + lpdd->ddpfPixelFormat.dwRGBBitCount, + lpdd->ddpfPixelFormat.dwRBitMask, + lpdd->ddpfPixelFormat.dwGBitMask, + lpdd->ddpfPixelFormat.dwBBitMask, + lpdd->ddpfPixelFormat.dwRGBAlphaBitMask); +} + +static char *SetPixFmt(LPDDSURFACEDESC2 lpdd) +{ + char *pfstr; + OutTraceD("SetPixFmt: BPP=%d Use565=%d\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.dwFlags1 & USERGB565 ? 1:0); + memset(&lpdd->ddpfPixelFormat,0,sizeof(DDPIXELFORMAT)); + lpdd->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + lpdd->ddpfPixelFormat.dwRGBBitCount = dxw.ActualPixelFormat.dwRGBBitCount; + if(dxw.ActualPixelFormat.dwRGBBitCount==dxw.VirtualPixelFormat.dwRGBBitCount && dxw.ActualPixelFormat.dwRBitMask){ + // if same color depth, choose current color masks + pfstr="CURRENT"; + lpdd->ddpfPixelFormat=dxw.ActualPixelFormat; + } + else + { + switch (dxw.VirtualPixelFormat.dwRGBBitCount) + { + case 8: + pfstr="RGB8"; + FixPixelFormat(8, &lpdd->ddpfPixelFormat); + break; + case 16: + pfstr=(dxw.dwFlags1 & USERGB565)?"RGB16-565":"RGB16-555"; + FixPixelFormat(16, &lpdd->ddpfPixelFormat); + break; + case 24: + pfstr="RGB24"; + FixPixelFormat(24, &lpdd->ddpfPixelFormat); + break; + case 32: + pfstr="RGB32"; + FixPixelFormat(32, &lpdd->ddpfPixelFormat); + break; + default: + pfstr="unsupported"; + OutTraceE("CreateSurface ERROR: Unsupported resolution ColorBPP=%d\n", dxw.VirtualPixelFormat.dwRGBBitCount); + break; + } + } + + // remember current virtual settings + dxw.VirtualPixelFormat=lpdd->ddpfPixelFormat; + + OutTraceD("SetPixFmt: RGBBitCount=%d Flags=%x FourCC=%x RGBA BitMask=(%x,%x,%x,%x)\n", + lpdd->ddpfPixelFormat.dwRGBBitCount, + lpdd->ddpfPixelFormat.dwFlags, + lpdd->ddpfPixelFormat.dwFourCC, + lpdd->ddpfPixelFormat.dwRBitMask, + lpdd->ddpfPixelFormat.dwGBitMask, + lpdd->ddpfPixelFormat.dwBBitMask, + lpdd->ddpfPixelFormat.dwRGBAlphaBitMask); + + return pfstr; +} + +/* ------------------------------------------------------------------ */ +// hook query functions that determines the object versioning .... +/* ------------------------------------------------------------------ */ + +int Set_dwSize_From_Surface(LPDIRECTDRAWSURFACE lpdds) +{ + int dxversion; + if (lpdds==NULL || + lpdds==lpDDSEmu_Prim || + lpdds==lpDDSEmu_Back + ) + dxversion=lpddHookedVersion(lpServiceDD); // v2.1.87 fix + else + dxversion=lpddsHookedVersion(lpdds); + + return (dxversion < 4) ? sizeof(DDSURFACEDESC) : sizeof(DDSURFACEDESC2); +} + +int Set_dwSize_From_DDraw(LPDIRECTDRAW lpdd) +{ + return (lpddHookedVersion(lpdd) < 4) ? sizeof(DDSURFACEDESC) : sizeof(DDSURFACEDESC2); +} + +static void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion) +{ + OutTraceD("Hooking directdraw session dd=%x dxversion=%d thread_id=%x\n", + *lplpdd, dxversion, GetCurrentThreadId()); + + // IDIrectDraw::QueryInterface + SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD, (void **)&pQueryInterfaceD, "QueryInterface(D)"); + // IDIrectDraw::Release + SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD, (void **)&pReleaseD, "Release(D)"); + // IDIrectDraw::CreateClipper + SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper, (void **)&pCreateClipper, "CreateClipper(D)"); + // IDIrectDraw::CreatePalette + SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette, (void **)&pCreatePalette, "CreatePalette(D)"); + // IDIrectDraw::CreateSurface + switch(dxversion) { + case 1: + SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface1, (void **)&pCreateSurface1, "CreateSurface(S1)"); + break; + case 2: + SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface2, (void **)&pCreateSurface2, "CreateSurface(S2)"); + break; + case 4: + SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface4, (void **)&pCreateSurface4, "CreateSurface(S4)"); + break; + case 7: + SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface7, (void **)&pCreateSurface7, "CreateSurface(S7)"); + break; + } + // IDIrectDraw::DuplicateSurface + SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface, (void **)&pDuplicateSurface, "DuplicateSurface(D)"); + // IDIrectDraw::EnumDisplayModes + switch(dxversion) { + case 1: + case 2: + SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes1, (void **)&pEnumDisplayModes1, "EnumDisplayModes(D1)"); + break; + case 4: + case 7: + SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes4, (void **)&pEnumDisplayModes4, "EnumDisplayModes(D4)"); + break; + } + // IDIrectDraw::FlipToGDISurface + SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface, (void **)&pFlipToGDISurface, "FlipToGDISurface(D)"); + // IDIrectDraw::GetDisplayMode + SetHook((void *)(**(DWORD **)lplpdd + 48), extGetDisplayMode, (void **)&pGetDisplayMode, "GetDisplayMode(D)"); + // IDIrectDraw::GetGDISurface + SetHook((void *)(**(DWORD **)lplpdd + 56), extGetGDISurface, (void **)&pGetGDISurface, "GetGDISurface(D)"); + // IDIrectDraw::SetCooperativeLevel + SetHook((void *)(**(DWORD **)lplpdd + 80), extSetCooperativeLevel, (void **)&pSetCooperativeLevel, "SetCooperativeLevel(D)"); + // IDIrectDraw::SetDisplayMode + if (dxversion > 1) + SetHook((void *)(**(DWORD **)lplpdd + 84), extSetDisplayMode2, (void **)&pSetDisplayMode2, "SetDisplayMode(D2)"); + else + SetHook((void *)(**(DWORD **)lplpdd + 84), extSetDisplayMode1, (void **)&pSetDisplayMode1, "SetDisplayMode(D1)"); + // IDIrectDraw::WaitForVerticalBlank + SetHook((void *)(**(DWORD **)lplpdd + 88), extWaitForVerticalBlank, (void **)&pWaitForVerticalBlank, "WaitForVerticalBlank(D)"); + // IDIrectDraw::TestCooperativeLevel + if (dxversion >= 4) + SetHook((void *)(**(DWORD **)lplpdd + 104), extTestCooperativeLevel, (void **)&pTestCooperativeLevel, "TestCooperativeLevel(D)"); + + if (!(dxw.dwTFlags & OUTPROXYTRACE)) return; + // Just proxed ... + + // IDIrectDraw::AddRef + SetHook((void *)(**(DWORD **)lplpdd + 4), extAddRefDProxy, (void **)&pAddRefD, "AddRef(D)"); + // IDIrectDraw::Compact + SetHook((void *)(**(DWORD **)lplpdd + 12), extCompactProxy, (void **)&pCompact, "Compact(D)"); + // IDIrectDraw::EnumSurfaces + if (dxversion < 4) + SetHook((void *)(**(DWORD **)lplpdd + 36), extEnumSurfacesProxy1, (void **)&pEnumSurfaces1, "EnumSurfaces(D1)"); + else + SetHook((void *)(**(DWORD **)lplpdd + 36), extEnumSurfacesProxy4, (void **)&pEnumSurfaces4, "EnumSurfaces(D4)"); + // IDIrectDraw::GetCaps + SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCapsD, (void **)&pGetCapsD, "GetCaps(D)"); + // IDIrectDraw::GetFourCCCodes + SetHook((void *)(**(DWORD **)lplpdd + 52), extGetFourCCCodesProxy, (void **)&pGetFourCCCodes, "GetFourCCCodes(D)"); + // IDIrectDraw::GetMonitorFrequency + SetHook((void *)(**(DWORD **)lplpdd + 60), extGetMonitorFrequencyProxy, (void **)&pGetMonitorFrequency, "GetMonitorFrequency(D)"); + // IDIrectDraw::GetScanLine + SetHook((void *)(**(DWORD **)lplpdd + 64), extGetScanLineProxy, (void **)&pGetScanLine, "GetScanLine(D)"); + // IDIrectDraw::GetVerticalBlankStatus + SetHook((void *)(**(DWORD **)lplpdd + 68), extGetVerticalBlankStatusProxy, (void **)&pGetVerticalBlankStatus, "GetVerticalBlankStatus(D)"); + // IDIrectDraw::Initialize + // offset 72: Undocumented + // IDIrectDraw::RestoreDisplayMode + SetHook((void *)(**(DWORD **)lplpdd + 76), extRestoreDisplayModeProxy, (void **)&pRestoreDisplayMode, "RestoreDisplayMode(D)"); + // IDIrectDraw::GetAvailableVidMem + if (dxversion >= 2) + SetHook((void *)(**(DWORD **)lplpdd + 92), extGetAvailableVidMemProxy, (void **)&pGetAvailableVidMem, "GetAvailableVidMem(D)"); + if (dxversion >= 4){ + // IDIrectDraw::GetSurfaceFromDC + SetHook((void *)(**(DWORD **)lplpdd + 96), extGetSurfaceFromDCProxy, (void **)&pGetSurfaceFromDC, "GetSurfaceFromDC(D)"); + // IDIrectDraw::RestoreAllSurfaces + SetHook((void *)(**(DWORD **)lplpdd + 100), extRestoreAllSurfacesProxy, (void **)&pRestoreAllSurfaces, "RestoreAllSurfaces(D)"); + // IDIrectDraw::GetDeviceIdentifier + SetHook((void *)(**(DWORD **)lplpdd + 108), extGetDeviceIdentifierProxy, (void **)&pGetDeviceIdentifier, "GetDeviceIdentifier(D)"); + } +} + +static void HookDDClipper(LPDIRECTDRAWCLIPPER FAR* lplpDDClipper) +{ + OutTraceD("Hooking directdraw clipper dd=%x\n", *lplpDDClipper); + + // IDirectDrawClipper::Release + SetHook((void *)(**(DWORD **)lplpDDClipper + 8), extReleaseC, (void **)&pReleaseC, "Release(C)"); + + if (!(dxw.dwTFlags & OUTPROXYTRACE)) return; + // Just proxed ... + + // IDirectDrawClipper::QueryInterface + SetHook((void *)(**(DWORD **)lplpDDClipper), extQueryInterfaceCProxy, (void **)&pQueryInterfaceC, "QueryInterface(C)"); + // IDirectDrawClipper::AddRef + SetHook((void *)(**(DWORD **)lplpDDClipper + 4), extAddRefCProxy, (void **)&pAddRefC, "AddRef(C)"); + // IDirectDrawClipper::GetClipList + SetHook((void *)(**(DWORD **)lplpDDClipper + 12), extGetClipListProxy, (void **)&pGetClipList, "GetClipList(C)"); + // IDirectDrawClipper::GetHWnd + SetHook((void *)(**(DWORD **)lplpDDClipper + 16), extGetHWndProxy, (void **)&pGetHWnd, "GetHWnd(C)"); + // IDirectDrawClipper::Initialize + SetHook((void *)(**(DWORD **)lplpDDClipper + 20), extInitializeCProxy, (void **)&pInitializeC, "Initialize(C)"); + // IDirectDrawClipper::IsClipListChanged + SetHook((void *)(**(DWORD **)lplpDDClipper + 24), extIsClipListChangedProxy, (void **)&pIsClipListChanged, "IsClipListChanged(C)"); + // IDirectDrawClipper::SetClipList + SetHook((void *)(**(DWORD **)lplpDDClipper + 28), extSetClipListProxy, (void **)&pSetClipList, "SetClipList(C)"); + // IDirectDrawClipper::SetHWnd + SetHook((void *)(**(DWORD **)lplpDDClipper + 32), extSetHWndProxy, (void **)&pSetHWnd, "SetHWnd(C)"); + + return; +} + +static void HookDDPalette(LPDIRECTDRAWPALETTE FAR* lplpDDPalette) +{ + OutTraceD("Hooking directdraw palette dd=%x\n", *lplpDDPalette); + + /*** IDirectDrawPalette methods ***/ + // IDirectDrawPalette::Release + SetHook((void *)(**(DWORD **)lplpDDPalette + 8), extReleaseP, (void **)&pReleaseP, "Release(P)"); + // IDirectDrawPalette::SetEntries + SetHook((void *)(**(DWORD **)lplpDDPalette + 24), extSetEntries, (void **)&pSetEntries, "SetEntries(P)"); + + if (!(dxw.dwTFlags & OUTPROXYTRACE)) return; + + // IDirectDrawPalette::QueryInterface + SetHook((void *)(**(DWORD **)lplpDDPalette), extQueryInterfacePProxy, (void **)&pQueryInterfaceP, "QueryInterface(P)"); + // IDirectDrawPalette::AddRef + SetHook((void *)(**(DWORD **)lplpDDPalette + 4), extAddRefPProxy, (void **)&pAddRefP, "AddRef(P)"); + // IDirectDrawPalette::GetCaps + SetHook((void *)(**(DWORD **)lplpDDPalette + 12), extGetCapsPProxy, (void **)&pGetCapsP, "GetCaps(P)"); + // IDirectDrawPalette::GetEntries + SetHook((void *)(**(DWORD **)lplpDDPalette + 16), extGetEntriesProxy, (void **)&pGetEntries, "GetEntries(P)"); + + return; +} + +static void HookDDSurfacePrim(LPDIRECTDRAWSURFACE *lplpdds, int dxversion) +{ + OutTraceD("Hooking surface as primary dds=%x dxversion=%d thread_id=%x\n", + *lplpdds, dxversion, GetCurrentThreadId()); + + // IDirectDrawSurface::Query + SetHook((void *)(**(DWORD **)lplpdds), extQueryInterfaceS, (void **)&pQueryInterfaceS, "QueryInterface(S)"); + // IDirectDrawSurface::Release + SetHook((void *)(**(DWORD **)lplpdds + 8), extReleaseS, (void **)&pReleaseS, "Release(S)"); + // IDirectDrawSurface::AddAttachedSurface + SetHook((void *)(**(DWORD **)lplpdds + 12), extAddAttachedSurface, (void **)&pAddAttachedSurface, "AddAttachedSurface(S)"); + // IDirectDrawSurface::Blt + SetHook((void *)(**(DWORD **)lplpdds + 20), extBlt, (void **)&pBlt, "Blt(S)"); + // IDirectDrawSurface::BltFast + SetHook((void *)(**(DWORD **)lplpdds + 28), extBltFast, (void **)&pBltFast, "BltFast(S)"); + // IDirectDrawSurface::DeleteAttachedSurface + SetHook((void *)(**(DWORD **)lplpdds + 32), extDeleteAttachedSurface, (void **)&pDeleteAttachedSurface, "DeleteAttachedSurface(S)"); + // IDirectDrawSurface::EnumAttachedSurfaces + SetHook((void *)(**(DWORD **)lplpdds + 36), extEnumAttachedSurfaces, (void **)&pEnumAttachedSurfaces, "EnumAttachedSurfaces(S)"); + // IDirectDrawSurface::Flip + SetHook((void *)(**(DWORD **)lplpdds + 44), extFlip, (void **)&pFlip, "Flip(S)"); + // IDirectDrawSurface::GetAttachedSurface + switch(dxversion) { + case 1: + case 2: + SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface1, (void **)&pGetAttachedSurface1, "GetAttachedSurface(S1)"); + break; + case 3: + SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface3, (void **)&pGetAttachedSurface3, "GetAttachedSurface(S3)"); + break; + case 4: + SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface4, (void **)&pGetAttachedSurface4, "GetAttachedSurface(S4)"); + break; + case 7: + SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface7, (void **)&pGetAttachedSurface7, "GetAttachedSurface(S7)"); + break; + } + // IDirectDrawSurface::GetCaps + switch(dxversion) { + case 1: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps1S, (void **)&pGetCaps1S, "GetCaps(S1)"); + break; + case 2: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps2S, (void **)&pGetCaps2S, "GetCaps(S2)"); + break; + case 3: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps3S, (void **)&pGetCaps3S, "GetCaps(S3)"); + break; + case 4: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps4S, (void **)&pGetCaps4S, "GetCaps(S4)"); + break; + case 7: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps7S, (void **)&pGetCaps7S, "GetCaps(S7)"); + break; + } + // IDirectDrawSurface::GetColorKey + SetHook((void *)(**(DWORD **)lplpdds + 64), extGetColorKey, (void **)&pGetColorKey, "GetColorKey(S)"); + // IDirectDrawSurface::GetPalette + SetHook((void *)(**(DWORD **)lplpdds + 80), extGetPalette, (void **)&pGetPalette, "GetPalette(S)"); + // IDirectDrawSurface::GetPixelFormat + SetHook((void *)(**(DWORD **)lplpdds + 84), extGetPixelFormat, (void **)&pGetPixelFormat, "GetPixelFormat(S)"); + // IDirectDrawSurface::GetSurfaceDesc + if (dxversion < 4) { + SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc1, (void **)&pGetSurfaceDesc1, "GetSurfaceDesc(S1)"); + } + else { + SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc2, (void **)&pGetSurfaceDesc4, "GetSurfaceDesc(S4)"); + } + // IDirectDrawSurface::SetClipper + SetHook((void *)(**(DWORD **)lplpdds + 112), extSetClipper, (void **)&pSetClipper, "SetClipper(S)"); + // IDirectDrawSurface::SetColorKey + SetHook((void *)(**(DWORD **)lplpdds + 116), extSetColorKey, (void **)&pSetColorKey, "SetColorKey(S)"); + // IDirectDrawSurface::SetPalette + SetHook((void *)(**(DWORD **)lplpdds + 124), extSetPalette, (void **)&pSetPalette, "SetPalette(S)"); + // IDirectDrawSurface::GetDC + SetHook((void *)(**(DWORD **)lplpdds + 68), extGetDC, (void **)&pGetDC, "GetDC(S)"); + // IDirectDrawSurface::ReleaseDC + SetHook((void *)(**(DWORD **)lplpdds + 104), extReleaseDC, (void **)&pReleaseDC, "ReleaseDC(S)"); + if (dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER)){ + // IDirectDrawSurface::Lock + SetHook((void *)(**(DWORD **)lplpdds + 100), extLock, (void **)&pLock, "Lock(S)"); + // IDirectDrawSurface::Unlock + if (dxversion < 4) + SetHook((void *)(**(DWORD **)lplpdds + 128), extUnlock1, (void **)&pUnlock1, "Unlock(S1)"); + else + SetHook((void *)(**(DWORD **)lplpdds + 128), extUnlock4, (void **)&pUnlock4, "Unlock(S4)"); + } + + if (!(dxw.dwTFlags & OUTPROXYTRACE)) return; + + // Just proxed ... + + // IDirectDrawSurface::AddRef + SetHook((void *)(**(DWORD **)lplpdds + 4), extAddRefSProxy, (void **)&pAddRefS, "AddRef(S)"); + // IDirectDrawSurface::AddOverlayDirtyRect + SetHook((void *)(**(DWORD **)lplpdds + 16), extAddOverlayDirtyRectProxy, (void **)&pAddOverlayDirtyRect, "AddOverlayDirtyRect(S)"); + // IDirectDrawSurface::BltBatch + SetHook((void *)(**(DWORD **)lplpdds + 24), extBltBatchProxy, (void **)&pBltBatch, "BltBatch(S)"); + // IDirectDrawSurface::EnumOverlayZOrders + SetHook((void *)(**(DWORD **)lplpdds + 40), extEnumOverlayZOrdersProxy, (void **)&pEnumOverlayZOrders, "EnumOverlayZOrders(S)"); + // IDirectDrawSurface::GetBltStatus + SetHook((void *)(**(DWORD **)lplpdds + 52), extGetBltStatusProxy, (void **)&pGetBltStatus, "GetBltStatus(S)"); + // IDirectDrawSurface::GetClipper + SetHook((void *)(**(DWORD **)lplpdds + 60), extGetClipperProxy, (void **)&pGetClipper, "GetClipper(S)"); + // IDirectDrawSurface::GetFlipStatus + SetHook((void *)(**(DWORD **)lplpdds + 72), extGetFlipStatusProxy, (void **)&pGetFlipStatus, "GetFlipStatus(S)"); + // IDirectDrawSurface::GetOverlayPosition + SetHook((void *)(**(DWORD **)lplpdds + 76), extGetOverlayPositionProxy, (void **)&pGetOverlayPosition, "GetOverlayPosition(S)"); + // IDirectDrawSurface::IsLost + SetHook((void *)(**(DWORD **)lplpdds + 96), extIsLostProxy, (void **)&pIsLost, "IsLost(S)"); + // IDirectDrawSurface::Restore + SetHook((void *)(**(DWORD **)lplpdds + 108), extRestoreProxy, (void **)&pRestore, "Restore(S)"); + // IDirectDrawSurface::SetOverlayPosition + SetHook((void *)(**(DWORD **)lplpdds + 120), extSetOverlayPositionProxy, (void **)&pSetOverlayPosition, "SetOverlayPosition(S)"); + // IDirectDrawSurface::UpdateOverlay + SetHook((void *)(**(DWORD **)lplpdds + 132), extUpdateOverlayProxy, (void **)&pUpdateOverlay, "UpdateOverlay(S)"); + // IDirectDrawSurface::UpdateOverlayDisplay + SetHook((void *)(**(DWORD **)lplpdds + 136), extUpdateOverlayDisplayProxy, (void **)&pUpdateOverlayDisplay, "UpdateOverlayDisplay(S)"); + // IDirectDrawSurface::UpdateOverlayZOrder + SetHook((void *)(**(DWORD **)lplpdds + 140), extUpdateOverlayZOrderProxy, (void **)&pUpdateOverlayZOrder, "UpdateOverlayZOrder(S)"); + if (!(dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER))){ + // IDirectDrawSurface::Lock + SetHook((void *)(**(DWORD **)lplpdds + 100), extLock, (void **)&pLock, "Lock(S)"); + // IDirectDrawSurface::Unlock + if (dxversion < 4) + SetHook((void *)(**(DWORD **)lplpdds + 128), extUnlock1, (void **)&pUnlock1, "Unlock(S)"); + else + SetHook((void *)(**(DWORD **)lplpdds + 128), extUnlock4, (void **)&pUnlock4, "Unlock(S)"); + } +} + +static void HookDDSurfaceGeneric(LPDIRECTDRAWSURFACE *lplpdds, int dxversion) +{ + OutTraceD("Hooking surface as generic dds=%x dxversion=%d thread_id=%x\n", + *lplpdds, dxversion, GetCurrentThreadId()); + + // IDirectDrawSurface::Release + SetHook((void *)(**(DWORD **)lplpdds + 8), extReleaseS, (void **)&pReleaseS, "Release(S)"); + // IDirectDrawSurface::Flip + SetHook((void *)(**(DWORD **)lplpdds + 44), extFlip, (void **)&pFlip, "Flip(S)"); + // IDirectDrawSurface::Blt + SetHook((void *)(**(DWORD **)lplpdds + 20), extBlt, (void **)&pBlt, "Blt(S)"); + // IDirectDrawSurface::BltFast + SetHook((void *)(**(DWORD **)lplpdds + 28), extBltFast, (void **)&pBltFast, "BltFast(S)"); + // IDirectDrawSurface::DeleteAttachedSurface + SetHook((void *)(**(DWORD **)lplpdds + 32), extDeleteAttachedSurface, (void **)&pDeleteAttachedSurface, "DeleteAttachedSurface(S)"); + // IDirectDrawSurface::GetCaps + switch(dxversion) { + case 1: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps1S, (void **)&pGetCaps1S, "GetCaps(S1)"); + break; + case 2: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps2S, (void **)&pGetCaps2S, "GetCaps(S2)"); + break; + case 3: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps3S, (void **)&pGetCaps3S, "GetCaps(S3)"); + break; + case 4: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps4S, (void **)&pGetCaps4S, "GetCaps(S4)"); + break; + case 7: + SetHook((void *)(**(DWORD **)lplpdds + 56), extGetCaps7S, (void **)&pGetCaps7S, "GetCaps(S7)"); + break; + } + // IDirectDrawSurface::GetSurfaceDesc + if (dxversion < 4) { + SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc1, (void **)&pGetSurfaceDesc1, "GetSurfaceDesc(S1)"); + } + else { + SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc2, (void **)&pGetSurfaceDesc4, "GetSurfaceDesc(S4)"); + } + // IDirectDrawSurface::ReleaseDC + SetHook((void *)(**(DWORD **)lplpdds + 104), extReleaseDC, (void **)&pReleaseDC, "ReleaseDC(S)"); + + if (!(dxw.dwTFlags & OUTPROXYTRACE)) return; + + // just proxed .... + + // IDirectDrawSurface::QueryInterface + SetHook((void *)(**(DWORD **)lplpdds), extQueryInterfaceS, (void **)&pQueryInterfaceS, "QueryInterface(S)"); + // IDirectDrawSurface::AddRef + SetHook((void *)(**(DWORD **)lplpdds + 4), extAddRefSProxy, (void **)&pAddRefS, "AddRef(S)"); + // IDirectDrawSurface::AddAttachedSurface + SetHook((void *)(**(DWORD **)lplpdds + 12), extAddAttachedSurface, (void **)&pAddAttachedSurface, "AddAttachedSurface(S)"); + // IDirectDrawSurface::AddOverlayDirtyRect + SetHook((void *)(**(DWORD **)lplpdds + 16), extAddOverlayDirtyRectProxy, (void **)&pAddOverlayDirtyRect, "AddOverlayDirtyRect(S)"); + // IDirectDrawSurface::BltBatch + SetHook((void *)(**(DWORD **)lplpdds + 24), extBltBatchProxy, (void **)&pBltBatch, "BltBatch(S)"); + // IDirectDrawSurface::GetAttachedSurface + switch(dxversion) { + case 1: + case 2: + SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface1Proxy, (void **)&pGetAttachedSurface1, "GetAttachedSurface(S1)"); + break; + case 3: + SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface3Proxy, (void **)&pGetAttachedSurface3, "GetAttachedSurface(S3)"); + break; + case 4: + SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface4Proxy, (void **)&pGetAttachedSurface4, "GetAttachedSurface(S4)"); + break; + case 7: + SetHook((void *)(**(DWORD **)lplpdds + 48), extGetAttachedSurface7Proxy, (void **)&pGetAttachedSurface7, "GetAttachedSurface(S7)"); + break; + } + // IDirectDrawSurface::EnumAttachedSurfaces + SetHook((void *)(**(DWORD **)lplpdds + 36), extEnumAttachedSurfaces, (void **)&pEnumAttachedSurfaces, "EnumAttachedSurfaces(S)"); + // IDirectDrawSurface::EnumOverlayZOrders + SetHook((void *)(**(DWORD **)lplpdds + 40), extEnumOverlayZOrdersProxy, (void **)&pEnumOverlayZOrders, "EnumOverlayZOrders(S)"); + // IDirectDrawSurface::GetBltStatus + SetHook((void *)(**(DWORD **)lplpdds + 52), extGetBltStatusProxy, (void **)&pGetBltStatus, "GetBltStatus(S)"); + // IDirectDrawSurface::GetClipper + SetHook((void *)(**(DWORD **)lplpdds + 60), extGetClipperProxy, (void **)&pGetClipper, "GetClipper(S)"); + // IDirectDrawSurface::GetFlipStatus + SetHook((void *)(**(DWORD **)lplpdds + 72), extGetFlipStatusProxy, (void **)&pGetFlipStatus, "GetFlipStatus(S)"); + // IDirectDrawSurface::GetOverlayPosition + SetHook((void *)(**(DWORD **)lplpdds + 76), extGetOverlayPositionProxy, (void **)&pGetOverlayPosition, "GetOverlayPosition(S)"); + // IDirectDrawSurface::IsLost + SetHook((void *)(**(DWORD **)lplpdds + 96), extIsLostProxy, (void **)&pIsLost, "IsLost(S)"); + // IDirectDrawSurface::Lock + SetHook((void *)(**(DWORD **)lplpdds + 100), extLock, (void **)&pLock, "Lock(S)"); + // IDirectDrawSurface::Restore + SetHook((void *)(**(DWORD **)lplpdds + 108), extRestoreProxy, (void **)&pRestore, "Restore(S)"); + // IDirectDrawSurface::SetOverlayPosition + SetHook((void *)(**(DWORD **)lplpdds + 120), extSetOverlayPositionProxy, (void **)&pSetOverlayPosition, "SetOverlayPosition(S)"); + // IDirectDrawSurface::Unlock + if (dxversion < 4) + SetHook((void *)(**(DWORD **)lplpdds + 128), extUnlock1, (void **)&pUnlock1, "Unlock(S1)"); + else + SetHook((void *)(**(DWORD **)lplpdds + 128), extUnlock4, (void **)&pUnlock4, "Unlock(S4)"); + // IDirectDrawSurface::UpdateOverlay + SetHook((void *)(**(DWORD **)lplpdds + 132), extUpdateOverlayProxy, (void **)&pUpdateOverlay, "UpdateOverlay(S)"); + // IDirectDrawSurface::UpdateOverlayDisplay + SetHook((void *)(**(DWORD **)lplpdds + 136), extUpdateOverlayDisplayProxy, (void **)&pUpdateOverlayDisplay, "UpdateOverlayDisplay(S)"); + // IDirectDrawSurface::UpdateOverlayZOrder + SetHook((void *)(**(DWORD **)lplpdds + 140), extUpdateOverlayZOrderProxy, (void **)&pUpdateOverlayZOrder, "UpdateOverlayZOrder(S)"); +} + +static void RenewClipper(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpdds) +{ + HRESULT res; + + return; + + if (lpDDC) lpDDC->Release(); + res=lpdd->CreateClipper(0, &lpDDC, NULL); + if(res) OutTraceE("CreateSurface: CreateClipper ERROR: lpdd=%x res=%x(%s) at %d\n", lpdd, res, ExplainDDError(res), __LINE__); + //HookDDClipper(&lpDDC); + res=lpDDC->SetHWnd(0, dxw.GethWnd()); + if(res) OutTraceE("CreateSurface: SetHWnd ERROR: hWnd=%x res=%x(%s) at %d\n", dxw.GethWnd(), res, ExplainDDError(res), __LINE__); + res=lpdds->SetClipper(lpDDC); + //res=(*pSetClipper)(lpdds, lpDDC); + if(res) OutTraceE("CreateSurface: SetClipper ERROR: lpdds=%x res=%x(%s) at %d\n", lpdds, res, ExplainDDError(res), __LINE__); + return; +} + +/* ------------------------------------------------------------------------------ */ +// directdraw method hooks +/* ------------------------------------------------------------------------------ */ + +HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2) +{ + HRESULT res; + OutTraceD("GetCaps(D): PROXED lpdd=%x\n", lpdd); + res=(*pGetCapsD)(lpdd, c1, c2); + if(res) + OutTraceE("GetCaps(D): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + else { + OutTraceD("GetCaps(D): "); + if (c1) OutTraceD("hwcaps=%x(%s) ", c1->ddsCaps.dwCaps, ExplainDDSCaps(c1->ddsCaps.dwCaps)); + if (c2) OutTraceD("swcaps=%x(%s) ", c2->ddsCaps.dwCaps, ExplainDDSCaps(c2->ddsCaps.dwCaps)); + OutTraceD("\n"); + } + + // GHO TRY + // tricky: it seems that this DD method is called using an un-hooked directdraw handle.... + lpDD=lpdd; + + return res; +} + +HRESULT WINAPI extDirectDrawCreate(GUID FAR *lpguid, LPDIRECTDRAW FAR *lplpdd, IUnknown FAR *pu) +{ + HRESULT res; + + OutTraceD("DirectDrawCreate: guid=%x(%s)\n", lpguid, ExplainGUID(lpguid)); + + if(!pDirectDrawCreate){ // not hooked yet.... + HINSTANCE hinst; + hinst = LoadLibrary("ddraw.dll"); + pDirectDrawCreate = + (DirectDrawCreate_Type)GetProcAddress(hinst, "DirectDrawCreate"); + if(pDirectDrawCreate) + HookAPI(NULL, "ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreate); + else{ + char sMsg[81]; + sprintf_s(sMsg, 80, "DirectDrawCreate hook failed: error=%d\n", GetLastError()); + OutTraceD(sMsg); + if(IsAssertEnabled) MessageBox(0, sMsg, "Hook", MB_OK | MB_ICONEXCLAMATION); + return DDERR_GENERIC; // is there a better one? + } + } + + res = (*pDirectDrawCreate)(lpguid, lplpdd, pu); + if(res) { + OutTraceE("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; + } + + dxw.dwDDVersion=1; + char *mode; + switch ((DWORD)lpguid){ + case 0: mode="NULL"; break; + case DDCREATE_HARDWAREONLY: mode="DDCREATE_HARDWAREONLY"; break; + case DDCREATE_EMULATIONONLY: mode="DDCREATE_EMULATIONONLY"; break; + default: + switch (*(DWORD *)lpguid){ + case 0x6C14DB80: dxw.dwDDVersion=1; mode="IID_IDirectDraw"; break; + case 0xB3A6F3E0: dxw.dwDDVersion=2; mode="IID_IDirectDraw2"; break; + case 0x9c59509a: dxw.dwDDVersion=4; mode="IID_IDirectDraw4"; break; + case 0x15e65ec0: dxw.dwDDVersion=7; mode="IID_IDirectDraw7"; break; + default: mode="unknown"; break; + } + break; + } + OutTraceD("DirectDrawCreate: lpdd=%x guid=%s DDVersion=%d\n", *lplpdd, mode, dxw.dwDDVersion); + + HookDDSession(lplpdd, dxw.dwDDVersion); + + // added v2.1.44 + lpDD = *lplpdd; + return 0; +} + +/* ------------------------------------------------------------------------------ */ +// CleanRect: +// takes care of a corrupted RECT struct where some elements are not valid pointers. +// In this case, the whole RECT * variable is set to NULL, a value that is interpreted +// by directdraw functions as the whole surface area. +/* ------------------------------------------------------------------------------ */ + +static void CleanRect(RECT **lprect, int line) +{ + __try { + // normally unharmful statements + if(*lprect){ + int i; + i=(*lprect)->bottom; + i=(*lprect)->top; + i=(*lprect)->left; + i=(*lprect)->right; + } + } + __except(EXCEPTION_EXECUTE_HANDLER){ + OutTraceE("Rectangle exception caught at %d: invalid RECT\n", __LINE__); + if(IsAssertEnabled) MessageBox(0, "Rectangle exception", "CleanRect", MB_OK | MB_ICONEXCLAMATION); + *lprect=NULL; + } +} + +HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *lpguid, + LPDIRECTDRAW FAR *lplpdd, REFIID iid, IUnknown FAR *pu) +{ + HRESULT res; + OutTraceD("DirectDrawCreateEx: guid=%x(%s) refiid=%x\n", lpguid, ExplainGUID(lpguid), iid); + + // v2.1.70: auto-hooking (just in case...) + if(!pDirectDrawCreateEx){ // not hooked yet.... + HINSTANCE hinst; + hinst = LoadLibrary("ddraw.dll"); + if(!hinst){ + OutTraceE("LoadLibrary ERROR err=%d at %d\n", GetLastError(), __LINE__); + } + pDirectDrawCreateEx = + (DirectDrawCreateEx_Type)GetProcAddress(hinst, "DirectDrawCreateEx"); + if(pDirectDrawCreateEx) + HookAPI(NULL, "ddraw.dll", pDirectDrawCreateEx, "DirectDrawCreateEx", extDirectDrawCreateEx); + else{ + char sMsg[81]; + sprintf_s(sMsg, 80, "DirectDrawCreateEx hook failed: error=%d\n", GetLastError()); + OutTraceD(sMsg); + if(IsAssertEnabled) MessageBox(0, sMsg, "Hook", MB_OK | MB_ICONEXCLAMATION); + return DDERR_GENERIC; // is there a better one? + } + } + + res = (*pDirectDrawCreateEx)(lpguid, lplpdd, iid, pu); + if (res){ + OutTraceD("DirectDrawCreateEx: res=%x(%s)\n",res, ExplainDDError(res)); + return res; + } + + dxw.dwDDVersion=7; + char *mode; + switch ((DWORD)lpguid){ + case 0: mode="NULL"; break; + case DDCREATE_HARDWAREONLY: mode="DDCREATE_HARDWAREONLY"; break; + case DDCREATE_EMULATIONONLY: mode="DDCREATE_EMULATIONONLY"; break; + default: + switch (*(DWORD *)lpguid){ + case 0x6C14DB80: dxw.dwDDVersion=1; mode="IID_IDirectDraw"; break; + case 0xB3A6F3E0: dxw.dwDDVersion=2; mode="IID_IDirectDraw2"; break; + case 0x9c59509a: dxw.dwDDVersion=4; mode="IID_IDirectDraw4"; break; + case 0x15e65ec0: dxw.dwDDVersion=7; mode="IID_IDirectDraw7"; break; + default: mode="unknown"; break; + } + break; + } + OutTraceD("DirectDrawCreateEx: lpdd=%x guid=%s DDVersion=%d\n", *lplpdd, mode, dxw.dwDDVersion); + + HookDDSession(lplpdd,dxw.dwDDVersion); + + // added v2.1.44 + lpDD = *lplpdd; + return 0; +} + +HRESULT WINAPI extQueryInterfaceD(void *lpdd, REFIID riid, LPVOID *obp) +{ + HRESULT res; + unsigned int dwLocalDDVersion; + + res = (*pQueryInterfaceD)(lpdd, riid, obp); + OutTraceD("QueryInterface(D): lpdd=%x REFIID=%x obp=%x ret=%x at %d\n", + lpdd, riid.Data1, *obp, res, __LINE__); + + if(res) return res; + + dwLocalDDVersion=0; + switch(riid.Data1){ + case 0x6C14DB80: //DirectDraw1 + dwLocalDDVersion = 1; + break; + case 0xB3A6F3E0: //DirectDraw2 + dwLocalDDVersion = 2; + break; + case 0x9c59509a: //DirectDraw4 + dwLocalDDVersion = 4; + break; + case 0x15e65ec0: //DirectDraw7 + dwLocalDDVersion = 7; + break; + } + + if (! *obp) { + OutTraceD("QueryInterface(D): Interface for DX version %d not found\n", dwLocalDDVersion); + return(0); + } + + if (dwLocalDDVersion > dxw.dwMaxDDVersion) { + *obp = NULL; + OutTraceD("QueryInterface(D): lpdd=%x REFIID=%x obp=(NULL) ret=%x at %d\n", + lpdd, riid.Data1, res, __LINE__); + return(0); + } + + switch (dwLocalDDVersion){ + case 1: // you never know .... + case 2: + case 4: + // it's not supposed to be written for DDVersion==7, but it works .... + case 7: + dxw.dwDDVersion=dwLocalDDVersion; + HookDDSession((LPDIRECTDRAW *)obp, dxw.dwDDVersion); + + break; + } + + OutTraceD("QueryInterface(D): lpdd=%x REFIID=%x obp=%x DDVersion=%d ret=0\n", + lpdd, riid.Data1, *obp, dxw.dwDDVersion); + + return 0; +} + +HRESULT WINAPI extQueryInterfaceS(void *lpdds, REFIID riid, LPVOID *obp) +{ + HRESULT res; + BOOL IsPrim; + unsigned int dwLocalDDVersion; + + IsPrim=dxw.IsAPrimarySurface((LPDIRECTDRAWSURFACE)lpdds); + + dwLocalDDVersion=0; + switch(riid.Data1){ + case 0x6C14DB81: + dwLocalDDVersion = 1; + break; + case 0x57805885: //DDSurface2 - WIP (Dark Reign) + dwLocalDDVersion = 2; + break; + case 0xDA044E00: //DDSurface3 + dwLocalDDVersion = 3; + break; + case 0x0B2B8630: + dwLocalDDVersion = 4; + break; + case 0x06675a80: + dwLocalDDVersion = 7; + break; + } + + if (dwLocalDDVersion > dxw.dwMaxDDVersion) { + *obp = NULL; + OutTraceD("QueryInterface(S): DDVersion=%d SUPPRESSED lpdds=%x(%s) REFIID=%x obp=(NULL) ret=0 at %d\n", + dwLocalDDVersion, lpdds, IsPrim?"":"(PRIM)", riid.Data1, __LINE__); + return(0); + } + + res = (*pQueryInterfaceS)(lpdds, riid, obp); + + if(res) // added trace + { + OutTraceD("QueryInterface(S): ERROR lpdds=%x%s REFIID=%x obp=%x ret=%x(%s) at %d\n", + lpdds, IsPrim?"(PRIM)":"", riid.Data1, *obp, res, ExplainDDError(res), __LINE__); + return res; + } + + if (! *obp) { + OutTraceD("QueryInterface(S): Interface for DX version %d not found\n", dwLocalDDVersion); + return(0); + } + + // added trace + OutTraceD("QueryInterface(S): lpdds=%x%s REFIID=%x obp=%x DDVersion=%d ret=0\n", + lpdds, IsPrim?"(PRIM)":"", riid.Data1, *obp, dwLocalDDVersion); + + switch (dwLocalDDVersion){ + case 1: // added for The Sims + case 2: + case 3: + case 4: + case 7: + + dxw.dwDDVersion=dwLocalDDVersion; + + if(IsPrim){ + OutTraceD("QueryInterface(S): primary=%x new=%x\n", lpdds, *obp); + dxw.MarkPrimarySurface((LPDIRECTDRAWSURFACE)*obp); + HookDDSurfacePrim((LPDIRECTDRAWSURFACE *)obp, dxw.dwDDVersion); + } + else{ + dxw.UnmarkPrimarySurface((LPDIRECTDRAWSURFACE)*obp); + // v2.02.13: seems that hooking inconditionally gives troubles. What is the proper hook condition? + // maybe when in emulation mode? + //ASSERT TO BE FINISHED + if(dxw.dwFlags1 & EMULATESURFACE) HookDDSurfaceGeneric((LPDIRECTDRAWSURFACE *)obp, dxw.dwDDVersion); + } + + break; + } + + if (dxw.dwFlags3 & SAVECAPS) { + DDSURFACEDESC2 ddsd; + if (PopCaps(&ddsd, (LPDIRECTDRAWSURFACE)lpdds)) PushCaps(&ddsd, (LPDIRECTDRAWSURFACE)*obp); + } + + if(lpdds == lpDDSBack) lpDDSBack = (LPDIRECTDRAWSURFACE)*obp; + return 0; +} + +HRESULT WINAPI extSetDisplayMode(int version, LPDIRECTDRAW lpdd, + DWORD dwwidth, DWORD dwheight, DWORD dwbpp, DWORD dwrefreshrate, DWORD dwflags) +{ + DDSURFACEDESC2 ddsd; + HRESULT res = 0; + + if(IsTraceD){ + OutTrace("SetDisplayMode: version=%d dwWidth=%i dwHeight=%i dwBPP=%i", + version, dwwidth, dwheight, dwbpp); + if (version==2) + OutTrace(" dwRefresh=%i dwFlags=%x\n", dwrefreshrate, dwflags); + else + OutTrace("\n"); + } + + dxw.SetScreenSize(dwwidth, dwheight); + GetHookInfo()->Height=(short)dxw.GetScreenHeight(); + GetHookInfo()->Width=(short)dxw.GetScreenWidth(); + AdjustWindowFrame(dxw.GethWnd(), dwwidth, dwheight); + + if(dxw.dwFlags1 & EMULATESURFACE){ + dxw.VirtualPixelFormat.dwRGBBitCount = dwbpp; + dwbpp = dxw.ActualPixelFormat.dwRGBBitCount; + SetBltTransformations(); + OutTraceD("SetDisplayMode: mode=EMULATESURFACE EmuBPP=%d ActBPP=%d\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.ActualPixelFormat.dwRGBBitCount); + } + else { + OutTraceD("SetDisplayMode: mode=STANDARD BPP=%d\n", dwbpp); + dxw.ActualPixelFormat.dwRGBBitCount = dwbpp; + } + + ZeroMemory(&ddsd, sizeof(ddsd)); + ddsd.dwSize = Set_dwSize_From_DDraw(lpdd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_REFRESHRATE; + ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; + + (*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd); + if(ddsd.ddpfPixelFormat.dwRGBBitCount != dwbpp){ + OutTraceD("SetDisplayMode: fixing colordepth current=%d required=%d size=(%dx%d)\n", + ddsd.ddpfPixelFormat.dwRGBBitCount, dwbpp, ddsd.dwWidth, ddsd.dwHeight); + if (version==1) + res = (*pSetDisplayMode1)(lpdd, ddsd.dwWidth, ddsd.dwHeight, dwbpp); + else + res = (*pSetDisplayMode2)(lpdd, ddsd.dwWidth, ddsd.dwHeight, dwbpp, ddsd.dwRefreshRate, 0); + } + + return 0; +} + +HRESULT WINAPI extSetDisplayMode2(LPDIRECTDRAW lpdd, + DWORD dwwidth, DWORD dwheight, DWORD dwbpp, DWORD dwrefreshrate, DWORD dwflags) +{ + return extSetDisplayMode(2, lpdd, dwwidth, dwheight, dwbpp, dwrefreshrate, dwflags); +} + +HRESULT WINAPI extSetDisplayMode1(LPDIRECTDRAW lpdd, + DWORD dwwidth, DWORD dwheight, DWORD dwbpp) +{ + return extSetDisplayMode(1, lpdd, dwwidth, dwheight, dwbpp, 0, 0); +} + +HRESULT WINAPI extGetDisplayMode(LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd) +{ + OutTraceD("GetDisplayMode\n"); + + (*pGetDisplayMode)(lpdd, lpddsd); + if(dxw.dwFlags1 & EMULATESURFACE) SetPixFmt((LPDDSURFACEDESC2)lpddsd); + lpddsd->dwWidth = dxw.GetScreenWidth(); + lpddsd->dwHeight = dxw.GetScreenHeight(); + + // v2.1.96: fake screen color depth + if(dxw.dwFlags2 & INIT8BPP|INIT16BPP){ + if(dxw.dwFlags2 & INIT8BPP) FixPixelFormat(8, &lpddsd->ddpfPixelFormat); + if(dxw.dwFlags2 & INIT16BPP) FixPixelFormat(16, &lpddsd->ddpfPixelFormat); + OutTraceD("GetDisplayMode: fix RGBBitCount=%d\n", lpddsd->ddpfPixelFormat.dwRGBBitCount); + } + + OutTraceD("GetDisplayMode: returning WxH=(%dx%d) PixelFormat Flags=%x(%s) RGBBitCount=%d RGBAmask=(%x,%x,%x,%x) Caps=%x(%s)\n", + lpddsd->dwWidth, lpddsd->dwHeight, + lpddsd->ddpfPixelFormat.dwFlags, ExplainPixelFormatFlags(lpddsd->ddpfPixelFormat.dwFlags), + lpddsd->ddpfPixelFormat.dwRGBBitCount, + lpddsd->ddpfPixelFormat.dwRBitMask, lpddsd->ddpfPixelFormat.dwGBitMask, lpddsd->ddpfPixelFormat.dwBBitMask, + lpddsd->ddpfPixelFormat.dwRGBAlphaBitMask, + lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps)); + + return 0; +} + +void FixWindowFrame(HWND hwnd) +{ + LONG nOldStyle; + + OutTraceD("FixWindowFrame: hwnd=%x\n", hwnd); + + nOldStyle=(*pGetWindowLong)(hwnd, GWL_STYLE); + if (!nOldStyle){ + OutTraceE("GetWindowLong ERROR %d at %d\n",GetLastError(),__LINE__); + return; + } + + OutTraceD("FixWindowFrame: style=%x(%s)\n",nOldStyle,ExplainStyle(nOldStyle)); + + // fix style + if (!(*pSetWindowLong)(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW)){ + OutTraceE("SetWindowLong ERROR %d at %d\n",GetLastError(),__LINE__); + return; + } + // fix exstyle + if (!(*pSetWindowLong)(hwnd, GWL_EXSTYLE, 0)){ + OutTraceE("SetWindowLong ERROR %d at %d\n",GetLastError(),__LINE__); + return; + } + + // ShowWindow retcode means in no way an error code! Better ignore it. + (*pShowWindow)(hwnd, SW_RESTORE); + return; +} + +HRESULT WINAPI extSetCooperativeLevel(void *lpdd, HWND hwnd, DWORD dwflags) +{ + HRESULT res; + HWND hDesktop; + + OutTraceD("SetCooperativeLevel: hwnd=%x dwFlags=%x(%s)\n", + hwnd, dwflags,ExplainCoopFlags(dwflags)); + + InitDDScreenParameters((LPDIRECTDRAW)lpdd); + + // WARN: Tomb Raider 4 demo is setting cooperative level against hwnd 0 (desktop) + // so in this case better use the registered hWnd value. Same as GP500, who uses + // the desktop window handle. + // v2.1.82 fix: + hDesktop=(*pGetDesktopWindow)(); + if ((hwnd==0) || (hwnd==hDesktop)) { + OutTraceD("SetCooperativeLevel: detected desktop hwnd=%x redirected to %x\n", hwnd, dxw.GethWnd()); + hwnd=dxw.GethWnd(); + // this fixes the blocks on "Tomb Raider IV" !!!! + if(dxw.dwFlags1 & FIXPARENTWIN) hwnd=dxw.hParentWnd; + } + + if (dwflags & DDSCL_FULLSCREEN){ + dxw.SetFullScreen(TRUE); + dwflags &= ~(DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX); + dwflags |= DDSCL_NORMAL; + //res=(*pSetCooperativeLevel)(lpdd, hwnd, DDSCL_NORMAL); + res=(*pSetCooperativeLevel)(lpdd, hwnd, dwflags); + AdjustWindowFrame(hwnd, dxw.GetScreenWidth(), dxw.GetScreenHeight()); + //FixWindowFrame(hwnd); //-- incompatible with Microsoft Madness + if (dxw.dwFlags1 & FIXWINFRAME) FixWindowFrame(hwnd); + } + else{ + RECT client; + (*pGetClientRect)(hwnd, &client); + // v2.02.11: + // Non fullscreen cooperative mode means windowed, unless the window occupies the whole desktop area + dxw.SetFullScreen(client.right==dxw.iSizX && client.bottom==dxw.iSizY); + //dxw.SetFullScreen(FALSE); + res=(*pSetCooperativeLevel)(lpdd, hwnd, dwflags); + } + if(res) + OutTraceE("SetCooperativeLevel: ERROR err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + + GetHookInfo()->IsFullScreen=dxw.IsFullScreen(); + + // WARN: GP500 was setting cooperative level against the desktop! This can be partially + // intercepted by hooking the GetDesktopWindow() call, but in windowed mode this can't be + // done, so better repeat the check here. + + if ((res==DD_OK) && (hwnd!=NULL)){ + if (hwnd==hDesktop){ + OutTraceE("SetCooperativeLevel: attempt to work on desktop window\n"); + } + else + dxw.SethWnd(hwnd); // save the good one + } + + return res; +} + +static char *FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd) +{ + // experimental part: + switch (lpddsd->dwFlags){ + case DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH: + switch (lpddsd->ddsCaps.dwCaps){ + case DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY: + OutTrace("FixSurfaceCaps: null action (Airline Tycoon Evolution)\n"); + return "null"; + break; + default: + break; + } + case DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT: + default: + break; + } + + if(((lpddsd->dwFlags & (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT)) == (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT)) && + (lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)){ + OutTraceB("FixSurfaceCaps: Experimental pixelformat for ZBUFFER case\n"); + lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; // Evany + lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + return "ZBUFFER"; + } + if(((lpddsd->dwFlags & DDSD_WIDTH) && !(lpddsd->dwFlags & DDSD_HEIGHT)) || + (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) || + ((lpddsd->dwFlags & DDSD_PIXELFORMAT) && !(lpddsd->dwFlags & DDSD_PITCH) && !(lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) || // fix good for "Wargames" + ((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && !(lpddsd->dwFlags & DDSD_PIXELFORMAT)) // fix good for Premier Manager 98 + ){ + OutTraceB("FixSurfaceCaps: suppress DDSD_PIXELFORMAT case\n"); + // don't alter pixel format + lpddsd->dwFlags &= ~DDSD_PIXELFORMAT; // Wargames, Warhammer Dark Omen + return "(none)"; + } + // adjust pixel format + OutTraceB("FixSurfaceCaps: suppress DDSCAPS_VIDEOMEMORY case\n"); + lpddsd->dwFlags |= DDSD_CAPS | DDSD_PIXELFORMAT; + lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; + lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN; + return SetPixFmt(lpddsd); +} + +HRESULT WINAPI extCreateSurfaceEmu(int dxversion, CreateSurface_Type pCreateSurface, LPDIRECTDRAW lpdd, DDSURFACEDESC2 *lpddsd, + LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + HRESULT res; + DDSURFACEDESC2 ddsd; + LPDIRECTDRAWSURFACE lpDDSPrim; + char *pfmt; + DWORD CurFlags, CurSize; + + if((lpddsd->dwSize != sizeof(DDSURFACEDESC2)) && (lpddsd->dwSize != sizeof(DDSURFACEDESC))){ + char sMsg[81]; + sprintf_s(sMsg,80, "CreateSurface: ASSERT bad dwSize=%d\n", lpddsd->dwSize); + OutTraceD(sMsg); + if(IsAssertEnabled) MessageBox(0, sMsg, "CreateSurface", MB_OK | MB_ICONEXCLAMATION); + return DDERR_INVALIDPARAMS; + } + + memset(&ddsd, 0, sizeof(ddsd)); // Clean all + memcpy(&ddsd, lpddsd, lpddsd->dwSize); // Copy + CurSize = (dxversion < 4) ? sizeof(DDSURFACEDESC) : sizeof(DDSURFACEDESC2); + ddsd.dwSize = CurSize; + + if(ddsd.dwFlags & DDSD_CAPS && ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE){ + GetHookInfo()->Height=(short)dxw.GetScreenHeight(); + GetHookInfo()->Width=(short)dxw.GetScreenWidth(); + GetHookInfo()->ColorDepth=(short)dxw.VirtualPixelFormat.dwRGBBitCount; + GetHookInfo()->DXVersion=dxversion; + lpServiceDD = lpdd; // v2.1.87 + + dxw.dwPrimarySurfaceCaps = ddsd.ddsCaps.dwCaps; + dxw.dwBackBufferCount = (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) ? ddsd.dwBackBufferCount : 0; + + // beware of the different behaviour between older and newer directdraw releases... + if(dxversion >= 4){ + if (lpDDC) while(lpDDC->Release()); + if (lpDDSEmu_Back) while(lpDDSEmu_Back->Release()); + if (lpDDSEmu_Prim) while(lpDDSEmu_Prim->Release()); + if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) + if (lpDDSBack) while(lpDDSBack->Release()); + } + lpDDC=NULL; + lpDDSEmu_Back=NULL; + lpDDSEmu_Prim=NULL; + if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) + lpDDSBack=NULL; + + int BBCount=1; + if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) BBCount=ddsd.dwBackBufferCount; + if (BBCount > MAXBACKBUFFERS){ + char sMsg[81]; + sprintf_s(sMsg, 80, "CreateSurface: BackBufferCount=%d\n", BBCount); + OutTraceD(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "CreateSurface", MB_OK | MB_ICONEXCLAMATION); + // recover ... + dxw.dwBackBufferCount =MAXBACKBUFFERS; + BBCount = MAXBACKBUFFERS; + } + + // emulated primary surface + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; + if (lpddsd->dwFlags & DDSD_CKDESTBLT) ddsd.dwFlags|=DDSD_CKDESTBLT; + if (lpddsd->dwFlags & DDSD_CKDESTOVERLAY) ddsd.dwFlags|=DDSD_CKDESTOVERLAY; + if (lpddsd->dwFlags & DDSD_CKSRCBLT) ddsd.dwFlags|=DDSD_CKSRCBLT; + if (lpddsd->dwFlags & DDSD_CKSRCOVERLAY) ddsd.dwFlags|=DDSD_CKSRCOVERLAY; + ddsd.dwWidth = dxw.GetScreenWidth(); + ddsd.dwHeight = dxw.GetScreenHeight(); + pfmt=SetPixFmt(&ddsd); + CurFlags=ddsd.dwFlags; + + // create Primary surface + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__); + res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); + if(res){ + OutTraceE("CreateSurface ERROR: res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); + return res; + } + lpDDSPrim = *lplpdds; + OutTraceD("CreateSurface: created PRIMARY DDSPrim=%x\n", lpDDSPrim); + dxw.MarkPrimarySurface(*lplpdds); + HookDDSurfacePrim(lplpdds, dxversion); + //if (dxw.dwFlags3 & SAVECAPS) PushCaps(&ddsd, lpDDSPrim); handled outside .... + + if (BBCount){ + // create BackBuffer surface + memset(&ddsd, 0, sizeof(ddsd)); // Clean all + ddsd.dwSize = CurSize; + ddsd.dwFlags = CurFlags; + ddsd.ddsCaps.dwCaps=DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; + ddsd.dwWidth = dxw.GetScreenWidth(); + ddsd.dwHeight = dxw.GetScreenHeight(); + pfmt=SetPixFmt(&ddsd); + //ddsd.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Backbuf]" , __LINE__); + res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSBack, 0); + if(res){ + OutTraceE("CreateSurface ERROR: res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); + return res; + } + if (dxw.dwFlags3 & SAVECAPS) { + ddsd.ddsCaps.dwCaps=DDSCAPS_VIDEOMEMORY; + PushCaps(&ddsd, lpDDSBack); + } + OutTraceD("CreateSurface: created BACK DDSBack=%x\n", lpDDSBack); + dxw.UnmarkPrimarySurface(lpDDSBack); + HookDDSurfaceGeneric(&lpDDSBack, dxversion); // added !!! + } + FlipChainLength=BBCount; + // V2.1.85: tricky !!!! + // When a real backbuffer is created, it has a reference to its frontbuffer. + // some games (Monopoly 3D) may depend on this setting - i.e. they could close + // the exceeding references - so this is better be replicated adding an initial + // reference to the zero count. + if (lpDDSBack) lpDDSBack->AddRef(); // should it be repeated BBCount times???? + + // rebuild emulated primary surface + + if(lpDDSEmu_Prim==NULL){ + memset(&ddsd, 0, sizeof(ddsd)); // Clean all + ddsd.dwSize = CurSize; + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + pfmt=SetPixFmt(&ddsd); + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[EmuPrim]" , __LINE__); + res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSEmu_Prim, 0); + if(res==DDERR_PRIMARYSURFACEALREADYEXISTS){ + OutTraceD("CreateSurface: ASSERT DDSEmu_Prim already exists\n"); + res=(*pGetGDISurface)(lpdd, &lpDDSEmu_Prim); + } + if(res){ + OutTraceE("CreateSurface: CreateSurface ERROR on DDSEmu_Prim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); + return res; + } + OutTraceD("CreateSurface: created new DDSEmu_Prim=%x\n",lpDDSEmu_Prim); + InitDSScreenParameters(lpDDSEmu_Prim); + } + + if (lpDDC==NULL) RenewClipper(lpdd, lpDDSEmu_Prim); + + dxw.UnmarkPrimarySurface(lpDDSEmu_Prim); + // can't hook lpDDSEmu_Prim as generic, since the Flip method is unimplemented for a PRIMARY surface! + // better avoid it or hook just useful methods. + //if (dxw.dwTFlags & OUTPROXYTRACE) HookDDSurfaceGeneric(&lpDDSEmu_Prim, dxw.dwDDVersion); + + // rebuild emulated primary backbuffer surface + + if(lpDDSEmu_Back==NULL){ + memset(&ddsd, 0, sizeof(ddsd)); // Clean all + ddsd.dwSize = CurSize; + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + ddsd.dwWidth = dxw.GetScreenWidth(); + ddsd.dwHeight = dxw.GetScreenHeight(); + //pfmt=SetPixFmt(&ddsd); + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[EmuBack]" , __LINE__); + + res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSEmu_Back, 0); + if(res){ + OutTraceE("CreateSurface: CreateSurface ERROR on DDSEmuBack : res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); + return res; + } + OutTraceD("CreateSurface: created new DDSEmu_Back=%x\n", lpDDSEmu_Back); + } + + dxw.UnmarkPrimarySurface(lpDDSEmu_Back); + if (dxw.dwTFlags & OUTPROXYTRACE) HookDDSurfaceGeneric(&lpDDSEmu_Back, dxversion); + + OutTraceD("CreateSurface: created DDSEmu_Prim=%x DDSEmu_Back=%x DDSPrim=%x DDSBack=%x\n", + lpDDSEmu_Prim, lpDDSEmu_Back, lpDDSPrim, lpDDSBack); + + // creation of lpDDSHDC service surface moved to GetDC method + + if(dxw.dwFlags1 & CLIPCURSOR) dxw.SetClipCursor(); + return 0; + } + + pfmt=FixSurfaceCaps(&ddsd); + + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]" , __LINE__); + DumpPixFmt(&ddsd); + //OutTrace("pCreateSurface=%x lpdd=%x &ddsd=%x lplpdds=%x pu=%x\n",pCreateSurface, lpdd, &ddsd, lplpdds, pu); + res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, pu); + if(res){ + // v2.1.81: retry on system memory may fix not only the DDERR_OUTOFVIDEOMEMORY + // error, but the DDERR_INVALIDPIXELFORMAT (see "The Sims ???") + if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && + ((res==DDERR_OUTOFVIDEOMEMORY) || (res==DDERR_INVALIDPIXELFORMAT))){ + OutTraceD("CreateSurface: CreateSurface ERROR err=%x(%s) at %d, retry in SYSTEMMEMORY\n", + res, ExplainDDError(res), __LINE__); + ddsd.dwFlags |= DDSD_CAPS; + ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic2]" , __LINE__); + res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); + } + } + if (res) { + OutTraceE("CreateSurface: CreateSurface ERROR res=%x(%s) pfmt=%s at %d\n", res, ExplainDDError(res), pfmt, __LINE__); + //if((res==DDERR_INVALIDPIXELFORMAT) || (res && (ddsd.dwFlags & DDSD_PIXELFORMAT))) DumpPixFmt(&ddsd); + DumpPixFmt(&ddsd); // why Pandemonium2 fails ??? + return res; + } + + // diagnostic hooks .... + HookDDSurfaceGeneric(lplpdds, dxversion); + // unmark this as possible primary + dxw.UnmarkPrimarySurface(*lplpdds); + OutTraceD("CreateSurface: created EMU_GENERIC dds=%x type=%s\n", *lplpdds, pfmt); + + return 0; +} + +HRESULT WINAPI extCreateSurfaceDir(int dxversion, CreateSurface_Type pCreateSurface, LPDIRECTDRAW lpdd, DDSURFACEDESC2 *lpddsd, + LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + HRESULT res; + DDSURFACEDESC2 ddsd; + LPDIRECTDRAWSURFACE lpDDSPrim; + int dwSize; + + memset(&ddsd, 0, sizeof(ddsd)); // Clean all + memcpy(&ddsd, lpddsd, lpddsd->dwSize); // Copy + dwSize = (dxversion < 4) ? sizeof(DDSURFACEDESC) : sizeof(DDSURFACEDESC2); + ddsd.dwSize = dwSize; + + if(ddsd.dwFlags & DDSD_CAPS && ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE){ + GetHookInfo()->Height=(short)dxw.GetScreenHeight(); + GetHookInfo()->Width=(short)dxw.GetScreenWidth(); + GetHookInfo()->ColorDepth=(short)dxw.VirtualPixelFormat.dwRGBBitCount; + GetHookInfo()->DXVersion=dxversion; + dxw.dwPrimarySurfaceCaps = ddsd.ddsCaps.dwCaps; + dxw.dwBackBufferCount = (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) ? ddsd.dwBackBufferCount : 0; + lpServiceDD = lpdd; // v2.1.87 + + // clean up service objects + // beware of the different behaviour between older and newer directdraw releases... + if(dxversion >= 4){ + if (lpDDC){ + __try { while(lpDDC && lpDDC->Release()); } + __except(EXCEPTION_EXECUTE_HANDLER){ + OutTraceD("Release(lpDDC): exception caught at %d\n", __LINE__); + lpDDC=NULL; + } + } + if (lpDDSBack){ + __try { while(lpDDSBack && lpDDSBack->Release()); } + __except(EXCEPTION_EXECUTE_HANDLER){ + OutTraceD("Release(lpDDSBack): exception caught at %d\n", __LINE__); + lpDDSBack=NULL; + } + } + } + lpDDC=NULL; + + int BBCount=1; + if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) BBCount=ddsd.dwBackBufferCount; + if (BBCount > 0){ + lpDDSBack=NULL; + OutTraceD("CreateSurface: BackBufferCount=%d\n", BBCount); + } + + if((dxw.dwFlags1 & EMULATEBUFFER) && lpDDSEmu_Prim){ + __try { while(lpDDSEmu_Prim && lpDDSEmu_Prim->Release()); } + __except(EXCEPTION_EXECUTE_HANDLER){ + OutTraceD("Release(lpDDSEmu_Prim): exception caught at %d\n", __LINE__); + lpDDSEmu_Prim=NULL; + } + } + + // genuine primary surface + ddsd.dwFlags &= ~(DDSD_WIDTH|DDSD_HEIGHT|DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE|DDSD_PIXELFORMAT); + ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_FLIP | DDSCAPS_COMPLEX); + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Dir Primary]" , __LINE__); + res = (*pCreateSurface)(lpdd, &ddsd, &lpDDSPrim, pu); + if(res){ + if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res==DDERR_OUTOFVIDEOMEMORY)){ + OutTraceD("CreateSurface: CreateSurface DDERR_OUTOFVIDEOMEMORY ERROR at %d, retry in SYSTEMMEMORY\n", __LINE__); + ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; // try ... + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; // try ... + res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); + } + if(res){ + OutTraceE("CreateSurface: CreateSurface ERROR on DDSPrim res=%x(%s) at %d\n", + res, ExplainDDError(res), __LINE__); + return res; + } + } + + if(dxw.dwFlags1 & EMULATEBUFFER){ + lpDDSEmu_Prim = lpDDSPrim; + dxw.UnmarkPrimarySurface(lpDDSEmu_Prim); + OutTraceD("CreateSurface: created PRIMARY DDSPrim=%x flags=%x(%s) caps=%x(%s)\n", + lpDDSPrim, ddsd.dwFlags, ExplainFlags(ddsd.dwFlags), ddsd.ddsCaps.dwCaps, ExplainDDSCaps(ddsd.ddsCaps.dwCaps)); + RenewClipper(lpdd, lpDDSEmu_Prim); + + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + // warning: can't create zero sized backbuffer surface !!!! + ddsd.dwWidth = dxw.GetScreenWidth(); + ddsd.dwHeight = dxw.GetScreenHeight(); + ddsd.ddsCaps.dwCaps = 0; + if (dxversion >= 4) ddsd.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Dir FixBuf]" , __LINE__); + res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSPrim, 0); + if(res){ + OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__); + return res; + } + + *lplpdds = lpDDSPrim; + dxw.MarkPrimarySurface(lpDDSPrim); + OutTraceD("CreateSurface: created FIX DDSPrim=%x flags=%x(%s) caps=%x(%s)\n", + *lplpdds, ddsd.dwFlags, ExplainFlags(ddsd.dwFlags), ddsd.ddsCaps.dwCaps, ExplainDDSCaps(ddsd.ddsCaps.dwCaps)); + } + else{ + *lplpdds = lpDDSPrim; + dxw.MarkPrimarySurface(lpDDSPrim); + OutTraceD("CreateSurface: created PRIMARY DDSPrim=%x flags=%x(%s) caps=%x(%s)\n", + *lplpdds, ddsd.dwFlags, ExplainFlags(ddsd.dwFlags), ddsd.ddsCaps.dwCaps, ExplainDDSCaps(ddsd.ddsCaps.dwCaps)); + RenewClipper(lpdd, lpDDSPrim); + } + + + HookDDSurfacePrim(&lpDDSPrim, dxversion); + + if (!BBCount) return 0; + FlipChainLength=BBCount; + + ddsd.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + // warning: can't create zero sized backbuffer surface !!!! + ddsd.dwWidth = dxw.GetScreenWidth(); + ddsd.dwHeight = dxw.GetScreenHeight(); + if (dxw.dwFlags2 & BACKBUFATTACH) { + DDSURFACEDESC2 prim; + prim.dwSize = dwSize; + res=lpDDSPrim->GetSurfaceDesc((DDSURFACEDESC *)&prim); + ddsd.dwWidth = prim.dwWidth; + ddsd.dwHeight = prim.dwHeight; + OutTraceD("BMX FIX: res=%x(%s) wxh=(%dx%d)\n", res, ExplainDDError(res),ddsd.dwWidth, ddsd.dwHeight); + } + + // preserve original CAPS.... + ddsd.ddsCaps.dwCaps &= ~DDSCAPS_PRIMARYSURFACE; + if (dxversion >= 4) ddsd.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; + DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Dir Backbuf]" , __LINE__); + res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSBack, pu); + if(res) { + if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res==DDERR_OUTOFVIDEOMEMORY)){ + OutTraceD("CreateSurface: CreateSurface DDERR_OUTOFVIDEOMEMORY ERROR at %d, retry in SYSTEMMEMORY\n", __LINE__); + ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; // try ... + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; // try ... + res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSBack, pu); + } + if(res){ + OutTraceE("CreateSurface: CreateSurface ERROR on DDSBack res=%x(%s) caps=%x(%s) at %d\n", + res, ExplainDDError(res), ddsd.ddsCaps.dwCaps, ExplainDDSCaps(ddsd.ddsCaps.dwCaps), __LINE__); + return res; + } + } + OutTraceD("CreateSurface: created BACK DDSBack=%x flags=%x(%s) caps=%x(%s)\n", + lpDDSBack, ddsd.dwFlags, ExplainFlags(ddsd.dwFlags), ddsd.ddsCaps.dwCaps, ExplainDDSCaps(ddsd.ddsCaps.dwCaps)); + + HookDDSurfaceGeneric(&lpDDSBack, dxversion); + // V2.1.84: tricky !!!! + // When a real backbuffer is created, it has a reference to its frontbuffer. + // some games (Monopoly 3D) may depend on this setting - i.e. they could close + // the exceeding references - so this is better be replicated adding an initial + // reference to the zero count. + // Should this hold for EMULATED mode as well? Maybe, but Diablo crashes.... + lpDDSBack->AddRef(); + + if(dxw.dwFlags1 & CLIPCURSOR) dxw.SetClipCursor(); + return 0; + } + + //BACKBUFATTACH: needed for Syberia + if ((dxw.dwFlags2 & BACKBUFATTACH) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)){ + DDSURFACEDESC2 backbuf; + backbuf.dwSize = dwSize; + res=lpDDSBack->GetSurfaceDesc((DDSURFACEDESC *)&backbuf); + ddsd.dwWidth = backbuf.dwWidth; + ddsd.dwHeight = backbuf.dwHeight; + } + + DumpSurfaceAttributes((LPDDSURFACEDESC)lpddsd, "[Dir Generic]" , __LINE__); + res = (*pCreateSurface)(lpdd, lpddsd, lplpdds, 0); + if(res){ + if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res==DDERR_OUTOFVIDEOMEMORY)){ + OutTraceD("CreateSurface ERROR: res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__); + lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; + lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + res = (*pCreateSurface)(lpdd, lpddsd, lplpdds, 0); + } + if(res){ + OutTraceE("CreateSurface: CreateSurface ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + } + OutTraceD("CreateSurface: created GENERIC surface dds=%x flags=%x(%s) caps=%x(%s)\n", + *lplpdds, lpddsd->dwFlags, ExplainFlags(lpddsd->dwFlags), lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps)); + + // hooks .... + HookDDSurfaceGeneric(lplpdds, dxversion); + dxw.UnmarkPrimarySurface(*lplpdds); + + OutTraceD("CreateSurface: created lpdds=%x type=GENUINE Return=%x\n", *lplpdds, res); + return res; +} + +HRESULT WINAPI extCreateSurface1(LPDIRECTDRAW lpdd, DDSURFACEDESC *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + return extCreateSurface(1, (CreateSurface_Type)pCreateSurface1, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); +} + +HRESULT WINAPI extCreateSurface2(LPDIRECTDRAW lpdd, DDSURFACEDESC *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + return extCreateSurface(2, (CreateSurface_Type)pCreateSurface2, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); +} + +HRESULT WINAPI extCreateSurface4(LPDIRECTDRAW lpdd, DDSURFACEDESC2 *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + return extCreateSurface(4, (CreateSurface_Type)pCreateSurface4, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); +} + +HRESULT WINAPI extCreateSurface7(LPDIRECTDRAW lpdd, DDSURFACEDESC2 *lpddsd, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + return extCreateSurface(7, (CreateSurface_Type)pCreateSurface7, lpdd, (DDSURFACEDESC2 *)lpddsd, lplpdds, pu); +} + +HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreateSurface, LPDIRECTDRAW lpdd, DDSURFACEDESC2 *lpddsd, + LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + HRESULT res; + DDSURFACEDESC2 ddsd; + + if(IsTraceD){ + // beware: incomplete trace lines - must be line terminated below! + OutTrace("CreateSurface: Version=%d lpdd=%x Flags=%x(%s)", dxversion, lpdd, lpddsd->dwFlags, ExplainFlags(lpddsd->dwFlags)); + if (lpddsd->dwFlags & DDSD_CAPS && lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) OutTrace(" VirtualScreen=(%d,%d)", dxw.GetScreenWidth(), dxw.GetScreenHeight()); + if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) OutTrace(" BackBufferCount=%d", lpddsd->dwBackBufferCount); + if (lpddsd->dwFlags & DDSD_WIDTH) OutTrace(" Width=%d", lpddsd->dwWidth); + if (lpddsd->dwFlags & DDSD_HEIGHT) OutTrace(" Height=%d", lpddsd->dwHeight); + if (lpddsd->dwFlags & DDSD_CAPS) OutTrace(" Caps=%x(%s)", lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps)); + if (lpddsd->dwFlags & DDSD_CKDESTBLT ) OutTrace(" CKDestBlt=(%x,%x)", lpddsd->ddckCKDestBlt.dwColorSpaceLowValue, lpddsd->ddckCKDestBlt.dwColorSpaceHighValue); + if (lpddsd->dwFlags & DDSD_CKDESTOVERLAY ) OutTrace(" CKDestOverlay=(%x,%x)", lpddsd->ddckCKDestOverlay.dwColorSpaceLowValue, lpddsd->ddckCKDestOverlay.dwColorSpaceHighValue); + if (lpddsd->dwFlags & DDSD_CKSRCBLT ) OutTrace(" CKSrcBlt=(%x,%x)", lpddsd->ddckCKSrcBlt.dwColorSpaceLowValue, lpddsd->ddckCKSrcBlt.dwColorSpaceHighValue); + if (lpddsd->dwFlags & DDSD_CKSRCOVERLAY ) OutTrace(" CKSrcOverlay=(%x,%x)", lpddsd->ddckCKSrcOverlay.dwColorSpaceLowValue, lpddsd->ddckCKSrcOverlay.dwColorSpaceHighValue); + OutTrace("\n"); + if (lpddsd->dwFlags & DDSD_PIXELFORMAT) DumpPixFmt(lpddsd); + } + + //GHO workaround (needed for WarWind, Rogue Spear): + if (lpddsd->dwFlags && !(lpddsd->dwFlags & 0x1)){ + OutTraceD("CreateSurface: fixing illegal dwFlags value: %x -> %x\n", + lpddsd->dwFlags, lpddsd->dwFlags+1); + lpddsd->dwFlags++; + } + + lpDD = lpdd; + if (dxw.dwFlags3 & SAVECAPS) ddsd=*lpddsd; + + if (dxw.dwFlags1 & EMULATESURFACE) + res= extCreateSurfaceEmu(dxversion, pCreateSurface, lpdd, lpddsd, lplpdds, pu); + else + res= extCreateSurfaceDir(dxversion, pCreateSurface, lpdd, lpddsd, lplpdds, pu); + + if (dxw.dwFlags3 & SAVECAPS) PushCaps(&ddsd, *lplpdds); + + return res; +} + +HRESULT WINAPI extGetAttachedSurface(int dxversion, GetAttachedSurface_Type pGetAttachedSurface, + LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpddsc, LPDIRECTDRAWSURFACE *lplpddas) +{ + HRESULT res; + BOOL IsPrim; + + IsPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("GetAttachedSurface(%d): lpdds=%x%s caps=%x(%s)\n", + dxversion, lpdds, (IsPrim?"(PRIM)":""), lpddsc->dwCaps, ExplainDDSCaps(lpddsc->dwCaps)); + + // if not primary, just proxy the method + + // v2.1.81: fix to make "Silver" working: if the primary surface was created with + // backbuffercount == 2, the game expects some more surface to be attached to + // the attached backbuffer. Since there would be no use for it, just return + // the attached backbuffer itself. Makes Silver working, anyway.... + // beware: "Snowboard Racer" fails if you return an attached surface anyhow! There, + // the primary surface was created with back buffer count == 1. + + if ((lpdds == lpDDSBack) && (dxw.dwBackBufferCount > 1)){ + *lplpddas = lpDDSBack; + OutTraceD("GetAttachedSurface(%d): DOUBLEBUFFER attached=%x\n", dxversion, *lplpddas); + return 0; + } + + if(!IsPrim){ + res=(*pGetAttachedSurface)(lpdds, lpddsc, lplpddas); + if(res) + OutTraceE("GetAttachedSurface(%d): ERROR res=%x(%s) at %d\n", dxversion, res, ExplainDDError(res), __LINE__); + else + OutTraceD("GetAttachedSurface(%d): attached=%x\n", dxversion, *lplpddas); + return(res); + } + + // on primary surface return the lpDDSBack surface coming from either an explicit + // AddAttachedSurface, or a primary complex surface creation otherwise.... + + if(lpddsc->dwCaps & DDSCAPS_BACKBUFFER){ // WIPWIP + if (lpDDSBack) { + *lplpddas = lpDDSBack; + OutTraceD("GetAttachedSurface(%d): BACKBUFFER attached=%x\n", dxversion, *lplpddas); + return 0; + } + else { + *lplpddas = NULL; + OutTraceD("GetAttachedSurface(%d): no attached BACKBUFFER\n", dxversion); + return DDERR_NOTFOUND; + } + } + else{ + res=(*pGetAttachedSurface)(lpdds, lpddsc, lplpddas); + if(res) + OutTraceE("GetAttachedSurface(%d): ERROR res=%x(%s) at %d\n", dxversion, res, ExplainDDError(res), __LINE__); + else + OutTraceD("GetAttachedSurface(%d): attached=%x\n", dxversion, *lplpddas); + return res; + } +} + +HRESULT WINAPI extGetAttachedSurface1(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpddsc, LPDIRECTDRAWSURFACE *lplpddas) +{ + return extGetAttachedSurface(1, pGetAttachedSurface1, lpdds, lpddsc, lplpddas); +} + +HRESULT WINAPI extGetAttachedSurface3(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpddsc, LPDIRECTDRAWSURFACE *lplpddas) +{ + return extGetAttachedSurface(3, pGetAttachedSurface3, lpdds, lpddsc, lplpddas); +} + +HRESULT WINAPI extGetAttachedSurface4(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpddsc, LPDIRECTDRAWSURFACE *lplpddas) +{ + return extGetAttachedSurface(4, pGetAttachedSurface4, lpdds, lpddsc, lplpddas); +} + +HRESULT WINAPI extGetAttachedSurface7(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpddsc, LPDIRECTDRAWSURFACE *lplpddas) +{ + return extGetAttachedSurface(7, pGetAttachedSurface7, lpdds, lpddsc, lplpddas); +} + +static void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line) +{ + OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), line); + if (res==DDERR_INVALIDRECT){ + if (lps) + OutTraceE(" src=(%d,%d)-(%d,%d)",lps->left, lps->top, lps->right, lps->bottom); + else + OutTraceE(" src=(NULL)"); + if (lpd) + OutTraceE(" dest=(%d,%d)-(%d,%d)",lpd->left, lpd->top, lpd->right, lpd->bottom); + else + OutTraceE(" dest=(NULL)"); + } + OutTraceE("\n"); + return; +} + +static void BlitTrace(char *label, LPRECT lps, LPRECT lpd, int line) +{ + OutTrace("Blt: %s", label); + if (lps) + OutTrace(" src=(%d,%d)-(%d,%d)",lps->left, lps->top, lps->right, lps->bottom); + else + OutTrace(" src=(NULL)"); + if (lpd) + OutTrace(" dest=(%d,%d)-(%d,%d)",lpd->left, lpd->top, lpd->right, lpd->bottom); + else + OutTrace(" dest=(NULL)"); + OutTrace(" at %d\n", __LINE__); + return; +} + +HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping) +{ + RECT emurect, destrect; + POINT p = {0, 0}; + HRESULT res; + BOOL ToPrim, FromPrim, ToScreen, FromScreen; + //CkArg arg; + + ToPrim=dxw.IsAPrimarySurface(lpdds); + FromPrim=dxw.IsAPrimarySurface(lpddssrc); + ToScreen=ToPrim && !(dxw.dwFlags1 & EMULATESURFACE); + FromScreen=FromPrim && !(dxw.dwFlags1 & EMULATESURFACE); + + CleanRect(&lpdestrect,__LINE__); + CleanRect(&lpsrcrect,__LINE__); + + // log + if(IsTraceD){ + OutTrace("%s: dest=%x%s src=%x%s dwFlags=%x(%s)", + api, lpdds, (ToPrim ? "(PRIM)":""), lpddssrc, (FromPrim ? "(PRIM)":""), dwflags, ExplainBltFlags(dwflags)); + if (lpdestrect) + OutTrace(" destrect=(%d,%d)-(%d,%d)", lpdestrect->left, lpdestrect->top, lpdestrect->right, lpdestrect->bottom); + else + OutTrace(" destrect=(NULL)"); + if (lpsrcrect) + OutTrace(" srcrect=(%d,%d)-(%d,%d)", lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom); + else + OutTrace(" srcrect=(NULL)"); + //if (lpddbltfx) + // OutTrace(" ddbltfx.(destcolor=%x srccolor=%x fillcolor=%x filldepth=%x)", + // lpddbltfx->ddckDestColorkey, + // lpddbltfx->ddckSrcColorkey, + // lpddbltfx->dwFillColor, + // lpddbltfx->dwFillDepth); + OutTrace("\n"); + } + +#ifdef ONEPIXELFIX + if (lpdestrect){ + if ((lpdestrect->top == 0) && (lpdestrect->bottom == dxw.GetScreenHeight() -1)) lpdestrect->bottom = dxw.GetScreenHeight(); + if ((lpdestrect->left == 0) && (lpdestrect->right == dxw.GetScreenWidth() -1)) lpdestrect->right = dxw.GetScreenWidth(); + } + if (lpsrcrect){ + if ((lpsrcrect->top == 0) && (lpsrcrect->bottom == dxw.GetScreenHeight() -1)) lpsrcrect->bottom = dxw.GetScreenHeight(); + if ((lpsrcrect->left == 0) && (lpsrcrect->right == dxw.GetScreenWidth() -1)) lpsrcrect->right = dxw.GetScreenWidth(); + } +#endif + +#define FIXBIGGERRECT 1 +#ifdef FIXBIGGERRECT + if(ToPrim && lpdestrect){ + if((DWORD)lpdestrect->bottom > dxw.GetScreenHeight()) lpdestrect->bottom = dxw.GetScreenHeight(); + if((DWORD)lpdestrect->right > dxw.GetScreenWidth()) lpdestrect->right = dxw.GetScreenWidth(); + } +#endif + + if((dxw.dwFlags1 & EMULATESURFACE) && (dwflags==DDBLT_COLORFILL)){ + OutTraceD("Debug: dwFillDepth=%d, EmuBPP=%d, dwFillColor=%x\n", + lpddbltfx->dwFillDepth, dxw.VirtualPixelFormat.dwRGBBitCount, lpddbltfx->dwFillColor); + //lpddbltfx->dwFillDepth=VirtualScr.dwRGBBitCount; + } + + if(IsDebug){ + if(dwflags & DDBLT_COLORFILL){ + OutTrace("DEBUG: ColorFill=%x depth=%d\n", lpddbltfx->dwFillColor, lpddbltfx->dwFillDepth); + } + if(dwflags & DDBLT_KEYSRC){ + DDCOLORKEY ColorKey; + (*pGetColorKey)(lpddssrc, DDCKEY_SRCBLT, &ColorKey); + OutTrace("DEBUG: KeySrc=%x\n", ColorKey.dwColorSpaceHighValue); + } + if(dwflags & DDBLT_KEYDEST){ + DDCOLORKEY ColorKey; + (*pGetColorKey)(lpddssrc, DDCKEY_DESTBLT, &ColorKey); + OutTrace("DEBUG: KeyDest=%x\n", ColorKey.dwColorSpaceHighValue); + } + if(dwflags & DDBLT_KEYSRCOVERRIDE){ + OutTrace("DEBUG: SrcColorkey=%x\n", lpddbltfx->ddckSrcColorkey.dwColorSpaceHighValue); + OutTrace("DEBUG: KeySrcAlpha=%x depth=%d\n", lpddbltfx->dwAlphaSrcConst, lpddbltfx->dwAlphaSrcConstBitDepth); + } + if(dwflags & DDBLT_KEYDESTOVERRIDE){ + OutTrace("DEBUG: DestColorkey=%x\n", lpddbltfx->ddckDestColorkey.dwColorSpaceHighValue); + OutTrace("DEBUG: KeyDestAlpha=%x depth=%d\n", lpddbltfx->dwAlphaDestConst, lpddbltfx->dwAlphaDestConstBitDepth); + } + } + + // blit to non primary surface + + if(!ToPrim){ + //RECT srcrect, winrect; + RECT srcrect; + // make a working copy of srcrect if not NULL + if (lpsrcrect){ + srcrect=*lpsrcrect; + } + // when blitting from a primary surface on screen (that is in non emulated mode), correct offsets + // You should take account also for scaled primary surfaces, but that would be a hard task: + // a reduced primary surface (in not-emulated mode) would bring quality loss!!! + // v2.1.83: BLITFROMBACKBUFFER mode, let you chose to blit from backbuffer, where the surface size + // is fixed no matter how the window/primary surface is scaled. + // In "The Sims" there is no quality loss, but some scrolling artifact. + if(lpsrcrect && FromScreen){ + if(lpDDSBack && (dxw.dwFlags1 & BLITFROMBACKBUFFER)){ + lpddssrc=lpDDSBack; + srcrect=dxw.GetScreenRect(); + } + else{ + srcrect=dxw.MapWindowRect(lpsrcrect); + } + } + + if (IsDebug) BlitTrace("NOPRIM", lpsrcrect, lpdestrect, __LINE__); + res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx); + // Blitting compressed data may work to screen surfaces only. In this case, it may be worth + // trying blitting directly to lpDDSEmu_Prim: it makes DK2 intro movies working. + switch(res){ + case DDERR_UNSUPPORTED: + if (dxw.dwFlags1 & EMULATESURFACE){ + if (IsDebug) BlitTrace("UNSUPP", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__); + res=(*pBlt)(lpDDSEmu_Prim, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx); + } + break; + case DDERR_SURFACEBUSY: + (*pUnlockMethod(lpdds))(lpdds, NULL); + if (lpddssrc) (*pUnlockMethod(lpddssrc))(lpddssrc, NULL); + if (IsDebug) BlitTrace("BUSY", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__); + res=(*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_WAIT, lpddbltfx); + break; + default: + break; + } + if (res) BlitError(res, &srcrect, lpdestrect, __LINE__); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + return res; + } + + // Blit to primary surface + + if(dxw.HandleFPS()) return DD_OK; + + destrect=dxw.MapWindowRect(lpdestrect); + + if(!(dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER))){ + res=0; + // blit only when source and dest surface are different. Should make ScreenRefresh faster. + if (lpdds != lpddssrc) { + if (dxw.dwFlags2 & SHOWFPSOVERLAY) dxw.ShowFPS(lpddssrc); + if (IsDebug) BlitTrace("PRIM-NOEMU", lpsrcrect, &destrect, __LINE__); + res= (*pBlt)(lpdds, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + } + if(res){ + BlitError(res, lpsrcrect, &destrect, __LINE__); + // Try to handle HDC lock concurrency.... + if(res==DDERR_SURFACEBUSY){ + (*pUnlockMethod(lpdds))(lpdds, NULL); + if (IsDebug) BlitTrace("BUSY", lpsrcrect, &destrect, __LINE__); + res= (*pBlt)(lpdds, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + if (res) BlitError(res, lpsrcrect, &destrect, __LINE__); + } + + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + } + + return res; + } + + // ... else blitting on emulated surface + // Blit/Flip to emulated primary surface + + if(!lpddssrc) { + if (isFlipping){ + // handle the flipping chain ... + lpddssrc=lpDDSBack; + OutTraceD("Flip: setting flip chain to lpdds=%x\n", lpddssrc); + } + } + + if (lpdestrect){ + emurect=*lpdestrect; + } + else{ + // emurect: emulated rect is full surface (dwWidth x dwHeight) + emurect.left = 0; + emurect.top = 0; + emurect.right = dxw.GetScreenWidth(); + emurect.bottom = dxw.GetScreenHeight(); + } + + res=0; + // blit only when source and dest surface are different. Should make ScreenRefresh faster. + if (lpdds != lpddssrc){ + if (IsDebug) BlitTrace("SRC2EMU", &emurect, &destrect, __LINE__); + res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + } + + if (res) { + BlitError(res, lpsrcrect, &emurect, __LINE__); + /* + 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. + */ + if(res==DDERR_UNSUPPORTED){ + if (dxw.dwFlags2 & SHOWFPSOVERLAY) dxw.ShowFPS(lpddssrc); + if (IsDebug) BlitTrace("UNSUPP", &emurect, &destrect, __LINE__); + res=(*pBlt)(lpDDSEmu_Prim, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + if (res) BlitError(res, lpsrcrect, &destrect, __LINE__); + } + + // Try to handle HDC lock concurrency.... + if(res==DDERR_SURFACEBUSY){ + res=(*pUnlockMethod(lpddssrc))(lpddssrc, NULL); + if(res) OutTraceE("Unlock ERROR: err=%x(%s)\n", res, ExplainDDError(res)); + if (IsDebug) BlitTrace("BUSY", &emurect, &destrect, __LINE__); + res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); + if (res) BlitError(res, lpsrcrect, &destrect, __LINE__); + } + + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + return res; + } + + 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) { + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + return res; + } + lpDDSSource = lpDDSEmu_Back; + } + else{ + lpDDSSource = lpdds; + } + + if (dxw.dwFlags2 & SHOWFPSOVERLAY) dxw.ShowFPS(lpDDSSource); + if (IsDebug) BlitTrace("BACK2PRIM", &emurect, &destrect, __LINE__); + res=(*pBlt)(lpDDSEmu_Prim, &destrect, lpDDSSource, &emurect, DDBLT_WAIT, 0); + if (res==DDERR_NOCLIPLIST){ + RenewClipper(lpDD, lpDDSEmu_Prim); + if (IsDebug) BlitTrace("NOCLIP", &emurect, &destrect, __LINE__); + res=(*pBlt)(lpDDSEmu_Prim, &destrect, lpDDSSource, &emurect, DDBLT_WAIT, 0); + } + + if (res) BlitError(res, &emurect, &destrect, __LINE__); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + if (IsDebug) OutTrace("%s: done ret=%x at %d\n", api, res, __LINE__); + return res; +} + +HRESULT WINAPI extFlip(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags) +{ + BOOL IsPrim; + HRESULT res; + + IsPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("Flip: lpdds=%x%s, src=%x, flags=%x(%s)\n", + lpdds, IsPrim?"(PRIM)":"", lpddssrc, dwflags, ExplainFlipFlags(dwflags)); + + if (!IsPrim){ + if(lpddssrc){ + //return 0; + res=(*pFlip)(lpdds, lpddssrc, dwflags); + } + else{ + LPDIRECTDRAWSURFACE lpddsAttached; + DDSCAPS ddsc; + DDSURFACEDESC2 sd; + + sd.dwSize=Set_dwSize_From_Surface(lpdds); + res=lpdds->GetSurfaceDesc((DDSURFACEDESC *)&sd); + if (res) OutTraceD("Flip: GetSurfaceDesc res=%x at %d\n",res, __LINE__); + + // replace these CAPS (good for seven kingdoms II) with same as lpdds surface + //ddsc.dwCaps=DDSCAPS_OFFSCREENPLAIN+DDSCAPS_SYSTEMMEMORY; + ddsc.dwCaps=sd.ddsCaps.dwCaps; + + //res=lpdds->GetAttachedSurface(0,&lpddsAttached); + //res=(*pGetAttachedSurface)(lpdds, &ddsc, &lpddsAttached); + res=lpdds->GetAttachedSurface(&ddsc, &lpddsAttached); + if(res){ + OutTraceE("Flip: GetAttachedSurface ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + res=sBlt("Flip", lpdds, NULL, lpddsAttached, NULL, DDBLT_WAIT, 0, TRUE); + if(res){ + OutTraceE("Flip: Blt ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + } + if(res) OutTraceE("Flip: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + + // emulation to primary surface Flip - you can't flip to window surfaces, + // so you have to replace it with Blt operations. + + //lpdds->GetDDInterface(lpDD); from IDirectDrawSurface2 only + if((dwflags & DDFLIP_WAIT) || (dxw.dwFlags1 & SAVELOAD)) lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKEND , 0); + + if(lpddssrc){ + //res=lpdds->Blt(0, lpddssrc, 0, DDBLT_WAIT, 0); + res=sBlt("Flip", lpdds, NULL, lpddssrc, NULL, DDBLT_WAIT, 0, TRUE); + } + else{ + if (dxw.dwFlags2 & BACKBUFATTACH){ + RECT NullArea; + NullArea.left=NullArea.top=0; + NullArea.bottom=dxw.GetScreenHeight(); + NullArea.right=dxw.GetScreenWidth(); + res=sBlt("Flip", lpdds, NULL, lpDDSBack, &NullArea, DDBLT_WAIT, 0, TRUE); + } + else + res=sBlt("Flip", lpdds, NULL, lpDDSBack, NULL, DDBLT_WAIT, 0, TRUE); + } + + if(res) OutTraceE("Flip: Blt ERROR %x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx) +{ + if ((dxw.dwFlags2 & FULLRECTBLT) && dxw.IsAPrimarySurface(lpdds)){ + lpsrcrect=NULL; + lpdestrect=NULL; + } + + return sBlt("Blt", lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx, FALSE); +} + +HRESULT WINAPI extBltFast(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, + LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans) +{ + // BltFast is supported just on screen surfaces, so it has to be replaced + // by ordinary Blt operation in EMULATESURFACE mode. + // Mind that screen surface doesn't necessarily mean PRIMARY surfaces! + + RECT srcrect, destrect; + DWORD flags = 0; + DDSURFACEDESC2 ddsd; + HRESULT ret; + BOOL ToPrim, FromPrim; + + ToPrim=dxw.IsAPrimarySurface(lpdds); + FromPrim=dxw.IsAPrimarySurface(lpddssrc); + + CleanRect(&lpsrcrect,__LINE__); + + if(IsTraceD){ + OutTrace("BltFast: dest=%x%s src=%x%s dwTrans=%x(%s) (x,y)=(%d,%d) ", + lpdds, ToPrim?"(PRIM)":"", lpddssrc, FromPrim?"(PRIM)":"", dwtrans, ExplainBltFastFlags(dwtrans), dwx, dwy); + if (lpsrcrect) + OutTrace("srcrect=(%d,%d)-(%d,%d)\n", + lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom); + else + OutTrace("srcrect=(NULL)\n"); + } + + // consistency check .... + if (lpsrcrect) + if((lpsrcrect->left >= lpsrcrect->right) || (lpsrcrect->top >= lpsrcrect->bottom)) { + OutTraceD("BltFast: ASSERT bad rect at %d\n", __LINE__); + return 0; + } + + if(dwtrans & DDBLTFAST_WAIT) flags = DDBLT_WAIT; + if(dwtrans & DDBLTFAST_DESTCOLORKEY) flags |= DDBLT_KEYDEST; + if(dwtrans & DDBLTFAST_SRCCOLORKEY) flags |= DDBLT_KEYSRC; + + destrect.left = dwx; + destrect.top = dwy; + if(lpsrcrect){ + destrect.right = destrect.left + lpsrcrect->right - lpsrcrect->left; + destrect.bottom = destrect.top + lpsrcrect->bottom - lpsrcrect->top; + // avoid altering pointed values.... + srcrect=*lpsrcrect; + //ret=lpdds->Blt(&destrect, lpddssrc, &srcrect, flags, 0); + ret=sBlt("BltFast", lpdds, &destrect, lpddssrc, &srcrect, flags, 0, FALSE); + } + else{ + // does it EVER goes through here? NULL is not a valid rect value for BltFast call.... + ddsd.dwSize=Set_dwSize_From_Surface(lpddssrc); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; + ret=lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd); + if (ret){ + OutTraceE("BltFast: GetSurfaceDesc ERROR %x at %d\n", ret, __LINE__); + return 0; + } + destrect.right = destrect.left + ddsd.dwWidth; + destrect.bottom = destrect.top + ddsd.dwHeight; + ret=sBlt("BltFast", lpdds, &destrect, lpddssrc, NULL, flags, 0, FALSE); + } + + return ret; +} + +HRESULT WINAPI extCreatePalette(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY lpddpa, + LPDIRECTDRAWPALETTE *lplpddp, IUnknown *pu) +{ + HRESULT res; + + OutTraceD("CreatePalette: dwFlags=%x(%s)\n", dwflags, ExplainCreatePaletteFlags(dwflags)); + + if(!(dxw.dwFlags1 & EMULATESURFACE)){ + res = (*pCreatePalette)(lpdd, dwflags, lpddpa, lplpddp, pu); + if (res) { + OutTraceD("CreatePalette: res=%x(%s)\n", res, ExplainDDError(res)); + return res; + } + HookDDPalette(lplpddp); + OutTraceD("CreatePalette: GENUINE lpddp=%x\n", *lplpddp); + return res; + } + + res = (*pCreatePalette)(lpdd, dwflags & ~DDPCAPS_PRIMARYSURFACE, lpddpa, lplpddp, pu); + if(res) { + if (res) OutTraceD("CreatePalette: res=%x(%s)\n", res, ExplainDDError(res)); + return res; + } + + HookDDPalette(lplpddp); + + if(dwflags & DDPCAPS_PRIMARYSURFACE){ + mySetPalette(0, 256, lpddpa); + lpDDP = *lplpddp; + } + OutTraceD("CreatePalette: EMULATED lpddp=%x\n", *lplpddp); + return 0; +} + +HRESULT WINAPI extWaitForVerticalBlank(LPDIRECTDRAW lpdd, DWORD dwflags, HANDLE hevent) +{ + static DWORD time = 0; + static BOOL step = 0; + DWORD tmp; + if(!(dxw.dwFlags1 & SAVELOAD)) return (*pWaitForVerticalBlank)(lpdd, dwflags, hevent); + tmp = (*pGetTickCount)(); + if((time - tmp) > 32) time = tmp; + (*pSleep)(time - tmp); + if(step) time += 16; + else time += 17; + step ^= 1; + return 0; +} + +// extGetPalette: To revise completely. Un-hooked right now, to make things working. + +HRESULT WINAPI extGetPalette(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) +{ + HRESULT res; + + OutTraceD("GetPalette: lpdds=%x\n", lpdds); + + // if NO-EMU mode, just proxy the call + if(!(dxw.dwFlags1 & EMULATESURFACE)){ + res=(*pGetPalette)(lpdds, lplpddp); + if (res) OutTraceE("GetPalette: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return 0; + return res; + } + + // in EMU mode, return the global palette ptr + if (lpDDP){ + *lplpddp = lpDDP; + return 0; + } + else { + OutTraceD("GetPalette: ASSERT no lpDDP\n"); + *lplpddp = lpDDP; + return DDERR_NOPALETTEATTACHED; + } +} + +HRESULT WINAPI extSetPalette(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp) +{ + PALETTEENTRY *lpentries; + BOOL isPrim; + HRESULT res; + + dxw.IsGDIPalette=FALSE; + isPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("SetPalette: lpdds=%x%s lpddp=%x\n", lpdds, isPrim?"(PRIM)":"", lpddp); + + res=(*pSetPalette)(lpdds, lpddp); + if(res)OutTraceE("SetPalette: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + + if(dxw.dwFlags1 & EMULATESURFACE){ + OutTraceD("SetPalette: DEBUG emulating palette\n"); + lpDDP = lpddp; + + if(lpddp){ + HRESULT res2; + lpentries = (LPPALETTEENTRY)PaletteEntries; + res2=lpddp->GetEntries(0, 0, 256, lpentries); + if(res2) OutTraceE("SetPalette: GetEntries ERROR res=%x(%s)\n", res2, ExplainDDError(res2)); + mySetPalette(0, 256, lpentries); + } + res=0; + } + + return res; +} + +HRESULT WINAPI extSetEntries(LPDIRECTDRAWPALETTE lpddp, DWORD dwflags, DWORD dwstart, DWORD dwcount, LPPALETTEENTRY lpentries) +{ + HRESULT res; + + dxw.IsGDIPalette=FALSE; + OutTraceD("SetEntries: dwFlags=%x, start=%d, count=%d\n", //GHO: added trace infos + dwflags, dwstart, dwcount); + + res = (*pSetEntries)(lpddp, dwflags, dwstart, dwcount, lpentries); + if(res) OutTraceE("SetEntries: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + + if(!(dxw.dwFlags1 & EMULATESURFACE) || lpDDP != lpddp){ + return res; + } + + if ((dwstart + dwcount > 256) || (dwstart<0)){ + dwcount=256; + dwstart=0; + OutTraceD("SetEntries: ASSERT start+count > 256\n"); + } + + mySetPalette(dwstart, dwcount, lpentries); + + // GHO: needed for fixed rect and variable palette animations, + // e.g. dungeon keeper loading screen, Warcraft II splash, ... + // GHO: but refreshing cause flickering when GDI was used without updating the primary surface + // e.g. Tomb Raider 2 intro titles + if ((dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags2 & NOPALETTEUPDATE)) dxw.ScreenRefresh(); + return 0; +} + +HRESULT WINAPI extSetClipper(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpddc) +{ + HRESULT res; + BOOL isPrim; + isPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("SetClipper: lpdds=%x%s lpddc=%x\n", lpdds, isPrim?"(PRIM)":"", lpddc); + + // v2.1.84: SUPPRESSCLIPPING flag - improves "Monopoly Edition 3D" where continuous + // clipping ON & OFF affects blitting on primary surface. + if(dxw.dwFlags1 & SUPPRESSCLIPPING) return 0; + + if(dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER)){ + if ((isPrim && lpDDSEmu_Prim) || + ((lpdds == lpDDSBack) && lpDDSEmu_Back)){ + OutTraceD("SetClipper: skip primary/backbuffer lpdds=%x\n", lpdds); + res=0; + } + else + res=(*pSetClipper)(lpdds, lpddc); + } + else + res=(*pSetClipper)(lpdds, lpddc); + + if (res) + OutTraceE("SetClipper: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extLock(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDIRECTDRAWSURFACE lpdds2, DWORD flags, HANDLE hEvent) +{ + HRESULT res; + BOOL IsPrim; + + IsPrim=dxw.IsAPrimarySurface(lpdds); + + if(IsTraceD){ + OutTrace("Lock: lpdds=%x%s flags=%x(%s) lpdds2=%x", + lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpdds2); + if (lprect) + OutTrace(" rect=(%d,%d)-(%d,%d)\n", lprect->left, lprect->top, lprect->right, lprect->bottom); + else + OutTrace(" rect=(NULL)\n"); + } + + res=(*pLock)(lpdds, lprect, lpdds2, flags, hEvent); + if(res==DDERR_SURFACEBUSY){ // v70: fix for "Ancient Evil" + (*pUnlockMethod(lpdds))(lpdds, NULL); + res = (*pLock)(lpdds, lprect, lpdds2, flags, hEvent); + OutTraceD("Lock RETRY: ret=%x(%s)\n", res, ExplainDDError(res)); + } + if(res) OutTraceE("Lock ERROR: ret=%x(%s)\n", res, ExplainDDError(res)); + DumpSurfaceAttributes((LPDDSURFACEDESC)lpdds2, "[Locked]" , __LINE__); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + + // shouldn't happen.... if hooked to non primary surface, just call regular method. + // it happens in "Deadlock 2" backbuffer surface!!! + return res; +} + +HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRAWSURFACE lpdds, LPRECT lprect) +{ + HRESULT res; + //RECT screen, rect; + BOOL IsPrim; + + IsPrim=dxw.IsAPrimarySurface(lpdds); + + if ((dxversion == 4) && lprect) CleanRect(&lprect,__LINE__); + + if(IsTraceD){ + OutTrace("Unlock: lpdds=%x%s ", lpdds, (IsPrim ? "(PRIM)":"")); + if (dxversion == 4){ + if (lprect){ + OutTrace("rect=(%d,%d)-(%d,%d)\n", lprect->left, lprect->top, lprect->right, lprect->bottom); + } + else + OutTrace("rect=(NULL)\n"); + } + else + OutTrace("lpvoid=%x\n", lprect); + } + + res=(*pUnlock)(lpdds, lprect); + 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); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + return res; +} + +HRESULT WINAPI extUnlock4(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect) +{ + return extUnlock(4, pUnlock4, lpdds, lprect); +} + +HRESULT WINAPI extUnlock1(LPDIRECTDRAWSURFACE lpdds, LPVOID lpvoid) +{ + return extUnlock(1, (Unlock4_Type)pUnlock1, lpdds, (LPRECT)lpvoid); +} + +/* to do: instead of calling GDI GetDC, try to map GetDC with Lock and +ReleaseDC with Unlock, returning the surface memory ptr (???) as HDC +and avoiding the consistency check performed by surface::GetDC (why +should it bother if the screen is 32BPP and the surface is not??? */ + +HRESULT WINAPI extGetDC(LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC) +{ + HRESULT res; + BOOL IsPrim; + RECT client; + + IsPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("GetDC: lpdss=%x%s\n",lpdds, IsPrim?"(PRIM)":""); + res=(*pGetDC)(lpdds, pHDC); + + if (res==DDERR_CANTCREATEDC && + (dxw.dwFlags1 & EMULATESURFACE) && + dxw.VirtualPixelFormat.dwRGBBitCount==8) { + // for 8BPP palettized surfaces, connect them to either the ddraw emulated palette or the GDI emulated palette + OutTraceD("GetDC: adding 8BPP palette to surface lpdds=%x\n", lpdds); + if(lpDDP==NULL){ + // should link here to the GDI palette? See Hyperblade.... + dxw.palNumEntries=256; + res=(*pCreatePalette)(lpDD, DDPCAPS_ALLOW256|DDPCAPS_8BIT|DDPCAPS_INITIALIZE, dxw.palPalEntry, &lpDDP, NULL); + if (res) { + OutTraceE("CreateSurface: CreatePalette ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + } + res=(*pSetPalette)(lpdds, lpDDP); + if (res) { + OutTraceE("CreateSurface: SetPalette ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + // retry .... + res=(*pGetDC)(lpdds, pHDC); + } + + OutTraceD("GetDC: res=%x hdc=%x\n",res, *pHDC); + return res; +} + +HRESULT WINAPI extReleaseDC(LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc) +{ + HRESULT res; + BOOL IsPrim; + + IsPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("ReleaseDC: lpdss=%x%s hdc=%x\n",lpdds, IsPrim?"(PRIM)":"", hdc); + res=(*pReleaseDC)(lpdds,hdc); + if((IsPrim) && (dxw.dwFlags1 & EMULATESURFACE)) sBlt("ReleaseDC", lpdds, NULL, lpdds, NULL, 0, NULL, FALSE); + if (res) OutTraceE("ReleaseDC: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + + return res; +} + + +HRESULT WINAPI extFlipToGDISurface(LPDIRECTDRAW lpdd) +{ + //HRESULT res; + + OutTraceD("FlipToGDISurface: lpdd=%x\n", lpdd); + // to revise: so far, it seems the best thing to do is NOTHING, just return 0. + //res=(*pFlipToGDISurface)(lpdd); + //if (res) OutTraceE("FlipToGDISurface: ERROR res=%x(%s), skipping\n", res, ExplainDDError(res)); + // pretend you flipped anyway.... + return 0; +} + +HRESULT WINAPI extGetGDISurface(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE *w) +{ + int res; + res=(*pGetGDISurface)(lpdd, w); + if (res) { + OutTraceE("GetGDISurface: ERROR lpdd=%x res=%x(%s)\n", lpdd, res, ExplainDDError(res)); + } + else { + OutTraceD("GetGDISurface: PROXED lpdd=%x w=%x\n", lpdd, *w); + } + + return res; +} + +// debug function to dump all video modes queried by the DirectDrav::EnumDisplayModes method + +HRESULT WINAPI EnumModesCallbackDumper(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) +{ + OutTrace("EnumModesCallback:\n"); + OutTrace("\tdwSize=%d\n", lpDDSurfaceDesc->dwSize); + OutTrace("\tdwFlags=%x(%s)\n", lpDDSurfaceDesc->dwFlags, ExplainFlags(lpDDSurfaceDesc->dwFlags)); + OutTrace("\tdwHeight x dwWidth=(%d,%d)\n", lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->dwWidth); + OutTrace("\tlPitch=%d\n", lpDDSurfaceDesc->lPitch); + OutTrace("\tdwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount); + OutTrace("\tdwRefreshRate=%d\n", lpDDSurfaceDesc->dwRefreshRate); + OutTrace("\tlpSurface=%x\n", lpDDSurfaceDesc->lpSurface); + OutTrace("\tddpfPixelFormat.dwSize=%D\n", lpDDSurfaceDesc->ddpfPixelFormat.dwSize); + OutTrace("\tddpfPixelFormat.dwFlags=%x\n", lpDDSurfaceDesc->ddpfPixelFormat.dwFlags); + OutTrace("\tddpfPixelFormat.dwRGBBitCount=%d\n", lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount); + OutTrace("\tddpfPixelFormat.dwARGBBitMask=(%x,%x,%x,%x)\n", + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask, + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask, + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask, + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask); + return DDENUMRET_OK; +} + +typedef HRESULT (WINAPI *EnumModesCallback_Type)(LPDDSURFACEDESC, LPVOID); +typedef struct {LPVOID lpContext; EnumModesCallback_Type lpCallback; } NewContext_Type; + +HRESULT WINAPI myEnumModesFilter(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) +{ + if (IsDebug) EnumModesCallbackDumper(lpDDSurfaceDesc, NULL); + + if (dxw.dwFlags1 & PREVENTMAXIMIZE){ + // if PREVENTMAXIMIZE is set, don't let the caller know about forbidden screen settings. + if((lpDDSurfaceDesc->dwHeight > dxw.GetScreenHeight()) || + (lpDDSurfaceDesc->dwWidth > dxw.GetScreenWidth())){ + OutTraceD("EnumDisplayModes: skipping screen size=(%d,%d)\n", lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->dwWidth); + return DDENUMRET_OK; + } + } + + // tricky part: in 16BPP color depth let the callback believe that the pixel encoding + // is actually the one implemented in the emulation routines. + // should it fix also the other color depths? + + switch(lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount){ + case 8: + case 16: + case 24: + case 32: + FixPixelFormat(lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, &lpDDSurfaceDesc->ddpfPixelFormat); + return (*((NewContext_Type *)lpContext)->lpCallback)(lpDDSurfaceDesc, ((NewContext_Type *)lpContext)->lpContext); + break; + } + return DDENUMRET_OK; +} + +HRESULT WINAPI extEnumDisplayModes(EnumDisplayModes1_Type pEnumDisplayModes, LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK cb) +{ + HRESULT res; + OutTraceP("EnumDisplayModes(D): lpdd=%x flags=%x lpddsd=%x callback=%x\n", lpdd, dwflags, lpddsd, cb); + + // note: extEnumDisplayModes serves both the EnumDisplayModes and EnumDisplayModes2 interfaces: + // they differ for the lpddsd argument that should point to either DDSURFACEDESC or DDSURFACEDESC2 + // structures, but unification is possible if the lpddsd->dwSize is properly set and is left untouched. + + if(dxw.dwFlags1 & EMULATESURFACE){ +#if 0 + struct {int w; int h;}SupportedRes[5]= {(320,240),(640,480),(800,600),(1024,1200),(0,0)}; + int SupportedDepths[5]={8,16,24,32,0}; + int ResIdx, DepthIdx, ColorDepth; + DDSURFACEDESC2 EmuDesc; + + //if (1) res=(*pEnumDisplayModes)(lpdd, dwflags, lpddsd, lpContext, EnumModesCallbackDumper); + + EmuDesc.dwRefreshRate = 0; + EmuDesc.ddpfPixelFormat.dwFlags = DDPF_RGB; + if (lpddsd) EmuDesc.dwSize=lpddsd->dwSize; // sizeof either DDSURFACEDESC or DDSURFACEDESC2 !!! + else EmuDesc.dwSize = sizeof(DDSURFACEDESC2); + EmuDesc.dwFlags=DDSD_PIXELFORMAT|DDSD_REFRESHRATE|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH; + for (ResIdx=0; ResIdx<4; ResIdx++){ + EmuDesc.dwHeight=SupportedRes[ResIdx].h; + EmuDesc.dwWidth=SupportedRes[ResIdx].w; + EmuDesc.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); + EmuDesc.ddpfPixelFormat.dwFlags=DDPF_RGB; + for (DepthIdx=0; DepthIdx<4; DepthIdx++) { + ColorDepth=SupportedDepths[DepthIdx]; + EmuDesc.ddpfPixelFormat.dwRGBBitCount=ColorDepth; + EmuDesc.lPitch=(ColorDepth/8) * SupportedRes[ResIdx].w; + switch (SupportedDepths[DepthIdx]){ + case 8: + EmuDesc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8; + break; + case 16: + if (dxw.dwFlags1 & USERGB565){ + EmuDesc.ddpfPixelFormat.dwRBitMask = 0xf800; // Grim Fandango + EmuDesc.ddpfPixelFormat.dwGBitMask = 0x07e0; + EmuDesc.ddpfPixelFormat.dwBBitMask = 0x001f; + EmuDesc.ddpfPixelFormat.dwRGBAlphaBitMask = 0x0000; + } + else { + EmuDesc.ddpfPixelFormat.dwRBitMask = 0x7c00; + EmuDesc.ddpfPixelFormat.dwGBitMask = 0x03e0; + EmuDesc.ddpfPixelFormat.dwBBitMask = 0x001f; + EmuDesc.ddpfPixelFormat.dwRGBAlphaBitMask = 0x8000; + } + break; + case 24: + EmuDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000; + EmuDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00; + EmuDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF; + EmuDesc.ddpfPixelFormat.dwRGBAlphaBitMask = 0x00000000; + break; + case 32: + EmuDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000; + EmuDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00; + EmuDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF; + EmuDesc.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000; + break; + } + res=(*cb)((LPDDSURFACEDESC)&EmuDesc, lpContext); + if(res==DDENUMRET_CANCEL) break; + } + if(res==DDENUMRET_CANCEL) break; + } + OutTraceD("EnumDisplayModes(D): cycled to res=%d size=(%d,%d)\n", + SupportedDepths[DepthIdx], SupportedRes[ResIdx].w, SupportedRes[ResIdx].h); +#else + NewContext_Type NewContext; + NewContext.lpContext=lpContext; + NewContext.lpCallback=cb; + + res=(*pEnumDisplayModes)(lpdd, dwflags, lpddsd, &NewContext, myEnumModesFilter); +#endif + } + else{ + // proxy the call + res=(*pEnumDisplayModes)(lpdd, dwflags, lpddsd, lpContext, cb); + } + if(res) OutTraceD("EnumDisplayModes(D): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extEnumDisplayModes1(LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK cb) +{ + return extEnumDisplayModes(pEnumDisplayModes1, lpdd, dwflags, lpddsd, lpContext, cb); +} + +HRESULT WINAPI extEnumDisplayModes4(LPDIRECTDRAW lpdd, DWORD dwflags, LPDDSURFACEDESC2 lpddsd, LPVOID lpContext, LPDDENUMMODESCALLBACK2 cb) +{ + return extEnumDisplayModes((EnumDisplayModes1_Type)pEnumDisplayModes4, lpdd, dwflags, (LPDDSURFACEDESC)lpddsd, lpContext, (LPDDENUMMODESCALLBACK)cb); +} + +HRESULT WINAPI extDuplicateSurface(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE s, LPDIRECTDRAWSURFACE *sp) +{ + int res; + res=(*pDuplicateSurface)(lpdd, s, sp); + if (res) + OutTraceE("DuplicateSurface: ERROR dds=%x res=%x(%s)\n", s, res, ExplainDDError(res)); + else + OutTraceD("DuplicateSurface: dds=%x pdds=%x\n", s, *sp); + return res; +} + +HRESULT WINAPI extGetPixelFormat(LPDIRECTDRAWSURFACE lpdds, LPDDPIXELFORMAT p) +{ + DWORD res; + BOOL IsPrim; + + IsPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("GetPixelFormat: lpdds=%x%s\n", lpdds, IsPrim?"(PRIM)":""); + res=(*pGetPixelFormat)(lpdds, p); + if(res){ + OutTraceE("GetPixelFormat: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + } + else{ + OutTraceD("GetPixelFormat: Flags=%x(%s) FourCC=%x BitCount=%d RGBA=(%x,%x,%x,%x)\n", + p->dwFlags, ExplainPixelFormatFlags(p->dwFlags), p->dwFourCC, p->dwRGBBitCount, + p->dwRBitMask, p->dwGBitMask, p->dwBBitMask, p->dwRGBAlphaBitMask ); + } + + if ((dxw.dwFlags1 & EMULATESURFACE) && IsPrim){ + p->dwFlags = dxw.VirtualPixelFormat.dwFlags; + p->dwRGBBitCount= dxw.VirtualPixelFormat.dwRGBBitCount; + p->dwRBitMask = dxw.VirtualPixelFormat.dwRBitMask; + p->dwGBitMask = dxw.VirtualPixelFormat.dwGBitMask; + p->dwBBitMask = dxw.VirtualPixelFormat.dwBBitMask; + p->dwRGBAlphaBitMask = dxw.VirtualPixelFormat.dwRGBAlphaBitMask; + OutTraceD("GetPixelFormat: EMULATED BitCount=%d RGBA=(%x,%x,%x,%x)\n", + p->dwRGBBitCount, p->dwRBitMask, p->dwGBitMask, p->dwBBitMask, p->dwRGBAlphaBitMask ); + } + + return res; +} + +HRESULT WINAPI extTestCooperativeLevel(LPDIRECTDRAW lpdd) +{ + HRESULT res; + res=(*pTestCooperativeLevel)(lpdd); + if(IsDebug) + OutTrace("TestCooperativeLevel: lpdd=%x res=%x(%s)\n", lpdd, res, ExplainDDError(res)); + return DD_OK; +} + +HRESULT WINAPI extReleaseS(LPDIRECTDRAWSURFACE lpdds) +{ + HRESULT res; + BOOL IsPrim; + BOOL IsClosed; + OutTraceD("Release(S): DEBUG - lpdds=%x\n", lpdds); + + IsPrim=dxw.IsAPrimarySurface(lpdds); + + // handling of service closed surfaces + IsClosed=0; + __try{ + HRESULT dw=(DWORD)(*pReleaseS); + if ((dw & 0xF0000000) == 0xF0000000) IsClosed=1; + if ((*(DWORD *)lpdds & 0xF0000000) == 0xF0000000) IsClosed=1; + if(IsClosed) OutTraceE("Release(S): ASSERT got closed surface lpdds=%x\n", lpdds); + } + __except (EXCEPTION_EXECUTE_HANDLER){ + OutTraceE("Exception at %d\n",__LINE__); + IsClosed=1; + }; + + res = IsClosed ? 0 :(*pReleaseS)(lpdds); + + OutTraceD("Release(S): lpdds=%x%s refcount=%d\n", lpdds, IsPrim?"(PRIM)":"", res); + if (res==0) { // common precondition + // when releasing primary surface, erase clipping region + if(IsPrim && (dxw.dwFlags1 & CLIPCURSOR)) dxw.EraseClipCursor(); + // if primary, clean primay surface list + if(IsPrim) dxw.UnmarkPrimarySurface(lpdds); + // service surfaces cleanup + if(lpdds==lpDDSBack) { + OutTraceD("Release(S): NOT Clearing lpDDSBack pointer\n"); + //lpDDSBack=NULL; + } + if (dxw.dwFlags1 & EMULATESURFACE) { + if(lpdds==lpDDSEmu_Prim) { + OutTraceD("Release(S): Clearing lpDDSEmu_Prim pointer\n"); + lpDDSEmu_Prim=NULL; + } + if(lpdds==lpDDSEmu_Back) { + OutTraceD("Release(S): Clearing lpDDSEmu_Back pointer\n"); + lpDDSEmu_Back=NULL; + } + if(lpdds==dxw.lpDDSPrimHDC) { + OutTraceD("Release(S): Clearing lpDDSPrimHDC pointer\n"); + dxw.ResetPrimarySurface(); + } + } + } + return res; +} + +HRESULT WINAPI extSetColorKey(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) +{ + HRESULT res; + BOOL IsPrim; + IsPrim=dxw.IsAPrimarySurface(lpdds); + if(IsTraceD){ + OutTrace("SetColorKey: lpdds=%x%s flags=%x(%s) ", + lpdds, (IsPrim ? "(PRIM)" : ""), flags, ExplainColorKeyFlag(flags)); + if (lpDDColorKey) + OutTrace("colors=(L:%x,H:%x)\n",lpDDColorKey->dwColorSpaceLowValue, lpDDColorKey->dwColorSpaceHighValue); + else + OutTrace("colors=(NULL)\n"); + } + + res=(*pSetColorKey)(lpdds, flags, lpDDColorKey); + if(res) OutTraceE("SetColorKey: ERROR flags=%x lpdds=%x res=%x(%s)\n", + flags, lpdds, res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extGetColorKey(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) +{ + HRESULT res; + BOOL IsPrim; + IsPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("GetColorKey(S): lpdds=%x%s flags=%x(%s)\n", + lpdds, (IsPrim ? "(PRIM)" : ""), flags, ExplainColorKeyFlag(flags)); + res=(*pGetColorKey)(lpdds, flags, lpDDColorKey); + if(res) + OutTraceE("GetColorKey: ERROR lpdds=%x flags=%x res=%x(%s)\n", lpdds, flags, res, ExplainDDError(res)); + else + OutTraceD("GetColorKey: colors=(L:%x,H:%x)\n", + lpdds, lpDDColorKey->dwColorSpaceLowValue, lpDDColorKey->dwColorSpaceHighValue); + return res; +} + +HRESULT WINAPI extEnumAttachedSurfaces(LPDIRECTDRAWSURFACE lpdds, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) +{ + HRESULT res; + BOOL IsPrim; + + IsPrim=dxw.IsAPrimarySurface(lpdds); + + OutTraceD("EnumAttachedSurfaces: lpdds=%x%s Context=%x Callback=%x\n", + lpdds, (IsPrim ? "(PRIM)":""), lpContext, lpEnumSurfacesCallback); + + if (IsPrim){ + // A Primary surface has not backbuffer attached surfaces actually, + // so don't rely on ddraw and call the callback function directly. + // Needed to make Nox working. + DDSURFACEDESC2 ddsd; + // first, call hooked function + res=(*pEnumAttachedSurfaces)(lpdds, lpContext, lpEnumSurfacesCallback); + if (res) + OutTraceE("EnumAttachedSurfaces: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(lpDDSBack){ + ddsd.dwSize=Set_dwSize_From_Surface(lpDDSBack); + res=lpDDSBack->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd); + if(res){ + OutTraceE("EnumAttachedSurfaces: GetSurfaceDesc ERROR %x(%s)\n", + res, ExplainDDError(res)); + return res; + } + res=(lpEnumSurfacesCallback)(lpDDSBack, (LPDDSURFACEDESC)&ddsd, lpContext); + OutTraceD("EnumSurfacesCallback: on DDSBack res=%x(%s)\n", res, ExplainDDError(res)); + } + res=0; // for Black Dahlia + } + else { + res=(*pEnumAttachedSurfaces)(lpdds, lpContext, lpEnumSurfacesCallback); + if (res) + OutTraceE("EnumAttachedSurfaces: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + } + return res; +} + +HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd) +{ + HRESULT res; + BOOL IsPrim; + + // You can add backbuffers to primary surfaces to join the flipping chain, but you can't do that + // to an emulated primary surface, and you receive a DDERR_CANNOTATTACHSURFACE error code. + // In that case, it's worth to try to emulate the attach, and since the Flip method is emulated, + // just remember this for further handling in the Flip operation. + // But beware: this holds to BACKBUFFER surfaces only, and NOT for attached ZBUFFERS or similar! + + IsPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("AddAttachedSurface: lpdds=%x%s lpddsadd=%x\n", lpdds, IsPrim?"(PRIM)":"", lpddsadd); + res=(*pAddAttachedSurface)(lpdds, lpddsadd); + if (res) { + HRESULT sdres; + DDSURFACEDESC2 sd; + sd.dwSize=Set_dwSize_From_Surface(lpddsadd); + sdres=lpddsadd->GetSurfaceDesc((DDSURFACEDESC *)&sd); + if (sdres) + OutTraceE("AddAttachedSurface: GetSurfaceDesc ERROR res=%x at %d\n", sdres, __LINE__); + else + OutTraceD("AddAttachedSurface: GetSurfaceDesc dwCaps=%x(%s)\n", + sd.ddsCaps.dwCaps, ExplainDDSCaps(sd.ddsCaps.dwCaps)); + if (IsPrim){ + if (sd.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) + if ((dxw.dwFlags1 & EMULATESURFACE) && (res==DDERR_CANNOTATTACHSURFACE) || + (res==DDERR_NOEXCLUSIVEMODE)) + OutTraceD("AddAttachedSurface: emulating BACKBUFFER attach on PRIMARY\n"); + lpDDSBack=lpddsadd; + if (pAddRefS) (*pAddRefS)(lpdds); + res=DD_OK; + } + else if (lpdds == lpDDSBack) { + // v2.02.13: emulate ZBUFFER attach to backbuffer: do nothing and return OK + // this trick makes at least "Nocturne" work also in emulated mode when hardware acceleration + // is set in the game "Options" menu. + if (sd.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) // DDSCAPS_BACKBUFFER for double buffering ??? + if ((dxw.dwFlags1 & EMULATESURFACE) && (res==DDERR_CANNOTATTACHSURFACE)){ + OutTraceD("AddAttachedSurface: emulating ZBUFFER attach on BACKBUFFER\n"); + if (pAddRefS) (*pAddRefS)(lpdds); + res=DD_OK; + } + } + } + if (res) OutTraceE("AddAttachedSurface: ERROR %x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extDeleteAttachedSurface(LPDIRECTDRAWSURFACE lpdds, DWORD dwflags, LPDIRECTDRAWSURFACE lpddsdel) +{ + HRESULT res; + OutTraceD("DeleteAttachedSurface: lpdds=%x flags=%x lpddsdel=%x\n", lpdds, dwflags, lpddsdel); + res=(*pDeleteAttachedSurface)(lpdds, dwflags, lpddsdel); + if(res) OutTraceE("DeleteAttachedSurface: ERROR %x(%s)\n", res, ExplainDDError(res)); + if (res && (lpddsdel==lpDDSBack)){ + OutTraceD("DeleteAttachedSurface: emulating surface detach lpdds=%x\n", lpddsdel); + lpDDSBack->Release(); // GHO TRY + lpDDSBack=NULL; + res=0; + } + return res; +} + +HRESULT WINAPI cbDump(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) +{ + OutTraceD("EnumDisplayModes: CALLBACK lpdds=%x Context=%x Caps=%x(%s)\n", + lpDDSurfaceDesc, lpContext, + lpDDSurfaceDesc->ddsCaps.dwCaps, ExplainDDSCaps(lpDDSurfaceDesc->ddsCaps.dwCaps)); + return 1; +} + +HRESULT WINAPI extGetCapsS(int dxInterface, GetCapsS_Type pGetCapsS, LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS caps) +{ + HRESULT res; + BOOL IsPrim; + IsPrim=dxw.IsAPrimarySurface(lpdds); + OutTraceD("GetCaps(S%d): lpdds=%x%s, lpcaps=%x\n", dxInterface, lpdds, IsPrim?"(PRIM)":"", caps); + res=(*pGetCapsS)(lpdds, caps); + if(res) + OutTraceE("GetCaps(S%d): ERROR %x(%s)\n", dxInterface, res, ExplainDDError(res)); + else + OutTraceD("GetCaps(S%d): lpdds=%x caps=%x(%s)\n", dxInterface, lpdds, caps->dwCaps, ExplainDDSCaps(caps->dwCaps)); + + if (!(dxw.dwFlags1 & EMULATESURFACE)) return res; + + // note: C&C95 Gold Edition includes a check for the primary surface NOT having + // DDSCAPS_SYSTEMMEMORY bit set + + if(IsPrim) caps->dwCaps = dxw.dwPrimarySurfaceCaps; + // v2.1.83: add FLIP capability (Funtraks a.k.a. Ignition) + // v2.2.26: add VIDEOMEMORY|LOCALVIDMEM capability (Alien Cabal 95 - partial fix) + if(dxw.dwFlags1 & EMULATESURFACE) { + if ((lpdds == lpDDSBack) || (caps->dwCaps & DDSCAPS_ZBUFFER)) { + caps->dwCaps |= DDSCAPS_FLIP|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM; + caps->dwCaps &= ~DDSCAPS_SYSTEMMEMORY; + } + } + + OutTraceD("GetCaps(S%d): lpdds=%x FIXED caps=%x(%s)\n", dxInterface, lpdds, caps->dwCaps, ExplainDDSCaps(caps->dwCaps)); + return res; +} + +HRESULT WINAPI extGetCaps1S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS caps) +{ + return extGetCapsS(1, pGetCaps1S, lpdds, caps); +} +HRESULT WINAPI extGetCaps2S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS caps) +{ + return extGetCapsS(2, pGetCaps2S, lpdds, caps); +} +HRESULT WINAPI extGetCaps3S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS caps) +{ + return extGetCapsS(3, pGetCaps3S, lpdds, caps); +} +HRESULT WINAPI extGetCaps4S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS2 caps) +{ + return extGetCapsS(4, (GetCapsS_Type)pGetCaps4S, lpdds, (LPDDSCAPS)caps); +} +HRESULT WINAPI extGetCaps7S(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS2 caps) +{ + return extGetCapsS(7, (GetCapsS_Type)pGetCaps7S, lpdds, (LPDDSCAPS)caps); +} + +ULONG WINAPI extReleaseD(LPDIRECTDRAW lpdd) +{ + ULONG ref; + int dxversion; + BOOL IsClosed; + + dxversion=lpddHookedVersion(lpdd); // must be called BEFORE releasing the session!! + OutTraceD("Release(D): lpdd=%x\n", lpdd); + + IsClosed=0; + __try{ + HRESULT dw=(DWORD)(*pReleaseD); + if ((dw & 0xF0000000) == 0xF0000000) IsClosed=1; + if ((*(DWORD *)lpdd & 0xF0000000) == 0xF0000000) IsClosed=1; + if(IsClosed) OutTraceE("Release(D): ASSERT got closed session lpdd=%x\n", lpdd); + } + __except (EXCEPTION_EXECUTE_HANDLER){ + OutTraceE("Exception at %d\n",__LINE__); + IsClosed=1; + }; + + ref=IsClosed?0:(*pReleaseD)(lpdd); + + if (lpdd == lpServiceDD) { // v2.1.87: fix for Dungeon Keeper II + OutTraceD("Release(D): service lpdd=%x version=%d\n", lpdd, dxversion); + if((dxversion<4) && (ref==0)){ + // directdraw old versions automatically free all linked objects when the parent session is closed. + OutTraceD("Release(D): RefCount=0 - service object RESET condition\n"); + lpDDSEmu_Prim=NULL; + lpDDSEmu_Back=NULL; + lpDDC=NULL; + lpDDSBack=NULL; + lpDDP=NULL; + lpServiceDD=NULL; // v2.02.11 + } + } + + OutTraceD("Release(D): lpdd=%x ref=%x\n", lpdd, ref); + return ref; +} + +HRESULT WINAPI extCreateClipper(LPDIRECTDRAW lpdd, DWORD dwflags, + LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter) +{ + HRESULT res; + OutTraceD("CreateClipper: lpdd=%x flags=%x\n", lpdd, dwflags); + res=(*pCreateClipper)(lpdd, dwflags, lplpDDClipper, pUnkOuter); + if(res) { + OutTraceE("CreateClipper: ERROR res=%x(%s)\n", lpdd, res, ExplainDDError(res)); + return res; + } + HookDDClipper(lplpDDClipper); + return res; +} + +HRESULT WINAPI extReleaseC(LPDIRECTDRAWCLIPPER lpddClip) +{ + ULONG ref; + BOOL IsClosed; + + // handling of service closed clipper + IsClosed=0; + __try{DWORD dw=(DWORD)(*pReleaseC);} + __except (EXCEPTION_EXECUTE_HANDLER){ + OutTraceD("Exception at %d\n",__LINE__); + IsClosed=1; + }; + + // avoid crashing.... + ref= IsClosed ? 0 : (*pReleaseC)(lpddClip); + + OutTraceD("Release(C): PROXED lpddClip=%x ref=%x\n", lpddClip, ref); + if (lpddClip==lpDDC && ref==0) { + OutTraceD("Release(C): Clearing lpDDC pointer\n"); + lpDDC=NULL; + } + return ref; +} + +HRESULT WINAPI extGetSurfaceDesc(GetSurfaceDesc_Type pGetSurfaceDesc, LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd) +{ + HRESULT res; + BOOL IsPrim, IsFixed; + IsPrim=dxw.IsAPrimarySurface(lpdds); + IsFixed=FALSE; + + if (!pGetSurfaceDesc) { + OutTraceE("GetSurfaceDesc: ERROR no hooked function\n"); + return DDERR_INVALIDPARAMS; + } + + res=(*pGetSurfaceDesc)(lpdds, lpddsd); + OutTraceD("GetSurfaceDesc: %slpdds=%x%s res=%x(%s)\n", + res?"ERROR ":"", lpdds, IsPrim?"(PRIM)":"", res, ExplainDDError(res)); + if(res) { + OutTraceE("GetSurfaceDesc: ERROR err=%d(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + + LogSurfaceAttributes(lpddsd, "GetSurfaceDesc", __LINE__); + + if (IsPrim) { + IsFixed=TRUE; + // expose original caps + if (dxw.dwFlags1 & EMULATESURFACE) { + lpddsd->ddpfPixelFormat = dxw.VirtualPixelFormat; + } + //lpddsd->ddsCaps.dwCaps=dxw.dwPrimarySurfaceCaps; + // V2.1.84: better .OR. the capabilities (you don't ask but get for DDSCAPS_VISIBLE...) + lpddsd->ddsCaps.dwCaps |= dxw.dwPrimarySurfaceCaps; + lpddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER; // you never know.... + lpddsd->dwBackBufferCount=dxw.dwBackBufferCount; + lpddsd->dwHeight=dxw.GetScreenHeight(); + lpddsd->dwWidth=dxw.GetScreenWidth(); + } + + if((dxw.dwFlags1 & EMULATESURFACE) && + (dxw.dwFlags1 & SWITCHVIDEOMEMORY) && + (lpddsd->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)){ + IsFixed=TRUE; + lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; + lpddsd->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; + } + + if (dxw.dwFlags3 & SAVECAPS) { + if (PopCaps((LPDDSURFACEDESC2)lpddsd, lpdds)) IsFixed=TRUE; + if (lpddsd->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) lpddsd->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM; + } + + //if(dxw.dwFlags1 & EMULATESURFACE) lpddsd->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE; + if(dxw.dwFlags1 & EMULATESURFACE) lpddsd->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM; + + if(IsFixed) DumpSurfaceAttributes(lpddsd, "GetSurfaceDesc [FIXED]", __LINE__); + return DD_OK; +} + +// Beware: despite the surface version, some game (The Sims!!!) intentionally uses a different dwSize, so that +// you shouldn't reset the value + +HRESULT WINAPI extGetSurfaceDesc1(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd) +{ + if (!lpddsd->dwSize) lpddsd->dwSize = sizeof(DDSURFACEDESC); // enforce correct dwSize value + switch(lpddsd->dwSize){ + case sizeof(DDSURFACEDESC): + if (pGetSurfaceDesc1) return extGetSurfaceDesc(pGetSurfaceDesc1, lpdds, lpddsd); + break; + case sizeof(DDSURFACEDESC2): + if (pGetSurfaceDesc4) return extGetSurfaceDesc((GetSurfaceDesc_Type)pGetSurfaceDesc4, (LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)lpddsd); + break; + default: + OutTraceD("GetSurfaceDesc: ASSERT - bad dwSize=%d lpdds=%x at %d\n", lpddsd->dwSize, lpdds, __LINE__); + return DDERR_INVALIDOBJECT; + break; + } + OutTraceD("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; +} + +HRESULT WINAPI extGetSurfaceDesc2(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 lpddsd) +{ + if (!lpddsd->dwSize) lpddsd->dwSize = sizeof(DDSURFACEDESC2); // enforce correct dwSize value + switch(lpddsd->dwSize){ + case sizeof(DDSURFACEDESC): + if (pGetSurfaceDesc1) return extGetSurfaceDesc(pGetSurfaceDesc1, (LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)lpddsd); + break; + case sizeof(DDSURFACEDESC2): + if (pGetSurfaceDesc4) return extGetSurfaceDesc((GetSurfaceDesc_Type)pGetSurfaceDesc4, (LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)lpddsd); + break; + default: + OutTraceD("GetSurfaceDesc: ASSERT - bad dwSize=%d lpdds=%x at %d\n", lpddsd->dwSize, lpdds, __LINE__); + return DDERR_INVALIDOBJECT; + } + OutTraceD("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; +} + +HRESULT WINAPI extReleaseP(LPDIRECTDRAWPALETTE lpddPalette) +{ + // v2.1.26: Release Palette FIX: + // Uprising 2 crashed trying to use palette functions after having fully released the + // current palette (ref=0!) causing a game crash. The fix pretends that the palette + // was released when attempting the operation to the last object reference (LastRefCount==1) + // returning a ref 0 without actually releasing the object. + //v2.02.08: Better fix: to avoid the problem, just remember to NULL-ify the global main + // palette pointer lpDDP + //v2.02.13: still problems in Virtua Fighter 2 in emu mode. Added try catch protection. + ULONG ref; + BOOL IsClosed; + + // handling of service closed surfaces + IsClosed=0; + __try{ + HRESULT dw=(DWORD)(*pReleaseP); + if ((dw & 0xF0000000) == 0xF0000000) IsClosed=1; + if ((*(DWORD*)lpddPalette & 0xF0000000) == 0xF0000000) IsClosed=1; + if(IsClosed) OutTraceE("Release(P): ASSERT got closed palette lpddPalette=%x\n", lpddPalette); + } + __except (EXCEPTION_EXECUTE_HANDLER){ + OutTraceE("Exception at %d\n",__LINE__); + IsClosed=1; + }; + + ref=IsClosed ? 0 :(*pReleaseP)(lpddPalette); + OutTraceD("Release(P): lpddPalette=%x ref=%x\n", lpddPalette, ref); + if(lpddPalette==lpDDP && ref==0){ + OutTraceD("Release(P): clearing lpDDP=%x->NULL\n", lpDDP); + lpDDP=NULL; + } + return ref; +} + +BOOL WINAPI DDEnumerateCallbackFilter(GUID *lpGuid, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext) +{ + BOOL res; + typedef struct {LPDDENUMCALLBACK lpCallback; LPVOID lpContext;} Context_Type; + Context_Type *p=(Context_Type *)lpContext; + OutTraceD("DDEnumerateCallback: guid=%x DriverDescription=\"%s\" DriverName=\"%s\" Context=%x\n", + lpGuid, lpDriverDescription, lpDriverName, p->lpContext); + if((lpGuid==NULL) || !(dxw.dwFlags2 & HIDEMULTIMONITOR)) res=(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext); + if((lpGuid==NULL) && (dxw.dwFlags2 & HIDEMULTIMONITOR)) res=FALSE; + OutTraceD("DDEnumerateCallback: res=%x(%s)\n", res, res?"continue":"break"); + return res; +} + +BOOL WINAPI DDEnumerateCallbackExFilter(GUID *lpGuid, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR hm) +{ + BOOL res; + typedef struct {LPDDENUMCALLBACKEX lpCallback; LPVOID lpContext;} Context_Type; + Context_Type *p=(Context_Type *)lpContext; + OutTrace("DDEnumerateCallbackEx: guid=%x DriverDescription=\"%s\" DriverName=\"%s\" Context=%x hm=%x\n", + lpGuid, lpDriverDescription, lpDriverName, lpContext, hm); + res=TRUE; + if((lpGuid==NULL) || !(dxw.dwFlags2 & HIDEMULTIMONITOR)) res=(*p->lpCallback)(lpGuid, lpDriverDescription, lpDriverName, p->lpContext, hm); + if((lpGuid==NULL) && (dxw.dwFlags2 & HIDEMULTIMONITOR)) res=FALSE; + OutTraceD("DDEnumerateCallbackEx: res=%x(%s)\n", res, res?"continue":"break"); + return res; +} + +HRESULT WINAPI extDirectDrawEnumerate(LPDDENUMCALLBACK lpCallback, LPVOID lpContext) +{ + HRESULT ret; + OutTraceP("DirectDrawEnumerate: lpCallback=%x lpContext=%x\n", lpCallback, lpContext); + if((dxw.dwFlags2 & HIDEMULTIMONITOR) || (dxw.dwTFlags & OUTDEBUG)){ + struct {LPDDENUMCALLBACK lpCallback; LPVOID lpContext;} myContext; + myContext.lpCallback=lpCallback; + myContext.lpContext=lpContext; + ret=(*pDirectDrawEnumerate)(DDEnumerateCallbackFilter, (LPVOID)&myContext); + } + else + ret=(*pDirectDrawEnumerate)(lpCallback, lpContext); + if(ret) OutTraceP("DirectDrawEnumerate: ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); + return ret; +} + +HRESULT WINAPI extDirectDrawEnumerateEx(LPDDENUMCALLBACKEX lpCallback, LPVOID lpContext, DWORD dwFlags) +{ + HRESULT ret; + OutTraceP("DirectDrawEnumerateEx: lpCallback=%x lpContext=%x Flags=%x(%s)\n", + lpCallback, lpContext, dxw.dwFlags1, ExplainDDEnumerateFlags(dwFlags)); + if((dxw.dwFlags2 & HIDEMULTIMONITOR) || (dxw.dwTFlags & OUTDEBUG)){ + struct {LPDDENUMCALLBACKEX lpCallback; LPVOID lpContext;} myContext; + myContext.lpCallback=lpCallback; + myContext.lpContext=lpContext; + ret=(*pDirectDrawEnumerateEx)(DDEnumerateCallbackExFilter, (LPVOID)&myContext, dwFlags); + } + else + ret=(*pDirectDrawEnumerateEx)(lpCallback, lpContext, dwFlags); + if(ret) OutTraceP("DirectDrawEnumerateEx: ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); + return ret; +} diff --git a/dll/dinput.cpp b/dll/dinput.cpp new file mode 100644 index 0000000..2b720db --- /dev/null +++ b/dll/dinput.cpp @@ -0,0 +1,304 @@ +#include +#include +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "syslibs.h" + +typedef HRESULT (WINAPI *QueryInterface_Type)(void *, REFIID, LPVOID *); +typedef HRESULT (WINAPI *DirectInputCreate_Type)(HINSTANCE, DWORD, LPDIRECTINPUT *, LPUNKNOWN); +typedef HRESULT (WINAPI *DirectInputCreateEx_Type)(HINSTANCE, DWORD, REFIID, LPVOID *, LPUNKNOWN); +typedef HRESULT (WINAPI *DICreateDevice_Type)(LPDIRECTINPUT, REFGUID, LPDIRECTINPUTDEVICE *, LPUNKNOWN); +typedef HRESULT (WINAPI *DICreateDeviceEx_Type)(LPDIRECTINPUT, REFGUID, REFIID, LPVOID *, LPUNKNOWN); +typedef HRESULT (WINAPI *GetDeviceData_Type)(LPDIRECTINPUTDEVICE, DWORD, LPVOID, LPDWORD, DWORD); +typedef HRESULT (WINAPI *GetDeviceState_Type)(LPDIRECTINPUTDEVICE, DWORD, LPDIMOUSESTATE); +typedef HRESULT (WINAPI *DISetCooperativeLevel_Type)(LPDIRECTINPUTDEVICE, HWND, DWORD); +typedef HRESULT (WINAPI *SetDataFormat_Type)(LPDIRECTINPUTDEVICE, LPCDIDATAFORMAT); + +HRESULT WINAPI extDirectInputCreate(HINSTANCE, DWORD, LPDIRECTINPUT *, LPUNKNOWN); +HRESULT WINAPI extDirectInputCreateEx(HINSTANCE, DWORD, REFIID, LPVOID *, LPUNKNOWN); +HRESULT WINAPI extDirectInput8Create(HINSTANCE, DWORD, REFIID, LPVOID *, LPUNKNOWN); +HRESULT WINAPI extDICreateDevice(LPDIRECTINPUT, REFGUID, LPDIRECTINPUTDEVICE *, LPUNKNOWN); +HRESULT WINAPI extDICreateDeviceEx(LPDIRECTINPUT, REFGUID, REFIID, LPVOID *, LPUNKNOWN); +HRESULT WINAPI extGetDeviceData(LPDIRECTINPUTDEVICE, DWORD, LPVOID, LPDWORD, DWORD); +HRESULT WINAPI extGetDeviceState(LPDIRECTINPUTDEVICE, DWORD, LPDIMOUSESTATE); +HRESULT WINAPI extDISetCooperativeLevel(LPDIRECTINPUTDEVICE, HWND, DWORD); +HRESULT WINAPI extSetDataFormat(LPDIRECTINPUTDEVICE, LPCDIDATAFORMAT); +HRESULT WINAPI extQueryInterfaceI(void *, REFIID, LPVOID *); +void GetMousePosition(int *, int *); +void InitPosition(int, int, int, int, int, int); + +DirectInputCreate_Type pDirectInputCreate = 0; +DirectInputCreateEx_Type pDirectInputCreateEx = 0; +DICreateDevice_Type pDICreateDevice = 0; +DICreateDeviceEx_Type pDICreateDeviceEx = 0; +GetDeviceData_Type pGetDeviceData; +GetDeviceState_Type pGetDeviceState; +DISetCooperativeLevel_Type pDISetCooperativeLevel; +SetDataFormat_Type pSetDataFormat; +QueryInterface_Type pQueryInterfaceI; + +int iCursorX; +int iCursorY; +int iCursorXBuf; +int iCursorYBuf; +int iCurMinX; +int iCurMinY; +int iCurMaxX; +int iCurMaxY; + +int HookDirectInput(HMODULE module, int version) +{ + HINSTANCE hinst; + void *tmp; + LPDIRECTINPUT lpdi; + const GUID di7 = {0x9A4CB684,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE}; + const GUID di8 = {0xBF798030,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00}; + + tmp = HookAPI(module, "dinput.dll", NULL, "DirectInputCreateA", extDirectInputCreate); + if(tmp) pDirectInputCreate = (DirectInputCreate_Type)tmp; + tmp = HookAPI(module, "dinput.dll", NULL, "DirectInputCreateW", extDirectInputCreate); + if(tmp) pDirectInputCreate = (DirectInputCreate_Type)tmp; + tmp = HookAPI(module, "dinput.dll", NULL, "DirectInputCreateEx", extDirectInputCreateEx); + if(tmp) pDirectInputCreateEx = (DirectInputCreateEx_Type)tmp; + tmp = HookAPI(module, "dinput8.dll", NULL, "DirectInput8Create", extDirectInput8Create); + if(tmp) pDirectInputCreateEx = (DirectInputCreateEx_Type)tmp; + if(!pDirectInputCreate && !pDirectInputCreateEx){ + if(version < 8){ + hinst = LoadLibrary("dinput.dll"); + pDirectInputCreate = + (DirectInputCreate_Type)GetProcAddress(hinst, "DirectInputCreateA"); + if(pDirectInputCreate) + if(!extDirectInputCreate(GetModuleHandle(0), DIRECTINPUT_VERSION, + &lpdi, 0)) lpdi->Release(); + pDirectInputCreateEx = + (DirectInputCreateEx_Type)GetProcAddress(hinst, "DirectInputCreateEx"); + if(pDirectInputCreateEx) + if(!extDirectInputCreateEx(GetModuleHandle(0), DIRECTINPUT_VERSION, + di7, (void **)&lpdi, 0)) lpdi->Release(); + } + else{ + hinst = LoadLibrary("dinput8.dll"); + pDirectInputCreateEx = + (DirectInputCreateEx_Type)GetProcAddress(hinst, "DirectInput8Create"); + if(pDirectInputCreateEx) + if(!extDirectInputCreateEx(GetModuleHandle(0), DIRECTINPUT_VERSION, + di8, (void **)&lpdi, 0)) lpdi->Release(); + } + } + if(pDirectInputCreate || pDirectInputCreateEx) return 1; + return 0; +} + +HRESULT WINAPI extDirectInputCreate(HINSTANCE hinst, + DWORD dwversion, LPDIRECTINPUT *lplpdi, LPUNKNOWN pu) +{ + HRESULT res; + + OutTraceD("DirectInputCreate: dwVersion = %x\n", + dwversion); + + res = (*pDirectInputCreate)(hinst, dwversion, lplpdi, pu); + if(res) return res; + SetHook((void *)(**(DWORD **)lplpdi + 12), extDICreateDevice, (void **)&pDICreateDevice, "CreateDevice(I)"); + SetHook((void *)(**(DWORD **)lplpdi), extQueryInterfaceI, (void **)&pQueryInterfaceI, "QueryInterface(I)"); + return 0; +} + +HRESULT WINAPI extDirectInputCreateEx(HINSTANCE hinst, + DWORD dwversion, REFIID riidltf, LPVOID *ppvout, LPUNKNOWN pu) +{ + HRESULT res; + + OutTraceD("DirectInputCreateEx: dwVersion = %x REFIID = %x\n", + dwversion, riidltf.Data1); + + res = (*pDirectInputCreateEx)(hinst, dwversion, riidltf, ppvout, pu); + if(res) return res; + SetHook((void *)(**(DWORD **)ppvout + 12), extDICreateDevice, (void **)&pDICreateDevice, "CreateDevice(I)"); + SetHook((void *)(**(DWORD **)ppvout + 36), extDICreateDeviceEx, (void **)pDICreateDeviceEx, "DICreateDeviceEx(I)"); + return 0; +} + +HRESULT WINAPI extQueryInterfaceI(void * lpdi, REFIID riid, LPVOID *obp) +{ + HRESULT res; + + OutTraceD("lpDI->QueryInterface: REFIID = %x\n", + riid.Data1); + + res = (*pQueryInterfaceI)(lpdi, riid, obp); + if(res) return res; + + switch(riid.Data1){ + case 0x5944E662: //DirectInput2A + case 0x5944E663: //DirectInput2W + SetHook((void *)(**(DWORD **)obp + 12), extDICreateDevice, (void **)pDICreateDevice, "CreateDevice(I)"); + break; + } + return 0; +} + +HRESULT WINAPI extDirectInput8Create(HINSTANCE hinst, + DWORD dwversion, REFIID riidltf, LPVOID *ppvout, LPUNKNOWN pu) +{ + HRESULT res; + + OutTraceD("DirectInput8Create: dwVersion = %x REFIID = %x\n", + dwversion, riidltf.Data1); + + res = (*pDirectInputCreateEx)(hinst, dwversion, riidltf, ppvout, pu); + if(res) return res; + SetHook((void *)(**(DWORD **)ppvout + 12), extDICreateDevice, (void **)&pDICreateDevice, "CreateDevice(I8)"); + return 0; +} + +HRESULT WINAPI extDICreateDevice(LPDIRECTINPUT lpdi, REFGUID rguid, + LPDIRECTINPUTDEVICE *lplpdid, LPUNKNOWN pu) +{ + HRESULT res; + + OutTraceD("lpDI->CreateDevice: REFGUID = %x\n", + rguid.Data1); + + res = (*pDICreateDevice)(lpdi, rguid, lplpdid, pu); + if(res) return res; + SetHook((void *)(**(DWORD **)lplpdid + 36), extGetDeviceState, (void **)&pGetDeviceState, "GetDeviceState(I)"); + SetHook((void *)(**(DWORD **)lplpdid + 40), extGetDeviceData, (void **)&pGetDeviceData, "GetDeviceData(I)"); + SetHook((void *)(**(DWORD **)lplpdid + 44), extSetDataFormat, (void **)&pSetDataFormat, "SetDataFormat(I)"); + SetHook((void *)(**(DWORD **)lplpdid + 52), extDISetCooperativeLevel, (void **)&pDISetCooperativeLevel, "SetCooperativeLevel(I)"); + return 0; +} + +HRESULT WINAPI extDICreateDeviceEx(LPDIRECTINPUT lpdi, REFGUID rguid, + REFIID riid, LPVOID *pvout, LPUNKNOWN pu) +{ + HRESULT res; + + OutTraceD("lpDI->CreateDeviceEx: GUID = %x REFIID = %x\n", + rguid.Data1, riid.Data1); + + res = (*pDICreateDeviceEx)(lpdi, rguid, riid, pvout, pu); + if(res) return res; + SetHook((void *)(**(DWORD **)pvout + 36), extGetDeviceState, (void **)&pGetDeviceState, "GetDeviceState(I)"); + SetHook((void *)(**(DWORD **)pvout + 40), extGetDeviceData, (void **)&pGetDeviceData, "GetDeviceData(I)"); + SetHook((void *)(**(DWORD **)pvout + 44), extSetDataFormat, (void **)&pSetDataFormat, "SetDataFormat(I)"); + SetHook((void *)(**(DWORD **)pvout + 52), extDISetCooperativeLevel, (void **)&pDISetCooperativeLevel, "SetCooperativeLevel(I)"); + return 0; +} + +HRESULT WINAPI extGetDeviceData(LPDIRECTINPUTDEVICE lpdid, DWORD cbdata, LPVOID rgdod, LPDWORD pdwinout, DWORD dwflags) +{ + HRESULT res; + BYTE *tmp; + unsigned int i; + POINT p; + + OutTraceD("GetDeviceData cbdata:%i\n", cbdata); + + res = (*pGetDeviceData)(lpdid, cbdata, rgdod, pdwinout, dwflags); + if(res) return res; + + if(!dxw.bActive) *pdwinout = 0; + GetMousePosition((int *)&p.x, (int *)&p.y); + if(cbdata == 20 || cbdata == 24){ + tmp = (BYTE *)rgdod; + for(i = 0; i < *pdwinout; i ++){ + if(((LPDIDEVICEOBJECTDATA)tmp)->dwOfs == DIMOFS_X){ + ((LPDIDEVICEOBJECTDATA)tmp)->dwData = p.x; + if(!dxw.bDInputAbs){ + if(p.x < iCurMinX) p.x = iCurMinX; + if(p.x > iCurMaxX) p.x = iCurMaxX; + ((LPDIDEVICEOBJECTDATA)tmp)->dwData = p.x - iCursorXBuf; + iCursorXBuf = p.x; + } + } + if(((LPDIDEVICEOBJECTDATA)tmp)->dwOfs == DIMOFS_Y){ + ((LPDIDEVICEOBJECTDATA)tmp)->dwData = p.y; + if(!dxw.bDInputAbs){ + if(p.y < iCurMinY) p.y = iCurMinY; + if(p.y > iCurMaxY) p.y = iCurMaxY; + ((LPDIDEVICEOBJECTDATA)tmp)->dwData = p.y - iCursorYBuf; + iCursorYBuf = p.y; + } + } + tmp += cbdata; + } + OutTraceD("DEBUG: directinput mousedata=(%d,%d)\n", p.x, p.y); + } + return 0; +} + +HRESULT WINAPI extGetDeviceState(LPDIRECTINPUTDEVICE lpdid, DWORD cbdata, LPDIMOUSESTATE lpvdata) +{ + HRESULT res; + POINT p = {0, 0}; + + OutTraceD("GetDeviceState cbData:%i %i\n", cbdata, dxw.bActive); + + res = (*pGetDeviceState)(lpdid, cbdata, lpvdata); + if(res) return res; + if(cbdata == sizeof(DIMOUSESTATE) || cbdata == sizeof(DIMOUSESTATE2)){ + GetMousePosition((int *)&p.x, (int *)&p.y); + lpvdata->lX = p.x; + lpvdata->lY = p.y; + if(!dxw.bDInputAbs){ + if(p.x < iCurMinX) p.x = iCurMinX; + if(p.x > iCurMaxX) p.x = iCurMaxX; + if(p.y < iCurMinY) p.y = iCurMinY; + if(p.y > iCurMaxY) p.y = iCurMaxY; + lpvdata->lX = p.x - iCursorX; + lpvdata->lY = p.y - iCursorY; + iCursorX = p.x; + iCursorY = p.y; + } + if(!dxw.bActive){ + lpvdata->lZ = 0; + *(DWORD *)lpvdata->rgbButtons = 0; + } + OutTraceD("DEBUG: directinput mousestate=(%d,%d)\n", p.x, p.y); + } + + if(cbdata == 256 && !dxw.bActive) ZeroMemory(lpvdata, 256); + return 0; +} + +HRESULT WINAPI extSetDataFormat(LPDIRECTINPUTDEVICE lpdid, LPCDIDATAFORMAT lpdf) +{ + OutTraceD("SetDataFormat: flags = 0x%x\n", lpdf->dwFlags); + + if(lpdf->dwFlags & DIDF_ABSAXIS) dxw.bDInputAbs = 1; + if(lpdf->dwFlags & DIDF_RELAXIS) dxw.bDInputAbs = 0; + return (*pSetDataFormat)(lpdid, lpdf); +} + +HRESULT WINAPI extDISetCooperativeLevel(LPDIRECTINPUTDEVICE lpdid, HWND hwnd, DWORD dwflags) +{ + OutTraceD("lpDI->SetCooperativeLevel\n"); + + dwflags = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND; + return (*pDISetCooperativeLevel)(lpdid, hwnd, dwflags); +} + +// Simplified version, taking in proper account the GetCursorPos API hooking & coordinate processing +void GetMousePosition(int *x, int *y) +{ + POINT p; + //GetCursorPos(&p); + extern BOOL WINAPI extGetCursorPos(LPPOINT); + extGetCursorPos(&p); + *x = p.x; + *y = p.y; + OutTraceD("GetMousePosition: x,y=(%d,%d)\n", *x, *y); +} + +void InitPosition(int x, int y, int minx, int miny, int maxx, int maxy) +{ + iCursorX = x; + iCursorY = y; + iCursorXBuf = x; + iCursorYBuf = y; + iCurMinX = minx; + iCurMinY = miny; + iCurMaxX = maxx; + iCurMaxY = maxy; +} diff --git a/dll/dxemublt.cpp b/dll/dxemublt.cpp index 830e30f..52e086b 100644 --- a/dll/dxemublt.cpp +++ b/dll/dxemublt.cpp @@ -193,21 +193,31 @@ static HRESULT WINAPI EmuBlt_16_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes if (!Palette16BPP) { // first time through ..... unsigned int pi; Palette16BPP = (DWORD *)malloc(0x10000 * sizeof(DWORD)); - if (dxw.dwFlags1 & USERGB565){ - for (pi=0; pi<0x10000; pi++) { - Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x7E0)<<5 | (pi & 0xF800)<<8; // RGB565 + if (dxw.dwFlags3 & BLACKWHITE){ + DWORD grey; + if (dxw.dwFlags1 & USERGB565){ + for (pi=0; pi<0x10000; pi++) { + grey = ((((pi & 0x1F)<<3) + ((pi & 0x7E0)>>3) + ((pi & 0xF800)>>8)) / 3) & 0xFF; + Palette16BPP[pi] = (grey) + (grey<<8) + (grey<<16); + } + } + else { + for (pi=0; pi<0x10000; pi++) { + grey = ((((pi & 0x1F)<<3) + ((pi & 0x3E0)>>2) + ((pi & 0x7C00)>>7)) / 3) & 0xFF; + Palette16BPP[pi] = grey + (grey<<8) + (grey<<16); + } } } else { - for (pi=0; pi<0x10000; pi++) { - Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x3E0)<<6 | (pi & 0x7C00)<<9; // RGB555 + if (dxw.dwFlags1 & USERGB565){ + for (pi=0; pi<0x10000; pi++) { + Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x7E0)<<5 | (pi & 0xF800)<<8; // RGB565 + } } - } - if (dxw.dwFlags3 & BLACKWHITE){ - for (pi=0; pi<0x10000; pi++) { - DWORD grey; - grey=((pi & 0xFF) + ((pi & 0xFF00)>>8) + ((pi & 0xFF0000)>>16)) / 3; - Palette16BPP[pi] = grey + (grey<<8) + (grey<<16); + else { + for (pi=0; pi<0x10000; pi++) { + Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x3E0)<<6 | (pi & 0x7C00)<<9; // RGB555 + } } } } diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index f713702..eb5bf88 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -23,6 +23,8 @@ extern void InitScreenParameters(); void HookModule(HMODULE, int); static void RecoverScreenMode(); static void LockScreenMode(DWORD, DWORD, DWORD); +DEVMODE SetDevMode; +DEVMODE *pSetDevMode=NULL; extern HANDLE hTraceMutex; @@ -305,6 +307,144 @@ void SetHook(void *target, void *hookproc, void **hookedproc, char *hookname) *hookedproc = tmp; } +#ifdef HOOKBYIAT +PIMAGE_SECTION_HEADER ImageRVA2Section(PIMAGE_NT_HEADERS pimage_nt_headers,DWORD dwRVA) +{ + int i; + PIMAGE_SECTION_HEADER pimage_section_header=(PIMAGE_SECTION_HEADER)((PCHAR(pimage_nt_headers)) + sizeof(IMAGE_NT_HEADERS)); + for(i=0;iFileHeader.NumberOfSections;i++) + { + if((pimage_section_header->VirtualAddress) && (dwRVA<=(pimage_section_header->VirtualAddress+pimage_section_header->SizeOfRawData))) + { + return ((PIMAGE_SECTION_HEADER)pimage_section_header); + } + pimage_section_header++; + } + return(NULL); +} + +DWORD RVA2Offset(PCHAR pImageBase,DWORD dwRVA) +{ + DWORD _offset; + PIMAGE_SECTION_HEADER section; + PIMAGE_DOS_HEADER pimage_dos_header; + PIMAGE_NT_HEADERS pimage_nt_headers; + pimage_dos_header = PIMAGE_DOS_HEADER(pImageBase); + pimage_nt_headers = (PIMAGE_NT_HEADERS)(pImageBase+pimage_dos_header->e_lfanew); + section=ImageRVA2Section(pimage_nt_headers,dwRVA); + if(section==NULL) + { + return(0); + } + _offset=dwRVA+section->PointerToRawData-section->VirtualAddress; + return(_offset); +} + +void *HookAPI(HMODULE module, char *dll, void *apiproc, const char *apiname, void *hookproc) +{ + PIMAGE_NT_HEADERS pnth; + PIMAGE_IMPORT_DESCRIPTOR pidesc; + DWORD base, rva; + PSTR impmodule; + PIMAGE_THUNK_DATA ptaddr; + PIMAGE_THUNK_DATA ptname; + PIMAGE_IMPORT_BY_NAME piname; + DWORD oldprotect; + void *org; + PCHAR pThunk; + DWORD dwThunk; + PCHAR pDllName; + + OutTraceB("HookAPI: module=%x dll=%s apiproc=%x apiname=%s hookproc=%x\n", + module, dll, apiproc, apiname, hookproc); + + if(!*apiname) { // check + char *sMsg="HookAPI: NULL api name\n"; + OutTraceE(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "HookAPI", MB_OK | MB_ICONEXCLAMATION); + return 0; + } + + base = (DWORD)module; + __try{ + pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); + if(!pnth) { + OutTraceE("HookAPI: ERROR no PNTH at %d\n", __LINE__); + return 0; + } + rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress; + if(!rva) { + OutTraceE("HookAPI: ERROR no IAT at %d\n", __LINE__); + return 0; + } + pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); + OutTraceD("HookAPI: pidesc=%x\n", pidesc); + + while(pidesc->Name){ + pThunk=(PCHAR)base+pidesc->FirstThunk; + dwThunk = pidesc->FirstThunk; + pDllName=(PSTR)base+pidesc->Name; + OutTraceD("HookAPI: pDllName=%s Name=%s\n", pDllName, pidesc->Name); + //impmodule = (PSTR)(base + pidesc->Name); + //if(!lstrcmpi(dll, impmodule)) break; + pidesc ++; + } + if(!pidesc->FirstThunk) { + OutTraceB("HookAPI: PE unreferenced dll=%s\n", dll); + return 0; + } + + ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); + ptname = (pidesc->OriginalFirstThunk) ? (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk) : NULL; + + if((apiproc==NULL) && (ptname==NULL)){ + if (IsDebug) OutTraceD("HookAPI: unreacheable api=%s dll=%s\n", apiname, dll); + return 0; + } + + while(ptaddr->u1.Function){ + if (ptname){ + if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){ + piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); + if(!lstrcmpi(apiname, (char *)piname->Name)) break; + } + } + if (apiproc){ + if(ptaddr->u1.Function == (DWORD)apiproc) break; + } + ptaddr ++; + if (ptname) ptname ++; + } + if(!ptaddr->u1.Function) return 0; + + org = (void *)ptaddr->u1.Function; + if(org == hookproc) return 0; // already hooked + + if(!VirtualProtect(&ptaddr->u1.Function, 4, PAGE_EXECUTE_READWRITE, &oldprotect)) { + OutTraceD("HookAPI: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); + return 0; + } + ptaddr->u1.Function = (DWORD)hookproc; + if(!VirtualProtect(&ptaddr->u1.Function, 4, oldprotect, &oldprotect)) { + OutTraceD("HookAPI: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); + return 0; + } + if (!FlushInstructionCache(GetCurrentProcess(), &ptaddr->u1.Function, 4)) { + OutTraceD("HookAPI: FlushInstructionCache error %d at %d\n", GetLastError(), __LINE__); + return 0; + } + if(IsDebug) OutTrace("HookAPI hook=%s address=%x->%x\n", apiname, org, hookproc); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + OutTraceD("HookAPI: EXCEPTION hook=%s:%s Hook Failed.\n", dll, apiname); + org = 0; + } + return org; +} + +#else + void *HookAPI(HMODULE module, char *dll, void *apiproc, const char *apiname, void *hookproc) { PIMAGE_NT_HEADERS pnth; @@ -331,12 +471,12 @@ void *HookAPI(HMODULE module, char *dll, void *apiproc, const char *apiname, voi __try{ pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); if(!pnth) { - OutTraceE("HookAPI: ERROR no pnth at %d\n", __LINE__); + OutTraceE("HookAPI: ERROR no PNTH at %d\n", __LINE__); return 0; } rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; if(!rva) { - OutTraceE("HookAPI: ERROR no rva at %d\n", __LINE__); + OutTraceE("HookAPI: ERROR no RVA at %d\n", __LINE__); return 0; } pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); @@ -391,7 +531,7 @@ void *HookAPI(HMODULE module, char *dll, void *apiproc, const char *apiname, voi return 0; } if(IsDebug) OutTrace("HookAPI hook=%s address=%x->%x\n", apiname, org, hookproc); - } + } __except(EXCEPTION_EXECUTE_HANDLER) { OutTraceD("HookAPI: EXCEPTION hook=%s:%s Hook Failed.\n", dll, apiname); @@ -400,6 +540,8 @@ void *HookAPI(HMODULE module, char *dll, void *apiproc, const char *apiname, voi return org; } +#endif + // v.2.1.80: unified positioning logic into CalculateWindowPos routine // now taking in account for window menus (see "Alien Cabal") @@ -580,7 +722,7 @@ LRESULT CALLBACK extChildWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPAR // Cybermercs: it seems that all game menus are conveniently handled by the WindowProc routine, // while the action screen get messages processed by the ChildWindowProc, that needs some different // setting .......... - // Beware: Cybermercs handles some static info about curror position handling, so that if you resize + // Beware: Cybermercs handles some static info about cursor position handling, so that if you resize // a menu it doesn't work correctly until you don't change screen. case WM_MOUSEMOVE: case WM_MOUSEWHEEL: @@ -968,134 +1110,9 @@ void HookSysLibsInit() if(DoOnce) return; DoOnce=TRUE; - pLoadLibraryA = LoadLibraryA; - pLoadLibraryExA = LoadLibraryExA; - pLoadLibraryW = LoadLibraryW; - pLoadLibraryExW = LoadLibraryExW; - pGetProcAddress = (GetProcAddress_Type)GetProcAddress; - pGDICreateCompatibleDC=CreateCompatibleDC; - pGDIDeleteDC=DeleteDC; - pGDIGetDC=GetDC; - pGDIGetWindowDC=GetWindowDC; - pGDIReleaseDC=ReleaseDC; - pGDICreateDC=CreateDC; - pGDIBitBlt=BitBlt; - pGDIStretchBlt=StretchBlt; - pBeginPaint=BeginPaint; - pEndPaint=EndPaint; - pInvalidateRect=InvalidateRect; - pScreenToClient = ScreenToClient; - pClientToScreen = ClientToScreen; - pGetClientRect = GetClientRect; - pGetWindowRect = GetWindowRect; - pMapWindowPoints= MapWindowPoints; - pChangeDisplaySettings=ChangeDisplaySettingsA; - pChangeDisplaySettingsEx=ChangeDisplaySettingsExA; - pClipCursor = ClipCursor; - pFillRect = FillRect; - pPeekMessage = PeekMessage; - pGetMessage = GetMessage; - pDefWindowProc = DefWindowProc; - pGDIGetDeviceCaps = GetDeviceCaps; - pGDITextOutA = TextOutA; - pGDIScaleWindowExtEx = ScaleWindowExtEx; - pCreateWindowExA = CreateWindowExA; - pRegisterClassExA = (RegisterClassExA_Type)RegisterClassExA; - pGDIRectangle = Rectangle; - pSetWindowPos=SetWindowPos; - pGDIDeferWindowPos=DeferWindowPos; - pSetWindowLong=SetWindowLongA; - pGetWindowLong=GetWindowLongA; - pCallWindowProc=CallWindowProcA; - pShowWindow=ShowWindow; - pGDISetTextColor = SetTextColor; - pGDISetBkColor = SetBkColor; - pGDICreateFont = CreateFont; - pGDICreateFontIndirect = CreateFontIndirect; - pGetSystemMetrics = GetSystemMetrics; - pGetCursorPos = GetCursorPos; - pSetCursorPos = SetCursorPos; - pSetCursor = SetCursor; - pCreateDialogIndirectParam=CreateDialogIndirectParamA; - pCreateDialogParam=CreateDialogParamA; - pMoveWindow=MoveWindow; - pGetDesktopWindow=GetDesktopWindow; - pShowCursor=ShowCursor; - pGetTickCount=GetTickCount; - pSleep=Sleep; - pSleepEx=SleepEx; - pGetSystemTime=GetSystemTime; - pGetLocalTime=GetLocalTime; - pSetTimer=SetTimer; -} - -void HookGDILib(HMODULE module) -{ - void *tmp; - - if(dxw.dwFlags1 & MAPGDITOPRIMARY){ - tmp = HookAPI(module, "GDI32.dll", CreateCompatibleDC, "CreateCompatibleDC", extDDCreateCompatibleDC); - if(tmp) pGDICreateCompatibleDC = (CreateCompatibleDC_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", DeleteDC, "DeleteDC", extDDDeleteDC); - if(tmp) pGDIDeleteDC = (DeleteDC_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", CreateDCA, "CreateDCA", extDDCreateDC); - if(tmp) pGDICreateDC = (CreateDC_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", BitBlt, "BitBlt", extDDBitBlt); - if(tmp) pGDIBitBlt = (BitBlt_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", StretchBlt, "StretchBlt", extDDStretchBlt); - if(tmp) pGDIStretchBlt = (StretchBlt_Type)tmp; - } - else { - tmp = HookAPI(module, "GDI32.dll", CreateCompatibleDC, "CreateCompatibleDC", extGDICreateCompatibleDC); - if(tmp) pGDICreateCompatibleDC = (CreateCompatibleDC_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", DeleteDC, "DeleteDC", extGDIDeleteDC); - if(tmp) pGDIDeleteDC = (DeleteDC_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", CreateDCA, "CreateDCA", extGDICreateDC); - if(tmp) pGDICreateDC = (CreateDC_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", BitBlt, "BitBlt", extGDIBitBlt); - if(tmp) pGDIBitBlt = (BitBlt_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", StretchBlt, "StretchBlt", extGDIStretchBlt); - if(tmp) pGDIStretchBlt = (StretchBlt_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", PatBlt, "PatBlt", extGDIPatBlt); - if(tmp) pGDIPatBlt = (PatBlt_Type)tmp; - } - tmp = HookAPI(module, "GDI32.dll", GetDeviceCaps, "GetDeviceCaps", extGetDeviceCaps); // GHO: added for caesar3 - if(tmp) pGDIGetDeviceCaps = (GetDeviceCaps_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", TextOutA, "TextOutA", extTextOutA); - if(tmp) pGDITextOutA = (TextOut_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", ScaleWindowExtEx, "ScaleWindowExtEx", extScaleWindowExtEx); - if(tmp) pGDIScaleWindowExtEx = (ScaleWindowExtEx_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", Rectangle, "Rectangle", extRectangle); - if(tmp) pGDIRectangle = (Rectangle_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", SaveDC, "SaveDC", extGDISaveDC); - if(tmp) pGDISaveDC = (SaveDC_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", RestoreDC, "RestoreDC", extGDIRestoreDC); - if(tmp) pGDIRestoreDC = (RestoreDC_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", CreatePalette, "CreatePalette", extGDICreatePalette); - if(tmp) pGDICreatePalette = (GDICreatePalette_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", SelectPalette, "SelectPalette", extSelectPalette); - if(tmp) pGDISelectPalette = (SelectPalette_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", RealizePalette, "RealizePalette", extRealizePalette); - if(tmp) pGDIRealizePalette = (RealizePalette_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", GetSystemPaletteEntries, "GetSystemPaletteEntries", extGetSystemPaletteEntries); - if(tmp) pGDIGetSystemPaletteEntries = (GetSystemPaletteEntries_Type)tmp; - if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC)){ - tmp = HookAPI(module, "GDI32.dll", SetTextColor, "SetTextColor", extSetTextColor); - if(tmp) pGDISetTextColor = (SetTextColor_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", SetBkColor, "SetBkColor", extSetBkColor); - if(tmp) pGDISetBkColor = (SetBkColor_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", CreateFont, "CreateFont", extCreateFont); - if(tmp) pGDICreateFont = (CreateFont_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", CreateFontIndirectA, "CreateFontIndirectA", extCreateFontIndirect); - if(tmp) pGDICreateFontIndirect = (CreateFontIndirect_Type)tmp; - } - - if(dxw.dwFlags2 & DISABLEGAMMARAMP){ - tmp = HookAPI(module, "GDI32.dll", SetDeviceGammaRamp, "SetDeviceGammaRamp", extSetDeviceGammaRamp); - if(tmp) pGDISetDeviceGammaRamp = (SetDeviceGammaRamp_Type)tmp; - tmp = HookAPI(module, "GDI32.dll", GetDeviceGammaRamp, "GetDeviceGammaRamp", extGetDeviceGammaRamp); - if(tmp) pGDIGetDeviceGammaRamp = (GetDeviceGammaRamp_Type)tmp; - } + HookKernel32Init(); + HookUser32Init(); + HookGDI32Init(); } static void RecoverScreenMode() @@ -1184,6 +1201,13 @@ LONG WINAPI myUnhandledExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo) } } +LPTOP_LEVEL_EXCEPTION_FILTER WINAPI extSetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) +{ + OutTraceD("SetUnhandledExceptionFilter: lpExceptionFilter=%x\n", lpTopLevelExceptionFilter); + extern LONG WINAPI myUnhandledExceptionFilter(LPEXCEPTION_POINTERS); + return (*pSetUnhandledExceptionFilter)(myUnhandledExceptionFilter); +} + void HookExceptionHandler(void) { void *tmp; @@ -1210,13 +1234,13 @@ void HookModule(HMODULE base, int dxversion) { HookKernel32(base); HookUser32(base); + HookOle32(base); HookWinMM(base); //if(dxw.dwFlags2 & SUPPRESSIME) HookImeLib(module); - if(dxw.dwFlags2 & HOOKGDI) HookGDILib(base); + if(dxw.dwFlags2 & HOOKGDI) HookGDI32(base); if(dxw.dwFlags1 & HOOKDI) HookDirectInput(base, dxversion); HookDirectDraw(base, dxversion); HookDirect3D(base, dxversion); - HookOle32(base); if(dxw.dwFlags2 & HOOKOPENGL) HookOpenGLLibs(base, dxw.CustomOpenGLLib); HookMSV4WLibs(base); } @@ -1308,6 +1332,8 @@ int HookInit(TARGETMAP *target, HWND hwnd) OutTrace("HookInit: dxw.hParentWnd style=%x(%s) exstyle=%x(%s)\n", dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); } + HookSysLibsInit(); // this just once... + base=GetModuleHandle(NULL); if(dxw.dwFlags3 & SINGLEPROCAFFINITY) SetSingleProcessAffinity(); if(dxw.dwFlags1 & HANDLEEXCEPTIONS) HookExceptionHandler(); @@ -1324,8 +1350,6 @@ int HookInit(TARGETMAP *target, HWND hwnd) target->minx, target->miny, target->maxx, target->maxy); dxw.InitWindowPos(target->posx, target->posy, target->sizx, target->sizy); - HookSysLibsInit(); // this just once... - OutTraceB("HookInit: base hmodule=%x\n", base); HookModule(base, dxw.dwTargetDDVersion); if (dxw.dwFlags3 & HOOKDLLS) HookDlls(base); @@ -1361,23 +1385,6 @@ int HookInit(TARGETMAP *target, HWND hwnd) return 0; } -HWND WINAPI extGetDesktopWindow(void) -{ - // V2.1.73: correct ??? - HWND res; - - OutTraceD("GetDesktopWindow: FullScreen=%x\n", dxw.IsFullScreen()); - if (dxw.IsFullScreen()){ - OutTraceD("GetDesktopWindow: returning main window hwnd=%x\n", dxw.GethWnd()); - return dxw.GethWnd(); - } - else{ - res=(*pGetDesktopWindow)(); - OutTraceD("GetDesktopWindow: returning desktop window hwnd=%x\n", res); - return res; - } -} - LPCSTR ProcToString(LPCSTR proc) { static char sBuf[24+1]; @@ -1391,14 +1398,11 @@ LPCSTR ProcToString(LPCSTR proc) FARPROC RemapLibrary(LPCSTR proc, HMODULE hModule, HookEntry_Type *Hooks) { - int i; - HookEntry_Type *Hook; - for(i=0; Hooks[i].APIName; i++){ - Hook=&Hooks[i]; - if (!strcmp(proc,Hook->APIName)){ - if (Hook->StoreAddress) *(Hook->StoreAddress)=(*pGetProcAddress)(hModule, proc); - OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), (Hook->StoreAddress) ? *(Hook->StoreAddress) : 0); - return Hook->HookerAddress; + for(; Hooks->APIName; Hooks++){ + if (!strcmp(proc,Hooks->APIName)){ + if (Hooks->StoreAddress) *(Hooks->StoreAddress)=(*pGetProcAddress)(hModule, proc); + OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), (Hooks->StoreAddress) ? *(Hooks->StoreAddress) : 0); + return Hooks->HookerAddress; } } return NULL; @@ -1406,12 +1410,15 @@ FARPROC RemapLibrary(LPCSTR proc, HMODULE hModule, HookEntry_Type *Hooks) void HookLibrary(HMODULE hModule, HookEntry_Type *Hooks, char *DLLName) { - int i; void *tmp; - HookEntry_Type *Hook; - for(i=0; Hooks[i].APIName; i++){ - Hook=&Hooks[i]; - tmp = HookAPI(hModule, DLLName, Hook->OriginalAddress, Hook->APIName, Hook->HookerAddress); - if(tmp) *(Hook->StoreAddress) = (FARPROC)tmp; + for(; Hooks->APIName; Hooks++){ + tmp = HookAPI(hModule, DLLName, Hooks->OriginalAddress, Hooks->APIName, Hooks->HookerAddress); + if(tmp) *(Hooks->StoreAddress) = (FARPROC)tmp; } } + +void HookLibInit(HookEntry_Type *Hooks) +{ + for(; Hooks->APIName; Hooks++) + if (Hooks->StoreAddress) *(Hooks->StoreAddress) = Hooks->OriginalAddress; +} diff --git a/dll/dxhook.h b/dll/dxhook.h index a40dbc1..cd11d2f 100644 --- a/dll/dxhook.h +++ b/dll/dxhook.h @@ -2,6 +2,7 @@ extern int HookDirectDraw(HMODULE, int); extern int HookDDProxy(HMODULE, int); extern int HookDirect3D(HMODULE, int); extern void HookOle32(HMODULE); +extern void HookGDI32(HMODULE); extern int HookDirectInput(HMODULE, int); extern void HookImeLib(HMODULE); extern void HookKernel32(HMODULE); @@ -27,6 +28,7 @@ extern FARPROC Remap_ole32_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_trust_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_WinMM_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_ImeLib_ProcAddress(LPCSTR, HMODULE); +extern FARPROC Remap_vfw_ProcAddress(LPCSTR, HMODULE); typedef struct { char *APIName; @@ -37,3 +39,4 @@ typedef struct { extern FARPROC RemapLibrary(LPCSTR, HMODULE, HookEntry_Type *); extern void HookLibrary(HMODULE, HookEntry_Type *, char *); +extern void HookLibInit(HookEntry_Type *); diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index 460b8f4..ba187d5 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -293,6 +293,21 @@ RECT dxwCore::MapWindowRect(LPRECT lpRect) } else { RetRect=ClientRect; + if ((dxw.Coordinates == DXW_DESKTOP_WORKAREA) && (dwFlags2 & KEEPASPECTRATIO)){ + int w, h, b; // width, height and border + w = RetRect.right - RetRect.left; + h = RetRect.bottom - RetRect.top; + if ((w * 600) > (h * 800)){ + b = (w - (h * 800 / 600))/2; + RetRect.left = ClientRect.left + b; + RetRect.right = ClientRect.right - b; + } + else { + b = (h - (w * 600 / 800))/2; + RetRect.top = ClientRect.top + b; + RetRect.bottom = ClientRect.bottom - b; + } + } } if(!(*pClientToScreen)(hWnd, &UpLeft)){ OutTraceE("ClientToScreen ERROR: err=%d hwnd=%x at %d\n", GetLastError(), hWnd, __LINE__); @@ -748,13 +763,12 @@ void dxwCore::ShowBanner(HWND hwnd) HBITMAP g_hbmBall; RECT client; - JustOnce=TRUE; - hClientDC=GetDC(hwnd); (*pGetClientRect)(hwnd, &client); BitBlt(hClientDC, 0, 0, client.right, client.bottom, NULL, 0, 0, BLACKNESS); if(JustOnce || (dwFlags2 & NOBANNER)) return; + JustOnce=TRUE; g_hbmBall = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BANNER)); HDC hdcMem = CreateCompatibleDC(hClientDC); diff --git a/dll/dxwnd.aps b/dll/dxwnd.aps index 412bf145de0f169b55252c1b13a26e9e5ee0e9fa..9d1f741ebce5990ff4b6132130b295be315ba250 100644 GIT binary patch delta 313 zcmbQUjA_9#rU_Qc0xS$ruwfztLyA?5OGS8IN=%tiyn#`?ky(66QRT+i-G0)K?HL$U zfGRy0!Wo=^^#A`S!1@dr1ST8%t8hE|`MCx$7#bKduud-ZmuKXjJk?);k!SKYe|b4x z28MXYfZ%vP*NBk#;7DIrm-sM8pHNq@a=y)<{T=Lek1?W~e-dUs3lo?HvJ(OXCMWjG za~m<3F~l>JFcdLVPVVm4WENm?nH)Glo?C%IgQ0@K0w}9FIe$X@WRnR}IOH}n3QSg> tn9T<9=Hw|8jer8jCn^KU*AtI2KAyaBk}@mEVJ?$zPEuwxnEZE=JODeCSGxcJ delta 369 zcmZ3mjA_m?rU_QcoGc7bux26yLyA?5OGS8IN=%tiyn#`?p>ce1QS!#v-G0*F>=_tT zfGRy0!Wo=^^#A`S!1@drI42wXtJHgj_&Np{G8h^dGO#i*c)B>nJ30FKxdwqn*cce% z9Rq^n{ahnL;)7g+{X>JCUE{+XeL`J<@LL`0|TIuyr>HNLW2B# z;QE2`e6q+2f+KxhVfsN1;@|wh-@%@VVclfKeo0|Y7AB~V|3d-iWZ!;yZbJrRhIocz zh9ZXK$>sf;%$zLFlRYQMPd?XQfy9oRd}%@mBj;rGiP>zB;F&yQq7hKw^h9MK`F`S2 b#&46iPEuxF$H>4CG5PK!Wk#LJjFaU7SU728 diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index faf6f89..205aa8b 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.25" +#define VERSION "2.02.27" LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam); diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index f6042ca626a1d04bad14ada29d98ea786262caac..05d3b3b25898b1ecb1e275d509d128f00aeb661c 100644 GIT binary patch delta 38725 zcmb822VfS(-t~8rJSmhALJuV!2qm=85kf-m9R!pvs3=__fDckc#R4oEq$7eIkRVOP zh#*`Gy%!Y(>@@Kzi13}W&)F~+dB69*1OLp~-~M-Ic4l^VcAhrnl5fhF5woil3$`rF zhPffivVtJ;&1qUBg!H`uOYJ!$Bi04A3$h0~@gcE=`oGbzSM{fM+dM42i0w=a+2wp1 zQp3ru9TK!V#L4n?aCQ}_;)}rUUd}aNg}6c?NDo^#Z{508Kyf7ELe$92Ne@lx#+{D= zl!3+JfFX!u=>Q&&I04oJ2VoDvvS7|TVP#s4ffx&;(+h|nhjl`2O%R)i zcnWN?w*89ppR03fcj1TItxXx&JMxwGpE*y~tL{vxoDfmh>W2hJTN9kc4i`v0Il}WMWGqe#L%a#+F~DyvCzel8WW7cAMR%De=NVUVm`2s?qEPx zTo9`bAwiDx=>yFI^cAB{gl2eHtO4|Ju?b?0z_P^N7Grvwp;^!^Vtt_Bk>5^d^XUAA z_hBm&^pHGyI~T_#7pdbl7*1)hH5~u?Iur7hb-GoKa#rOl=ZqeoQ0Fc_);MbnI{s*@ zmQ~YAwFX%u@eghGc&lF#S?Er;oRaz56v^ukM)EHnEEdwdU+1Atr_-b77RU^>+4`YQ z=gO5s3qlQxbg~NUwo4H>V+(fj4F`OLTM;Fp*xxM{-N`ywG^bAF=eCnuDIp@SjLxs) zlYQI6>#VbIND*h)=913f{pS9r6N>Sy?t12b6m9EV8JAEtFSXmnM(qs7`3|ricTQ&{ z{zpeI6~T*ZMtsIr=2^lyTX-jq35g+7 zc7EBHm6P+pU*FpPCU9n=yb#hU5L%11g>EC(RjeXdH?clqJeHX<3>D+C!^Fmj@z}9q zlLO4}j%7~>&Xpr?0gl*8gRK%Chc$*Oe!)`Ms4AEy z#)N8%wGfL3Ybn-4ECsBm*nMK$9EU$05I-)~3i^KTK$s%N{H^);L&pVzb)cW*4ulnA zC7@pudqa#h@}}4hvFc!-iG3%=8ayj~K`~F{VvyAuk!AfR$o9Dk%}_cx&@p-IF9Xfc zMT~{*DmEFh+uNTlQ->E+<-Fc*3`9dQ5IuOuz}w}oHO`!T#r(WIuqk;q_rMrfEV81o zHZX?HFf#gdfid)lkueMiMAoB-$!fwzh;0$$<_BWAh~ejVozG#THtc)=TCB!TU<^g! z#RPeODn@~jB=$0NvKVi|l!IV(#JtP9A6U9r7x~43b@i?QUccPWQr{=X2gHEf>zeU! zG1l56@_SOOBiK~2XT`Yr68f<{5FYg6{`$C zZ)$NwECKAO{LYB+YahE8sjIj?y;Ez$RVTBQbodC&Q@8265xHrl61B3+sZ zdMVhs4r;SVK`u=NE#PyqlG}u{%-rE@EmX1eAU6&CLAX8bj5Ds+jkQPoO`A@jl@csCL!K9g)6nbgn(OW~&fZ0egu( z-WgZ3qt6GoX!a)OYRyjJvDnIU=<1BC)gi)8G+4gw*x)S^>24h}m9@<$3}-{y=gyRd z>DfVz?DV;HGDF=dbV(*__i)D5>F8sZEbeaia(=Jlw;y)K)t%+!j*W3LHjNJMV0Fvx zmtdE6DuxuV6>8Ziw)I0Wb17n74{j2akEOzBO3twM;Vbs8;a6Ng>z9W@v5rwRDAIQJ zHg1<)JIQWi&VSu`dT93RNp=^^&HfMR6}@YEnAB%4PqKTvX{`@=;{Q;#5{*MKTMrc4 zvPuO`#ro>)wCIaBFWe&kAk?z{1!JR_ya~2DTF%Xe%>$Qz8Mh|KIpZ3kePXcFYct=A z*!aP@)~IcGX#fARQI^*MHhL^b%1Nw8r5^)ryuG$Z+ccnTeliP&&!h;u8m85gsB%aHcB&V**4 zhuSHS32u)c+q{#HbHF5SW=PRLy`xqyEYLilAWIONvoWo(A`MCLun_gZEGj9 zZEfezwv+62&bW4ae7IFvsewvq-^s^fROVLB)%JS|M7WD`EV?^xbj$g@_rhQw$DTIM zOZR7ov_r|A>ivqw^n&11@fAl|>V6x{W*+c$M*L3#xiS~S>A1@vs%YmVHyCT+j z--6)(ZJ1%v@&d14^BRr8cvTbT%U)jIE;57@5UwMbF4M5h!Jki7Cg+XyVHktS8(n6C0MqfuZi`KV)XsLiWA#N8hI$-zQ)C-;RZNgO$_JoTL2M{k z2s8s1Y3M`iEqu}Gy+3!a&N z`=CIfk^uI>SpI`B7PPG8JW(QJ-Qi3-)aJ8z{Xkzi^4yBt5;pI^PN&QmXZ84~oOZ|l zC>m-tgirH;&xMYmHV3*UZcn>r)W5ubpa zgna<}8uktB=9~cy%U*=I1iK8o0{abi74|#qmUF0DV)z9p&Js6-*qOHTX@MHqV|{iv zdjL;y<5i#CE;!wrNLGehJy=;B;@wejvG*--C;doJz;Oa?uYe;^?~uw`xI06haLbM z2pa@*VA-?t+at4s3fZ~-7?d6V-FuLa0->T9H*4ZgKEzz~;x^|{oN=^5%vlH-uh$d` zgh68T8w=eP@nd2&pa;v3Ygzd34BDS~*OxvfgqQY(E}MVUoz51kgd=%iJd76@Lrvav z?m9oqyGd-kRnTshFVKJ`?M}W9IIIsFG5cysv}bo$jxA+(bX~5NvU~aGp?Y3{z07KY z&4;lX7a(2;TLfDSTLN1OTLxPWdlj|<_8M#@Y!&Qv*uP+J!rp?t4SNUnE^IYy4Qws! zJ=i)}PB1RYo7rE**d6`5u>CdcbJ!QKFJWK7cEk3-_QLkT_QMXq4#Ez>4#SSXj>3+? zj>AsCPQp&XcrM={{uXu`b_Vtx>@4gY>^$uIU`(g^RQMz8C)m%hUtqt&F2F9rF2OFt zuE2hSU4{J)`#0Gkw@+s;WZl^g7@ z#C-@25wpoTUN#czD27YQeO(xl^^n0Hmf!PY9DiRBW2G~_WEd--VXGLs*T(_ocTbj% zyw&lf8F-Rpv}hEZ37167ZH}WAp}QfjB*w!UL33cdM~uFFvMG+Zv%z{o^TyN5WwW|%G31$vIyA~8-C7mIx&#*DW^bLr(XF`n@@`CSy_g>}gSeyx1Yfu9{jRc zD)dzDKv*osSVwc2bf?XC1#%cg+%5U`s48aCN`v7!b!RsLQ zfEe3*sMy0|=?RE&QQiWw_W0P*oB{i>NSIlEW2+QK$+_mZh_l{7u5%#lO zD_eh5J^MO|_jVeahK&0w+@-EtK<|k%7|)R6uTYT0|JmtrvD!&fkggI&)M^ zct0RkC!g~}Ct*VsP&ZI@1wwp%0sFIl@(+OGWr&b%N7+r+mCX%y^R5|iMm_hyzMgJn z^4U^prFpxWzb3ap!_y}qs%zCf$8oa5g zo3nRjb?2?@e9r1kMeSl-k9Ts%6~$6Wq+7j(SaB(Ld(_IiH54$Ufu_)6BG~rlhUm?D^BZyN#tFe0wZ=3D`_|pr|0>iCNn4=HElfVE>e}-5c zo$NX(PUBkn@>YHQ8OSDF$Jpr3L9k$02#l|qgu=pL;jjo;K3INO0a!s8v!q2q7l!e^ zgLjr$MPbEY#bG62ybqOv#lYxa265RC3}odXVqrC~9YhmYI;<%y1C|ME z25Sy$0c#0s1#1m!18WOw2g6K#Pfl)JZ#(;BA-m$nW>NOwV1I|Oz!b0xVzv$M4I`jA zdW|vILg=Poi^M8IpVsKMQLF;k0cZ}QhYfaI?37q}?Ee`WW%64W1etLMG%hEUT@kY| z%w#k6GfWg44Lu2(VT!??6q_M72K%29d)8pH#9nlnKaj~B!Oe1H=G&pu5r1K@lhAF! zPKmXH{s5Zcs@N##-^H#O?7G-ZgWd8A21f+Wm}S2jKg(hXoituycLfYn<&O({m?BD zKPiR_$C@m^kHolw@o~Ob{6+XiuqX7la=bw1G%fa9LA`4Zi{W^OSkA2yw*8+=1a?hl z#Q0=q+2ci>DdR%$%_UPT3IY zyX!*vZ?6kAaH_RvdB=;fb0)Yi+}bVN8p^v5^EG$({@g*WRv>#%GG;k=-8MLhbDD(% z>=JxEEm?4HQhKuU5m(-2BgIyNO zhhzdZjC&!IM5ri6o(`ReI8*Ei=oI<2H2gY3^TD8#7zc$`emM>@9G`$r!%psF2IFCa z;{uTqWZi?LsFu(iQY8BuvOd}980}egK#Y%{gCqq|5TtSRe`I7QWGyEDr z55vAjV!WR=f#$6-%U}}=p#9knQv}yR*M??zR_qz*Sz<4W%>tV(HcyNL_Df<*#hBqT zv8`fUJos2_r(ZA`@E9})^OItQpie`y)0`1wRqujkxFOab`fstQf`J+&D-6vLC&rPW z3UnOeR5AZ_Y{bj4l_0CS1M~pIUBpEJH&n!%K*D5_Lmrs4T;1bgmA>nqaN&r{ECRVZ+owf4KCi)5ajh< z6q=!(7| zR*6jmdtGe37z^{h*mf}vQai*BA;uj47LZj~`*D)_^QymC15-vpNVF5(E>) zd|)-9nPyWlYA)FE$^R3v1Zb{;Vg}=`gfcxcu40m5CDYA=oR2eX7CzE&+iea$yOhKR zpIHcLd>n~K%*PRK^9GfKgc!VqJ1*jN!G4Cm@{5JOPi&Z2X|M;y#)&b#$M}H8@RT6+ zOgTO)#%q2aG#^1;GT1_~MFx9SY=s!_3A3OX)`?|7=ZI|%(dEc9+yTe~K9eKQWQ!d4 zh_Q|LihV7{S~w4#iTHvTn~p1rX^3x%aYgeRXa*Y&%rlYaA4G42qJov6i-|oX76iB)J_U(lnKDPyP9V4_C`td-l^Z3kFx<|3Qpu0N`s!pi8 zTk9&(X+Dk*^Rhcvv)g8GPemz%W~4e#FDz*nykm_9Z!ol5xob3mwV+UE+5Vz-6v+=RzWFEz8%s6*l#`{E18~Asxv@S&Vs~@r#(b+Cr~DoEM?32$^thuXJ>Lxa8tLLauUHLbC*b2%dY1e4 zPORjXbe2shYFBn!PA{a|DehLFrrb9W*YT30sCm$R&NR%rHumUel*k5!9&Y}gQc5FRHIoyh&~Zrs<( zuHoAlRNcOre^m!NXhSzUD9E3RUh`*I;9BR6BnF+3*L^uJhAzpDi4Z4N2D*e;f><;i zpgF83iWP(Y3u!YX8>}KU^GylI=*rCK*hH|o;n-5FmBHGGwG+cCuhmhkv*E|}9%j;A zj6-}cvA%hJ7~RGQjx!v`i%l>X7l@ePWP@>mh-|9CxL8E?j2KVuIkD#rHk*v2>&pgQ zEXO5c*loQE&HLIa!|zRK-Z^s&zfJPnV)z|`=Gx6s!|#OrxZuQ(9=O$i8XFvG&&ZLb zJ`2tEJSWDv#0F@F@5QKpf@T4KG1wI`Zv~6h{|6Wg{ipmQk-rs+1)bV}VTf56-Uhfz zMaC5>GKPZC%!F^>@mO)Ok_L+vix*?Y3DR6V@{XrKY?=M=2FV1GHrgAJB`P%$$Z1kGFg2!oA= zW*B3zZqTt{W5u|CGBj(@Z!kaC;0Tu(@Ex($Vl4G~Xof8Y`%vslF&1!-n759{V-JDx z`Q(VNphCIgLwCqT1}v&4ADlf<|f$V?a(LbK3|#hAxC(7Y5^ z8*D9C6$#%n;Ciw5#Y$lR2CX0X;`ZM_98X3`muovW)HS?XS5y~XI) z9Xb(lA2CSlerOh^zZmxqkRE3EJtV*3V*WTdKBA4s4aW&`oG8YEO_KIj+<>g<@_S1A znDI>M*^22mPkt|pv5DWvkL#b+`lcY;m`ieGT#jSYux(dMf2x=VAAwFmd{m6b9uqq* z#$!)OdnWBG%Plow+ug451Eaa zwZ%Mq()qa9<-s_>hS_CStrSQ=oZl zx>#A{Z#BgRLpwoc(hr)0#Q=j15*s4M>aPIJ^`&8k-xz2XW~>+sI0L!~;-|z|z?o!h ze{W5Y)9Sf^p@_YuK4!wTMP7a@bubg$49zy)BE|%{oJZy@<NijrLEdC@TjuWF_yjX%5BC84h@I=zZ=+{)tTQ);Et;%#}`*Z!w z>u}9oh~ZR>E{{UPSU_*-kQvVwn`8JbgXX}soQ&;H$5#bc z7>-;=WVLb)(JSBvv5kfw*AtoGXNKQSv0aAWF=)4m4L|=0!IOeKyDiWRUyD(H2hCbI zC&sJf2k3f;e-uMx6~M%RnG{6q6*^L^kQn`9pmB13tF+-*CIGFnVk}HLG)K6WVvyE- z&@4ZLq;G-f)~K_M#XI^9D2vvs#R2vRV3L z!*3Hb!&hQFCL+p3Rw8273_~+NHh3m21er+>XkPEV497w88)~qJ#D~C3OWhWYrEDYOjisy*8PtD?oPWi;(mYFMwEFz1?36$5uJU9H+bF_NTR& z;B2vZhTltK^Tp`51ja7AREz~&1|wUJ{M}3tS*u{|F>k<_G0%7ltTJpXjEoDppTL^J zcEZS*;4WB4*lrjZo9s0h!#)^U9PA*B&370^=4T1NhY|h&BV>Xf%pp~qVJp&2R|e*C-w6Rc*i zrec}d3!B)btFjE0fEc{*g`nn_aq&>^?enbY?%Dey?IQUe(5_*2_KhlbjGw1F5v(QR z$%yga4NuBX@1l3vOfi0p$Mah+w#i`pVh3iQYp`F%_`NIm?}n>3x+fj~ZNTet{L5hc zd=LHdA?Cp>wD+YC{AdpuLyG+P?0gqxl_iGC3q?1{4lSr~q9i0oxCPO$hb z6J!ewwp47H7<=||u~)^I-V*2p#4E(;_ZqaH39b}`wBCm1*}ZG94Pu)Nwq5Kqu{a#F zQ~C?T?@RgZHvGJ=yg0z`&tNU_+B*mbju?mK$PykAJ0=EXorGoqzZOe`{zm#c!|%NO z`288ogK7UL?R||6hiB`O9It36+x;9g13&%hwL5cV#zFYwvHW5M#aPwR(7Z{M5@UL$ z#mX8ij*P=2Uz%isbj*aVg1EoI28sHi^YSZb}Wg(lu177P8E zt5N@73DS|Dd%=JA6<;RE!tB?6e&&TN5q3iQYsI`9@pCXu5POUr_#3ga@?)(YgXU8M zKMUhdqM_Z-!C*V@qamE3^P?fmke`8J%xdLlW?C4G&nr{VNqHH2A0dHsKPSWV_&FKx z*jv!-n0%`+84Kg*dxZ%@1tHz{2=idRN7y?!A2cr^zE_xxf$tTjAKxoX#!kq$0&~K_ zxBrr{7Rrn9t-xM-d>b%M$nU=I*K_3ie|eUC&D?Y3`+Ye_Yazx=?uD+6xVIQH=_BU7 zR?c+#fiVo1UmWx(X}ms;Jb3*fjK>DgBuhJa@CaxIzGlwCF!1$m`aN&3`C<#iSitqr z$%x+sw zyw}g^7mgi?i2V@|UiIe_%rC~d7~d(t-Wn^$gE?PgNEM^53C)^GGgzirbAz=KYZGA3 zz28;2mNz16jM!K)`b~po51THA$eJPclo%)YHK4iX^okhUbUifh%^Sp6 zRh#|V_((A`*$3Sa@qRHx)&a4DV)Xl7><2MK){kO8iLs3qaRI%lj$7gw5KR!d<2hFO!UyR50knXRTJ-c(Lu0ih;PGA;4 z*~A1#8;%p98J-lQepY_Zi7}J;&}`RN#F)tWuF-WTr zG!rarurgxh#Nx0&Ryt8JJ6w6`%8Hpsau~)yKC7Cr8XS0b8FFL++ljRoW9RBC*3V#r z#0DE|sMs)rjTL)54DHV|W``RuI6;mq;UuvsVnFW4E?5go47LKAY^4|r_y#mbt2Ygn z4V?(~mRL0V-^+q;dl2kJXoh#iSeO@}*(9qCwvGT{tyq2N9nh@7&&1g7yTraQ*jLc* z8yR*RaGxCai*b&{50Ws!gJK+<4vBdmE@2HG5j!eB*1}2XnuyOB>>TtxV862cy$*L3 z@JT$6R=|#_h{+jdK(lIRibX;{Ej`;{4m7KKo)`=ClGw|J-vVe3^$T5w`lsU}!NrE- z`(hi!=(ka9li~LjG|y(Y;kQR@ui~;1cV*a9ntk%-dyjIH?j%CHl8Ggyotitk!Uj?y>hTpx= zEMRZLua8*Y04w6&en$w7Ec`d#!{&tCKitMAq%sTFKymq|HZL4~uX96ATfMUwrQ=2i z5_8j93e8*eGBGyWa-q7L-6zKbf~>vc(6NY5 zc#hB~#ZHLHmlL!S|2VZMXr4eP8J3w=)Pyck;48h}5{-}*t2H<+KHIVZa$#==~K zPDXrPj0yfFc0&xv3dZot!uSxgRyocT<&cX|T8!y+faciJFHRmnw@Qg z82v_yjS^!f&qG&4yiAO*tl7})f6K)nt=FJgz*S@g-R@8!@Yz)fxrOj0=nL zM54ut7=CfkJT@M&``Ap!1i?hZ5nt}(CRj_1eraO04ZjR%4$ql}Uo)}hhF>?a?zjE? zRu93Rf^5&;(Convi9uSAK(p;e7;KW*6Jo4|XQAT}&k|#ypA&oD@LK>~jqShCa9rd< zJdqfVZ$UG`w++8{#NIXhwupUT_k4EOD|F!0k#sFL+e{&d?I>P`fbH5 z;0$Pn^~-}hoah_Mz9 zLo<^L2D>D7Sq!_aD$U@{UY&}V?ani)2c3Ypz8I^z2{cEz3^5ik6FL!b^X$Jy+oj#t z2c84syybbr?FF$H#dsb|pgFKEHT;%|EjRo&LDz!cX2Wlb*awE+?qax-=(xvl+$+a@ zV!XXpbrS6CL9i}jUB%dP-Nd?!v4DM{%Ok!|jAz_m zY=FTAiw!YYFKFg(4HZNevko%_gi&H__o>j#Y?>GgGhJ+k;WrnW{m3!==83&z_-%w{ zKi^aw`Lp_&;AX)shT~D_Wb8X8M!(}?C&XB=U!WN-h;b@17MkZ0g-f4#@I*48nQ^9= zkLTY^u({#bOYGh}N8Db-`WSvA#YP!^qs7LEv4C$#zoVE1TMiw=`rjnT#py4k4=M(- zeuidG|5c1v?`7#f4ZrL1yJ0X6`#d%XvDeW*z<%B}LcrWRIZG3U4JKUBaEyZHS8s-Se=Q|wG6+e^2;#%(xjUyMw9rh=Gb6qS_-m_TZy%~?Pzs?<{;Y9@arVj+3*_z z&Ga5H{Dz7RGyEn(r?CAe8IF@(XjxAfj&sE38h(!0JTcZ_0yL)|Tf`u(kDyuo9~*u< zpjp#jk+J>RK@JHXmLu6wv14M)WRKW!F(B&l zWXbwUk5SBnpMz#6dtQtOzaaLa7z_9~G^Zc4#i)xxGt3oZdTXGW-ddNT{+Zx=g6rf6 zWNm=v1J6b=p24TkT#ncw#stqnb0T$KjOl$Z_JbG;_&ziX^`jV%4e{fmPloUz_C~@` zu`n?@mVvH;xUAtym|5!mDJPjKEt?6R!851CU zAx8Z-G!MRIuxL1w6-Dd~G#Su*l`c~Z(wZc{Cj!jxR&fh#FwBx8&v+3uYRXzH#%f(6 zw$$)jEw;w+TPyaS;g<`|cK^ii+r}552|qO)4?@R-9Wopbiybli&O@`^zc>7T5c|>a z`xBZ?e9iE?F7_ASfWYeF85h8XOUHtUy}l4BR!Ge43(#&~F#O7i#fq`jnoGA=%qGr& zW*BDpS&w3aZ8y?ze7uZv^m;{94;M0CFm}v?W~07jutm@e%f-045`WSVuM%VXy)O2K z7_a%)#NHC)8GZ`QX4&o+w zSw89FirwjP32g9=5+le2ON*5gW5$)CSzA>Mzp7%XVr+wJ$e05`H8HNf31jl>7RyQNeo?_9+yGPGv+agV#x-Jg~nl4`EqD~ z&oKqCCSWzgu|70Ix)|qOS9v5t8!=8Qw?gwplUy;@)(Plj#3#jAtEa@i_WY2)by4t= z;doi>iWnafeuri#gN9_GnMph}XQT;Y%p_4P$?!`Nt7Q09hW7K|Dh4bI&5$a_Oxi)S z!?id3I*4^N{Q8RxF#HCJ4HDytJOIt`d@QCX-kHn=*h^w8%mT56hTkHw z#Rhu;nqjFJ`@(C`afsK5xeHy#v4Q{A2|;FjQtXr%GrkPXTDW5P{U&x*jG253&2U4E z$5xFC9Gi-mC(Jymk@+F2LlE+MuO;0=F-A|TFEqozxPTw^2x#{HQHXggGae7kzBvK0 zmr0h`Brz5y8=9BJz1Q#H-U&?RSM#;XQ*8VS{*;l?2gS5VZW+6@^rXSn( z3^Yf@vxvQ8&p|f?`(BLW!AxkL@DE~;)&*#$cNwueapYM=#Rp1T7%>whD<)RlU@_3$ zv9GkjVxjr)Skqv2pqWOx7^Ia6&5WCiv6lQTw9(ptZKXRZ=6LXP9R4757NhO~%>;Xi zF~bL;c?CaWu#wOlutteNT4SMcY>f4o;n)qDVFFq95!+5d`>+?i0Dz8Wy(niEeTmpo zG5ReNTW5yClZ3XDUH~N*k%k174wG)(lHU5GlnF?FjD&A6=?FP9#!Jy#%%-$$Hb^lLI)%Mns*Mi zCm-NG1Z10>mLuEv2eF^Tn8~kVmko9mx+?blB?f8PsOMnB{7Nt8!DADlIh3Y&4EbAC z1XDc-b`uFP)DWXigJyzt4Aw}ju^2OH56wGMAH(l{`SmyahC;jVY#nYmj*#Oh!|`!w zUL{!uni=`WF9mu3-3QHZIL{HYPWgQ!#;fEaG^bma#CVll z7P}(G^iD%FTovQ7Q5a-m+5Uwg*g<%3G$G<5VvtsGXqLL97!OW^W);>J^Fh}Ut1Cvo zcF?>zwHNb2cM$7{*j?D8<3McGMLYkXDGwoQx${1KX$-Opky;IA%2 z{a+B|^?pT;zZvY`Vt*LyPqAxa9K^1R{UzoDyCL?s7z?u%n&B21+n>RQ;;|OO5PO3~ zacKIM5aVbT1kF%Zj5;2g$0iz#U#de^*pqXG7 zF&;bux)S11VyxE3#l{IWdb-#QF(24d zVl%~ntl7{k^jt9(dJ#0I;EP>``sW!xj}3-pa-?1X&4X8p@!)r%dB$tRcqZ$_a>V$E zzEygsVjjBzn&G&?R{62Pk?VvY9Zo|t^w`G7k7kkO}S<+b0HO9fD@Z zJR-*0IuFh8hZqZ304w_(3ko9k?j@08g~aIhN(Eg1421=mU{Pp3$&?f0{v>E-T;A|& z4c!QAtih&2vpJ`W@hW**>{&5hp7Wvc-&(+xOO~)c>^Z?Da%5p%6o4)Z+!b%4A_7ZhZIQP51Vs2E4R1RY#l49F@4&6+7K#zNPI zX5XnJ#!EFxx}M?J2HH=@wuWPU>Gq1*P930Gz|LaqA6>+{i}5N+gyy`yhZvtN5}vDIR%;f>NC8tfx#gWP+bU z^NQLb#sohT+a<;}J_XGt`9_R=<^nXvDeIyb)3b56s*N}Zv3Ds3i-jQ0oBx%<2Csq` z!?Cnj88IeU9l8eM8irp@v08>-D`;li+VE>5*7mla-x`Pwp2;A?aj@7BF`jW9=<0|c z6k{9zhBIY&Sd49a1&nPxT#SXD0$mI7lVYsZsV+nPPZI>Qo`L4&G)s(w#dFg048ND< zH{bAEF1^z5dtH8Sim{n;pm`;KO2+ml{7epe6a!iNpjns$V)Q!+%{D$Q#?EzC`bWh; z*3Zy9_E#}pO+lFUun$BjCi558Myz61R~&RQ;sh~PSE5+57?4#FnweA*V*#r{v-)d^ zu?Fi%H&6^@HG;;meygz{2Zol?Z51=Y7SOCNk3m`;!I*Jp`H|f#)<=wm7zNE&LB< zhO*Ffj5Szgv3m@bA=b=b-NbqrjK2%X^hOwLwAjP|WB1-NRy#)+lJ6$QUt>dSj)t48Q5}d&=`;{m;~fV>m96<1#Uh)yt(SaL7=GvE_q`Yk_=EIi!|%HM zZWt^A_j?v5l5dgr2A>jwF^D~uAeJl^iG!*_`0FqY!oy@mKe1kn#VqAuo+}*|5*ln zL5_0`_LA6qgDnzUA{K{qmP)^7_^p!P8wPt2ncwc#Y0b(epWF%>mumdh!>0TM3#sxb(!ja1vYplE9D4jtrlA=76bc|%GPV_!&sX2Qv0oKIGiPEpLum$PlA6O>ZJ>0di8yMHx%aNeI@PP1JfqGsrD zAM7YQ1%mfgZzG}kRc{O>5Yw*}jNj(Q5GzKW3LTHQn!##9cLA#$Zh^Fj2LNB- zmEitpo_;tGKSKB*(8D||!iR2kKehrM`qjheG`>O9;c=VzY)74zaC(}iTMfzj^**;(7o7Ng#=kKrJ;ENloM+R9SY4* zQEV)9idb#2X<&84GR0V!W@25%hJtky8;rORKX@7VaL}t5LEIl_Dt`ONnam&UcJd|E zaS}c*pYwG_g6&i}6oW5?FW_7_7>*x4?)>(2@2jW z0j_-hu9I`P#i~1gb^zbro}c{&zuLrKvvO`F#^QIH_{*L6;Yz1}REVz^_6FM9{asE6 tJtdUaC4W5<-6sIk(M{R{hPmCOAJpx`0>40zi{EA(%Dn~HPkO@`{vXbOHLCys delta 4504 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 + + + + + + + + + + + + + + + + @@ -248,18 +288,6 @@ /> - - - - - - @@ -293,7 +321,7 @@ > - - - - - - - - - - - - - - - - + + + + + + > 16) | (PalColor & 0x0000FF00) | ((PalColor & 0x000000FF) << 16); + break; + case 16: + if(dxw.ActualPixelFormat.dwGBitMask==0x03E0){ + // RGB555 screen settings + PalColor = ((PalColor & 0x7C00) >> 7) | ((PalColor & 0x03E0) << 6) | ((PalColor & 0x001F) << 19); + } + else { + // RGB565 screen settings + PalColor = ((PalColor & 0xF800) >> 8) | ((PalColor & 0x07E0) << 5) | ((PalColor & 0x001F) << 19); + } + break; + } + + iDist = (crColor & 0x00FF0000) - (PalColor & 0x00FF0000); + iDist >>= 16; + if (iDist<0) iDist=-iDist; + iDist *= iDist; + iDistance += iDist; + + iDist = (crColor & 0x0000FF00) - (PalColor & 0x0000FF00); + iDist >>= 8; + if (iDist<0) iDist=-iDist; + iDist *= iDist; + iDistance += iDist; + + iDist = (crColor & 0x000000FF) - (PalColor & 0x000000FF); + // iDist >>= 0; + if (iDist<0) iDist=-iDist; + iDist *= iDist; + iDistance += iDist; + + if (iDistance < iMinDistance) { + iMinDistance = iDistance; + iMinColorIndex = iColorIndex; + } + + if (iMinDistance==0) break; // got the perfect match! + } + OutTraceD("GetMatchingColor: color=%x matched with palette[%d]=%x dist=%d\n", + crColor, iMinColorIndex, PaletteEntries[iMinColorIndex], iDistance); + PalColor=PaletteEntries[iMinColorIndex]; + switch(dxw.ActualPixelFormat.dwRGBBitCount){ + case 32: + crColor = ((PalColor & 0x00FF0000) >> 16) | (PalColor & 0x0000FF00) | ((PalColor & 0x000000FF) << 16); + break; + case 16: + if(dxw.ActualPixelFormat.dwGBitMask==0x03E0){ + // RGB555 screen settings + crColor = ((PalColor & 0x7C00) >> 7) | ((PalColor & 0x03E0) << 6) | ((PalColor & 0x001F) << 19); + } + else { + // RGB565 screen settings + crColor = ((PalColor & 0xF800) >> 8) | ((PalColor & 0x07E0) << 5) | ((PalColor & 0x001F) << 19); + } + break; + } + return crColor; +} + +//-------------------------------------------------------------------------------------------- +// +// API hookers +// +//-------------------------------------------------------------------------------------------- + +int WINAPI extGetDeviceCaps(HDC hdc, int nindex) +{ + DWORD res; + + res = (*pGDIGetDeviceCaps)(hdc, nindex); + OutTraceD("GetDeviceCaps: hdc=%x index=%x(%s) res=%x\n", + hdc, nindex, ExplainDeviceCaps(nindex), res); + + // if you have a bypassed setting, use it first! + if(pSetDevMode){ + switch(nindex){ + case BITSPIXEL: + case COLORRES: + res = pSetDevMode->dmBitsPerPel; + OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%x\n",res); + return res; + case HORZRES: + res = pSetDevMode->dmPelsWidth; + OutTraceD("GetDeviceCaps: fix HORZRES cap=%d\n", res); + return res; + case VERTRES: + res = pSetDevMode->dmPelsHeight; + OutTraceD("GetDeviceCaps: fix VERTRES cap=%d\n", res); + return res; + } + } + + switch(nindex){ + case VERTRES: + res= dxw.GetScreenHeight(); + OutTraceD("GetDeviceCaps: fix VERTRES cap=%d\n", res); + break; + case HORZRES: + res= dxw.GetScreenWidth(); + OutTraceD("GetDeviceCaps: fix HORZRES cap=%d\n", res); + break; + // WARNING: in no-emu mode, the INIT8BPP and INIT16BPP flags expose capabilities that + // are NOT implemented and may cause later troubles! + case RASTERCAPS: + if(dxw.dwFlags2 & INIT8BPP) { + res |= RC_PALETTE; // v2.02.12 + OutTraceD("GetDeviceCaps: fix RASTERCAPS setting RC_PALETTE cap=%x\n",res); + } + break; + case BITSPIXEL: + case COLORRES: + if(dxw.dwFlags2 & INIT8BPP|INIT16BPP){ + if(dxw.dwFlags2 & INIT8BPP) res = 8; + if(dxw.dwFlags2 & INIT16BPP) res = 16; + OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%d\n",res); + } + break; + } + + if(dxw.dwFlags1 & EMULATESURFACE){ + switch(nindex){ + case RASTERCAPS: + if((dxw.VirtualPixelFormat.dwRGBBitCount==8) || (dxw.dwFlags2 & INIT8BPP)){ + res = RC_PALETTE; + OutTraceD("GetDeviceCaps: fix RASTERCAPS setting RC_PALETTE cap=%x\n",res); + } + break; + case BITSPIXEL: + case COLORRES: + int PrevRes; + PrevRes=res; + if(dxw.VirtualPixelFormat.dwRGBBitCount!=0) res = dxw.VirtualPixelFormat.dwRGBBitCount; + if(dxw.dwFlags2 & INIT8BPP) res = 8; + if(dxw.dwFlags2 & INIT16BPP) res = 16; + if(PrevRes != res) OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%d\n",res); + break; + case SIZEPALETTE: + res = 256; + OutTraceD("GetDeviceCaps: fix SIZEPALETTE cap=%x\n",res); + break; + case NUMRESERVED: + res = 0; + OutTraceD("GetDeviceCaps: fix NUMRESERVED cap=%x\n",res); + break; + } + } + return res; +} + +BOOL WINAPI extTextOutA(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cchString) +{ + BOOL res; + OutTraceD("TextOut: hdc=%x xy=(%d,%d) str=(%d)\"%s\"\n", hdc, nXStart, nYStart, cchString, lpString); + if (dxw.dwFlags1 & FIXTEXTOUT) { + POINT anchor; + anchor.x=nXStart; + anchor.y=nYStart; + (*pClientToScreen)(dxw.GethWnd(), &anchor); + nXStart=anchor.x; + nYStart=anchor.y; + } + res=(*pGDITextOutA)(hdc, nXStart, nYStart, lpString, cchString); + return res; +} + +LONG WINAPI extTabbedTextOutA(HDC hDC, int X, int Y, LPCTSTR lpString, int nCount, int nTabPositions, const LPINT lpnTabStopPositions, int nTabOrigin) +{ + BOOL res; + OutTraceD("TabbedTextOut: hdc=%x xy=(%d,%d) nCount=%d nTP=%d nTOS=%d str=(%d)\"%s\"\n", + hDC, X, Y, nCount, nTabPositions, nTabOrigin, lpString); + if (dxw.dwFlags1 & FIXTEXTOUT) { + POINT anchor; + anchor.x=X; + anchor.y=Y; + (*pClientToScreen)(dxw.GethWnd(), &anchor); + X=anchor.x; + Y=anchor.y; + } + res=(*pTabbedTextOutA)(hDC, X, Y, lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin); + return res; +} + +BOOL WINAPI extScaleWindowExtEx(HDC hdc, int Xnum, int Xdenom, int Ynum, int Ydenom, LPSIZE lpSize) +{ + OutTraceD("ScaleWindowExtEx: hdc=%x num=(%d,%d) denom=(%d,%d) lpSize=%d\n", + hdc, Xnum, Ynum, Xdenom, Ydenom, lpSize); + + if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 1; + + return (*pGDIScaleWindowExtEx)(hdc, Xnum, Xdenom, Ynum, Ydenom, lpSize); +} + +BOOL WINAPI extRectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) +{ + OutTraceD("Rectangle: hdc=%x xy=(%d,%d)-(%d,%d)\n", hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); + if (dxw.dwFlags1 & FIXTEXTOUT) { + POINT anchor; + anchor.x=nLeftRect; + anchor.y=nTopRect; + (*pClientToScreen)(dxw.GethWnd(), &anchor); + nLeftRect=anchor.x; + nTopRect=anchor.y; + anchor.x=nRightRect; + anchor.y=nBottomRect; + (*pClientToScreen)(dxw.GethWnd(), &anchor); + nRightRect=anchor.x; + nBottomRect=anchor.y; + } + return (*pGDIRectangle)(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); +} + +int WINAPI extGDISaveDC(HDC hdc) +{ + int ret; + + ret=(*pGDISaveDC)(hdc); + OutTraceD("GDI.SaveDC: hdc=%x ret=%x\n", hdc, ret); + //AutoRefreshThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AutoRefresh, (LPVOID)hdc, 0, &dwThrdId); + return ret; +} + +BOOL WINAPI extGDIRestoreDC(HDC hdc, int nSavedDC) +{ + BOOL ret; + + ret=(*pGDIRestoreDC)(hdc, nSavedDC); + OutTraceD("GDI.RestoreDC: hdc=%x nSavedDC=%x ret=%x\n", hdc, nSavedDC, ret); + //TerminateThread(AutoRefreshThread, 0); + return ret; +} + +/* --------------------------------------------------------------------------- */ + +// v2.1.75: Hooking for GDI32 CreatePalette, SelectPalette, RealizePalette: +// maps the GDI palette to the buffered DirectDraw one. This fixes the screen +// output for "Dementia" (a.k.a. "Armed & Delirious"). + +HPALETTE WINAPI extGDICreatePalette(CONST LOGPALETTE *plpal) +{ + HPALETTE ret; + int idx; + + dxw.IsGDIPalette=TRUE; + OutTraceD("GDI.CreatePalette: plpal=%x version=%x NumEntries=%x\n", plpal, plpal->palVersion, plpal->palNumEntries); + ret=(*pGDICreatePalette)(plpal); + if(IsDebug){ + OutTraceD("PalEntry[%x]= ", plpal->palNumEntries); + for(idx=0; idxpalNumEntries; idx++) OutTraceD("(%x)", plpal->palPalEntry[idx]); + OutTraceD("\n"); + } + dxw.palVersion=plpal->palVersion; + dxw.palNumEntries=plpal->palNumEntries; + if(dxw.palNumEntries>256) dxw.palNumEntries=256; + for(idx=0; idxpalPalEntry[idx]; + OutTraceD("GDI.CreatePalette: hPalette=%x\n", ret); + return ret; +} + +HPALETTE WINAPI extSelectPalette(HDC hdc, HPALETTE hpal, BOOL bForceBackground) +{ + HPALETTE ret; + + ret=(*pGDISelectPalette)(hdc, hpal, bForceBackground); + OutTraceD("GDI.SelectPalette: hdc=%x hpal=%x ForceBackground=%x ret=%x\n", hdc, hpal, bForceBackground, ret); + return ret; +} + +UINT WINAPI extRealizePalette(HDC hdc) +{ + UINT ret; + extern void mySetPalette(int, int, LPPALETTEENTRY); + + ret=(*pGDIRealizePalette)(hdc); + OutTraceD("GDI.RealizePalette: hdc=%x ret=%x\n", hdc, ret); + + if(!dxw.IsGDIPalette) return ret; + + // quick & dirty implementation through a nasty global: + // if the SelectPalette didn't force to the background (arg bForceBackground==FALSE) + // then don't override the current palette set by the DirectDrawPalette class. + // should be cleaned up a little.... + // maybe not: now both Diablo & Dementia colors are working... + if(dxw.dwFlags1 & EMULATESURFACE) + mySetPalette(0, dxw.palNumEntries, dxw.palPalEntry); + // DEBUGGING + if(IsDebug){ + int idx; + OutTraceD("PaletteEntries[%x]= ", dxw.palNumEntries); + for(idx=0; idxlfHeight, lplf->lfWidth, lplf->lfFaceName); + memcpy((char *)&lf, (char *)lplf, sizeof(LOGFONT)); + lf.lfQuality=NONANTIALIASED_QUALITY; + retHFont=((*pGDICreateFontIndirect)(&lf)); + if(retHFont) + OutTraceD("CreateFontIndirect: hfont=%x\n", retHFont); + else + OutTraceD("CreateFontIndirect: error=%d at %d\n", GetLastError(), __LINE__); + return retHFont; +} + +BOOL WINAPI extSetDeviceGammaRamp(HDC hDC, LPVOID lpRamp) +{ + BOOL ret; + OutTraceD("SetDeviceGammaRamp: hdc=%x\n", hDC); + if(dxw.dwFlags2 & DISABLEGAMMARAMP) { + OutTraceD("SetDeviceGammaRamp: SUPPRESSED\n"); + return TRUE; + } + ret=(*pGDISetDeviceGammaRamp)(hDC, lpRamp); + if(!ret) OutTraceE("SetDeviceGammaRamp: ERROR err=%d\n", GetLastError()); + return ret; +} + +BOOL WINAPI extGetDeviceGammaRamp(HDC hDC, LPVOID lpRamp) +{ + BOOL ret; + OutTraceD("GetDeviceGammaRamp: hdc=%x\n", hDC); + ret=(*pGDIGetDeviceGammaRamp)(hDC, lpRamp); + if(!ret) OutTraceE("GetDeviceGammaRamp: ERROR err=%d\n", GetLastError()); + return ret; +} + diff --git a/dll/hddraw.cpp b/dll/hddraw.cpp index 75c63e9..5598ca1 100644 --- a/dll/hddraw.cpp +++ b/dll/hddraw.cpp @@ -591,7 +591,7 @@ int HookDirectDraw(HMODULE module, int version) FreeLibrary(hinst); } - OutTraceD("HookDirectDraw version=%d\n", version); //GHO + OutTraceB("HookDirectDraw version=%d\n", version); //GHO switch(version){ case 0: // automatic tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawCreate", extDirectDrawCreate); @@ -1735,7 +1735,7 @@ static char *FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd) if(((lpddsd->dwFlags & (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT)) == (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT)) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)){ - OutTraceB("FixSurfaceCaps: Experimental pixelformat for ZBUFFER case\n"); + OutTraceB("FixSurfaceCaps: Experimental pixelformat for ZBUFFER case\n"); lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; // Evany lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; return "ZBUFFER"; diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp new file mode 100644 index 0000000..3cb4c8d --- /dev/null +++ b/dll/kernel32.cpp @@ -0,0 +1,486 @@ +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "syslibs.h" +#include "dxhook.h" +#include "dxhelper.h" +#include "hddraw.h" +#include "hddproxy.h" + +static HookEntry_Type Hooks[]={ + {"IsDebuggerPresent", (FARPROC)NULL, (FARPROC *)NULL, (FARPROC)extIsDebuggerPresent}, + {"GetProcAddress", (FARPROC)GetProcAddress, (FARPROC *)&pGetProcAddress, (FARPROC)extGetProcAddress}, + {"LoadLibraryA", (FARPROC)LoadLibraryA, (FARPROC *)&pLoadLibraryA, (FARPROC)extLoadLibraryA}, + {"LoadLibraryExA", (FARPROC)LoadLibraryExA, (FARPROC *)&pLoadLibraryExA, (FARPROC)extLoadLibraryExA}, + {"LoadLibraryW", (FARPROC)LoadLibraryW, (FARPROC *)&pLoadLibraryW, (FARPROC)extLoadLibraryW}, + {"LoadLibraryExW", (FARPROC)LoadLibraryExW, (FARPROC *)&pLoadLibraryExW, (FARPROC)extLoadLibraryExW}, + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type LimitHooks[]={ + {"GetDiskFreeSpaceA", (FARPROC)GetDiskFreeSpaceA, (FARPROC *)&pGetDiskFreeSpaceA, (FARPROC)extGetDiskFreeSpaceA}, + {"GlobalMemoryStatus", (FARPROC)GlobalMemoryStatus, (FARPROC *)&pGlobalMemoryStatus, (FARPROC)extGlobalMemoryStatus}, + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type TimeHooks[]={ + {"GetTickCount", (FARPROC)GetTickCount, (FARPROC *)&pGetTickCount, (FARPROC)extGetTickCount}, + {"GetLocalTime", (FARPROC)GetLocalTime, (FARPROC *)&pGetLocalTime, (FARPROC)extGetLocalTime}, + {"GetSystemTime", (FARPROC)GetSystemTime, (FARPROC *)&pGetSystemTime, (FARPROC)extGetSystemTime}, + {"GetSystemTimeAsFileTime", (FARPROC)GetSystemTimeAsFileTime, (FARPROC *)&pGetSystemTimeAsFileTime, (FARPROC)extGetSystemTimeAsFileTime}, + {"Sleep", (FARPROC)Sleep, (FARPROC *)&pSleep, (FARPROC)extSleep}, + {"SleepEx", (FARPROC)SleepEx, (FARPROC *)&pSleepEx, (FARPROC)extSleepEx}, + {"SetTimer", (FARPROC)SetTimer, (FARPROC *)&pSetTimer, (FARPROC)extSetTimer}, + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type VersionHooks[]={ + {"GetVersion", (FARPROC)GetVersion, (FARPROC *)&pGetVersion, (FARPROC)extGetVersion}, + {"GetVersionEx", (FARPROC)GetVersionEx, (FARPROC *)&pGetVersionEx, (FARPROC)extGetVersionEx}, + {0, NULL, 0, 0} // terminator +}; + +static char *libname = "kernel32.dll"; + +void HookKernel32(HMODULE module) +{ + HookLibrary(module, Hooks, libname); + if(dxw.dwFlags2 & LIMITRESOURCES) HookLibrary(module, LimitHooks, libname); + if(dxw.dwFlags2 & TIMESTRETCH) HookLibrary(module, TimeHooks, libname); + if(dxw.dwFlags2 & FAKEVERSION) HookLibrary(module, VersionHooks, libname); +} + +void HookKernel32Init() +{ + HookLibInit(Hooks); + HookLibInit(LimitHooks); + HookLibInit(TimeHooks); + HookLibInit(VersionHooks); +} + +FARPROC Remap_kernel32_ProcAddress(LPCSTR proc, HMODULE hModule) +{ + FARPROC addr; + + if (addr=RemapLibrary(proc, hModule, Hooks)) return addr; + + if(dxw.dwFlags2 & LIMITRESOURCES) + if (addr=RemapLibrary(proc, hModule, LimitHooks)) return addr; + + if(dxw.dwFlags2 & TIMESTRETCH) + if (addr=RemapLibrary(proc, hModule, TimeHooks)) return addr; + + if(dxw.dwFlags2 & FAKEVERSION) + if (addr=RemapLibrary(proc, hModule, VersionHooks)) return addr; + + return NULL; +} + +extern DirectDrawEnumerate_Type pDirectDrawEnumerate; +extern DirectDrawEnumerateEx_Type pDirectDrawEnumerateEx; +extern void HookModule(HMODULE, int); + +int WINAPI extIsDebuggerPresent(void) +{ + OutTraceD("extIsDebuggerPresent: return FALSE\n"); + return FALSE; +} + +BOOL WINAPI extGetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters) +{ + BOOL ret; + OutTraceD("GetDiskFreeSpace: RootPathName=\"%s\"\n", lpRootPathName); + ret=(*pGetDiskFreeSpaceA)(lpRootPathName, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters); + if(!ret) OutTraceE("GetDiskFreeSpace: ERROR err=%d at %d\n", GetLastError(), __LINE__); + *lpNumberOfFreeClusters = 16000; + return ret; +} + +/* ------------------------------------------------------------------------------- + +GlobalMemoryStatus: MSDN documents that on modern PCs that have more than DWORD +memory values the GlobalMemoryStatus sets the fields to -1 (0xFFFFFFFF) and you +should use GlobalMemoryStatusEx instead. +But in some cases the value is less that DWORD max, but greater that DWORD>>1, that +is the calling application may get a big value and see it as a signed negative +value, as it happened to Nocturne on my PC. That's why it's not adviseable to write: +if(lpBuffer->dwTotalPhys== -1) ... +but this way: +if ((int)lpBuffer->dwTotalPhys < 0) ... +and also don't set +BIGENOUGH 0x80000000 // possibly negative!!! +but: +BIGENOUGH 0x20000000 // surely positive !!! + +/* ---------------------------------------------------------------------------- */ +#define BIGENOUGH 0x20000000 + +void WINAPI extGlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) +{ + (*pGlobalMemoryStatus)(lpBuffer); + OutTraceD("GlobalMemoryStatus: Length=%x MemoryLoad=%x " + "TotalPhys=%x AvailPhys=%x TotalPageFile=%x AvailPageFile=%x TotalVirtual=%x AvailVirtual=%x\n", + lpBuffer->dwMemoryLoad, lpBuffer->dwTotalPhys, lpBuffer->dwAvailPhys, + lpBuffer->dwTotalPageFile, lpBuffer->dwAvailPageFile, lpBuffer->dwTotalVirtual, lpBuffer->dwAvailVirtual); + if(lpBuffer->dwLength==sizeof(MEMORYSTATUS)){ + if ((int)lpBuffer->dwTotalPhys < 0) lpBuffer->dwTotalPhys = BIGENOUGH; + if ((int)lpBuffer->dwAvailPhys < 0) lpBuffer->dwAvailPhys = BIGENOUGH; + if ((int)lpBuffer->dwTotalPageFile < 0) lpBuffer->dwTotalPageFile = BIGENOUGH; + if ((int)lpBuffer->dwAvailPageFile < 0) lpBuffer->dwAvailPageFile = BIGENOUGH; + if ((int)lpBuffer->dwTotalVirtual < 0) lpBuffer->dwTotalVirtual = BIGENOUGH; + if ((int)lpBuffer->dwAvailVirtual < 0) lpBuffer->dwAvailVirtual = BIGENOUGH; + } +} + +/* +From MSDN: +Operating system Version number dwMajorVersion dwMinorVersion Other +Windows 8 6.2 6 2 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION +Windows Server 2012 6.2 6 2 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION +Windows 7 6.1 6 1 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION +Windows Server 2008 R2 6.1 6 1 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION +Windows Server 2008 6.0 6 0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION +Windows Vista 6.0 6 0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION +Windows Server 2003 R2 5.2 5 2 GetSystemMetrics(SM_SERVERR2) != 0 +Windows Home Server 5.2 5 2 OSVERSIONINFOEX.wSuiteMask & VER_SUITE_WH_SERVER +Windows Server 2003 5.2 5 2 GetSystemMetrics(SM_SERVERR2) == 0 +Windows XP Pro x64 Ed. 5.2 5 2 (OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) +Windows XP 5.1 5 1 Not applicable +Windows 2000 5.0 5 0 Not applicable +From http://delphi.about.com/cs/adptips2000/a/bltip1100_2.htm +Windows 95 4.0 4 0 +Windows 98/SE" 4.10 4 10 if osVerInfo.szCSDVersion[1] = 'A' then Windows98SE +Windows ME 4.90 4 90 +*/ + +static struct {char bMajor; char bMinor; char *sName;} WinVersions[9]= +{ + {4, 0, "Windows 95"}, + {4,10, "Windows 98/SE"}, + {4,90, "Windows ME"}, + {5, 0, "Windows 2000"}, + {5, 1, "Windows XP"}, + {5, 2, "Windows Server 2003"}, + {6, 0, "Windows Vista"}, + {6, 1, "Windows 7"}, + {6, 2, "Windows 8"} +}; + +BOOL WINAPI extGetVersionEx(LPOSVERSIONINFO lpVersionInfo) +{ + BOOL ret; + + ret=(*pGetVersionEx)(lpVersionInfo); + if(!ret) { + OutTraceE("GetVersionEx: ERROR err=%d\n", GetLastError()); + return ret; + } + + OutTraceD("GetVersionEx: version=%d.%d build=(%d)\n", + lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, lpVersionInfo->dwBuildNumber); + + if(dxw.dwFlags2 & FAKEVERSION) { + // fake Win XP build 0 + lpVersionInfo->dwMajorVersion = WinVersions[dxw.FakeVersionId].bMajor; + lpVersionInfo->dwMinorVersion = WinVersions[dxw.FakeVersionId].bMinor; + lpVersionInfo->dwBuildNumber = 0; + OutTraceD("GetVersionEx: FIXED version=%d.%d build=(%d) os=\"%s\"\n", + lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, lpVersionInfo->dwBuildNumber, + WinVersions[dxw.FakeVersionId].sName); + } + return TRUE; +} + +DWORD WINAPI extGetVersion(void) +{ + DWORD dwVersion; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuild = 0; + + dwVersion = (*pGetVersion)(); + + // Get the Windows version. + + dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); + dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); + + // Get the build number. + + if (dwVersion < 0x80000000) + dwBuild = (DWORD)(HIWORD(dwVersion)); + + OutTraceD("GetVersion: version=%d.%d build=(%d)\n", dwMajorVersion, dwMinorVersion, dwBuild); + + if(dxw.dwFlags2 & FAKEVERSION) { + dwVersion = WinVersions[dxw.FakeVersionId].bMajor | (WinVersions[dxw.FakeVersionId].bMinor << 8); + dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); + dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); + dwBuild = (DWORD)(HIWORD(dwVersion)); + OutTraceD("GetVersion: FIXED version=%d.%d build=(%d) os=\"%s\"\n", + dwMajorVersion, dwMinorVersion, dwBuild, WinVersions[dxw.FakeVersionId].sName); + } + + return dwVersion; +} + +/* ------------------------------------------------------------------------------- + +time related APIs + +/* ---------------------------------------------------------------------------- */ + +DWORD WINAPI extGetTickCount(void) +{ + return dxw.GetTickCount(); +} + +void WINAPI extGetSystemTime(LPSYSTEMTIME lpSystemTime) +{ + dxw.GetSystemTime(lpSystemTime); + if (IsDebug) OutTrace("GetSystemTime: %02d:%02d:%02d.%03d\n", + lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds); +} + +void WINAPI extGetLocalTime(LPSYSTEMTIME lpLocalTime) +{ + SYSTEMTIME SystemTime; + dxw.GetSystemTime(&SystemTime); + SystemTimeToTzSpecificLocalTime(NULL, &SystemTime, lpLocalTime); + if (IsDebug) OutTrace("GetLocalTime: %02d:%02d:%02d.%03d\n", + lpLocalTime->wHour, lpLocalTime->wMinute, lpLocalTime->wSecond, lpLocalTime->wMilliseconds); +} + +UINT_PTR WINAPI extSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc) +{ + UINT uShiftedElapse; + // beware: the quicker the time flows, the more the time clicks are incremented, + // and the lesser the pauses must be lasting! Shift operations are reverted in + // GetSystemTime vs. Sleep or SetTimer + uShiftedElapse = dxw.StretchTime(uElapse); + if (IsDebug) OutTrace("SetTimer: elapse=%d->%d timeshift=%d\n", uElapse, uShiftedElapse, dxw.TimeShift); + return (*pSetTimer)(hWnd, nIDEvent, uShiftedElapse, lpTimerFunc); +} + +VOID WINAPI extSleep(DWORD dwMilliseconds) +{ + DWORD dwNewDelay; + dwNewDelay=dwMilliseconds; + if (dwMilliseconds!=INFINITE && dwMilliseconds!=0){ + dwNewDelay = dxw.StretchTime(dwMilliseconds); + if (dwNewDelay==0){ // oh oh! troubles... + if (dxw.TimeShift > 0) dwNewDelay=1; // minimum allowed... + else dwNewDelay = INFINITE-1; // maximum allowed !!! + } + } + if (IsDebug) OutTrace("Sleep: msec=%d->%d timeshift=%d\n", dwMilliseconds, dwNewDelay, dxw.TimeShift); + (*pSleep)(dwNewDelay); +} + +DWORD WINAPI extSleepEx(DWORD dwMilliseconds, BOOL bAlertable) +{ + DWORD dwNewDelay; + dwNewDelay=dwMilliseconds; + if (dwMilliseconds!=INFINITE && dwMilliseconds!=0){ + dwNewDelay = dxw.StretchTime(dwMilliseconds); + if (dwNewDelay==0){ // oh oh! troubles... + if (dxw.TimeShift > 0) dwNewDelay=1; // minimum allowed... + else dwNewDelay = INFINITE-1; // maximum allowed !!! + } + } + if (IsDebug) OutTrace("SleepEx: msec=%d->%d alertable=%x, timeshift=%d\n", dwMilliseconds, dwNewDelay, bAlertable, dxw.TimeShift); + return (*pSleepEx)(dwNewDelay, bAlertable); +} + +void WINAPI extGetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) +{ + if (IsDebug) OutTrace("GetSystemTimeAsFileTime\n"); + dxw.GetSystemTimeAsFileTime(lpSystemTimeAsFileTime); +} + +HMODULE SysLibs[SYSLIBIDX_MAX]; + +HMODULE WINAPI LoadLibraryExWrapper(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags, char *api) +{ + HMODULE libhandle; + int idx; + + //if(!strcmp(lpFileName, "d3d9.dll") && GetModuleHandle(lpFileName)) return GetModuleHandle(lpFileName); // attempt to avoid loading same dll twice.... + + libhandle=(*pLoadLibraryExA)(lpFileName, hFile, dwFlags); + OutTraceD("%s: FileName=%s hFile=%x Flags=%x(%s) hmodule=%x\n", api, lpFileName, hFile, dwFlags, ExplainLoadLibFlags(dwFlags), libhandle); + if(!libhandle){ + OutTraceE("%s: ERROR FileName=%s err=%d\n", api, lpFileName, GetLastError()); + return libhandle; + } + + // when loaded with LOAD_LIBRARY_AS_DATAFILE or LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE flags, + // there's no symbol map, then itìs no possible to hook function calls. + if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE|LOAD_LIBRARY_AS_DATAFILE)) return libhandle; + + idx=dxw.GetDLLIndex((char *)lpFileName); + if(idx != -1) SysLibs[idx]=libhandle; + // handle custom OpenGL library + if(!lstrcmpi(lpFileName,dxw.CustomOpenGLLib)){ + idx=SYSLIBIDX_OPENGL; + SysLibs[idx]=libhandle; + } + if (idx == -1) HookModule(libhandle, 0); + return libhandle; +} + +HMODULE WINAPI extLoadLibraryA(LPCTSTR lpFileName) +{ + return LoadLibraryExWrapper(lpFileName, NULL, 0, "LoadLibraryA"); +} + +HMODULE WINAPI extLoadLibraryW(LPCWSTR lpFileName) +{ + char sFileName[256+1]; + wcstombs_s(NULL, sFileName, lpFileName, 80); + return LoadLibraryExWrapper(sFileName, NULL, 0, "LoadLibraryW");; +} + +HMODULE WINAPI extLoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags) +{ + return LoadLibraryExWrapper(lpFileName, hFile, dwFlags, "LoadLibraryExA"); +} + +HMODULE WINAPI extLoadLibraryExW(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags) +{ + char sFileName[256+1]; + wcstombs_s(NULL, sFileName, lpFileName, 80); + return LoadLibraryExWrapper(sFileName, hFile, dwFlags, "LoadLibraryExW");; +} + +extern DirectDrawCreate_Type pDirectDrawCreate; +extern DirectDrawCreateEx_Type pDirectDrawCreateEx; +extern HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); +extern HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *); +extern GetProcAddress_Type pGetProcAddress; +//extern HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID FAR*); + +FARPROC WINAPI extGetProcAddress(HMODULE hModule, LPCSTR proc) +{ + FARPROC ret; + int idx; + + // WARNING: seems to be called with bad LPCSTR value.... + // from MSDN: + // The function or variable name, or the function's ordinal value. + // If this parameter is an ordinal value, it must be in the low-order word; + // the high-order word must be zero. + + OutTraceD("GetProcAddress: hModule=%x proc=%s\n", hModule, ProcToString(proc)); + + for(idx=0; idx +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "syslibs.h" +#include "dxhook.h" +#include "dxhelper.h" + +static HookEntry_Type Hooks[]={ + {"CoCreateInstance", NULL, (FARPROC *)&pCoCreateInstance, (FARPROC)extCoCreateInstance}, + // {"CoCreateInstanceEx", NULL, (FARPROC *)&pCoCreateInstanceEx, (FARPROC)extCoCreateInstanceEx}, remote object creation.... + {0, NULL, 0, 0} // terminator +}; + +extern HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); +extern HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *); + +void HookOle32(HMODULE module) +{ + HookLibrary(module, Hooks, "ole32.dll"); +} + +FARPROC Remap_ole32_ProcAddress(LPCSTR proc, HMODULE hModule) +{ + FARPROC addr; + if (addr=RemapLibrary(proc, hModule, Hooks)) return addr; + return NULL; +} + +// ------------------------------------------------------------------------------------- +// Ole32 CoCreateInstance handling: you can create DirectDraw objects through it! +// utilized so far in a single game: Axiz & Allies +// ------------------------------------------------------------------------------------- + +static void HookDDSession(LPDIRECTDRAW *, int); + +HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID FAR* ppv) +{ + HRESULT res; + OutTraceD("CoCreateInstance: rclsid=%x UnkOuter=%x ClsContext=%x refiid=%x\n", + rclsid, pUnkOuter, dwClsContext, riid); + + // CLSID e436ebb3 implies loading quartz.dll to play movies through dshow: + // quartz.dll must be hooked. + if (*(DWORD *)&rclsid==0xe436ebb3){ + HMODULE qlib; + OutTraceD("CoCreateInstance: CLSID_FilterGraph RIID=%x\n", *(DWORD *)&riid); + qlib=(*pLoadLibraryA)("quartz.dll"); + OutTraceD("CoCreateInstance: quartz lib handle=%x\n", qlib); + HookKernel32(qlib); + HookUser32(qlib); + HookWinMM(qlib); + } + + res=(*pCoCreateInstance)(rclsid, pUnkOuter, dwClsContext, riid, ppv); + if(res) + OutTraceE("CoCreateInstance: ERROR res=%x\n", res); + else + OutTraceD("CoCreateInstance: ppv=%x->%x\n", *ppv, *(DWORD *)*ppv); + + if (*(DWORD *)&rclsid==*(DWORD *)&CLSID_DirectDraw){ + LPDIRECTDRAW lpOldDDraw; + OutTraceD("CoCreateInstance: CLSID_DirectDraw object\n"); + switch (*(DWORD *)&riid){ + case 0x6C14DB80: + OutTraceD("DirectDrawCreate: IID_DirectDraw RIID\n"); + res=extDirectDrawCreate(NULL, (LPDIRECTDRAW *)&ppv, 0); + if(res)OutTraceD("DirectDrawCreate: res=%x(%s)\n", res, ExplainDDError(res)); + break; + case 0xB3A6F3E0: + OutTraceD("DirectDrawCreate: IID_DirectDraw2 RIID\n"); + res=extDirectDrawCreate(NULL, &lpOldDDraw, 0); + if(res)OutTraceD("DirectDrawCreate: res=%x(%s)\n", res, ExplainDDError(res)); + res=lpOldDDraw->QueryInterface(IID_IDirectDraw2, (LPVOID *)&ppv); + if(res)OutTraceD("QueryInterface: res=%x(%s)\n", res, ExplainDDError(res)); + lpOldDDraw->Release(); + break; + case 0x9c59509a: + OutTraceD("DirectDrawCreate: IID_DirectDraw4 RIID\n"); + res=extDirectDrawCreate(NULL, &lpOldDDraw, 0); + if(res)OutTraceD("DirectDrawCreate: res=%x(%s)\n", res, ExplainDDError(res)); + res=lpOldDDraw->QueryInterface(IID_IDirectDraw4, (LPVOID *)&ppv); + if(res)OutTraceD("QueryInterface: res=%x(%s)\n", res, ExplainDDError(res)); + lpOldDDraw->Release(); + case 0x15e65ec0: + OutTraceD("CoCreateInstance: IID_DirectDraw7 RIID\n"); + res=extDirectDrawCreateEx(NULL, (LPDIRECTDRAW *)&ppv, IID_IDirectDraw7, 0); + if(res)OutTraceD("DirectDrawCreateEx: res=%x(%s)\n", res, ExplainDDError(res)); + break; + case 0xe436ebb3: + break; + } + } + else + if (*(DWORD *)&rclsid==*(DWORD *)&CLSID_DxDiagProvider) res=HookDxDiag(riid, ppv); + + return res; +} diff --git a/dll/glhook.cpp b/dll/opengl.cpp similarity index 100% rename from dll/glhook.cpp rename to dll/opengl.cpp diff --git a/dll/resource.h b/dll/resource.h index 52de46d..7e069c5 100644 --- a/dll/resource.h +++ b/dll/resource.h @@ -2,7 +2,6 @@ // Microsoft Visual C++ generated include file. // Used by dxwnd.rc // -#define IDB_BITMAP1 101 #define IDB_BANNER 101 // Next default values for new objects diff --git a/dll/syslibs.h b/dll/syslibs.h index 329fdb5..c8c0163 100644 --- a/dll/syslibs.h +++ b/dll/syslibs.h @@ -45,6 +45,7 @@ typedef COLORREF (WINAPI *SetBkColor_Type)(HDC, COLORREF); typedef BOOL (WINAPI *SetDeviceGammaRamp_Type)(HDC, LPVOID); typedef COLORREF(WINAPI *SetTextColor_Type)(HDC, COLORREF); typedef BOOL (WINAPI *StretchBlt_Type)(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); +typedef LONG (WINAPI *TabbedTextOutA_Type)(HDC, int, int, LPCTSTR, int, int, const LPINT, int); typedef BOOL (WINAPI *TextOut_Type)(HDC, int, int, LPCTSTR, int); // Kernel32.dll: @@ -159,6 +160,7 @@ DXWEXTERN SetBkColor_Type pGDISetBkColor DXWINITIALIZED; DXWEXTERN SetDeviceGammaRamp_Type pGDISetDeviceGammaRamp DXWINITIALIZED; DXWEXTERN SetTextColor_Type pGDISetTextColor DXWINITIALIZED; DXWEXTERN StretchBlt_Type pGDIStretchBlt DXWINITIALIZED; +DXWEXTERN TabbedTextOutA_Type pTabbedTextOutA DXWINITIALIZED; DXWEXTERN TextOut_Type pGDITextOutA DXWINITIALIZED; // Kernel32.dll: @@ -266,6 +268,7 @@ extern BOOL WINAPI extSetDeviceGammaRamp(HDC, LPVOID); extern COLORREF WINAPI extSetTextColor(HDC, COLORREF); extern BOOL WINAPI extGDIStretchBlt(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); extern BOOL WINAPI extDDStretchBlt(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); +extern LONG WINAPI extTabbedTextOutA(HDC, int, int, LPCTSTR, int, int, const LPINT, int); extern BOOL WINAPI extTextOutA(HDC, int, int, LPCTSTR, int); // Kernel32.dll: @@ -337,4 +340,10 @@ extern BOOL WINAPI extShowWindow(HWND, int); // Winmm.dll: extern DWORD WINAPI exttimeGetTime(void); +// extern function declaration + +extern void HookKernel32Init(); +extern void HookUser32Init(); +extern void HookGDI32Init(); + /* eof */ \ No newline at end of file diff --git a/dll/syslibs.cpp b/dll/user32.cpp similarity index 59% rename from dll/syslibs.cpp rename to dll/user32.cpp index 3088d7d..1beefd7 100644 --- a/dll/syslibs.cpp +++ b/dll/user32.cpp @@ -1,41 +1,358 @@ #define _WIN32_WINNT 0x0600 #define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include #include "dxwnd.h" #include "dxwcore.hpp" -#include "dxhook.h" -#include "glhook.h" -#include "msvfwhook.h" #include "syslibs.h" -#include "dxhelper.h" +#include "dxhook.h" #include "hddraw.h" -#include "hddproxy.h" +#include "dxhelper.h" -#define WINDOWDC 0xFFFFFFFF +static HookEntry_Type Hooks[]={ + {"ChangeDisplaySettingsA", (FARPROC)ChangeDisplaySettingsA, (FARPROC *)&pChangeDisplaySettings, (FARPROC)extChangeDisplaySettings}, + {"ChangeDisplaySettingsExA", (FARPROC)ChangeDisplaySettingsA, (FARPROC *)&pChangeDisplaySettingsEx, (FARPROC)extChangeDisplaySettingsEx}, + {"BeginPaint", (FARPROC)BeginPaint, (FARPROC *)&pBeginPaint, (FARPROC)extBeginPaint}, + {"EndPaint", (FARPROC)EndPaint, (FARPROC *)&pEndPaint, (FARPROC)extEndPaint}, + {"ShowCursor", (FARPROC)ShowCursor, (FARPROC *)&pShowCursor, (FARPROC)extShowCursor}, + {"CreateDialogIndirectParamA", (FARPROC)CreateDialogIndirectParamA, (FARPROC *)&pCreateDialogIndirectParam, (FARPROC)extCreateDialogIndirectParam}, + {"CreateDialogParamA", (FARPROC)CreateDialogParamA, (FARPROC *)&pCreateDialogParam, (FARPROC)extCreateDialogParam}, + {"MoveWindow", (FARPROC)MoveWindow, (FARPROC *)&pMoveWindow, (FARPROC)extMoveWindow}, + {"EnumDisplaySettingsA", (FARPROC)EnumDisplaySettingsA, (FARPROC *)&pEnumDisplaySettings, (FARPROC)extEnumDisplaySettings}, + {"GetClipCursor", (FARPROC)GetClipCursor, (FARPROC*)&pGetClipCursor, (FARPROC)extGetClipCursor}, + {"ClipCursor", (FARPROC)ClipCursor, (FARPROC *)&pClipCursor, (FARPROC)extClipCursor}, + {"FillRect", (FARPROC)FillRect, (FARPROC *)&pFillRect, (FARPROC)extFillRect}, + {"DefWindowProcA", (FARPROC)DefWindowProcA, (FARPROC *)&pDefWindowProc, (FARPROC)extDefWindowProc}, + {"CreateWindowExA", (FARPROC)CreateWindowExA, (FARPROC *)&pCreateWindowExA, (FARPROC)extCreateWindowExA}, + {"RegisterClassExA", (FARPROC)RegisterClassExA, (FARPROC *)&pRegisterClassExA, (FARPROC)extRegisterClassExA}, + {"GetSystemMetrics", (FARPROC)GetSystemMetrics, (FARPROC *)&pGetSystemMetrics, (FARPROC)extGetSystemMetrics}, + {"GetDesktopWindow", (FARPROC)GetDesktopWindow, (FARPROC *)&pGetDesktopWindow, (FARPROC)extGetDesktopWindow}, + {0, NULL, 0, 0} // terminator +}; -extern DWORD PaletteEntries[256]; -extern LPDIRECTDRAW lpDD; -extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); +static HookEntry_Type DDHooks[]={ + {"GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extDDGetDC}, + {"GetWindowDC", (FARPROC)GetWindowDC, (FARPROC *)&pGDIGetWindowDC, (FARPROC)extDDGetDC}, + {"ReleaseDC", (FARPROC)ReleaseDC, (FARPROC *)&pGDIReleaseDC, (FARPROC)extDDReleaseDC}, + {"InvalidateRect", (FARPROC)InvalidateRect, (FARPROC *)&pInvalidateRect, (FARPROC)extDDInvalidateRect}, + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type GDIHooks[]={ + {"GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extGDIGetDC}, + {"GetWindowDC", (FARPROC)GetWindowDC, (FARPROC *)&pGDIGetWindowDC, (FARPROC)extGDIGetDC}, + {"ReleaseDC", (FARPROC)ReleaseDC, (FARPROC *)&pGDIReleaseDC, (FARPROC)extGDIReleaseDC}, + {"InvalidateRect", (FARPROC)InvalidateRect, (FARPROC *)&pInvalidateRect, (FARPROC)extInvalidateRect}, + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type RemapHooks[]={ + {"ScreenToClient", (FARPROC)ScreenToClient, (FARPROC *)&pScreenToClient, (FARPROC)extScreenToClient}, + {"ClientToScreen", (FARPROC)ClientToScreen, (FARPROC *)&pClientToScreen, (FARPROC)extClientToScreen}, + {"GetClientRect", (FARPROC)GetClientRect, (FARPROC *)&pGetClientRect, (FARPROC)extGetClientRect}, + {"GetWindowRect", (FARPROC)GetWindowRect, (FARPROC *)&pGetWindowRect, (FARPROC)extGetWindowRect}, + {"MapWindowPoints", (FARPROC)MapWindowPoints, (FARPROC *)&pMapWindowPoints, (FARPROC)extMapWindowPoints}, + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type MessageHooks[]={ + {"PeekMessageA", (FARPROC)PeekMessageA, (FARPROC *)&pPeekMessage, (FARPROC)extPeekMessage}, + {"GetMessageA", (FARPROC)GetMessageA, (FARPROC *)&pGetMessage, (FARPROC)extGetMessage}, + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type MouseHooks[]={ + {"GetCursorPos", (FARPROC)GetCursorPos, (FARPROC *)&pGetCursorPos, (FARPROC)extGetCursorPos}, + {"SetCursor", (FARPROC)SetCursor, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, + {"SendMessageA", (FARPROC)SendMessageA, (FARPROC *)&pSendMessage, (FARPROC)extSendMessage}, // ??? + //{"SetPhysicalCursorPos", NULL, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, // ??? + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type WinHooks[]={ + {"ShowWindow", (FARPROC)ShowWindow, (FARPROC *)&pShowWindow, (FARPROC)extShowWindow}, + {"SetWindowLongA", (FARPROC)SetWindowLongA, (FARPROC *)&pSetWindowLong, (FARPROC)extSetWindowLong}, + {"GetWindowLongA", (FARPROC)GetWindowLongA, (FARPROC *)&pGetWindowLong, (FARPROC)extGetWindowLong}, + {"SetWindowPos", (FARPROC)SetWindowPos, (FARPROC *)&pSetWindowPos, (FARPROC)extSetWindowPos}, + {"DeferWindowPos", (FARPROC)DeferWindowPos, (FARPROC *)&pGDIDeferWindowPos, (FARPROC)extDeferWindowPos}, + {"CallWindowProcA", (FARPROC)CallWindowProcA, (FARPROC *)&pCallWindowProc, (FARPROC)extCallWindowProc}, + {0, NULL, 0, 0} // terminator +}; + +static HookEntry_Type MouseHooks2[]={ + {"SetCursorPos", (FARPROC)SetCursorPos, (FARPROC *)&pSetCursorPos, (FARPROC)extSetCursorPos}, + {0, NULL, 0, 0} // terminator +}; + +FARPROC Remap_user32_ProcAddress(LPCSTR proc, HMODULE hModule) +{ + FARPROC addr; + if (addr=RemapLibrary(proc, hModule, Hooks)) return addr; + if (addr=RemapLibrary(proc, hModule, (dxw.dwFlags1 & MAPGDITOPRIMARY) ? DDHooks : GDIHooks)) return addr; + if (dxw.dwFlags1 & CLIENTREMAPPING) + if (addr=RemapLibrary(proc, hModule, RemapHooks)) return addr; + if (dxw.dwFlags1 & MESSAGEPROC) + if (addr=RemapLibrary(proc, hModule, MessageHooks)) return addr; + if(dxw.dwFlags1 & MODIFYMOUSE) + if (addr=RemapLibrary(proc, hModule, MouseHooks)) return addr; + if (dxw.dwFlags1 & (PREVENTMAXIMIZE|FIXWINFRAME|LOCKWINPOS|LOCKWINSTYLE)) + if (addr=RemapLibrary(proc, hModule, WinHooks)) return addr; + if((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED)) + if (addr=RemapLibrary(proc, hModule, MouseHooks2)) return addr; + return NULL; +} + +static char *libname = "user32.dll"; + +void HookUser32(HMODULE hModule) +{ + HookLibrary(hModule, Hooks, libname); + + HookLibrary(hModule, (dxw.dwFlags1 & MAPGDITOPRIMARY) ? DDHooks : GDIHooks, libname); + if (dxw.dwFlags1 & CLIENTREMAPPING) HookLibrary(hModule, RemapHooks, libname); + if (dxw.dwFlags1 & MESSAGEPROC) HookLibrary(hModule, MessageHooks, libname); + if(dxw.dwFlags1 & MODIFYMOUSE)HookLibrary(hModule, MouseHooks, libname); + if (dxw.dwFlags1 & (PREVENTMAXIMIZE|FIXWINFRAME|LOCKWINPOS|LOCKWINSTYLE))HookLibrary(hModule, WinHooks, libname); + if((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED)) HookLibrary(hModule, MouseHooks2, libname); + return; +} + +void HookUser32Init() +{ + HookLibInit(Hooks); + HookLibInit(DDHooks); + HookLibInit(RemapHooks); + HookLibInit(MessageHooks); + HookLibInit(MouseHooks); + HookLibInit(WinHooks); + HookLibInit(MouseHooks2); +} + +// -------------------------------------------------------------------------- +// +// globals, externs, static functions... +// +// -------------------------------------------------------------------------- + +// PrimHDC: DC handle of the selected DirectDraw primary surface. NULL when invalid. +HDC PrimHDC=NULL; + +BOOL isWithinDialog=FALSE; +LPRECT lpClipRegion=NULL; +RECT ClipRegion; +int LastCurPosX, LastCurPosY; extern GetDC_Type pGetDC; extern ReleaseDC_Type pReleaseDC; - -DEVMODE SetDevMode; -DEVMODE *pSetDevMode=NULL; - -extern HRESULT WINAPI extBlt(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX); +extern DEVMODE *pSetDevMode; +extern void FixWindowFrame(HWND); +extern LRESULT CALLBACK extChildWindowProc(HWND, UINT, WPARAM, LPARAM); extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL); -extern DirectDrawEnumerate_Type pDirectDrawEnumerate; -extern DirectDrawEnumerateEx_Type pDirectDrawEnumerateEx; - -extern LRESULT CALLBACK extChildWindowProc(HWND, UINT, WPARAM, LPARAM); extern INT_PTR CALLBACK extDialogWindowProc(HWND, UINT, WPARAM, LPARAM); -/* ------------------------------------------------------------------ */ +LONG WINAPI MyChangeDisplaySettings(char *fname, DEVMODE *lpDevMode, DWORD dwflags) +{ + HRESULT res; + + // save desired settings first v.2.1.89 + // v2.1.95 protect when lpDevMode is null (closing game... Jedi Outcast) + // v2.2.23 consider new width/height only when dmFields flags are set. + if(lpDevMode && (lpDevMode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT))) + dxw.SetScreenSize(lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight); + + if ((dwflags==0 || dwflags==CDS_FULLSCREEN) && lpDevMode){ + if (dxw.dwFlags1 & EMULATESURFACE || !(lpDevMode->dmFields & DM_BITSPERPEL)){ + OutTraceD("%s: BYPASS res=DISP_CHANGE_SUCCESSFUL\n", fname); + return DISP_CHANGE_SUCCESSFUL; + } + else{ + DEVMODE NewMode; + if(dwflags==CDS_FULLSCREEN) dwflags=0; // no FULLSCREEN + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &NewMode); + OutTraceD("ChangeDisplaySettings: CURRENT wxh=(%dx%d) BitsPerPel=%d -> %d\n", + NewMode.dmPelsWidth, NewMode.dmPelsHeight, NewMode.dmBitsPerPel, + lpDevMode->dmBitsPerPel); + NewMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + NewMode.dmBitsPerPel = lpDevMode->dmBitsPerPel; + res=(*pChangeDisplaySettings)(&NewMode, 0); + if(res) OutTraceE("ChangeDisplaySettings: ERROR err=%d at %d\n", GetLastError(), __LINE__); + return res; + } + } + else + return (*pChangeDisplaySettings)(lpDevMode, dwflags); +} + +void dxwFixWindowPos(char *ApiName, HWND hwnd, LPARAM lParam) +{ + LPWINDOWPOS wp; + int MaxX, MaxY; + wp = (LPWINDOWPOS)lParam; + MaxX = dxw.iSizX; + MaxY = dxw.iSizY; + if (!MaxX) MaxX = dxw.GetScreenWidth(); + if (!MaxY) MaxY = dxw.GetScreenHeight(); + static int iLastCX, iLastCY; + static int BorderX=-1; + static int BorderY=-1; + int cx, cy; + + OutTraceD("%s: GOT hwnd=%x pos=(%d,%d) dim=(%d,%d) Flags=%x(%s)\n", + ApiName, hwnd, wp->x, wp->y, wp->cx, wp->cy, wp->flags, ExplainWPFlags(wp->flags)); + + if ((wp->flags & (SWP_NOMOVE|SWP_NOSIZE))==(SWP_NOMOVE|SWP_NOSIZE)) return; //v2.02.13 + //if (wp->flags & (SWP_NOMOVE|SWP_NOSIZE)) return; //v2.02.10 + + if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){ + extern void CalculateWindowPos(HWND, DWORD, DWORD, LPWINDOWPOS); + CalculateWindowPos(hwnd, MaxX, MaxY, wp); + OutTraceD("%s: LOCK pos=(%d,%d) dim=(%d,%d)\n", ApiName, wp->x, wp->y, wp->cx, wp->cy); + } + + if ((dxw.dwFlags2 & KEEPASPECTRATIO) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){ + // note: while keeping aspect ration, resizing from one corner doesn't tell + // which coordinate is prevalent to the other. We made an arbitrary choice. + // note: v2.1.93: compensation must refer to the client area, not the wp + // window dimensions that include the window borders. + if(BorderX==-1){ + RECT client, full; + (*pGetClientRect)(hwnd, &client); + (*pGetWindowRect)(hwnd, &full); + BorderX= full.right - full.left - client.right; + BorderY= full.bottom - full.top - client.bottom; + OutTraceD("%s: KEEPASPECTRATIO window borders=(%d,%d)\n", ApiName, BorderX, BorderY); + } + extern LRESULT LastCursorPos; + switch (LastCursorPos){ + case HTBOTTOM: + case HTTOP: + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + case HTTOPLEFT: + case HTTOPRIGHT: + cx = BorderX + ((wp->cy - BorderY) * dxw.GetScreenWidth()) / dxw.GetScreenHeight(); + if(cx!=wp->cx){ + OutTraceD("%s: KEEPASPECTRATIO adjusted cx=%d->%d\n", ApiName, wp->cx, cx); + wp->cx = cx; + } + break; + case HTLEFT: + case HTRIGHT: + cy = BorderY + ((wp->cx - BorderX) * dxw.GetScreenHeight()) / dxw.GetScreenWidth(); + if(cy!=wp->cy){ + OutTraceD("%s: KEEPASPECTRATIO adjusted cy=%d->%d\n", ApiName, wp->cy, cy); + wp->cy = cy; + } + break; + } + } + + if (dxw.dwFlags1 & PREVENTMAXIMIZE){ + int UpdFlag = 0; + + if(wp->cx>MaxX) { wp->cx=MaxX; UpdFlag=1; } + if(wp->cy>MaxY) { wp->cy=MaxY; UpdFlag=1; } + if (UpdFlag) + OutTraceD("%s: SET max dim=(%d,%d)\n", ApiName, wp->cx, wp->cy); + } + + iLastCX= wp->cx; + iLastCY= wp->cy; +} + +void dxwFixMinMaxInfo(char *ApiName, HWND hwnd, LPARAM lParam) +{ + if (dxw.dwFlags1 & PREVENTMAXIMIZE){ + LPMINMAXINFO lpmmi; + lpmmi=(LPMINMAXINFO)lParam; + OutTraceD("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, + lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); + lpmmi->ptMaxPosition.x=0; + lpmmi->ptMaxPosition.y=0; + if(pSetDevMode){ + lpmmi->ptMaxSize.x = pSetDevMode->dmPelsWidth; + lpmmi->ptMaxSize.y = pSetDevMode->dmPelsHeight; + } + else{ + lpmmi->ptMaxSize.x = dxw.GetScreenWidth(); + lpmmi->ptMaxSize.y = dxw.GetScreenHeight(); + } + OutTraceD("%s: SET PREVENTMAXIMIZE MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, + lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); + } + // v2.1.75: added logic to fix win coordinates to selected ones. + // fixes the problem with "Achtung Spitfire", that can't be managed through PREVENTMAXIMIZE flag. + if (dxw.dwFlags1 & LOCKWINPOS){ + LPMINMAXINFO lpmmi; + lpmmi=(LPMINMAXINFO)lParam; + OutTraceD("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, + lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); + lpmmi->ptMaxPosition.x=dxw.iPosX; + lpmmi->ptMaxPosition.y=dxw.iPosY; + lpmmi->ptMaxSize.x = dxw.iSizX ? dxw.iSizX : dxw.GetScreenWidth(); + lpmmi->ptMaxSize.y = dxw.iSizY ? dxw.iSizY : dxw.GetScreenHeight(); + OutTraceD("%s: SET LOCKWINPOS MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, + lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); + } +} + +static LRESULT WINAPI FixWindowProc(char *ApiName, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM *lpParam) +{ + LPARAM lParam; + + lParam=*lpParam; + OutTraceW("%s: hwnd=%x msg=[0x%x]%s(%x,%x)\n", + ApiName, hwnd, Msg, ExplainWinMessage(Msg), wParam, lParam); + + switch(Msg){ + // attempt to fix Sleepwalker + //case WM_NCCALCSIZE: + // if (dxw.dwFlags1 & PREVENTMAXIMIZE) + // return 0; + // break; + case WM_ERASEBKGND: + OutTraceD("%s: prevent erase background\n", ApiName); + return 1; // 1=erased + break; // useless + case WM_GETMINMAXINFO: + dxwFixMinMaxInfo(ApiName, hwnd, lParam); + break; + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + dxwFixWindowPos(ApiName, hwnd, lParam); + break; + case WM_STYLECHANGING: + case WM_STYLECHANGED: + dxw.FixStyle(ApiName, hwnd, wParam, lParam); + break; + case WM_DISPLAYCHANGE: + // too late? to be deleted.... + if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 0; + if (dxw.dwFlags1 & PREVENTMAXIMIZE){ + OutTraceD("%s: WM_DISPLAYCHANGE depth=%d size=(%d,%d)\n", + ApiName, wParam, HIWORD(lParam), LOWORD(lParam)); + return 0; + } + break; + case WM_SIZE: + if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 0; + if (dxw.dwFlags1 & PREVENTMAXIMIZE){ + if ((wParam == SIZE_MAXIMIZED)||(wParam == SIZE_MAXSHOW)){ + OutTraceD("%s: prevent screen SIZE to fullscreen wparam=%d(%s) size=(%d,%d)\n", ApiName, + wParam, ExplainResizing(wParam), HIWORD(lParam), LOWORD(lParam)); + return 0; // checked + //lParam = MAKELPARAM(dxw.GetScreenWidth(), dxw.GetScreenHeight()); + //OutTraceD("%s: updated SIZE wparam=%d(%s) size=(%d,%d)\n", ApiName, + // wParam, ExplainResizing(wParam), HIWORD(lParam), LOWORD(lParam)); + } + } + break; + default: + break; + } + + // marker to run hooked function + return(-1); +} static POINT FixMessagePt(HWND hwnd, POINT point) { @@ -68,526 +385,34 @@ static POINT FixMessagePt(HWND hwnd, POINT point) return curr; } -/* ------------------------------------------------------------------ */ +// -------------------------------------------------------------------------- +// +// user32 API hookers +// +// -------------------------------------------------------------------------- -static COLORREF GetMatchingColor(COLORREF crColor) +BOOL WINAPI extDDInvalidateRect(HWND hwnd, RECT *lpRect, BOOL bErase) { - int iDistance, iMinDistance; - int iColorIndex, iMinColorIndex; - COLORREF PalColor; - - iMinDistance=0xFFFFFF; - iMinColorIndex=0; - - for(iColorIndex=0; iColorIndex<256; iColorIndex++){ - int iDist; - iDistance=0; - - PalColor=PaletteEntries[iColorIndex]; - switch(dxw.ActualPixelFormat.dwRGBBitCount){ - case 32: - PalColor = ((PalColor & 0x00FF0000) >> 16) | (PalColor & 0x0000FF00) | ((PalColor & 0x000000FF) << 16); - break; - case 16: - if(dxw.ActualPixelFormat.dwGBitMask==0x03E0){ - // RGB555 screen settings - PalColor = ((PalColor & 0x7C00) >> 7) | ((PalColor & 0x03E0) << 6) | ((PalColor & 0x001F) << 19); - } - else { - // RGB565 screen settings - PalColor = ((PalColor & 0xF800) >> 8) | ((PalColor & 0x07E0) << 5) | ((PalColor & 0x001F) << 19); - } - break; - } - - iDist = (crColor & 0x00FF0000) - (PalColor & 0x00FF0000); - iDist >>= 16; - if (iDist<0) iDist=-iDist; - iDist *= iDist; - iDistance += iDist; - - iDist = (crColor & 0x0000FF00) - (PalColor & 0x0000FF00); - iDist >>= 8; - if (iDist<0) iDist=-iDist; - iDist *= iDist; - iDistance += iDist; - - iDist = (crColor & 0x000000FF) - (PalColor & 0x000000FF); - // iDist >>= 0; - if (iDist<0) iDist=-iDist; - iDist *= iDist; - iDistance += iDist; - - if (iDistance < iMinDistance) { - iMinDistance = iDistance; - iMinColorIndex = iColorIndex; - } - - if (iMinDistance==0) break; // got the perfect match! - } - OutTraceD("GetMatchingColor: color=%x matched with palette[%d]=%x dist=%d\n", - crColor, iMinColorIndex, PaletteEntries[iMinColorIndex], iDistance); - PalColor=PaletteEntries[iMinColorIndex]; - switch(dxw.ActualPixelFormat.dwRGBBitCount){ - case 32: - crColor = ((PalColor & 0x00FF0000) >> 16) | (PalColor & 0x0000FF00) | ((PalColor & 0x000000FF) << 16); - break; - case 16: - if(dxw.ActualPixelFormat.dwGBitMask==0x03E0){ - // RGB555 screen settings - crColor = ((PalColor & 0x7C00) >> 7) | ((PalColor & 0x03E0) << 6) | ((PalColor & 0x001F) << 19); - } - else { - // RGB565 screen settings - crColor = ((PalColor & 0xF800) >> 8) | ((PalColor & 0x07E0) << 5) | ((PalColor & 0x001F) << 19); - } - break; - } - return crColor; -} - -extern void FixWindowFrame(HWND); - -// GHO: pro Diablo -HWND WINAPI extCreateWindowExA( - DWORD dwExStyle, - LPCTSTR lpClassName, - LPCTSTR lpWindowName, - DWORD dwStyle, - int x, - int y, - int nWidth, - int nHeight, - HWND hWndParent, - HMENU hMenu, - HINSTANCE hInstance, - LPVOID lpParam) -{ - HWND wndh; - WNDPROC pWindowProc; - BOOL isValidHandle=TRUE; - - OutTraceD("CreateWindowEx: class=\"%s\" wname=\"%s\" pos=(%d,%d) size=(%d,%d) Style=%x(%s) ExStyle=%x(%s)\n", - lpClassName, lpWindowName, x, y, nWidth, nHeight, - dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); - if(IsDebug) OutTrace("CreateWindowEx: DEBUG screen=(%d,%d)\n", dxw.GetScreenWidth(), dxw.GetScreenHeight()); - - // no maximized windows in any case - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - OutTraceD("CreateWindowEx: handling PREVENTMAXIMIZE mode\n"); - dwStyle &= ~(WS_MAXIMIZE | WS_POPUP); - dwExStyle &= ~WS_EX_TOPMOST; - } - - // v2.1.92: fixes size & position for auxiliary big window, often used - // for intro movies etc. : needed for ...... - // evidently, this was supposed to be a fullscreen window.... - // v2.1.100: fixes for "The Grinch": this game creates a new main window for OpenGL - // rendering using CW_USEDEFAULT placement and 800x600 size while the previous - // main win was 640x480 only! - // v2.02.13: if it's a WS_CHILD window, don't reposition the x,y, placement for BIG win. - if ( - ( - ((x==0)&&(y==0)) || ((x==CW_USEDEFAULT)&&(y==CW_USEDEFAULT)) - ) - && - (((DWORD)nWidth>=dxw.GetScreenWidth())&&((DWORD)nHeight>=dxw.GetScreenHeight())) - && - !(dwExStyle & WS_EX_CONTROLPARENT) // Diablo fix - && - !(dwStyle & WS_CHILD) // Diablo fix - ){ - RECT screen; - POINT upleft = {0,0}; - // update virtual screen size if it has grown - dxw.SetScreenSize(nWidth, nHeight); - // inserted some checks here, since the main window could be destroyed - // or minimized (see "Jedi Outcast") so that you may get a dangerous - // zero size. In this case, better renew the hWnd assignement and its coordinates. - do { // fake loop - isValidHandle = FALSE; - if (!(*pGetClientRect)(dxw.GethWnd(),&screen)) break; - if (!(*pClientToScreen)(dxw.GethWnd(),&upleft)) break; - if (screen.right==0 || screen.bottom==0) break; - isValidHandle = TRUE; - } while(FALSE); - if (isValidHandle){ - if (!(dwStyle & WS_CHILD)){ - x=upleft.x; - y=upleft.y; - } - nWidth=screen.right; - nHeight=screen.bottom; - OutTraceD("CreateWindowEx: fixed BIG win pos=(%d,%d) size=(%d,%d)\n", x, y, nWidth, nHeight); - } - else { - // invalid parent coordinates: use initial placement, but leave the size. - // should also fix the window style and compensate for borders here? - if (!(dwStyle & WS_CHILD)){ - x=dxw.iPosX; - y=dxw.iPosY; - } - nWidth=dxw.iSizX; - nHeight=dxw.iSizY; - OutTraceD("CreateWindowEx: renewed BIG win pos=(%d,%d) size=(%d,%d)\n", x, y, nWidth, nHeight); - } - dxw.SetFullScreen(TRUE); - } - - if(!dxw.IsFullScreen()){ // v2.1.63: needed for "Monster Truck Madness" - wndh= (*pCreateWindowExA)(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, - hWndParent, hMenu, hInstance, lpParam); - OutTraceD("CreateWindowEx: windowed mode ret=%x\n", wndh); - return wndh; - } - - // tested on Gangsters: coordinates must be window-relative!!! - // Age of Empires.... - if (dwStyle & WS_CHILD){ - dxw.MapClient(&x, &y, &nWidth, &nHeight); - OutTraceD("CreateWindowEx: fixed WS_CHILD pos=(%d,%d) size=(%d,%d)\n", - x, y, nWidth, nHeight); - } - // needed for Diablo, that creates a new control parent window that must be - // overlapped to the directdraw surface. - else if (dwExStyle & WS_EX_CONTROLPARENT){ - dxw.MapWindow(&x, &y, &nWidth, &nHeight); - OutTraceD("CreateWindowEx: fixed WS_EX_CONTROLPARENT pos=(%d,%d) size=(%d,%d)\n", - x, y, nWidth, nHeight); - } - - OutTraceB("CreateWindowEx: fixed pos=(%d,%d) size=(%d,%d) Style=%x(%s) ExStyle=%x(%s)\n", - x, y, nWidth, nHeight, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); - - wndh= (*pCreateWindowExA)(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, - hWndParent, hMenu, hInstance, lpParam); - if (wndh==(HWND)NULL){ - OutTraceE("CreateWindowEx: ERROR err=%d Style=%x(%s) ExStyle=%x\n", - GetLastError(), dwStyle, ExplainStyle(dwStyle), dwExStyle); - return wndh; - } - - if ((!isValidHandle) && dxw.IsFullScreen()) { - dxw.SethWnd(wndh); - extern void AdjustWindowPos(HWND, DWORD, DWORD); - (*pSetWindowLong)(wndh, GWL_STYLE, (dxw.dwFlags2 & MODALSTYLE) ? 0 : WS_OVERLAPPEDWINDOW); - (*pSetWindowLong)(wndh, GWL_EXSTYLE, 0); - OutTraceD("CreateWindow: hwnd=%x, set style=WS_OVERLAPPEDWINDOW extstyle=0\n", wndh); - AdjustWindowPos(wndh, nWidth, nHeight); - (*pShowWindow)(wndh, SW_SHOWNORMAL); - } - - if ((dxw.dwFlags1 & FIXWINFRAME) && !(dwStyle & WS_CHILD)) - FixWindowFrame(wndh); - - // to do: handle inner child, and leave dialogue & modal child alone!!! - if (dwStyle & WS_CHILD){ - long res; - pWindowProc = (WNDPROC)(*pGetWindowLong)(wndh, GWL_WNDPROC); - OutTraceD("Hooking CHILD wndh=%x WindowProc %x->%x\n", wndh, pWindowProc, extChildWindowProc); - res=(*pSetWindowLong)(wndh, GWL_WNDPROC, (LONG)extChildWindowProc); - WhndStackPush(wndh, pWindowProc); - if(!res) OutTraceE("CreateWindowExA: SetWindowLong ERROR %x\n", GetLastError()); - } - - OutTraceD("CreateWindowEx: ret=%x\n", wndh); - return wndh; -} - -COLORREF WINAPI extSetTextColor(HDC hdc, COLORREF crColor) -{ - COLORREF res; - - if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC) && (dxw.VirtualPixelFormat.dwRGBBitCount==8)) - crColor=GetMatchingColor(crColor); - - res=(*pGDISetTextColor)(hdc, crColor); - OutTraceD("SetTextColor: color=%x res=%x%s\n", crColor, res, (res==CLR_INVALID)?"(CLR_INVALID)":""); - return res; -} - -COLORREF WINAPI extSetBkColor(HDC hdc, COLORREF crColor) -{ - COLORREF res; - - if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC) && (dxw.VirtualPixelFormat.dwRGBBitCount==8)) - crColor=GetMatchingColor(crColor); - - res=(*pGDISetBkColor)(hdc, crColor); - OutTraceD("SetBkColor: color=%x res=%x%s\n", crColor, res, (res==CLR_INVALID)?"(CLR_INVALID)":""); - return res; -} - -LPRECT lpClipRegion=NULL; -RECT ClipRegion; - -BOOL WINAPI extClipCursor(RECT *lpRectArg) -{ - // reference: hooking and setting ClipCursor is mandatori in "Emergency: Fighters for Life" - // where the application expects the cursor to be moved just in a inner rect within the - // main window surface. - - BOOL res; - RECT *lpRect; - RECT Rect; - - if(IsTraceC){ - if (lpRectArg) - OutTrace("ClipCursor: rect=(%d,%d)-(%d,%d)\n", - lpRectArg->left,lpRectArg->top,lpRectArg->right,lpRectArg->bottom); - else - OutTrace("ClipCursor: rect=(NULL)\n"); - } - - if (!(dxw.dwFlags1 & ENABLECLIPPING)) return 1; - - if(lpRectArg){ - Rect=*lpRectArg; - lpRect=&Rect; - } + if(lpRect) + OutTraceD("InvalidateRect: hwnd=%x rect=(%d,%d)-(%d,%d) erase=%x\n", + hwnd, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, bErase); else - lpRect=NULL; + OutTraceD("InvalidateRect: hwnd=%x rect=NULL erase=%x\n", + hwnd, bErase); - if(dxw.dwFlags1 & MODIFYMOUSE){ - // save desired clip region - if (lpRect) { - ClipRegion=*lpRectArg; - lpClipRegion=&ClipRegion; - } - else - lpClipRegion=NULL; - - *lpRect=dxw.MapWindowRect(lpRect); - } - - if (pClipCursor) res=(*pClipCursor)(lpRect); - OutTraceD("ClipCursor: rect=(%d,%d)-(%d,%d) res=%x\n", - lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, res); - - return TRUE; + return (*pInvalidateRect)(hwnd, NULL, bErase); } -BOOL WINAPI extGetClipCursor(LPRECT lpRect) +BOOL WINAPI extInvalidateRect(HWND hwnd, RECT *lpRect, BOOL bErase) { - // v2.1.93: if ENABLECLIPPING, return the saved clip rect coordinates - - BOOL ret; - - // proxy.... - if (!(dxw.dwFlags1 & ENABLECLIPPING)) { - ret=(*pGetClipCursor)(lpRect); - if(IsTraceD){ - if (lpRect) - OutTrace("ClipCursor: PROXED rect=(%d,%d)-(%d,%d) ret=%d\n", - lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, ret); - else - OutTrace("ClipCursor: PROXED rect=(NULL) ret=%d\n", ret); - } - return ret; - } - - if(lpRect){ - if(lpClipRegion) - *lpRect=ClipRegion; - else{ - lpRect->top = lpRect->left = 0; - lpRect->right = dxw.GetScreenWidth(); - lpRect->bottom = dxw.GetScreenHeight(); - } - OutTraceD("ClipCursor: rect=(%d,%d)-(%d,%d) ret=%d\n", - lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, TRUE); - } - - return TRUE; -} - -int LastCurPosX, LastCurPosY; - -BOOL WINAPI extGetCursorPos(LPPOINT lppoint) -{ - HRESULT res; - static int PrevX, PrevY; - POINT prev; - - if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(2); - - if (pGetCursorPos) { - res=(*pGetCursorPos)(lppoint); - } - else { - lppoint->x =0; lppoint->y=0; - res=1; - } - - prev=*lppoint; - *lppoint=dxw.ScreenToClient(*lppoint); - *lppoint=dxw.FixCursorPos(*lppoint); - GetHookInfo()->CursorX=(short)lppoint->x; - GetHookInfo()->CursorY=(short)lppoint->y; - OutTraceC("GetCursorPos: FIXED pos=(%d,%d)->(%d,%d)\n", prev.x, prev.y, lppoint->x, lppoint->y); - - return res; -} - -BOOL WINAPI extSetCursorPos(int x, int y) -{ - BOOL res; - int PrevX, PrevY; - - PrevX=x; - PrevY=y; - - if(dxw.dwFlags2 & KEEPCURSORFIXED) { - OutTraceC("SetCursorPos: FIXED pos=(%d,%d)\n", x, y); - LastCurPosX=x; - LastCurPosY=y; - return 1; - } - - if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(2); - - if(dxw.dwFlags1 & KEEPCURSORWITHIN){ - // Intercept SetCursorPos outside screen boundaries (used as Cursor OFF in some games) - if ((y<0)||(y>=(int)dxw.GetScreenHeight())||(x<0)||(x>=(int)dxw.GetScreenWidth())) return 1; - } - - if(dxw.dwFlags1 & MODIFYMOUSE){ - POINT cur; - RECT rect; - - // find window metrics - if (!(*pGetClientRect)(dxw.GethWnd(), &rect)) { - // report error and ignore ... - OutTraceE("GetClientRect(%x) ERROR %d at %d\n", dxw.GethWnd(), GetLastError(), __LINE__); - return 0; - } - - x= x * rect.right / dxw.GetScreenWidth(); - y= y * rect.bottom / dxw.GetScreenHeight(); - - // check for boundaries (???) - if (x >= rect.right) x=rect.right-1; - if (x<0) x=0; - if (y >= rect.bottom) y=rect.bottom-1; - if (y<0) y=0; - - // make it screen absolute - cur.x = x; - cur.y = y; - if (!(*pClientToScreen)(dxw.GethWnd(), &cur)) { - OutTraceE("ClientToScreen(%x) ERROR %d at %d\n", dxw.GethWnd(), GetLastError(), __LINE__); - return 0; - } - x = cur.x; - y = cur.y; - } - - res=0; - if (pSetCursorPos) res=(*pSetCursorPos)(x,y); - - OutTraceC("SetCursorPos: res=%x XY=(%d,%d)->(%d,%d)\n",res, PrevX, PrevY, x, y); - return res; -} - -BOOL WINAPI extTextOutA(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cchString) -{ - BOOL res; - OutTraceD("TextOut: hdc=%x xy=(%d,%d) str=(%d)\"%s\"\n", hdc, nXStart, nYStart, cchString, lpString); - if (dxw.dwFlags1 & FIXTEXTOUT) { - POINT anchor; - anchor.x=nXStart; - anchor.y=nYStart; - (*pClientToScreen)(dxw.GethWnd(), &anchor); - nXStart=anchor.x; - nYStart=anchor.y; - } - res=(*pGDITextOutA)(hdc, nXStart, nYStart, lpString, cchString); - return res; -} - -BOOL WINAPI extRectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) -{ - OutTraceD("Rectangle: hdc=%x xy=(%d,%d)-(%d,%d)\n", hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); - if (dxw.dwFlags1 & FIXTEXTOUT) { - POINT anchor; - anchor.x=nLeftRect; - anchor.y=nTopRect; - (*pClientToScreen)(dxw.GethWnd(), &anchor); - nLeftRect=anchor.x; - nTopRect=anchor.y; - anchor.x=nRightRect; - anchor.y=nBottomRect; - (*pClientToScreen)(dxw.GethWnd(), &anchor); - nRightRect=anchor.x; - nBottomRect=anchor.y; - } - return (*pGDIRectangle)(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); -} - -int WINAPI extFillRect(HDC hdc, const RECT *lprc, HBRUSH hbr) -{ - RECT rc, trim; - HWND hWnd; - OutTraceD("FillRect: hdc=%x xy=(%d,%d)-(%d,%d)\n", hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); - memcpy(&rc, lprc, sizeof(rc)); - hWnd = WindowFromDC(hdc); - if((hWnd == dxw.GethWnd()) || - (hWnd == 0) || - (hWnd == GetDesktopWindow())){ - // trim: some games (Player Manager 98) clear the screen by filling an exagerated rect - (*pGetClientRect)(dxw.GethWnd(), &trim); - hdc=GetDC(dxw.GethWnd()); - dxw.MapWindowRect(&rc); - if(rc.left < trim.left) rc.left = trim.left; - if(rc.top < trim.top) rc.top = trim.top; - if(rc.right > trim.right) rc.right = trim.right; - if(rc.bottom > trim.bottom) rc.bottom = trim.bottom; - OutTraceD("FillRect: hwnd=%x hdc=%x fixed xy=(%d,%d)-(%d,%d)\n", hWnd, hdc, rc.left, rc.top, rc.right, rc.bottom); - } - if (dxw.dwFlags1 & FIXTEXTOUT) { - // to be verified: why shifting and not scaling? - POINT anchor; - anchor.x=rc.left; - anchor.y=rc.top; - (*pClientToScreen)(dxw.GethWnd(), &anchor); - rc.left=anchor.x; - rc.top=anchor.y; - anchor.x=rc.right; - anchor.y=rc.bottom; - (*pClientToScreen)(dxw.GethWnd(), &anchor); - rc.right=anchor.x; - rc.bottom=anchor.y; - } - return (*pFillRect)(hdc, &rc, hbr); -} - -HFONT WINAPI extCreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, - DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, - DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, - DWORD fdwPitchAndFamily, LPCTSTR lpszFace) -{ - OutTraceD("CreateFont: h=%d w=%d face=\"%s\"\n", nHeight, nWidth, lpszFace); - return (*pGDICreateFont)(nHeight, nWidth, nEscapement, nOrientation, fnWeight, - fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet, - fdwOutputPrecision, fdwClipPrecision, NONANTIALIASED_QUALITY, - fdwPitchAndFamily, lpszFace); -} - -// CreateFontIndirect hook routine to avoid font aliasing that prevents reverse blitting working on palettized surfaces - -HFONT WINAPI extCreateFontIndirect(const LOGFONT* lplf) -{ - LOGFONT lf; - HFONT retHFont; - OutTraceD("CreateFontIndirect: h=%d w=%d face=\"%s\"\n", lplf->lfHeight, lplf->lfWidth, lplf->lfFaceName); - memcpy((char *)&lf, (char *)lplf, sizeof(LOGFONT)); - lf.lfQuality=NONANTIALIASED_QUALITY; - retHFont=((*pGDICreateFontIndirect)(&lf)); - if(retHFont) - OutTraceD("CreateFontIndirect: hfont=%x\n", retHFont); + if(lpRect) + OutTraceD("InvalidateRect: hwnd=%x rect=(%d,%d)-(%d,%d) erase=%x\n", + hwnd, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, bErase); else - OutTraceD("CreateFontIndirect: error=%d at %d\n", GetLastError(), __LINE__); - return retHFont; + OutTraceD("InvalidateRect: hwnd=%x rect=NULL erase=%x\n", + hwnd, bErase); + + return (*pInvalidateRect)(hwnd, NULL, bErase); } BOOL WINAPI extShowWindow(HWND hwnd, int nCmdShow) @@ -602,7 +427,7 @@ BOOL WINAPI extShowWindow(HWND hwnd, int nCmdShow) } } - res=pShowWindow(hwnd, nCmdShow); + res=(*pShowWindow)(hwnd, nCmdShow); return res; } @@ -786,422 +611,201 @@ HDWP WINAPI extDeferWindowPos(HDWP hWinPosInfo, HWND hwnd, HWND hWndInsertAfter, return res; } -void dxwFixWindowPos(char *ApiName, HWND hwnd, LPARAM lParam) +LRESULT WINAPI extSendMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) { - LPWINDOWPOS wp; - int MaxX, MaxY; - wp = (LPWINDOWPOS)lParam; - MaxX = dxw.iSizX; - MaxY = dxw.iSizY; - if (!MaxX) MaxX = dxw.GetScreenWidth(); - if (!MaxY) MaxY = dxw.GetScreenHeight(); - static int iLastCX, iLastCY; - static int BorderX=-1; - static int BorderY=-1; - int cx, cy; - - OutTraceD("%s: GOT hwnd=%x pos=(%d,%d) dim=(%d,%d) Flags=%x(%s)\n", - ApiName, hwnd, wp->x, wp->y, wp->cx, wp->cy, wp->flags, ExplainWPFlags(wp->flags)); - - if ((wp->flags & (SWP_NOMOVE|SWP_NOSIZE))==(SWP_NOMOVE|SWP_NOSIZE)) return; //v2.02.13 - //if (wp->flags & (SWP_NOMOVE|SWP_NOSIZE)) return; //v2.02.10 - - if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){ - extern void CalculateWindowPos(HWND, DWORD, DWORD, LPWINDOWPOS); - CalculateWindowPos(hwnd, MaxX, MaxY, wp); - OutTraceD("%s: LOCK pos=(%d,%d) dim=(%d,%d)\n", ApiName, wp->x, wp->y, wp->cx, wp->cy); - } - - if ((dxw.dwFlags2 & KEEPASPECTRATIO) && dxw.IsFullScreen() && (hwnd==dxw.GethWnd())){ - // note: while keeping aspect ration, resizing from one corner doesn't tell - // which coordinate is prevalent to the other. We made an arbitrary choice. - // note: v2.1.93: compensation must refer to the client area, not the wp - // window dimensions that include the window borders. - if(BorderX==-1){ - RECT client, full; - (*pGetClientRect)(hwnd, &client); - (*pGetWindowRect)(hwnd, &full); - BorderX= full.right - full.left - client.right; - BorderY= full.bottom - full.top - client.bottom; - OutTraceD("%s: KEEPASPECTRATIO window borders=(%d,%d)\n", ApiName, BorderX, BorderY); - } - extern LRESULT LastCursorPos; - switch (LastCursorPos){ - case HTBOTTOM: - case HTTOP: - case HTBOTTOMLEFT: - case HTBOTTOMRIGHT: - case HTTOPLEFT: - case HTTOPRIGHT: - cx = BorderX + ((wp->cy - BorderY) * dxw.GetScreenWidth()) / dxw.GetScreenHeight(); - if(cx!=wp->cx){ - OutTraceD("%s: KEEPASPECTRATIO adjusted cx=%d->%d\n", ApiName, wp->cx, cx); - wp->cx = cx; - } - break; - case HTLEFT: - case HTRIGHT: - cy = BorderY + ((wp->cx - BorderX) * dxw.GetScreenHeight()) / dxw.GetScreenWidth(); - if(cy!=wp->cy){ - OutTraceD("%s: KEEPASPECTRATIO adjusted cy=%d->%d\n", ApiName, wp->cy, cy); - wp->cy = cy; - } - break; + LRESULT ret; + OutTraceW("SendMessage: hwnd=%x WinMsg=[0x%x]%s(%x,%x)\n", + hwnd, Msg, ExplainWinMessage(Msg), wParam, lParam); + if(dxw.dwFlags1 & MODIFYMOUSE){ + switch (Msg){ + case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MBUTTONDBLCLK: + // revert here the WindowProc mouse correction + POINT prev, curr; + RECT rect; + prev.x = LOWORD(lParam); + prev.y = HIWORD(lParam); + (*pGetClientRect)(dxw.GethWnd(), &rect); + curr.x = (prev.x * rect.right) / dxw.GetScreenWidth(); + curr.y = (prev.y * rect.bottom) / dxw.GetScreenHeight(); + lParam = MAKELPARAM(curr.x, curr.y); + OutTraceC("SendMessage: hwnd=%x pos XY=(%d,%d)->(%d,%d)\n", hwnd, prev.x, prev.y, curr.x, curr.y); + break; + default: + break; } } - - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - int UpdFlag = 0; - - if(wp->cx>MaxX) { wp->cx=MaxX; UpdFlag=1; } - if(wp->cy>MaxY) { wp->cy=MaxY; UpdFlag=1; } - if (UpdFlag) - OutTraceD("%s: SET max dim=(%d,%d)\n", ApiName, wp->cx, wp->cy); - } - - iLastCX= wp->cx; - iLastCY= wp->cy; + ret=(*pSendMessage)(hwnd, Msg, wParam, lParam); + OutTraceW("SendMessage: lresult=%x\n", ret); + return ret; } -void dxwFixMinMaxInfo(char *ApiName, HWND hwnd, LPARAM lParam) +HCURSOR WINAPI extSetCursor(HCURSOR hCursor) { - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - LPMINMAXINFO lpmmi; - lpmmi=(LPMINMAXINFO)lParam; - OutTraceD("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, - lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - lpmmi->ptMaxPosition.x=0; - lpmmi->ptMaxPosition.y=0; - if(pSetDevMode){ - lpmmi->ptMaxSize.x = pSetDevMode->dmPelsWidth; - lpmmi->ptMaxSize.y = pSetDevMode->dmPelsHeight; - } - else{ - lpmmi->ptMaxSize.x = dxw.GetScreenWidth(); - lpmmi->ptMaxSize.y = dxw.GetScreenHeight(); - } - OutTraceD("%s: SET PREVENTMAXIMIZE MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, - lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - } - // v2.1.75: added logic to fix win coordinates to selected ones. - // fixes the problem with "Achtung Spitfire", that can't be managed through PREVENTMAXIMIZE flag. - if (dxw.dwFlags1 & LOCKWINPOS){ - LPMINMAXINFO lpmmi; - lpmmi=(LPMINMAXINFO)lParam; - OutTraceD("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, - lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - lpmmi->ptMaxPosition.x=dxw.iPosX; - lpmmi->ptMaxPosition.y=dxw.iPosY; - lpmmi->ptMaxSize.x = dxw.iSizX ? dxw.iSizX : dxw.GetScreenWidth(); - lpmmi->ptMaxSize.y = dxw.iSizY ? dxw.iSizY : dxw.GetScreenHeight(); - OutTraceD("%s: SET LOCKWINPOS MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, - lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - } + HCURSOR ret; + + ret=(*pSetCursor)(hCursor); + OutTraceD("GDI.SetCursor: Cursor=%x, ret=%x\n", hCursor, ret); + //MessageBox(0, "SelectPalette", "GDI32.dll", MB_OK | MB_ICONEXCLAMATION); + return ret; } - -static LRESULT WINAPI FixWindowProc(char *ApiName, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM *lpParam) -{ - LPARAM lParam; - - lParam=*lpParam; - OutTraceW("%s: hwnd=%x msg=[0x%x]%s(%x,%x)\n", - ApiName, hwnd, Msg, ExplainWinMessage(Msg), wParam, lParam); - - switch(Msg){ - // attempt to fix Sleepwalker - //case WM_NCCALCSIZE: - // if (dxw.dwFlags1 & PREVENTMAXIMIZE) - // return 0; - // break; - case WM_ERASEBKGND: - OutTraceD("%s: prevent erase background\n", ApiName); - return 1; // 1=erased - break; // useless - case WM_GETMINMAXINFO: - dxwFixMinMaxInfo(ApiName, hwnd, lParam); - break; - case WM_WINDOWPOSCHANGING: - case WM_WINDOWPOSCHANGED: - dxwFixWindowPos(ApiName, hwnd, lParam); - break; - case WM_STYLECHANGING: - case WM_STYLECHANGED: - dxw.FixStyle(ApiName, hwnd, wParam, lParam); - break; - case WM_DISPLAYCHANGE: - // too late? to be deleted.... - if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 0; - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - OutTraceD("%s: WM_DISPLAYCHANGE depth=%d size=(%d,%d)\n", - ApiName, wParam, HIWORD(lParam), LOWORD(lParam)); - return 0; - } - break; - case WM_SIZE: - if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 0; - if (dxw.dwFlags1 & PREVENTMAXIMIZE){ - if ((wParam == SIZE_MAXIMIZED)||(wParam == SIZE_MAXSHOW)){ - OutTraceD("%s: prevent screen SIZE to fullscreen wparam=%d(%s) size=(%d,%d)\n", ApiName, - wParam, ExplainResizing(wParam), HIWORD(lParam), LOWORD(lParam)); - return 0; // checked - //lParam = MAKELPARAM(dxw.GetScreenWidth(), dxw.GetScreenHeight()); - //OutTraceD("%s: updated SIZE wparam=%d(%s) size=(%d,%d)\n", ApiName, - // wParam, ExplainResizing(wParam), HIWORD(lParam), LOWORD(lParam)); - } - } - break; - default: - break; - } - - // marker to run hooked function - return(-1); -} - -LRESULT WINAPI extCallWindowProc(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) +BOOL WINAPI extGetCursorPos(LPPOINT lppoint) { HRESULT res; + static int PrevX, PrevY; + POINT prev; - res=FixWindowProc("CallWindowProc", hwnd, Msg, wParam, &lParam); + if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(2); - if (res==(HRESULT)-1) - return (*pCallWindowProc)(lpPrevWndFunc, hwnd, Msg, wParam, lParam); - else - return res; -} - -LRESULT WINAPI extDefWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - HRESULT res; - - res=FixWindowProc("DefWindowProc", hwnd, Msg, wParam, &lParam); - - if (res==(HRESULT)-1) - return (*pDefWindowProc)(hwnd, Msg, wParam, lParam); - else - return res; -} - -int WINAPI extGetDeviceCaps(HDC hdc, int nindex) -{ - DWORD res; - - res = (*pGDIGetDeviceCaps)(hdc, nindex); - OutTraceD("GetDeviceCaps: hdc=%x index=%x(%s) res=%x\n", - hdc, nindex, ExplainDeviceCaps(nindex), res); - - // if you have a bypassed setting, use it first! - if(pSetDevMode){ - switch(nindex){ - case BITSPIXEL: - case COLORRES: - res = pSetDevMode->dmBitsPerPel; - OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%x\n",res); - return res; - case HORZRES: - res = pSetDevMode->dmPelsWidth; - OutTraceD("GetDeviceCaps: fix HORZRES cap=%d\n", res); - return res; - case VERTRES: - res = pSetDevMode->dmPelsHeight; - OutTraceD("GetDeviceCaps: fix VERTRES cap=%d\n", res); - return res; - } + if (pGetCursorPos) { + res=(*pGetCursorPos)(lppoint); + } + else { + lppoint->x =0; lppoint->y=0; + res=1; } - switch(nindex){ - case VERTRES: - res= dxw.GetScreenHeight(); - OutTraceD("GetDeviceCaps: fix VERTRES cap=%d\n", res); - break; - case HORZRES: - res= dxw.GetScreenWidth(); - OutTraceD("GetDeviceCaps: fix HORZRES cap=%d\n", res); - break; - // WARNING: in no-emu mode, the INIT8BPP and INIT16BPP flags expose capabilities that - // are NOT implemented and may cause later troubles! - case RASTERCAPS: - if(dxw.dwFlags2 & INIT8BPP) { - res |= RC_PALETTE; // v2.02.12 - OutTraceD("GetDeviceCaps: fix RASTERCAPS setting RC_PALETTE cap=%x\n",res); - } - break; - case BITSPIXEL: - case COLORRES: - if(dxw.dwFlags2 & INIT8BPP|INIT16BPP){ - if(dxw.dwFlags2 & INIT8BPP) res = 8; - if(dxw.dwFlags2 & INIT16BPP) res = 16; - OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%d\n",res); - } - break; - } - - if(dxw.dwFlags1 & EMULATESURFACE){ - switch(nindex){ - case RASTERCAPS: - if((dxw.VirtualPixelFormat.dwRGBBitCount==8) || (dxw.dwFlags2 & INIT8BPP)){ - res = RC_PALETTE; - OutTraceD("GetDeviceCaps: fix RASTERCAPS setting RC_PALETTE cap=%x\n",res); - } - break; - case BITSPIXEL: - case COLORRES: - int PrevRes; - PrevRes=res; - if(dxw.VirtualPixelFormat.dwRGBBitCount!=0) res = dxw.VirtualPixelFormat.dwRGBBitCount; - if(dxw.dwFlags2 & INIT8BPP) res = 8; - if(dxw.dwFlags2 & INIT16BPP) res = 16; - if(PrevRes != res) OutTraceD("GetDeviceCaps: fix BITSPIXEL/COLORRES cap=%d\n",res); - break; - case SIZEPALETTE: - res = 256; - OutTraceD("GetDeviceCaps: fix SIZEPALETTE cap=%x\n",res); - break; - case NUMRESERVED: - res = 0; - OutTraceD("GetDeviceCaps: fix NUMRESERVED cap=%x\n",res); - break; - } - } - return res; -} - -int WINAPI extGetSystemMetrics(int nindex) -{ - HRESULT res; - - res=(*pGetSystemMetrics)(nindex); - OutTraceD("GetSystemMetrics: index=%x(%s), res=%d\n", nindex, ExplainsSystemMetrics(nindex), res); - - // if you have a bypassed setting, use it first! - if(pSetDevMode){ - switch(nindex){ - case SM_CXFULLSCREEN: - case SM_CXSCREEN: - res = pSetDevMode->dmPelsWidth; - OutTraceD("GetDeviceCaps: fix HORZRES cap=%d\n", res); - return res; - case SM_CYFULLSCREEN: - case SM_CYSCREEN: - res = pSetDevMode->dmPelsHeight; - OutTraceD("GetDeviceCaps: fix VERTRES cap=%d\n", res); - return res; - } - } - - switch(nindex){ - case SM_CXFULLSCREEN: - case SM_CXSCREEN: - res= dxw.GetScreenWidth(); - OutTraceD("GetSystemMetrics: fix SM_CXSCREEN=%d\n", res); - break; - case SM_CYFULLSCREEN: - case SM_CYSCREEN: - res= dxw.GetScreenHeight(); - OutTraceD("GetSystemMetrics: fix SM_CYSCREEN=%d\n", res); - break; - case SM_CMONITORS: - if((dxw.dwFlags2 & HIDEMULTIMONITOR) && res>1) { - res=1; - OutTraceD("GetSystemMetrics: fix SM_CMONITORS=%d\n", res); - } - break; - } + prev=*lppoint; + *lppoint=dxw.ScreenToClient(*lppoint); + *lppoint=dxw.FixCursorPos(*lppoint); + GetHookInfo()->CursorX=(short)lppoint->x; + GetHookInfo()->CursorY=(short)lppoint->y; + OutTraceC("GetCursorPos: FIXED pos=(%d,%d)->(%d,%d)\n", prev.x, prev.y, lppoint->x, lppoint->y); return res; } -BOOL WINAPI extScaleWindowExtEx(HDC hdc, int Xnum, int Xdenom, int Ynum, int Ydenom, LPSIZE lpSize) +BOOL WINAPI extSetCursorPos(int x, int y) { - OutTraceD("ScaleWindowExtEx: hdc=%x num=(%d,%d) denom=(%d,%d) lpSize=%d\n", - hdc, Xnum, Ynum, Xdenom, Ydenom, lpSize); + BOOL res; + int PrevX, PrevY; - if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 1; + PrevX=x; + PrevY=y; - return (*pGDIScaleWindowExtEx)(hdc, Xnum, Xdenom, Ynum, Ydenom, lpSize); -} - -LONG WINAPI MyChangeDisplaySettings(char *fname, DEVMODE *lpDevMode, DWORD dwflags) -{ - HRESULT res; - - // save desired settings first v.2.1.89 - // v2.1.95 protect when lpDevMode is null (closing game... Jedi Outcast) - // v2.2.23 consider new width/height only when dmFields flags are set. - if(lpDevMode && (lpDevMode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT))) - dxw.SetScreenSize(lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight); - - if ((dwflags==0 || dwflags==CDS_FULLSCREEN) && lpDevMode){ - if (dxw.dwFlags1 & EMULATESURFACE || !(lpDevMode->dmFields & DM_BITSPERPEL)){ - OutTraceD("%s: BYPASS res=DISP_CHANGE_SUCCESSFUL\n", fname); - return DISP_CHANGE_SUCCESSFUL; - } - else{ - DEVMODE NewMode; - if(dwflags==CDS_FULLSCREEN) dwflags=0; // no FULLSCREEN - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &NewMode); - OutTraceD("ChangeDisplaySettings: CURRENT wxh=(%dx%d) BitsPerPel=%d -> %d\n", - NewMode.dmPelsWidth, NewMode.dmPelsHeight, NewMode.dmBitsPerPel, - lpDevMode->dmBitsPerPel); - NewMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - NewMode.dmBitsPerPel = lpDevMode->dmBitsPerPel; - res=(*pChangeDisplaySettings)(&NewMode, 0); - if(res) OutTraceE("ChangeDisplaySettings: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return res; - } - } - else - return (*pChangeDisplaySettings)(lpDevMode, dwflags); -} - -LONG WINAPI extChangeDisplaySettings(DEVMODE *lpDevMode, DWORD dwflags) -{ - if(IsTraceD){ - OutTrace("ChangeDisplaySettings: lpDevMode=%x flags=%x", lpDevMode, dwflags); - if (lpDevMode) OutTrace(" fields=%x(%s) size=(%d x %d) bpp=%x", - lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields), - lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel); - OutTrace("\n"); - } - - return MyChangeDisplaySettings("ChangeDisplaySettings", lpDevMode, dwflags); -} - -LONG WINAPI extChangeDisplaySettingsEx(LPCTSTR lpszDeviceName, DEVMODE *lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam) -{ - if(IsTraceD){ - OutTrace("ChangeDisplaySettingsEx: DeviceName=%s lpDevMode=%x flags=%x", lpszDeviceName, lpDevMode, dwflags); - if (lpDevMode) OutTrace(" size=(%d x %d) bpp=%x", - lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel); - OutTrace("\n"); - } - - return MyChangeDisplaySettings("ChangeDisplaySettingsEx", lpDevMode, dwflags); -} - -LONG WINAPI extEnumDisplaySettings(LPCTSTR lpszDeviceName, DWORD iModeNum, DEVMODE *lpDevMode) -{ - OutTraceD("EnumDisplaySettings: Devicename=%s ModeNum=%x\n", lpszDeviceName, iModeNum); - if(pSetDevMode && iModeNum==ENUM_CURRENT_SETTINGS){ - lpDevMode=pSetDevMode; + if(dxw.dwFlags2 & KEEPCURSORFIXED) { + OutTraceC("SetCursorPos: FIXED pos=(%d,%d)\n", x, y); + LastCurPosX=x; + LastCurPosY=y; return 1; } - else - return (*pEnumDisplaySettings)(lpszDeviceName, iModeNum, lpDevMode); + + if(dxw.dwFlags1 & SLOWDOWN) dxw.DoSlow(2); + + if(dxw.dwFlags1 & KEEPCURSORWITHIN){ + // Intercept SetCursorPos outside screen boundaries (used as Cursor OFF in some games) + if ((y<0)||(y>=(int)dxw.GetScreenHeight())||(x<0)||(x>=(int)dxw.GetScreenWidth())) return 1; + } + + if(dxw.dwFlags1 & MODIFYMOUSE){ + POINT cur; + RECT rect; + + // find window metrics + if (!(*pGetClientRect)(dxw.GethWnd(), &rect)) { + // report error and ignore ... + OutTraceE("GetClientRect(%x) ERROR %d at %d\n", dxw.GethWnd(), GetLastError(), __LINE__); + return 0; + } + + x= x * rect.right / dxw.GetScreenWidth(); + y= y * rect.bottom / dxw.GetScreenHeight(); + + // check for boundaries (???) + if (x >= rect.right) x=rect.right-1; + if (x<0) x=0; + if (y >= rect.bottom) y=rect.bottom-1; + if (y<0) y=0; + + // make it screen absolute + cur.x = x; + cur.y = y; + if (!(*pClientToScreen)(dxw.GethWnd(), &cur)) { + OutTraceE("ClientToScreen(%x) ERROR %d at %d\n", dxw.GethWnd(), GetLastError(), __LINE__); + return 0; + } + x = cur.x; + y = cur.y; + } + + res=0; + if (pSetCursorPos) res=(*pSetCursorPos)(x,y); + + OutTraceC("SetCursorPos: res=%x XY=(%d,%d)->(%d,%d)\n",res, PrevX, PrevY, x, y); + return res; } -BOOL WINAPI extSetWindowPlacement(const WINDOWPLACEMENT*lpwndpl) +BOOL WINAPI extPeekMessage(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) { - OutTraceD("SetWindowPlacement: BYPASS\n"); - return 1; + BOOL res; + + res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); + + OutTraceW("PeekMessage: lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", + lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, + lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), + lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); + + // v2.1.74: skip message fix for WM_CHAR to avoid double typing bug + switch(lpMsg->message){ + //case WM_CHAR: + case WM_KEYUP: + case WM_KEYDOWN: + return res; + } + + // fix to avoid crash in Warhammer Final Liberation, that evidently intercepts mouse position by + // peeking & removing messages from window queue and considering the lParam parameter. + // v2.1.100 - never alter the mlMsg, otherwise the message is duplicated in the queue! Work on a copy of it. + if(wRemoveMsg){ + static MSG MsgCopy; + MsgCopy=*lpMsg; + MsgCopy.pt=FixMessagePt(dxw.GethWnd(), MsgCopy.pt); + if((MsgCopy.message <= WM_MOUSELAST) && (MsgCopy.message >= WM_MOUSEFIRST)) MsgCopy.lParam = MAKELPARAM(MsgCopy.pt.x, MsgCopy.pt.y); + OutTraceC("PeekMessage: fixed lparam/pt=(%d,%d)\n", MsgCopy.pt.x, MsgCopy.pt.y); + lpMsg=&MsgCopy; + GetHookInfo()->CursorX=(short)MsgCopy.pt.x; + GetHookInfo()->CursorY=(short)MsgCopy.pt.y; + } + + return res; } -ATOM WINAPI extRegisterClassExA(WNDCLASSEX *lpwcx) +BOOL WINAPI extGetMessage(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax) { - OutTraceD("RegisterClassEx: PROXED ClassName=%s style=%x(%s)\n", - lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style)); - return (*pRegisterClassExA)(lpwcx); + BOOL res; + HWND FixedHwnd; + + res=(*pGetMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax); + + OutTraceW("GetMessage: lpmsg=%x hwnd=%x filter=(%x-%x) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", + lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, + lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), + lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); + + // V2.1.68: processing ALL mouse events, to sync mouse over and mouse click events + // in "Uprising 2", now perfectly working. + DWORD Message; + Message=lpMsg->message & 0xFFFF; + if((Message <= WM_MOUSELAST) && (Message >= WM_MOUSEFIRST)){ + FixedHwnd=(hwnd)?hwnd:dxw.GethWnd(); + lpMsg->pt=FixMessagePt(FixedHwnd, lpMsg->pt); + lpMsg->lParam = MAKELPARAM(lpMsg->pt.x, lpMsg->pt.y); + OutTraceC("PeekMessage: fixed lparam/pt=(%d,%d)\n", lpMsg->pt.x, lpMsg->pt.y); + GetHookInfo()->CursorX=(short)lpMsg->pt.x; + GetHookInfo()->CursorY=(short)lpMsg->pt.y; + } + return res; } BOOL WINAPI extClientToScreen(HWND hwnd, LPPOINT lppoint) @@ -1306,21 +910,29 @@ BOOL WINAPI extGetWindowRect(HWND hwnd, LPRECT lpRect) int WINAPI extMapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints) { + UINT pi; + int ret; // a rarely used API, but responsible for a painful headache: needs hooking for "Commandos 2". OutTraceD("MapWindowPoints: hWndFrom=%x hWndTo=%x cPoints=%d FullScreen=%x\n", hWndFrom, hWndTo, cPoints, dxw.IsFullScreen()); if(IsDebug){ - UINT pi; OutTrace("Points: "); for(pi=0; pihwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, - lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), - lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); + OutTraceD("GetDesktopWindow: FullScreen=%x\n", dxw.IsFullScreen()); + if (dxw.IsFullScreen()){ + OutTraceD("GetDesktopWindow: returning main window hwnd=%x\n", dxw.GethWnd()); + return dxw.GethWnd(); + } + else{ + res=(*pGetDesktopWindow)(); + OutTraceD("GetDesktopWindow: returning desktop window hwnd=%x\n", res); + return res; + } +} - // v2.1.74: skip message fix for WM_CHAR to avoid double typing bug - switch(lpMsg->message){ - //case WM_CHAR: - case WM_KEYUP: - case WM_KEYDOWN: +int WINAPI extGetSystemMetrics(int nindex) +{ + HRESULT res; + + res=(*pGetSystemMetrics)(nindex); + OutTraceD("GetSystemMetrics: index=%x(%s), res=%d\n", nindex, ExplainsSystemMetrics(nindex), res); + + // if you have a bypassed setting, use it first! + if(pSetDevMode){ + switch(nindex){ + case SM_CXFULLSCREEN: + case SM_CXSCREEN: + res = pSetDevMode->dmPelsWidth; + OutTraceD("GetDeviceCaps: fix HORZRES cap=%d\n", res); return res; + case SM_CYFULLSCREEN: + case SM_CYSCREEN: + res = pSetDevMode->dmPelsHeight; + OutTraceD("GetDeviceCaps: fix VERTRES cap=%d\n", res); + return res; + } } - // fix to avoid crash in Warhammer Final Liberation, that evidently intercepts mouse position by - // peeking & removing messages from window queue and considering the lParam parameter. - // v2.1.100 - never alter the mlMsg, otherwise the message is duplicated in the queue! Work on a copy of it. - if(wRemoveMsg){ - static MSG MsgCopy; - MsgCopy=*lpMsg; - MsgCopy.pt=FixMessagePt(dxw.GethWnd(), MsgCopy.pt); - if((MsgCopy.message <= WM_MOUSELAST) && (MsgCopy.message >= WM_MOUSEFIRST)) MsgCopy.lParam = MAKELPARAM(MsgCopy.pt.x, MsgCopy.pt.y); - OutTraceC("PeekMessage: fixed lparam/pt=(%d,%d)\n", MsgCopy.pt.x, MsgCopy.pt.y); - lpMsg=&MsgCopy; - GetHookInfo()->CursorX=(short)MsgCopy.pt.x; - GetHookInfo()->CursorY=(short)MsgCopy.pt.y; + switch(nindex){ + case SM_CXFULLSCREEN: + case SM_CXSCREEN: + res= dxw.GetScreenWidth(); + OutTraceD("GetSystemMetrics: fix SM_CXSCREEN=%d\n", res); + break; + case SM_CYFULLSCREEN: + case SM_CYSCREEN: + res= dxw.GetScreenHeight(); + OutTraceD("GetSystemMetrics: fix SM_CYSCREEN=%d\n", res); + break; + case SM_CMONITORS: + if((dxw.dwFlags2 & HIDEMULTIMONITOR) && res>1) { + res=1; + OutTraceD("GetSystemMetrics: fix SM_CMONITORS=%d\n", res); + } + break; } return res; } -BOOL WINAPI extGetMessage(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax) +ATOM WINAPI extRegisterClassExA(WNDCLASSEX *lpwcx) { + OutTraceD("RegisterClassEx: PROXED ClassName=%s style=%x(%s)\n", + lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style)); + return (*pRegisterClassExA)(lpwcx); +} + +// GHO: pro Diablo +HWND WINAPI extCreateWindowExA( + DWORD dwExStyle, + LPCTSTR lpClassName, + LPCTSTR lpWindowName, + DWORD dwStyle, + int x, + int y, + int nWidth, + int nHeight, + HWND hWndParent, + HMENU hMenu, + HINSTANCE hInstance, + LPVOID lpParam) +{ + HWND wndh; + WNDPROC pWindowProc; + BOOL isValidHandle=TRUE; + + OutTraceD("CreateWindowEx: class=\"%s\" wname=\"%s\" pos=(%d,%d) size=(%d,%d) Style=%x(%s) ExStyle=%x(%s)\n", + lpClassName, lpWindowName, x, y, nWidth, nHeight, + dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); + if(IsDebug) OutTrace("CreateWindowEx: DEBUG screen=(%d,%d)\n", dxw.GetScreenWidth(), dxw.GetScreenHeight()); + + // no maximized windows in any case + if (dxw.dwFlags1 & PREVENTMAXIMIZE){ + OutTraceD("CreateWindowEx: handling PREVENTMAXIMIZE mode\n"); + dwStyle &= ~(WS_MAXIMIZE | WS_POPUP); + dwExStyle &= ~WS_EX_TOPMOST; + } + + // v2.1.92: fixes size & position for auxiliary big window, often used + // for intro movies etc. : needed for ...... + // evidently, this was supposed to be a fullscreen window.... + // v2.1.100: fixes for "The Grinch": this game creates a new main window for OpenGL + // rendering using CW_USEDEFAULT placement and 800x600 size while the previous + // main win was 640x480 only! + // v2.02.13: if it's a WS_CHILD window, don't reposition the x,y, placement for BIG win. + if ( + ( + ((x==0)&&(y==0)) || ((x==CW_USEDEFAULT)&&(y==CW_USEDEFAULT)) + ) + && + (((DWORD)nWidth>=dxw.GetScreenWidth())&&((DWORD)nHeight>=dxw.GetScreenHeight())) + && + !(dwExStyle & WS_EX_CONTROLPARENT) // Diablo fix + && + !(dwStyle & WS_CHILD) // Diablo fix + ){ + RECT screen; + POINT upleft = {0,0}; + // update virtual screen size if it has grown + dxw.SetScreenSize(nWidth, nHeight); + // inserted some checks here, since the main window could be destroyed + // or minimized (see "Jedi Outcast") so that you may get a dangerous + // zero size. In this case, better renew the hWnd assignement and its coordinates. + do { // fake loop + isValidHandle = FALSE; + if (!(*pGetClientRect)(dxw.GethWnd(),&screen)) break; + if (!(*pClientToScreen)(dxw.GethWnd(),&upleft)) break; + if (screen.right==0 || screen.bottom==0) break; + isValidHandle = TRUE; + } while(FALSE); + if (isValidHandle){ + if (!(dwStyle & WS_CHILD)){ + x=upleft.x; + y=upleft.y; + } + nWidth=screen.right; + nHeight=screen.bottom; + OutTraceD("CreateWindowEx: fixed BIG win pos=(%d,%d) size=(%d,%d)\n", x, y, nWidth, nHeight); + } + else { + // invalid parent coordinates: use initial placement, but leave the size. + // should also fix the window style and compensate for borders here? + if (!(dwStyle & WS_CHILD)){ + x=dxw.iPosX; + y=dxw.iPosY; + } + nWidth=dxw.iSizX; + nHeight=dxw.iSizY; + OutTraceD("CreateWindowEx: renewed BIG win pos=(%d,%d) size=(%d,%d)\n", x, y, nWidth, nHeight); + } + dxw.SetFullScreen(TRUE); + } + + if(!dxw.IsFullScreen()){ // v2.1.63: needed for "Monster Truck Madness" + wndh= (*pCreateWindowExA)(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, + hWndParent, hMenu, hInstance, lpParam); + OutTraceD("CreateWindowEx: windowed mode ret=%x\n", wndh); + return wndh; + } + + // tested on Gangsters: coordinates must be window-relative!!! + // Age of Empires.... + if (dwStyle & WS_CHILD){ + dxw.MapClient(&x, &y, &nWidth, &nHeight); + OutTraceD("CreateWindowEx: fixed WS_CHILD pos=(%d,%d) size=(%d,%d)\n", + x, y, nWidth, nHeight); + } + // needed for Diablo, that creates a new control parent window that must be + // overlapped to the directdraw surface. + else if (dwExStyle & WS_EX_CONTROLPARENT){ + dxw.MapWindow(&x, &y, &nWidth, &nHeight); + OutTraceD("CreateWindowEx: fixed WS_EX_CONTROLPARENT pos=(%d,%d) size=(%d,%d)\n", + x, y, nWidth, nHeight); + } + + OutTraceB("CreateWindowEx: fixed pos=(%d,%d) size=(%d,%d) Style=%x(%s) ExStyle=%x(%s)\n", + x, y, nWidth, nHeight, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); + + wndh= (*pCreateWindowExA)(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, + hWndParent, hMenu, hInstance, lpParam); + if (wndh==(HWND)NULL){ + OutTraceE("CreateWindowEx: ERROR err=%d Style=%x(%s) ExStyle=%x\n", + GetLastError(), dwStyle, ExplainStyle(dwStyle), dwExStyle); + return wndh; + } + + if ((!isValidHandle) && dxw.IsFullScreen()) { + dxw.SethWnd(wndh); + extern void AdjustWindowPos(HWND, DWORD, DWORD); + (*pSetWindowLong)(wndh, GWL_STYLE, (dxw.dwFlags2 & MODALSTYLE) ? 0 : WS_OVERLAPPEDWINDOW); + (*pSetWindowLong)(wndh, GWL_EXSTYLE, 0); + OutTraceD("CreateWindow: hwnd=%x, set style=WS_OVERLAPPEDWINDOW extstyle=0\n", wndh); + AdjustWindowPos(wndh, nWidth, nHeight); + (*pShowWindow)(wndh, SW_SHOWNORMAL); + } + + if ((dxw.dwFlags1 & FIXWINFRAME) && !(dwStyle & WS_CHILD)) + FixWindowFrame(wndh); + + // to do: handle inner child, and leave dialogue & modal child alone!!! + if ((dwStyle & WS_CHILD) && (dxw.dwFlags1 & HOOKCHILDWIN)){ + long res; + pWindowProc = (WNDPROC)(*pGetWindowLong)(wndh, GWL_WNDPROC); + OutTraceD("Hooking CHILD wndh=%x WindowProc %x->%x\n", wndh, pWindowProc, extChildWindowProc); + res=(*pSetWindowLong)(wndh, GWL_WNDPROC, (LONG)extChildWindowProc); + WhndStackPush(wndh, pWindowProc); + if(!res) OutTraceE("CreateWindowExA: SetWindowLong ERROR %x\n", GetLastError()); + } + + OutTraceD("CreateWindowEx: ret=%x\n", wndh); + return wndh; +} + +LRESULT WINAPI extCallWindowProc(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HRESULT res; + + res=FixWindowProc("CallWindowProc", hwnd, Msg, wParam, &lParam); + + if (res==(HRESULT)-1) + return (*pCallWindowProc)(lpPrevWndFunc, hwnd, Msg, wParam, lParam); + else + return res; +} + +LRESULT WINAPI extDefWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HRESULT res; + + res=FixWindowProc("DefWindowProc", hwnd, Msg, wParam, &lParam); + + if (res==(HRESULT)-1) + return (*pDefWindowProc)(hwnd, Msg, wParam, lParam); + else + return res; +} + +int WINAPI extFillRect(HDC hdc, const RECT *lprc, HBRUSH hbr) +{ + RECT rc, trim; + HWND hWnd; + OutTraceD("FillRect: hdc=%x xy=(%d,%d)-(%d,%d)\n", hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); + memcpy(&rc, lprc, sizeof(rc)); + hWnd = WindowFromDC(hdc); + if((hWnd == dxw.GethWnd()) || + (hWnd == 0) || + (hWnd == GetDesktopWindow())){ + // trim: some games (Player Manager 98) clear the screen by filling an exagerated rect + (*pGetClientRect)(dxw.GethWnd(), &trim); + hdc=GetDC(dxw.GethWnd()); + dxw.MapWindowRect(&rc); + if(rc.left < trim.left) rc.left = trim.left; + if(rc.top < trim.top) rc.top = trim.top; + if(rc.right > trim.right) rc.right = trim.right; + if(rc.bottom > trim.bottom) rc.bottom = trim.bottom; + OutTraceD("FillRect: hwnd=%x hdc=%x fixed xy=(%d,%d)-(%d,%d)\n", hWnd, hdc, rc.left, rc.top, rc.right, rc.bottom); + } + if (dxw.dwFlags1 & FIXTEXTOUT) { + // to be verified: why shifting and not scaling? + POINT anchor; + anchor.x=rc.left; + anchor.y=rc.top; + (*pClientToScreen)(dxw.GethWnd(), &anchor); + rc.left=anchor.x; + rc.top=anchor.y; + anchor.x=rc.right; + anchor.y=rc.bottom; + (*pClientToScreen)(dxw.GethWnd(), &anchor); + rc.right=anchor.x; + rc.bottom=anchor.y; + } + return (*pFillRect)(hdc, &rc, hbr); +} + +BOOL WINAPI extClipCursor(RECT *lpRectArg) +{ + // reference: hooking and setting ClipCursor is mandatori in "Emergency: Fighters for Life" + // where the application expects the cursor to be moved just in a inner rect within the + // main window surface. + BOOL res; - HWND FixedHwnd; + RECT *lpRect; + RECT Rect; - res=(*pGetMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax); - - OutTraceW("GetMessage: lpmsg=%x hwnd=%x filter=(%x-%x) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", - lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, - lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), - lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); - - // V2.1.68: processing ALL mouse events, to sync mouse over and mouse click events - // in "Uprising 2", now perfectly working. - DWORD Message; - Message=lpMsg->message & 0xFFFF; - if((Message <= WM_MOUSELAST) && (Message >= WM_MOUSEFIRST)){ - FixedHwnd=(hwnd)?hwnd:dxw.GethWnd(); - lpMsg->pt=FixMessagePt(FixedHwnd, lpMsg->pt); - lpMsg->lParam = MAKELPARAM(lpMsg->pt.x, lpMsg->pt.y); - OutTraceC("PeekMessage: fixed lparam/pt=(%d,%d)\n", lpMsg->pt.x, lpMsg->pt.y); - GetHookInfo()->CursorX=(short)lpMsg->pt.x; - GetHookInfo()->CursorY=(short)lpMsg->pt.y; - } - return res; -} - -// intercept GetProcAddress to initialize DirectDraw hook pointers. -// This is necessary in "The Sims" game, that loads DirectDraw dinamically - - -extern void HookModule(HMODULE, int); - -HMODULE SysLibs[SYSLIBIDX_MAX]; - -HMODULE WINAPI LoadLibraryExWrapper(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags, char *api) -{ - HMODULE libhandle; - int idx; - - //if(!strcmp(lpFileName, "d3d9.dll") && GetModuleHandle(lpFileName)) return GetModuleHandle(lpFileName); // attempt to avoid loading same dll twice.... - - libhandle=(*pLoadLibraryExA)(lpFileName, hFile, dwFlags); - OutTraceD("%s: FileName=%s hFile=%x Flags=%x(%s) hmodule=%x\n", api, lpFileName, hFile, dwFlags, ExplainLoadLibFlags(dwFlags), libhandle); - if(!libhandle){ - OutTraceE("%s: ERROR FileName=%s err=%d\n", api, lpFileName, GetLastError()); - return libhandle; + if(IsTraceC){ + if (lpRectArg) + OutTrace("ClipCursor: rect=(%d,%d)-(%d,%d)\n", + lpRectArg->left,lpRectArg->top,lpRectArg->right,lpRectArg->bottom); + else + OutTrace("ClipCursor: rect=(NULL)\n"); } - // when loaded with LOAD_LIBRARY_AS_DATAFILE or LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE flags, - // there's no symbol map, then itìs no possible to hook function calls. - if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE|LOAD_LIBRARY_AS_DATAFILE)) return libhandle; + if (!(dxw.dwFlags1 & ENABLECLIPPING)) return 1; - idx=dxw.GetDLLIndex((char *)lpFileName); - if(idx != -1) SysLibs[idx]=libhandle; - // handle custom OpenGL library - if(!lstrcmpi(lpFileName,dxw.CustomOpenGLLib)){ - idx=SYSLIBIDX_OPENGL; - SysLibs[idx]=libhandle; + if(lpRectArg){ + Rect=*lpRectArg; + lpRect=&Rect; } - if (idx == -1) HookModule(libhandle, 0); - return libhandle; -} + else + lpRect=NULL; -HMODULE WINAPI extLoadLibraryA(LPCTSTR lpFileName) -{ - return LoadLibraryExWrapper(lpFileName, NULL, 0, "LoadLibraryA"); -} - -HMODULE WINAPI extLoadLibraryW(LPCWSTR lpFileName) -{ - char sFileName[256+1]; - wcstombs_s(NULL, sFileName, lpFileName, 80); - return LoadLibraryExWrapper(sFileName, NULL, 0, "LoadLibraryW");; -} - -HMODULE WINAPI extLoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags) -{ - return LoadLibraryExWrapper(lpFileName, hFile, dwFlags, "LoadLibraryExA"); -} - -HMODULE WINAPI extLoadLibraryExW(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags) -{ - char sFileName[256+1]; - wcstombs_s(NULL, sFileName, lpFileName, 80); - return LoadLibraryExWrapper(sFileName, hFile, dwFlags, "LoadLibraryExW");; -} - -extern DirectDrawCreate_Type pDirectDrawCreate; -extern DirectDrawCreateEx_Type pDirectDrawCreateEx; -extern HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); -extern HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *); -extern GetProcAddress_Type pGetProcAddress; -//extern HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID FAR*); - -FARPROC WINAPI extGetProcAddress(HMODULE hModule, LPCSTR proc) -{ - FARPROC ret; - int idx; - - // WARNING: seems to be called with bad LPCSTR value.... - // from MSDN: - // The function or variable name, or the function's ordinal value. - // If this parameter is an ordinal value, it must be in the low-order word; - // the high-order word must be zero. - - OutTraceD("GetProcAddress: hModule=%x proc=%s\n", hModule, ProcToString(proc)); - - for(idx=0; idxleft,lpRect->top,lpRect->right,lpRect->bottom, res); + + return TRUE; +} + +BOOL WINAPI extGetClipCursor(LPRECT lpRect) +{ + // v2.1.93: if ENABLECLIPPING, return the saved clip rect coordinates + + BOOL ret; + + // proxy.... + if (!(dxw.dwFlags1 & ENABLECLIPPING)) { + ret=(*pGetClipCursor)(lpRect); + if(IsTraceD){ + if (lpRect) + OutTrace("ClipCursor: PROXED rect=(%d,%d)-(%d,%d) ret=%d\n", + lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, ret); + else + OutTrace("ClipCursor: PROXED rect=(NULL) ret=%d\n", ret); + } + return ret; + } + + if(lpRect){ + if(lpClipRegion) + *lpRect=ClipRegion; + else{ + lpRect->top = lpRect->left = 0; + lpRect->right = dxw.GetScreenWidth(); + lpRect->bottom = dxw.GetScreenHeight(); + } + OutTraceD("ClipCursor: rect=(%d,%d)-(%d,%d) ret=%d\n", + lpRect->left,lpRect->top,lpRect->right,lpRect->bottom, TRUE); + } + + return TRUE; +} + +LONG WINAPI extEnumDisplaySettings(LPCTSTR lpszDeviceName, DWORD iModeNum, DEVMODE *lpDevMode) +{ + OutTraceD("EnumDisplaySettings: Devicename=%s ModeNum=%x\n", lpszDeviceName, iModeNum); + if(pSetDevMode && iModeNum==ENUM_CURRENT_SETTINGS){ + lpDevMode=pSetDevMode; + return 1; + } + else + return (*pEnumDisplaySettings)(lpszDeviceName, iModeNum, lpDevMode); +} + +LONG WINAPI extChangeDisplaySettings(DEVMODE *lpDevMode, DWORD dwflags) +{ + if(IsTraceD){ + OutTrace("ChangeDisplaySettings: lpDevMode=%x flags=%x", lpDevMode, dwflags); + if (lpDevMode) OutTrace(" fields=%x(%s) size=(%d x %d) bpp=%x", + lpDevMode->dmFields, ExplainDevModeFields(lpDevMode->dmFields), + lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel); + OutTrace("\n"); + } + + return MyChangeDisplaySettings("ChangeDisplaySettings", lpDevMode, dwflags); +} + +LONG WINAPI extChangeDisplaySettingsEx(LPCTSTR lpszDeviceName, DEVMODE *lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam) +{ + if(IsTraceD){ + OutTrace("ChangeDisplaySettingsEx: DeviceName=%s lpDevMode=%x flags=%x", lpszDeviceName, lpDevMode, dwflags); + if (lpDevMode) OutTrace(" size=(%d x %d) bpp=%x", + lpDevMode->dmPelsWidth, lpDevMode->dmPelsHeight, lpDevMode->dmBitsPerPel); + OutTrace("\n"); + } + + return MyChangeDisplaySettings("ChangeDisplaySettingsEx", lpDevMode, dwflags); } HDC WINAPI extGDIGetDC(HWND hwnd) @@ -1592,10 +1339,26 @@ HDC WINAPI extGDIGetDC(HWND hwnd) OutTraceD("GDI.GetDC: hwnd=%x\n", hwnd); lochwnd=hwnd; - if (dxw.IsFullScreen() && ((hwnd==0) || (hwnd==(*pGetDesktopWindow)()))) { + //if (dxw.IsFullScreen() && dxw.IsDesktop()) { + if (dxw.IsDesktop(hwnd)) { OutTraceD("GDI.GetDC: desktop remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); lochwnd=dxw.GethWnd(); } + +#if 0 + dxw.lpDDSPrimHDC=dxw.GetPrimarySurface(); + if(dxw.lpDDSPrimHDC){ + HRESULT rc; + OutTraceD("GDI.GetDC: using ddraw primary lpdds=%x\n", dxw.lpDDSPrimHDC); + rc=(*pGetDC)(dxw.lpDDSPrimHDC, &ret); + if(rc) + OutTraceE("GDI.GetDC ERROR: err=%x(%s) at %d\n", rc, ExplainDDError(rc), __LINE__); + else + OutTraceD("GDI.GetDC: hwnd=%x ret=%x\n", hwnd, ret); + return ret; + } +#endif + ret=(*pGDIGetDC)(lochwnd); if(ret){ OutTraceD("GDI.GetDC: hwnd=%x ret=%x\n", lochwnd, ret); @@ -1650,372 +1413,29 @@ int WINAPI extGDIReleaseDC(HWND hwnd, HDC hDC) int res; OutTraceD("GDI.ReleaseDC: hwnd=%x hdc=%x\n", hwnd, hDC); - if (hwnd==0) hwnd=dxw.GethWnd(); + if (dxw.IsDesktop(hwnd)) hwnd=dxw.GethWnd(); + +#if 0 + if(dxw.lpDDSPrimHDC){ + HRESULT rc; + OutTraceD("GDI.ReleaseDC: using ddraw primary lpdds=%x\n", dxw.lpDDSPrimHDC); + rc=(*pReleaseDC)(dxw.lpDDSPrimHDC, hDC); + sBlt("ReleaseDC", dxw.lpDDSPrimHDC, NULL, dxw.lpDDSPrimHDC, NULL, DDBLT_WAIT, 0, TRUE); + if(rc) { + OutTraceE("GDI.ReleaseDC ERROR: hwnd=%x err=%x(%s) at %d\n", hwnd, rc, ExplainDDError(rc), __LINE__); + } + else { + sBlt("ReleaseDC", dxw.lpDDSPrimHDC, NULL, dxw.lpDDSPrimHDC, NULL, DDBLT_WAIT, 0, TRUE); + } + return (rc ? 0 : 1); + } +#endif + res=(*pGDIReleaseDC)(hwnd, hDC); if (!res) OutTraceE("GDI.ReleaseDC ERROR: err=%d at %d\n", GetLastError(), __LINE__); return(res); } -HDC WINAPI extGDICreateDC(LPSTR Driver, LPSTR Device, LPSTR Output, CONST DEVMODE *InitData) -{ - HDC WinHDC, RetHDC; - OutTraceD("GDI.CreateDC: Driver=%s Device=%s Output=%s InitData=%x\n", - Driver?Driver:"(NULL)", Device?Device:"(NULL)", Output?Output:"(NULL)", InitData); - - if (!Driver || !strncmp(Driver,"DISPLAY",7)) { - OutTraceD("GDI.CreateDC: returning window surface DC\n"); - WinHDC=(*pGDIGetDC)(dxw.GethWnd()); - RetHDC=(*pGDICreateCompatibleDC)(WinHDC); - (*pGDIReleaseDC)(dxw.GethWnd(), WinHDC); - } - else{ - RetHDC=(*pGDICreateDC)(Driver, Device, Output, InitData); - } - if(RetHDC) - OutTraceD("GDI.CreateDC: returning HDC=%x\n", RetHDC); - else - OutTraceE("GDI.CreateDC ERROR: err=%d at %d\n", GetLastError(), __LINE__); - return RetHDC; -} - -HDC WINAPI extGDICreateCompatibleDC(HDC hdc) -{ - HDC RetHdc, SrcHdc; - extern LPDIRECTDRAWSURFACE lpDDSHDC; - extern GetDC_Type pGetDC; - DWORD LastError; - - OutTraceD("GDI.CreateCompatibleDC: hdc=%x\n", hdc); - if(hdc==0){ - SrcHdc=(*pGDIGetDC)(dxw.GethWnd()); - OutTraceD("GDI.CreateCompatibleDC: duplicating win HDC hWnd=%x\n", dxw.GethWnd()); - } - - // eliminated error message for errorcode 0. - SetLastError(0); - RetHdc=(*pGDICreateCompatibleDC)(hdc); - LastError=GetLastError(); - if(!LastError) - OutTraceD("GDI.CreateCompatibleDC: returning HDC=%x\n", RetHdc); - else - OutTraceE("GDI.CreateCompatibleDC ERROR: err=%d at %d\n", LastError, __LINE__); - return RetHdc; -} - -BOOL WINAPI extGDIBitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop) -{ - BOOL res; - extern BOOL isWithinDialog; - - OutTraceD("GDI.BitBlt: HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d hdcSrc=%x nXSrc=%d nYSrc=%d dwRop=%x(%s)\n", - hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop, ExplainROP(dwRop)); - - if (dxw.HandleFPS()) return TRUE; - - // beware: HDC could refer to screen DC that are written directly on screen, or memory DC that will be scaled to - // the screen surface later on, on ReleaseDC or ddraw Blit / Flip operation. Scaling of rect coordinates is - // needed only in the first case, and must be avoided on the second, otherwise the image would be scaled twice! - - if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdcDest))){ - int nWDest, nHDest; - nWDest= nWidth; - nHDest= nHeight; - dxw.MapClient(&nXDest, &nYDest, &nWDest, &nHDest); - if (dxw.dwFlags2 & SHOWFPSOVERLAY) dxw.ShowFPS(hdcDest); - res=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWDest, nHDest, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, dwRop); - } - else { - res=(*pGDIBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); - } - if(!res) OutTraceE("GDI.BitBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); - - return res; -} - -BOOL WINAPI extGDIPatBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, DWORD dwRop) -{ - BOOL res; - - OutTraceD("GDI.PatBlt: HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d dwRop=%x(%s)\n", - hdcDest, nXDest, nYDest, nWidth, nHeight, dwRop, ExplainROP(dwRop)); - - if (dxw.HandleFPS()) return TRUE; - - if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdcDest))){ - int nWDest, nHDest; - dxw.MapClient(&nXDest, &nYDest, &nWDest, &nHDest); - if (dxw.dwFlags2 & SHOWFPSOVERLAY) dxw.ShowFPS(hdcDest); - res=(*pGDIPatBlt)(hdcDest, nXDest, nYDest, nWDest, nHDest, dwRop); - } - else { - res=(*pGDIPatBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, dwRop); - } - if(!res) OutTraceE("GDI.PatBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); - - return res; -} - -BOOL WINAPI extGDIStretchBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, - HDC hdcSrc, int nXSrc, int nYSrc, int nWSrc, int nHSrc, DWORD dwRop) -{ - BOOL res; - - OutTraceD("GDI.StretchBlt: HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d hdcSrc=%x nXSrc=%d nYSrc=%d nWSrc=%d nHSrc=%d dwRop=%x(%s)\n", - hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop, ExplainROP(dwRop)); - - if (dxw.HandleFPS()) return TRUE; - - // to do: what happend if StretchBlt is applied on screen DC ? - - if (dxw.dwFlags2 & SHOWFPSOVERLAY) dxw.ShowFPS(hdcDest); - res=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop); - if(!res) OutTraceE("GDI.StretchBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return res; -} - -BOOL WINAPI extGDIDeleteDC(HDC hdc) -{ - BOOL res; - OutTraceD("GDI.DeleteDC: hdc=%x\n", hdc); - res=(*pGDIDeleteDC)(hdc); - if(!res) OutTraceE("GDI.DeleteDC: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return res; -} - -static HANDLE AutoRefreshThread; -static DWORD dwThrdId; -void AutoRefresh(HDC hdc) -{ - while(1){ - (*pSleep)(10); - (*pInvalidateRect)(dxw.GethWnd(), 0, FALSE); - } -} - -int WINAPI extGDISaveDC(HDC hdc) -{ - int ret; - - ret=(*pGDISaveDC)(hdc); - //ret=1; - OutTraceD("GDI.SaveDC: hdc=%x ret=%x\n", hdc, ret); - //AutoRefreshThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AutoRefresh, (LPVOID)hdc, 0, &dwThrdId); - return ret; -} - -BOOL WINAPI extGDIRestoreDC(HDC hdc, int nSavedDC) -{ - BOOL ret; - - ret=(*pGDIRestoreDC)(hdc, nSavedDC); - //ret=1; - OutTraceD("GDI.RestoreDC: hdc=%x nSavedDC=%x ret=%x\n", hdc, nSavedDC, ret); - //TerminateThread(AutoRefreshThread, 0); - return ret; -} - -/* -------------------------------------------------------------------- */ -// directdraw supported GDI calls -/* -------------------------------------------------------------------- */ - -// PrimHDC: DC handle of the selected DirectDraw primary surface. NULL when invalid. -static HDC PrimHDC=NULL; - -HDC WINAPI extDDCreateCompatibleDC(HDC hdc) -{ - HDC RetHdc, SrcHdc; - extern GetDC_Type pGetDC; - - OutTraceD("GDI.CreateCompatibleDC: hdc=%x\n", hdc); - - if(hdc==0 && pGetDC && dxw.IsFullScreen()){ - dxw.SetPrimarySurface(); - (*pGetDC)(dxw.lpDDSPrimHDC,&SrcHdc); - OutTraceD("GDI.CreateCompatibleDC: duplicating screen HDC lpDDSPrimHDC=%x\n", dxw.lpDDSPrimHDC); - RetHdc=(*pGDICreateCompatibleDC)(SrcHdc); - (*pReleaseDC)(dxw.lpDDSPrimHDC,SrcHdc); - } - else - RetHdc=(*pGDICreateCompatibleDC)(hdc); - - if(RetHdc) - OutTraceD("GDI.CreateCompatibleDC: returning HDC=%x\n", RetHdc); - else - OutTraceE("GDI.CreateCompatibleDC ERROR: err=%d at %d\n", GetLastError(), __LINE__); - - return RetHdc; -} - -BOOL WINAPI extDDDeleteDC(HDC hdc) -{ - BOOL res; - - OutTraceD("GDI.DeleteDC: hdc=%x\n", hdc); - - res=(*pGDIDeleteDC)(hdc); - if(!res) OutTraceE("GDI.DeleteDC: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return res; -} - -static HDC WINAPI winDDGetDC(HWND hwnd, char *api) -{ - HDC hdc; - HRESULT res; - extern HRESULT WINAPI extGetDC(LPDIRECTDRAWSURFACE, HDC FAR *); - - OutTraceD("%s: hwnd=%x\n", api, hwnd); - - dxw.ResetPrimarySurface(); - dxw.SetPrimarySurface(); - - if(dxw.lpDDSPrimHDC){ - if (PrimHDC){ - OutTraceD("%s: reusing primary hdc\n", api); - (*pUnlockMethod(dxw.lpDDSPrimHDC))(dxw.lpDDSPrimHDC, NULL); - hdc=PrimHDC; - } - else{ - OutTraceD("%s: get hdc from PRIMARY surface lpdds=%x\n", api, dxw.lpDDSPrimHDC); - res=extGetDC(dxw.lpDDSPrimHDC,&hdc); - if(res) { - OutTraceE("%s: GetDC(%x) ERROR %x(%s) at %d\n", api, dxw.lpDDSPrimHDC, res, ExplainDDError(res), __LINE__); - if(res==DDERR_DCALREADYCREATED){ - // try recovery.... - (*pReleaseDC)(dxw.lpDDSPrimHDC,NULL); - res=extGetDC(dxw.lpDDSPrimHDC,&hdc); - } - if(res)return 0; - } - PrimHDC=hdc; - } - } - else { - hdc=(*pGDIGetDC)(hwnd ? hwnd : dxw.GethWnd()); - OutTraceD("%s: returning window DC handle hwnd=%x hdc=%x\n", api, hwnd, hdc); - PrimHDC=NULL; - } - - if(hdc) - OutTraceD("%s: hwnd=%x hdc=%x\n", api, hwnd, hdc); - else - OutTraceE("%s: ERROR err=%d at %d\n", api, GetLastError, __LINE__); - return(hdc); -} - -HDC WINAPI extDDCreateDC(LPSTR Driver, LPSTR Device, LPSTR Output, CONST DEVMODE *InitData) -{ - HDC RetHDC; - OutTraceD("GDI.CreateDC: Driver=%s Device=%s Output=%s InitData=%x\n", - Driver?Driver:"(NULL)", Device?Device:"(NULL)", Output?Output:"(NULL)", InitData); - - if (!Driver || !strncmp(Driver,"DISPLAY",7)) { - //HDC PrimHDC; - LPDIRECTDRAWSURFACE lpdds; - OutTraceD("GDI.CreateDC: returning primary surface DC\n"); - lpdds=dxw.GetPrimarySurface(); - (*pGetDC)(lpdds, &PrimHDC); - RetHDC=(*pGDICreateCompatibleDC)(PrimHDC); - (*pReleaseDC)(lpdds, PrimHDC); - } - else{ - RetHDC=(*pGDICreateDC)(Driver, Device, Output, InitData); - } - if(RetHDC) - OutTraceD("GDI.CreateDC: returning HDC=%x\n", RetHDC); - else - OutTraceE("GDI.CreateDC ERROR: err=%d at %d\n", GetLastError(), __LINE__); - return RetHDC; -} - -HDC WINAPI extDDGetDC(HWND hwnd) -{ - HDC ret; - ret=winDDGetDC(hwnd, "GDI.GetDC"); - return ret; -} - -HDC WINAPI extDDGetWindowDC(HWND hwnd) -{ - HDC ret; - ret=winDDGetDC(hwnd, "GDI.GetWindowDC"); - return ret; -} - -int WINAPI extDDReleaseDC(HWND hwnd, HDC hDC) -{ - int res; - extern HRESULT WINAPI extReleaseDC(LPDIRECTDRAWSURFACE, HDC); - - OutTraceD("GDI.ReleaseDC: hwnd=%x hdc=%x\n", hwnd, hDC); - res=0; - if ((hDC == PrimHDC) || (hwnd==0)){ - dxw.SetPrimarySurface(); - OutTraceD("GDI.ReleaseDC: refreshing primary surface lpdds=%x\n",dxw.lpDDSPrimHDC); - if(!dxw.lpDDSPrimHDC) return 0; - extReleaseDC(dxw.lpDDSPrimHDC, hDC); - PrimHDC=NULL; - res=1; // 1 = OK - } - else { - res=(*pGDIReleaseDC)(hwnd, hDC); - if (!res) OutTraceE("GDI.ReleaseDC: ERROR err=%d at %d\n", GetLastError(), __LINE__); - } - return(res); -} - -BOOL WINAPI extDDBitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop) -{ - BOOL ret; - HRESULT res; - extern HRESULT WINAPI extGetDC(LPDIRECTDRAWSURFACE, HDC FAR *); - - OutTraceD("GDI.BitBlt: HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d hdcSrc=%x nXSrc=%d nYSrc=%d dwRop=%x(%s)\n", - hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop, ExplainROP(dwRop)); - - ret=1; // OK - - if(hdcDest==0) hdcDest=PrimHDC; - if(hdcDest==0) { - dxw.ResetPrimarySurface(); - dxw.SetPrimarySurface(); - res=extGetDC(dxw.lpDDSPrimHDC, &PrimHDC); - hdcDest=PrimHDC; - } - - res=(*pGDIBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); - if(!res) OutTraceE("GDI.BitBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); - - res=(*pGDIBitBlt)(NULL, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); - - if(!res) ret=0; - return ret; -} - -BOOL WINAPI extDDStretchBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, - HDC hdcSrc, int nXSrc, int nYSrc, int nWSrc, int nHSrc, DWORD dwRop) -{ - BOOL ret; - HRESULT res; - RECT ClientRect; - - OutTraceD("GDI.StretchBlt: HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d hdcSrc=%x nXSrc=%d nYSrc=%d nWSrc=%x nHSrc=%x dwRop=%x\n", - hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop); - - if(hdcDest != hdcSrc){ - (*pGetClientRect)(dxw.GethWnd(),&ClientRect); - ret=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, dwRop); - if(!ret) { - OutTraceE("GDI.StretchBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return ret; - } - } - dxw.SetPrimarySurface(); - OutTraceD("GDI.StretchBlt: refreshing primary surface lpdds=%x\n",dxw.lpDDSPrimHDC); - sBlt("GDI.StretchBlt", dxw.lpDDSPrimHDC, NULL, dxw.lpDDSPrimHDC, NULL, 0, NULL, 0); - res=(*pUnlockMethod(dxw.lpDDSPrimHDC))(dxw.lpDDSPrimHDC, NULL); - return ret; -} - HDC WINAPI extBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) { HDC hdc; @@ -2025,6 +1445,8 @@ HDC WINAPI extBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) OutTraceD("GDI.BeginPaint: hwnd=%x lpPaint=%x FullScreen=%x\n", hwnd, lpPaint, dxw.IsFullScreen()); hdc=(*pBeginPaint)(hwnd, lpPaint); + return hdc; + // if not in fullscreen mode, that's all! if(!dxw.IsFullScreen()) return hdc; @@ -2062,6 +1484,8 @@ BOOL WINAPI extEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint) OutTraceD("GDI.EndPaint: hwnd=%x ret=%x\n", hwnd, ret); if(!ret) OutTraceE("GDI.EndPaint ERROR: err=%d at %d\n", GetLastError(), __LINE__); + return ret; + // if not in fullscreen mode, that's all! if(!dxw.IsFullScreen()) return ret; @@ -2076,25 +1500,6 @@ BOOL WINAPI extEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint) return ret; } -/* --------------------------------------------------------------------------- */ -// C&C Tiberian Sun: mixes DirectDraw with GDI Dialogues. -// To make them visible, the lpDialog call had to be hooked to insert a periodic -// InvalidateRect call to make GDI appear on screen -/* --------------------------------------------------------------------------- */ - -BOOL __cdecl TraceChildWin(HWND hwnd, LPARAM lParam) -{ - POINT pos={0,0}; - RECT child; - (*pGetClientRect)(hwnd, &child); - (*pClientToScreen)(hwnd,&pos); - OutTraceD("Father hwnd=%x has child=%x pos=(%d,%d) size=(%d,%d)\n", - HWND(lParam), hwnd, pos.x, pos.y, child.right, child.bottom); - return TRUE; -} - -BOOL isWithinDialog=FALSE; - HWND WINAPI extCreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM lParamInit) { HWND RetHWND; @@ -2133,121 +1538,6 @@ HWND WINAPI extCreateDialogParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HW return RetHWND; } -BOOL WINAPI extDDInvalidateRect(HWND hwnd, RECT *lpRect, BOOL bErase) -{ - if(lpRect) - OutTraceD("InvalidateRect: hwnd=%x rect=(%d,%d)-(%d,%d) erase=%x\n", - hwnd, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, bErase); - else - OutTraceD("InvalidateRect: hwnd=%x rect=NULL erase=%x\n", - hwnd, bErase); - - return (*pInvalidateRect)(hwnd, NULL, bErase); -} - -BOOL WINAPI extInvalidateRect(HWND hwnd, RECT *lpRect, BOOL bErase) -{ - if(lpRect) - OutTraceD("InvalidateRect: hwnd=%x rect=(%d,%d)-(%d,%d) erase=%x\n", - hwnd, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, bErase); - else - OutTraceD("InvalidateRect: hwnd=%x rect=NULL erase=%x\n", - hwnd, bErase); - - return (*pInvalidateRect)(hwnd, NULL, bErase); -} - -/* --------------------------------------------------------------------------- */ - -// v2.1.75: Hooking for GDI32 CreatePalette, SelectPalette, RealizePalette: -// maps the GDI palette to the buffered DirectDraw one. This fixes the screen -// output for "Dementia" (a.k.a. "Armed & Delirious"). - -HPALETTE WINAPI extGDICreatePalette(CONST LOGPALETTE *plpal) -{ - HPALETTE ret; - int idx; - - dxw.IsGDIPalette=TRUE; - OutTraceD("GDI.CreatePalette: plpal=%x version=%x NumEntries=%x\n", plpal, plpal->palVersion, plpal->palNumEntries); - ret=(*pGDICreatePalette)(plpal); - if(IsDebug){ - OutTraceD("PalEntry[%x]= ", plpal->palNumEntries); - for(idx=0; idxpalNumEntries; idx++) OutTraceD("(%x)", plpal->palPalEntry[idx]); - OutTraceD("\n"); - } - dxw.palVersion=plpal->palVersion; - dxw.palNumEntries=plpal->palNumEntries; - if(dxw.palNumEntries>256) dxw.palNumEntries=256; - for(idx=0; idxpalPalEntry[idx]; - OutTraceD("GDI.CreatePalette: hPalette=%x\n", ret); - return ret; -} - -HPALETTE WINAPI extSelectPalette(HDC hdc, HPALETTE hpal, BOOL bForceBackground) -{ - HPALETTE ret; - - ret=(*pGDISelectPalette)(hdc, hpal, bForceBackground); - OutTraceD("GDI.SelectPalette: hdc=%x hpal=%x ForceBackground=%x ret=%x\n", hdc, hpal, bForceBackground, ret); - return ret; -} - -UINT WINAPI extRealizePalette(HDC hdc) -{ - UINT ret; - extern void mySetPalette(int, int, LPPALETTEENTRY); - - ret=(*pGDIRealizePalette)(hdc); - OutTraceD("GDI.RealizePalette: hdc=%x ret=%x\n", hdc, ret); - - if(!dxw.IsGDIPalette) return ret; - - // quick & dirty implementation through a nasty global: - // if the SelectPalette didn't force to the background (arg bForceBackground==FALSE) - // then don't override the current palette set by the DirectDrawPalette class. - // should be cleaned up a little.... - // maybe not: now both Diablo & Dementia colors are working... - if(dxw.dwFlags1 & EMULATESURFACE) - mySetPalette(0, dxw.palNumEntries, dxw.palPalEntry); - // DEBUGGING - if(IsDebug){ - int idx; - OutTraceD("PaletteEntries[%x]= ", dxw.palNumEntries); - for(idx=0; idx(%d,%d)\n", hwnd, prev.x, prev.y, curr.x, curr.y); - break; - default: - break; - } - } - ret=(*pSendMessage)(hwnd, Msg, wParam, lParam); - OutTraceW("SendMessage: lresult=%x\n", ret); - return ret; -} - int WINAPI extShowCursor(BOOL bShow) { static int iFakeCounter; @@ -2414,3 +1637,22 @@ int WINAPI extShowCursor(BOOL bShow) return ret; } +int extDrawTextA(HDC hDC, LPCTSTR lpchText, int nCount, LPRECT lpRect, UINT uFormat) +{ + return 0; +} + +int extDrawTextExA(HDC hDC, LPCTSTR lpchText, int cchText, LPRECT lprc, UINT dwDTFormat, LPDRAWTEXTPARAMS lpDTParams) +{ + return 0; +} + +BOOL extDrawFocusRect(HDC hDC, const RECT *lprc) +{ + return TRUE; +} + +BOOL extScrollDC(HDC hDC, int dx, int dy, const RECT *lprcScroll, const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate) +{ + return TRUE; +} \ No newline at end of file diff --git a/dll/wndproc.cpp b/dll/wndproc.cpp index 7ca2078..200e756 100644 --- a/dll/wndproc.cpp +++ b/dll/wndproc.cpp @@ -15,7 +15,7 @@ typedef struct { WNDPROC wndproc; } wndstack_entry; -#define MAXWNDHSTACK 80 +#define MAXWNDHSTACK 256 wndstack_entry WhndStack[MAXWNDHSTACK]; static int WhndTOS = 0; @@ -37,7 +37,12 @@ void WhndStackPush(HWND hwnd, WNDPROC wndproc) return; } // push if not already there. - if(WhndTOS>=MAXWNDHSTACK) return; + if(WhndTOS>=MAXWNDHSTACK) { + char sMsg[80]; + sprintf(sMsg, "Table overflow: %d entries used", MAXWNDHSTACK); + MessageBox(0, sMsg, "WhndStackPush", MB_OK | MB_ICONEXCLAMATION); + return; + } WhndStack[WhndTOS].hwnd=hwnd; WhndStack[WhndTOS].wndproc=wndproc; WhndTOS++; diff --git a/host/TabLogs.cpp b/host/TabLogs.cpp index 209dc75..294d054 100644 --- a/host/TabLogs.cpp +++ b/host/TabLogs.cpp @@ -22,19 +22,31 @@ CTabLogs::CTabLogs(CWnd* pParent /*=NULL*/) //}}AFX_DATA_INIT } +BOOL CTabLogs::OnInitDialog() +{ + extern BOOL gbDebug; + CDialog::OnInitDialog(); + (CButton *)(this->GetDlgItem(IDC_DXPROXED))->EnableWindow(gbDebug ? TRUE : FALSE); + (CButton *)(this->GetDlgItem(IDC_ASSERT))->EnableWindow(gbDebug ? TRUE : FALSE); + return TRUE; +} + void CTabLogs::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); + extern BOOL gbDebug; DDX_Check(pDX, IDC_OUTTRACE, cTarget->m_OutTrace); DDX_Check(pDX, IDC_OUTDEBUG, cTarget->m_OutDebug); DDX_Check(pDX, IDC_CURSORTRACE, cTarget->m_CursorTrace); DDX_Check(pDX, IDC_LOGENABLED, cTarget->m_LogEnabled); DDX_Check(pDX, IDC_OUTWINMESSAGES, cTarget->m_OutWinMessages); DDX_Check(pDX, IDC_OUTDXTRACE, cTarget->m_OutDXTrace); - DDX_Check(pDX, IDC_DXPROXED, cTarget->m_DXProxed); - DDX_Check(pDX, IDC_ASSERT, cTarget->m_AssertDialog); DDX_Check(pDX, IDC_IMPORTTABLE, cTarget->m_ImportTable); + if(gbDebug){ + DDX_Check(pDX, IDC_DXPROXED, cTarget->m_DXProxed); + DDX_Check(pDX, IDC_ASSERT, cTarget->m_AssertDialog); + } } BEGIN_MESSAGE_MAP(CTabLogs, CDialog) diff --git a/host/TabLogs.h b/host/TabLogs.h index 96eb8fb..b587da5 100644 --- a/host/TabLogs.h +++ b/host/TabLogs.h @@ -16,6 +16,7 @@ class CTabLogs : public CDialog // Construction public: CTabLogs(CWnd* pParent = NULL); // standard constructor + virtual BOOL OnInitDialog(); // Dialog Data //{{AFX_DATA(CTabLogs) diff --git a/host/TabProgram.cpp b/host/TabProgram.cpp index e7f1bdf..9e47255 100644 --- a/host/TabProgram.cpp +++ b/host/TabProgram.cpp @@ -34,6 +34,7 @@ void CTabProgram::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_UNNOTIFY, cTarget->m_UnNotify); DDX_Check(pDX, IDC_WINDOWIZE, cTarget->m_Windowize); DDX_Check(pDX, IDC_HOOKDLLS, cTarget->m_HookDLLs); + DDX_Check(pDX, IDC_HOOKCHILDWIN, cTarget->m_HookChildWin); DDX_Check(pDX, IDC_HOOKENABLED, cTarget->m_HookEnabled); DDX_Check(pDX, IDC_NOBANNER, cTarget->m_NoBanner); DDX_Check(pDX, IDC_STARTDEBUG, cTarget->m_StartDebug); @@ -73,7 +74,7 @@ void CTabProgram::OnBnClickedCoordinates() { // TODO: Add your control notification handler code here //CWnd *cTarget = ((CTargetDlg *)(this->GetParent()); - //(CEdBoxEditor *)(cTarget->GetDlgItem(IDC_POSX)) + //(CButton*)(cTarget->GetDlgItem(IDC_POSX)) } void CTabProgram::OnBnClickedDesktopworkarea() diff --git a/host/TabWindow.cpp b/host/TabWindow.cpp index f3cdace..ac8e8fc 100644 --- a/host/TabWindow.cpp +++ b/host/TabWindow.cpp @@ -38,7 +38,6 @@ void CTabWindow::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_FORCEWINRESIZE, cTarget->m_ForceWinResize); DDX_Check(pDX, IDC_HIDEMULTIMONITOR, cTarget->m_HideMultiMonitor); DDX_Check(pDX, IDC_WALLPAPERMODE, cTarget->m_WallpaperMode); - DDX_Check(pDX, IDC_HOOKCHILDWIN, cTarget->m_HookChildWin); DDX_Check(pDX, IDC_RECOVERSCREENMODE, cTarget->m_RecoverScreenMode); DDX_Check(pDX, IDC_REFRESHONRESIZE, cTarget->m_RefreshOnResize); DDX_Check(pDX, IDC_FIXD3DFRAME, cTarget->m_FixD3DFrame); diff --git a/host/dxwnd.ini b/host/dxwnd.ini new file mode 100644 index 0000000..74f0945 --- /dev/null +++ b/host/dxwnd.ini @@ -0,0 +1,28 @@ +[window] +posx=1104 +posy=310 +sizx=303 +sizy=138 +[target] +title0=speeddemo.exe +path0=D:\Games\Need For Speed Underground Demo\speeddemo.exe +module0= +opengllib0= +ver0=0 +flag0=0 +flagg0=134217728 +flagh0=-842150435 +flagi0=-842150451 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=0 +posy0=0 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 0e02844460b7bc006c066d1370336cdbcdaf174f..fea184f3589ad8752db32bd88d11a08faf245ea2 100644 GIT binary patch delta 2537 zcmZux4Nz3q6+ZU?&uS^M3I4F?f}@p23@(e6B@%SYF0$j|F1w4nMBG<(5tM~R#2BJt zqHUT?jU^msZqky~7}FYK6}wISiBS5Z)r3^X$yk?}*k;DGsUnIqooSqiJ@+lTkD0!m z+3$Vd`R@6-@4k0xXyVZAiJjKWJs}B#&(vC9@HGc(pEoH+lVVz=w6(V57i*tn$4_ip z@|~S!ipRcUnZxFCJIgHP<@ObJZw(aC1-}5WTa`+u)m~l$g{GpS0_avHtIc8a+EmE| zZ>y5UYE^k5L{x6`yBtn;+_Mn&tD3udh3YAS11fh3VW~)LhIitMrdTl?jBAN%W+S{C z*T%}33*ZpC(lX}1r^+ksHlM?}OcXH}!7o+KYw;{smfIZ;RV{{J0akV9u)}yFZ6C?}uMzM#=;}#1RK`-`qO`F!22#)Qtxxfs+ z$1l>SW%jEvbz*y^%js5IGa2CzsMBTU{!xv(=%hS~nBY%w?NKIEA^aJubW_;JSg*^L zJ^>74HXFdhx@`6-UeL{8e~o^rTe2iNyXq;41+dcdTFT?|9Ub=UUDPs9Agpb#c2b2*EAULTzys|DnSz7ub-0; z@NUDm(bAx?VEzUfUu?)pcvuof8y=+;pTlGv8OKwi3pSjVCoTd7+MpHMqa)$_lUZtX zXlIEWUH-~hhI3xYoJikEVD!s~%CFWv%cN-NTz@Ltg->5uzzosVS90Y_7`u{yxsJeI z*bb9GpA7WKUV;h;)2|V7U>!8T1_(ir?tOIEOm|_}3NET0rfB?%;E%5@zza9b*nj6+ zvtEYXlqH@i2rrOZtjeb>VW_7(A!M;kR*qS*LhOji=#5R!7PG9Oe0A}Jv&IsG=q?@d zac3+`=U2w7Z{i2BJe|!wUOj~WiskC;Nbb4nI>xoi2i->eR>l3+RX(l4Od?&!n-#Q zO7z9tck4%3JM;tQ!2Lr%!N`z|^KX~3AU57EVlDXY?Xn5mVKeQ11-|^xC%cB{vR5&8 z*u(bWw&BI>K=kDBHc6rvY2nC0JbyI}Z;X`ld5zK}ynHno&G$N)Z}-J}CokS(zIJw; z&k9MoQbQHat1_enW&m{ZrjRsS%4oqOVFT|8Ny)6Ae@GJhhQ|b?^MWR6Cf7GfQ<+QL z7qV_u!qW3kq|BuO&hodKq--hq6O4SUPdQIpG{j><`D_522lOfP89*)1Y?iXwVO~ri z?Yo5em-O;8w7BFlf3aE8r|gme-sEpJOIdP6$T5DVSu%(w#DbnLF>*sM2Pl&BZ%q42 zFQ?K`Ja7y5-qg!Wsp7yL939rnRw_0BE(Y%CWixp@NBGafl;taaI!swy|KWpz{+E9( z=s)h`@YkjC_vQekKIDNG$sl=W^A3UCc|1bMuJPU$avoUBuM7F8gO3VqtKo)CgfDI6 zr2;Fq@qj?@9^N5v#@jqX$Zqi7O*Hj4{Br_n;W<7kqD!xGLn}ou@Ml{o`Was>;40Hj!93m}5CS|R&=uf)grfB}(UrnS1--^+ZXvpK t4KLk7uFzT@5V)s~cL=nu=Mh3WLA_)n_*}Sy8~G@yNvR=;FKLuA{|AH`A*KKT delta 2869 zcmZuze{|E;6~FJ5rgrv6`im0i52Qd598FR&Uw&CTlG?0k6WT&kX%}5vnhyGlBGx&! zy49^h(YDufp3{m&abr`kHK^T`QJlEpL?`DkC~!9ZVCQr~TSRxp#L4b^A>^y=J16Jm z^W)xk?|rX1y)+&@d?~ueZaTe*L+y$xdwWGwZPhlb&usNsm-*VZ)L_EKB-S(3nip&J z6}#=uf=bA>+H4kh7Qkuu*&QxNxkFJ_=vP#}-L7yhJcleU=_k7tTe_}9u{L;KVNZzA zU?527vM+}{K`xwLGs6o(?nZvi0xt#$hu7nBm#QK(E9_O|dZ(kp<-V7WoMY2$@RB0S z^UI2SMNXGXR-!G3U*Unc+t{!1uW{-2eacbbbUA#5Zg-J%EWZv}TFQX+snZE+Kwl~GGUsFThq)|cvbQ0bXlZw=fWWF ziJuuU1b{>3Dfm&mVfJgvS6-T5=__@Vl?S`l%o+r6GCtLGP|0?0zQ^Npc%8Cb&0>bv zsieLn_69y`Oiovv1>U@2tthcmfr_-kFz)V4W4|NcT=siB*Eg%+EoGB4^Lg^umB}G% zmb>8XFimx=D-QBDI27h@%vrN&@Q1#HRMTN4sTQ5Z9=DpMW;MeIniEXfN0jQJs|+bt zcqhn(5?OQMkJyrs!jA#&Y0u#A1HOfs{4aoqJ2Th^ecRI5@xYA4yu5&Y?IO;s*jV;> zoq^cXKMAOyo{r@n{=MnvARw-1H&;kAFf}=j5r*wPB|o8@6&~JlvLo z*VY?#8L#5E>a%tDzxds+;V*DUy}qJrc&vVb&i^Gw`E?i{ufG-D{yAX>|B7R$f4+{m z&hed_gvFnM(G5C3W4O9OpK-)*2y`?YG(;~0AGE<1s0plY`68Yr1hkG-27IhG=~jz{ z{yI4W2FZcupC4g(vMVuA*HyZjvB2=rkr<}o!zXfBIv)9_EpYzCJ`CnQ} z6o4lRBA@~uqfyG$0WRD>YGMxj(`YVRi`PceZwK9q0Om2m3UERU{5t|DssrrMP8ph@ z7C%0f!g8?Y%o6oO#^5Vw>9!C{^w>< z(8%Ypt)hV-8x*@F`|eR}dM{0U*vMzH8DglBr{mr4B}M|B;|anY1Q!x)5yeeBlMlZy znwoe98xXq)vM#Y-ZborjZdGDjZiOPYnXH#T5=)!;Y=dS1aGk&(pO|g9hZ5~QEt;As z!wj)Yx`r=^0|fb^G4Y{vduZbOJ`oerGE2m^kfnW6ENvmnxyz!2c6O&|lyv{+;t2`u zVn0E4hdAEC*JOFWk~hZb^Go#}%(_>x=oWy1c}%R#Vx|RSRLj_6M#c#GFl93uqsbCn z`(gm*i`G`2x#rS}kd2-at#8_{7KL;w{+qfHV8qMBhDv72-bdhrhLD-&GL8AEA2N~i z2s1@V^T1B3wwtPzz~3K=jGi{qELyjy@%Pde(eW-5bB6BgPc_Hr)rBDg7P7F9Z!#6?ju5B4x-k^`1=OPV&_=Zm>`a>)(z+bcunlxfYK zE-o^Q>6m1aFMpefolB|vc?1p?G2wPGQ=J4|YHo3K<_?v{th+0zSM8K7O1*oEZYJjH zp^*N>6kWy_ilMDMv*z5zkgaEmO%^!zWk~OxqRTX!lVrEDjJ|30K^jdFjm9Bsa#e@S zPfan)F8Y;jpk%=tH`6N!tyT1;Q1m`1FY0@AQ9f>pETCsRUwlklP51pWwG2&(lOg(0 z`YDCs2SR${6#Z%PpRNt*GpFeHk=|3s#gdJ5=HEF$jA-3P?pCC~o>Tc{-! diff --git a/host/dxwndhost.cpp b/host/dxwndhost.cpp index a826915..01aee28 100644 --- a/host/dxwndhost.cpp +++ b/host/dxwndhost.cpp @@ -35,6 +35,7 @@ END_MESSAGE_MAP() // too do: eliminate nasty global variables.... UINT m_StartToTray = FALSE; UINT m_InitialState = DXW_ACTIVE; +BOOL gbDebug = FALSE; extern char m_ConfigFileName[20+1] = "dxwnd.ini"; class CNewCommandLineInfo : public CCommandLineInfo @@ -58,6 +59,10 @@ void CNewCommandLineInfo::ParseParam(LPCTSTR lpszParam, BOOL bFlag, BOOL bLast) m_InitialState=DXW_IDLE; return; } + if (sParam.MakeLower() == "debug"){ + gbDebug = TRUE; + return; + } if (sParam.Left(2).MakeLower() == "c:"){ strcpy_s(m_ConfigFileName, sizeof(m_ConfigFileName)-1, sParam.Mid(2,sizeof(m_ConfigFileName)-1)); return; diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 58e75af..ea8742d 100644 --- a/host/dxwndhost.rc +++ b/host/dxwndhost.rc @@ -272,22 +272,24 @@ BEGIN CONTROL "X,Y coordinates",IDC_COORDINATES,"Button",BS_AUTORADIOBUTTON | WS_GROUP,170,198,95,10 CONTROL "Desktop work area",IDC_DESKTOPWORKAREA,"Button",BS_AUTORADIOBUTTON,170,208,95,10 CONTROL "Desktop center",IDC_DESKTOPCENTER,"Button",BS_AUTORADIOBUTTON,170,218,95,10 + CONTROL "Hook child WindowProc",IDC_HOOKCHILDWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,142,124,10 END IDD_TAB_LOG DIALOGEX 0, 0, 300, 240 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - GROUPBOX "Logs",IDC_STATIC,7,3,87,133 - CONTROL "Win Events",IDC_OUTWINMESSAGES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,69,73,12 - CONTROL "DirectX ",IDC_OUTDXTRACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,81,73,12 - CONTROL "DxWnd",IDC_OUTTRACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,58,73,12 - CONTROL "Assert Dialog",IDC_ASSERT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,47,73,12 - CONTROL "ddraw Proxy",IDC_DXPROXED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,35,73,12 - CONTROL "Cursor/Mouse",IDC_CURSORTRACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,93,73,12 - CONTROL "Import Table",IDC_IMPORTTABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,104,73,12 - CONTROL "Debug",IDC_OUTDEBUG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,116,73,12 - CONTROL "Enable Trace",IDC_LOGENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,13,73,12 + GROUPBOX "dxwnd.log logs",IDC_STATIC,7,3,129,131 + CONTROL "Win Events",IDC_OUTWINMESSAGES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,70,73,12 + CONTROL "DirectX trace",IDC_OUTDXTRACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,58,73,12 + CONTROL "DxWnd",IDC_OUTTRACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,46,73,12 + CONTROL "Assert Dialog",IDC_ASSERT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,152,73,12 + CONTROL "ddraw Proxy",IDC_DXPROXED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,164,73,12 + CONTROL "Cursor/Mouse",IDC_CURSORTRACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,82,73,12 + CONTROL "Import Table",IDC_IMPORTTABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,94,73,12 + CONTROL "Debug",IDC_OUTDEBUG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,106,73,12 + CONTROL "Enable Trace",IDC_LOGENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,25,73,12 + GROUPBOX "debug mode only",IDC_STATIC,7,139,130,94 END IDD_TAB_DIRECTX DIALOGEX 0, 0, 300, 240 @@ -381,17 +383,16 @@ BEGIN CONTROL "Prevent Win Maximize",IDC_PREVENTMAXIMIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,28,115,10 GROUPBOX "Windows handling",IDC_STATIC,6,4,140,229 CONTROL "Lock win coordinates",IDC_LOCKWINPOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,40,115,10 - CONTROL "Hook CHILD windows",IDC_HOOKCHILDWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,64,115,10 - CONTROL "Recover screen mode",IDC_RECOVERSCREENMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,76,115,10 - CONTROL "Refresh on win resize",IDC_REFRESHONRESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,88,115,10 + CONTROL "Recover screen mode",IDC_RECOVERSCREENMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,64,115,10 + CONTROL "Refresh on win resize",IDC_REFRESHONRESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,76,115,10 CONTROL "Lock win style",IDC_LOCKWINSTYLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,52,115,10 - CONTROL "Fix Parent Window",IDC_FIXPARENTWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,100,115,10 - CONTROL "Modal Style",IDC_MODALSTYLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,112,115,10 - CONTROL "Keep aspect ratio",IDC_KEEPASPECTRATIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,124,115,10 - CONTROL "Force win resize",IDC_FORCEWINRESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,136,115,10 - CONTROL "Hide multi-monitor config.",IDC_HIDEMULTIMONITOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,148,115,10 - CONTROL "Wallpaper mode",IDC_WALLPAPERMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,160,115,10 - CONTROL "Fix Windows Frame in D3D",IDC_FIXD3DFRAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,172,115,10 + CONTROL "Fix Parent Window",IDC_FIXPARENTWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,88,115,10 + CONTROL "Modal Style",IDC_MODALSTYLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,100,115,10 + CONTROL "Keep aspect ratio",IDC_KEEPASPECTRATIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,112,115,10 + CONTROL "Force win resize",IDC_FORCEWINRESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,124,115,10 + CONTROL "Hide multi-monitor config.",IDC_HIDEMULTIMONITOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,136,115,10 + CONTROL "Wallpaper mode",IDC_WALLPAPERMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,148,115,10 + CONTROL "Fix Windows Frame in D3D",IDC_FIXD3DFRAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,160,115,10 END IDD_TAB_EMPTY DIALOGEX 0, 0, 300, 240 diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index a4c7cd6fdd257ab6532617a6d7209a9a737ea4cd..c794487ff5cee607403a2fa3f27476b83bd159c0 100644 GIT binary patch delta 20360 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 bz|b^e@J4XZQB`|!rs9A5kdOb%!u0(gHlu3& delta 10126 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, sizeof(t->path), dlg->m_FilePath); + strcpy_s(t->module, sizeof(t->module), dlg->m_Module); + strcpy_s(t->OpenGLLib, sizeof(t->OpenGLLib), dlg->m_OpenGLLib); + if(dlg->m_DXVersion > 1) dlg->m_DXVersion += 5; + t->dxversion = dlg->m_DXVersion; + t->coordinates = dlg->m_Coordinates; + t->flags = 0; + t->flags2 = 0; + t->flags3 = 0; + t->flags4 = 0; + t->tflags = 0; + if(dlg->m_UnNotify) t->flags |= UNNOTIFY; + if(dlg->m_Windowize) t->flags2 |= WINDOWIZE; + if(dlg->m_HookDLLs) t->flags3 |= HOOKDLLS; + if(dlg->m_HookEnabled) t->flags3 |= HOOKENABLED; + if(dlg->m_NoBanner) t->flags2 |= NOBANNER; + if(dlg->m_StartDebug) t->flags2 |= STARTDEBUG; + if(dlg->m_NoEmulateSurface) { + dlg->m_EmulateSurface = FALSE; + dlg->m_EmulateBuffer = FALSE; + t->flags &= ~EMULATEFLAGS; + } + if(dlg->m_EmulateSurface) { + dlg->m_NoEmulateSurface = FALSE; + dlg->m_EmulateBuffer = FALSE; + t->flags &= ~EMULATEFLAGS; + t->flags |= EMULATESURFACE; + } + if(dlg->m_EmulateBuffer) { + dlg->m_NoEmulateSurface = FALSE; + dlg->m_EmulateSurface = FALSE; + t->flags &= ~EMULATEFLAGS; + t->flags |= EMULATEBUFFER; + } + if(dlg->m_HookDI) t->flags |= HOOKDI; + if(dlg->m_ModifyMouse) t->flags |= MODIFYMOUSE; + if(dlg->m_OutTrace) t->tflags |= OUTDDRAWTRACE; + if(dlg->m_OutDebug) t->tflags |= OUTDEBUG; + if(dlg->m_CursorTrace) t->tflags |= OUTCURSORTRACE; + if(dlg->m_LogEnabled) t->tflags |= OUTTRACE; + if(dlg->m_OutWinMessages) t->tflags |= OUTWINMESSAGES; + if(dlg->m_OutDXTrace) t->tflags |= OUTPROXYTRACE; + if(dlg->m_DXProxed) t->tflags |= DXPROXED; + if(dlg->m_AssertDialog) t->tflags |= ASSERTDIALOG; + if(dlg->m_ImportTable) t->tflags |= OUTIMPORTTABLE; + if(dlg->m_HandleDC) t->flags |= HANDLEDC; + if(dlg->m_HandleExceptions) t->flags |= HANDLEEXCEPTIONS; + if(dlg->m_LimitResources) t->flags2 |= LIMITRESOURCES; + if(dlg->m_SuppressIME) t->flags2 |= SUPPRESSIME; + if(dlg->m_SuppressD3DExt) t->flags3 |= SUPPRESSD3DEXT; + if(dlg->m_SetCompatibility) t->flags2 |= SETCOMPATIBILITY; + if(dlg->m_SaveCaps) t->flags3 |= SAVECAPS; + if(dlg->m_SingleProcAffinity) t->flags3 |= SINGLEPROCAFFINITY; + if(dlg->m_SaveLoad) t->flags |= SAVELOAD; + if(dlg->m_SlowDown) t->flags |= SLOWDOWN; + if(dlg->m_BlitFromBackBuffer) t->flags |= BLITFROMBACKBUFFER; + if(dlg->m_SuppressClipping) t->flags |= SUPPRESSCLIPPING; + 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; + if(dlg->m_FixTextOut) t->flags |= FIXTEXTOUT; + if(dlg->m_KeepCursorWithin) t->flags |= KEEPCURSORWITHIN; + if(dlg->m_KeepCursorFixed) t->flags2 |= KEEPCURSORFIXED; + if(dlg->m_UseRGB565) t->flags |= USERGB565; + if(dlg->m_SuppressDXErrors) t->flags |= SUPPRESSDXERRORS; + if(dlg->m_MarkBlit) t->flags3 |= MARKBLIT; + if(dlg->m_PreventMaximize) t->flags |= PREVENTMAXIMIZE; + if(dlg->m_ClientRemapping) t->flags |= CLIENTREMAPPING; + if(dlg->m_MapGDIToPrimary) t->flags |= MAPGDITOPRIMARY; + if(dlg->m_LockWinPos) t->flags |= LOCKWINPOS; + if(dlg->m_LockWinStyle) t->flags |= LOCKWINSTYLE; + if(dlg->m_FixParentWin) t->flags |= FIXPARENTWIN; + if(dlg->m_ModalStyle) t->flags2 |= MODALSTYLE; + if(dlg->m_KeepAspectRatio) t->flags2 |= KEEPASPECTRATIO; + if(dlg->m_ForceWinResize) t->flags2 |= FORCEWINRESIZE; + if(dlg->m_HookGDI) t->flags2 |= HOOKGDI; + if(dlg->m_HideMultiMonitor) t->flags2 |= HIDEMULTIMONITOR; + if(dlg->m_WallpaperMode) t->flags2 |= WALLPAPERMODE; + if(dlg->m_FixD3DFrame) t->flags3 |= FIXD3DFRAME; + if(dlg->m_Force16BPP) t->flags3 |= FORCE16BPP; + if(dlg->m_HookChildWin) t->flags |= HOOKCHILDWIN; + if(dlg->m_MessageProc) t->flags |= MESSAGEPROC; + if(dlg->m_FixNCHITTEST) t->flags2 |= FIXNCHITTEST; + if(dlg->m_RecoverScreenMode) t->flags2 |= RECOVERSCREENMODE; + if(dlg->m_RefreshOnResize) t->flags2 |= REFRESHONRESIZE; + if(dlg->m_Init8BPP) t->flags2 |= INIT8BPP; + if(dlg->m_Init16BPP) t->flags2 |= INIT16BPP; + if(dlg->m_BackBufAttach) t->flags2 |= BACKBUFATTACH; + if(dlg->m_HandleAltF4) t->flags |= HANDLEALTF4; + if(dlg->m_LimitFPS) t->flags2 |= LIMITFPS; + if(dlg->m_SkipFPS) t->flags2 |= SKIPFPS; + if(dlg->m_ShowFPS) t->flags2 |= SHOWFPS; + if(dlg->m_ShowFPSOverlay) t->flags2 |= SHOWFPSOVERLAY; + if(dlg->m_TimeStretch) t->flags2 |= TIMESTRETCH; + if(dlg->m_HookOpenGL) t->flags2 |= HOOKOPENGL; + if(dlg->m_ForceHookOpenGL) t->flags3 |= FORCEHOOKOPENGL; + if(dlg->m_WireFrame) t->flags2 |= WIREFRAME; + if(dlg->m_BlackWhite) t->flags3 |= BLACKWHITE; + if(dlg->m_FakeVersion) t->flags2 |= FAKEVERSION; + if(dlg->m_FullRectBlt) t->flags2 |= FULLRECTBLT; + if(dlg->m_NoPaletteUpdate) t->flags2 |= NOPALETTEUPDATE; + t->initx = dlg->m_InitX; + t->inity = dlg->m_InitY; + t->minx = dlg->m_MinX; + t->miny = dlg->m_MinY; + t->maxx = dlg->m_MaxX; + t->maxy = dlg->m_MaxY; + t->posx = dlg->m_PosX; + t->posy = dlg->m_PosY; + t->sizx = dlg->m_SizX; + t->sizy = dlg->m_SizY; + t->MaxFPS = dlg->m_MaxFPS; + t->InitTS = dlg->m_InitTS-8; + t->FakeVersionId = dlg->m_FakeVersionId; + strcpy_s(t->module, sizeof(t->module), dlg->m_Module); + strcpy_s(t->OpenGLLib, sizeof(t->OpenGLLib), dlg->m_OpenGLLib); +} + +static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) +{ + dlg->m_DXVersion = t->dxversion; + if(dlg->m_DXVersion > 6) dlg->m_DXVersion -= 5; + dlg->m_Coordinates = t->coordinates; + dlg->m_FilePath = t->path; + dlg->m_Module = t->module; + dlg->m_OpenGLLib = t->OpenGLLib; + dlg->m_UnNotify = t->flags & UNNOTIFY ? 1 : 0; + dlg->m_Windowize = t->flags2 & WINDOWIZE ? 1 : 0; + dlg->m_HookDLLs = t->flags3 & HOOKDLLS ? 1 : 0; + dlg->m_HookEnabled = t->flags3 & HOOKENABLED ? 1 : 0; + dlg->m_NoBanner = t->flags2 & NOBANNER ? 1 : 0; + dlg->m_StartDebug = t->flags2 & STARTDEBUG ? 1 : 0; + dlg->m_EmulateSurface = t->flags & EMULATESURFACE ? 1 : 0; + dlg->m_NoEmulateSurface = t->flags & EMULATEFLAGS ? 0 : 1; + dlg->m_EmulateBuffer = t->flags & EMULATEBUFFER ? 1 : 0; + dlg->m_HookDI = t->flags & HOOKDI ? 1 : 0; + dlg->m_ModifyMouse = t->flags & MODIFYMOUSE ? 1 : 0; + dlg->m_OutTrace = t->tflags & OUTDDRAWTRACE ? 1 : 0; + dlg->m_OutDebug = t->tflags & OUTDEBUG ? 1 : 0; + dlg->m_CursorTrace = t->tflags & OUTCURSORTRACE ? 1 : 0; + dlg->m_LogEnabled = t->tflags & OUTTRACE ? 1 : 0; + dlg->m_OutWinMessages = t->tflags & OUTWINMESSAGES ? 1 : 0; + dlg->m_OutDXTrace = t->tflags & OUTPROXYTRACE ? 1 : 0; + dlg->m_DXProxed = t->tflags & DXPROXED ? 1 : 0; + dlg->m_AssertDialog = t->tflags & ASSERTDIALOG ? 1 : 0; + dlg->m_ImportTable = t->tflags & OUTIMPORTTABLE ? 1 : 0; + dlg->m_HandleDC = t->flags & HANDLEDC ? 1 : 0; + dlg->m_HandleExceptions = t->flags & HANDLEEXCEPTIONS ? 1 : 0; + dlg->m_SuppressIME = t->flags2 & SUPPRESSIME ? 1 : 0; + dlg->m_SuppressD3DExt = t->flags3 & SUPPRESSD3DEXT ? 1 : 0; + dlg->m_SetCompatibility = t->flags2 & SETCOMPATIBILITY ? 1 : 0; + dlg->m_SaveCaps = t->flags3 & SAVECAPS ? 1 : 0; + dlg->m_SingleProcAffinity = t->flags3 & SINGLEPROCAFFINITY ? 1 : 0; + dlg->m_LimitResources = t->flags2 & LIMITRESOURCES ? 1 : 0; + dlg->m_SaveLoad = t->flags & SAVELOAD ? 1 : 0; + dlg->m_SlowDown = t->flags & SLOWDOWN ? 1 : 0; + dlg->m_BlitFromBackBuffer = t->flags & BLITFROMBACKBUFFER ? 1 : 0; + dlg->m_SuppressClipping = t->flags & SUPPRESSCLIPPING ? 1 : 0; + 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; + dlg->m_FixTextOut = t->flags & FIXTEXTOUT ? 1 : 0; + dlg->m_KeepCursorWithin = t->flags & KEEPCURSORWITHIN ? 1 : 0; + dlg->m_KeepCursorFixed = t->flags2 & KEEPCURSORFIXED ? 1 : 0; + dlg->m_UseRGB565 = t->flags & USERGB565 ? 1 : 0; + dlg->m_SuppressDXErrors = t->flags & SUPPRESSDXERRORS ? 1 : 0; + dlg->m_MarkBlit = t->flags3 & MARKBLIT ? 1 : 0; + dlg->m_PreventMaximize = t->flags & PREVENTMAXIMIZE ? 1 : 0; + dlg->m_ClientRemapping = t->flags & CLIENTREMAPPING ? 1 : 0; + dlg->m_MapGDIToPrimary = t->flags & MAPGDITOPRIMARY ? 1 : 0; + dlg->m_LockWinPos = t->flags & LOCKWINPOS ? 1 : 0; + dlg->m_LockWinStyle = t->flags & LOCKWINSTYLE ? 1 : 0; + dlg->m_FixParentWin = t->flags & FIXPARENTWIN ? 1 : 0; + dlg->m_ModalStyle = t->flags2 & MODALSTYLE ? 1 : 0; + dlg->m_KeepAspectRatio = t->flags2 & KEEPASPECTRATIO ? 1 : 0; + dlg->m_ForceWinResize = t->flags2 & FORCEWINRESIZE ? 1 : 0; + dlg->m_HookGDI = t->flags2 & HOOKGDI ? 1 : 0; + dlg->m_HideMultiMonitor = t->flags2 & HIDEMULTIMONITOR ? 1 : 0; + dlg->m_WallpaperMode = t->flags2 & WALLPAPERMODE ? 1 : 0; + dlg->m_FixD3DFrame = t->flags3 & FIXD3DFRAME ? 1 : 0; + dlg->m_Force16BPP = t->flags3 & FORCE16BPP ? 1 : 0; + dlg->m_HookChildWin = t->flags & HOOKCHILDWIN ? 1 : 0; + dlg->m_MessageProc = t->flags & MESSAGEPROC ? 1 : 0; + dlg->m_FixNCHITTEST = t->flags2 & FIXNCHITTEST ? 1 : 0; + dlg->m_RecoverScreenMode = t->flags2 & RECOVERSCREENMODE ? 1 : 0; + dlg->m_RefreshOnResize = t->flags2 & REFRESHONRESIZE ? 1 : 0; + dlg->m_Init8BPP = t->flags2 & INIT8BPP ? 1 : 0; + dlg->m_Init16BPP = t->flags2 & INIT16BPP ? 1 : 0; + dlg->m_BackBufAttach = t->flags2 & BACKBUFATTACH ? 1 : 0; + dlg->m_HandleAltF4 = t->flags & HANDLEALTF4 ? 1 : 0; + dlg->m_LimitFPS = t->flags2 & LIMITFPS ? 1 : 0; + dlg->m_SkipFPS = t->flags2 & SKIPFPS ? 1 : 0; + dlg->m_ShowFPS = t->flags2 & SHOWFPS ? 1 : 0; + dlg->m_ShowFPSOverlay = t->flags2 & SHOWFPSOVERLAY ? 1 : 0; + dlg->m_TimeStretch = t->flags2 & TIMESTRETCH ? 1 : 0; + dlg->m_HookOpenGL = t->flags2 & HOOKOPENGL ? 1 : 0; + dlg->m_ForceHookOpenGL = t->flags3 & FORCEHOOKOPENGL ? 1 : 0; + dlg->m_WireFrame = t->flags2 & WIREFRAME ? 1 : 0; + dlg->m_BlackWhite = t->flags3 & BLACKWHITE ? 1 : 0; + dlg->m_FakeVersion = t->flags2 & FAKEVERSION ? 1 : 0; + dlg->m_FullRectBlt = t->flags2 & FULLRECTBLT ? 1 : 0; + dlg->m_NoPaletteUpdate = t->flags2 & NOPALETTEUPDATE ? 1 : 0; + dlg->m_InitX = t->initx; + dlg->m_InitY = t->inity; + dlg->m_MinX = t->minx; + dlg->m_MinY = t->miny; + dlg->m_MaxX = t->maxx; + dlg->m_MaxY = t->maxy; + dlg->m_PosX = t->posx; + dlg->m_PosY = t->posy; + dlg->m_SizX = t->sizx; + dlg->m_SizY = t->sizy; + dlg->m_MaxFPS = t->MaxFPS; + dlg->m_InitTS = t->InitTS+8; + dlg->m_FakeVersionId = t->FakeVersionId; +} + static void SaveConfigItem(TARGETMAP *TargetMap, char *Title, int i, char *InitPath) { char key[32], val[32]; @@ -494,231 +723,11 @@ void CDxwndhostView::OnModify() if(!listctrl.GetSelectedCount()) return; pos = listctrl.GetFirstSelectedItemPosition(); i = listctrl.GetNextSelectedItem(pos); - dlg.m_DXVersion = TargetMaps[i].dxversion; - if(dlg.m_DXVersion > 6) dlg.m_DXVersion -= 5; - dlg.m_Coordinates = TargetMaps[i].coordinates; - dlg.m_FilePath = TargetMaps[i].path; - dlg.m_Module = TargetMaps[i].module; - dlg.m_OpenGLLib = TargetMaps[i].OpenGLLib; dlg.m_Title = TitleMaps[i].title; - dlg.m_UnNotify = TargetMaps[i].flags & UNNOTIFY ? 1 : 0; - dlg.m_Windowize = TargetMaps[i].flags2 & WINDOWIZE ? 1 : 0; - dlg.m_HookDLLs = TargetMaps[i].flags3 & HOOKDLLS ? 1 : 0; - dlg.m_HookEnabled = TargetMaps[i].flags3 & HOOKENABLED ? 1 : 0; - dlg.m_NoBanner = TargetMaps[i].flags2 & NOBANNER ? 1 : 0; - dlg.m_StartDebug = TargetMaps[i].flags2 & STARTDEBUG ? 1 : 0; - dlg.m_EmulateSurface = TargetMaps[i].flags & EMULATESURFACE ? 1 : 0; - dlg.m_NoEmulateSurface = TargetMaps[i].flags & EMULATEFLAGS ? 0 : 1; - dlg.m_EmulateBuffer = TargetMaps[i].flags & EMULATEBUFFER ? 1 : 0; - dlg.m_HookDI = TargetMaps[i].flags & HOOKDI ? 1 : 0; - dlg.m_ModifyMouse = TargetMaps[i].flags & MODIFYMOUSE ? 1 : 0; - dlg.m_OutTrace = TargetMaps[i].tflags & OUTDDRAWTRACE ? 1 : 0; - dlg.m_OutDebug = TargetMaps[i].tflags & OUTDEBUG ? 1 : 0; - dlg.m_CursorTrace = TargetMaps[i].tflags & OUTCURSORTRACE ? 1 : 0; - dlg.m_LogEnabled = TargetMaps[i].tflags & OUTTRACE ? 1 : 0; - dlg.m_OutWinMessages = TargetMaps[i].tflags & OUTWINMESSAGES ? 1 : 0; - dlg.m_OutDXTrace = TargetMaps[i].tflags & OUTPROXYTRACE ? 1 : 0; - dlg.m_DXProxed = TargetMaps[i].tflags & DXPROXED ? 1 : 0; - dlg.m_AssertDialog = TargetMaps[i].tflags & ASSERTDIALOG ? 1 : 0; - dlg.m_ImportTable = TargetMaps[i].tflags & OUTIMPORTTABLE ? 1 : 0; - dlg.m_HandleDC = TargetMaps[i].flags & HANDLEDC ? 1 : 0; - dlg.m_HandleExceptions = TargetMaps[i].flags & HANDLEEXCEPTIONS ? 1 : 0; - dlg.m_SuppressIME = TargetMaps[i].flags2 & SUPPRESSIME ? 1 : 0; - dlg.m_SuppressD3DExt = TargetMaps[i].flags3 & SUPPRESSD3DEXT ? 1 : 0; - dlg.m_SetCompatibility = TargetMaps[i].flags2 & SETCOMPATIBILITY ? 1 : 0; - dlg.m_SaveCaps = TargetMaps[i].flags3 & SAVECAPS ? 1 : 0; - dlg.m_SingleProcAffinity = TargetMaps[i].flags3 & SINGLEPROCAFFINITY ? 1 : 0; - dlg.m_LimitResources = TargetMaps[i].flags2 & LIMITRESOURCES ? 1 : 0; - dlg.m_SaveLoad = TargetMaps[i].flags & SAVELOAD ? 1 : 0; - dlg.m_SlowDown = TargetMaps[i].flags & SLOWDOWN ? 1 : 0; - dlg.m_BlitFromBackBuffer = TargetMaps[i].flags & BLITFROMBACKBUFFER ? 1 : 0; - dlg.m_SuppressClipping = TargetMaps[i].flags & SUPPRESSCLIPPING ? 1 : 0; - dlg.m_DisableGammaRamp = TargetMaps[i].flags2 & DISABLEGAMMARAMP ? 1 : 0; - dlg.m_AutoRefresh = TargetMaps[i].flags & AUTOREFRESH ? 1 : 0; - dlg.m_FixWinFrame = TargetMaps[i].flags & FIXWINFRAME ? 1 : 0; - dlg.m_HideHwCursor = TargetMaps[i].flags & HIDEHWCURSOR ? 1 : 0; - dlg.m_ShowHwCursor = TargetMaps[i].flags2 & SHOWHWCURSOR ? 1 : 0; - dlg.m_EnableClipping = TargetMaps[i].flags & ENABLECLIPPING ? 1 : 0; - dlg.m_CursorClipping = TargetMaps[i].flags & CLIPCURSOR ? 1 : 0; - dlg.m_VideoToSystemMem = TargetMaps[i].flags & SWITCHVIDEOMEMORY ? 1 : 0; - dlg.m_FixTextOut = TargetMaps[i].flags & FIXTEXTOUT ? 1 : 0; - dlg.m_KeepCursorWithin = TargetMaps[i].flags & KEEPCURSORWITHIN ? 1 : 0; - dlg.m_KeepCursorFixed = TargetMaps[i].flags2 & KEEPCURSORFIXED ? 1 : 0; - dlg.m_UseRGB565 = TargetMaps[i].flags & USERGB565 ? 1 : 0; - dlg.m_SuppressDXErrors = TargetMaps[i].flags & SUPPRESSDXERRORS ? 1 : 0; - dlg.m_MarkBlit = TargetMaps[i].flags3 & MARKBLIT ? 1 : 0; - dlg.m_PreventMaximize = TargetMaps[i].flags & PREVENTMAXIMIZE ? 1 : 0; - dlg.m_ClientRemapping = TargetMaps[i].flags & CLIENTREMAPPING ? 1 : 0; - dlg.m_MapGDIToPrimary = TargetMaps[i].flags & MAPGDITOPRIMARY ? 1 : 0; - dlg.m_LockWinPos = TargetMaps[i].flags & LOCKWINPOS ? 1 : 0; - dlg.m_LockWinStyle = TargetMaps[i].flags & LOCKWINSTYLE ? 1 : 0; - dlg.m_FixParentWin = TargetMaps[i].flags & FIXPARENTWIN ? 1 : 0; - dlg.m_ModalStyle = TargetMaps[i].flags2 & MODALSTYLE ? 1 : 0; - dlg.m_KeepAspectRatio = TargetMaps[i].flags2 & KEEPASPECTRATIO ? 1 : 0; - dlg.m_ForceWinResize = TargetMaps[i].flags2 & FORCEWINRESIZE ? 1 : 0; - dlg.m_HookGDI = TargetMaps[i].flags2 & HOOKGDI ? 1 : 0; - dlg.m_HideMultiMonitor = TargetMaps[i].flags2 & HIDEMULTIMONITOR ? 1 : 0; - dlg.m_WallpaperMode = TargetMaps[i].flags2 & WALLPAPERMODE ? 1 : 0; - dlg.m_FixD3DFrame = TargetMaps[i].flags3 & FIXD3DFRAME ? 1 : 0; - dlg.m_Force16BPP = TargetMaps[i].flags3 & FORCE16BPP ? 1 : 0; - dlg.m_HookChildWin = TargetMaps[i].flags & HOOKCHILDWIN ? 1 : 0; - dlg.m_MessageProc = TargetMaps[i].flags & MESSAGEPROC ? 1 : 0; - dlg.m_FixNCHITTEST = TargetMaps[i].flags2 & FIXNCHITTEST ? 1 : 0; - dlg.m_RecoverScreenMode = TargetMaps[i].flags2 & RECOVERSCREENMODE ? 1 : 0; - dlg.m_RefreshOnResize = TargetMaps[i].flags2 & REFRESHONRESIZE ? 1 : 0; - dlg.m_Init8BPP = TargetMaps[i].flags2 & INIT8BPP ? 1 : 0; - dlg.m_Init16BPP = TargetMaps[i].flags2 & INIT16BPP ? 1 : 0; - dlg.m_BackBufAttach = TargetMaps[i].flags2 & BACKBUFATTACH ? 1 : 0; - dlg.m_HandleAltF4 = TargetMaps[i].flags & HANDLEALTF4 ? 1 : 0; - dlg.m_LimitFPS = TargetMaps[i].flags2 & LIMITFPS ? 1 : 0; - dlg.m_SkipFPS = TargetMaps[i].flags2 & SKIPFPS ? 1 : 0; - dlg.m_ShowFPS = TargetMaps[i].flags2 & SHOWFPS ? 1 : 0; - dlg.m_ShowFPSOverlay = TargetMaps[i].flags2 & SHOWFPSOVERLAY ? 1 : 0; - dlg.m_TimeStretch = TargetMaps[i].flags2 & TIMESTRETCH ? 1 : 0; - dlg.m_HookOpenGL = TargetMaps[i].flags2 & HOOKOPENGL ? 1 : 0; - dlg.m_ForceHookOpenGL = TargetMaps[i].flags3 & FORCEHOOKOPENGL ? 1 : 0; - dlg.m_WireFrame = TargetMaps[i].flags2 & WIREFRAME ? 1 : 0; - dlg.m_BlackWhite = TargetMaps[i].flags3 & BLACKWHITE ? 1 : 0; - dlg.m_FakeVersion = TargetMaps[i].flags2 & FAKEVERSION ? 1 : 0; - dlg.m_FullRectBlt = TargetMaps[i].flags2 & FULLRECTBLT ? 1 : 0; - dlg.m_NoPaletteUpdate = TargetMaps[i].flags2 & NOPALETTEUPDATE ? 1 : 0; - dlg.m_InitX = TargetMaps[i].initx; - dlg.m_InitY = TargetMaps[i].inity; - dlg.m_MinX = TargetMaps[i].minx; - dlg.m_MinY = TargetMaps[i].miny; - dlg.m_MaxX = TargetMaps[i].maxx; - dlg.m_MaxY = TargetMaps[i].maxy; - dlg.m_PosX = TargetMaps[i].posx; - dlg.m_PosY = TargetMaps[i].posy; - dlg.m_SizX = TargetMaps[i].sizx; - dlg.m_SizY = TargetMaps[i].sizy; - dlg.m_MaxFPS = TargetMaps[i].MaxFPS; - dlg.m_InitTS = TargetMaps[i].InitTS+8; - dlg.m_FakeVersionId = TargetMaps[i].FakeVersionId; + SetDlgFromTarget(&TargetMaps[i], &dlg); if(dlg.DoModal() == IDOK && dlg.m_FilePath.GetLength()){ - strcpy_s(TargetMaps[i].path, sizeof(TargetMaps[i].path), dlg.m_FilePath); - strcpy_s(TargetMaps[i].module, sizeof(TargetMaps[i].module), dlg.m_Module); - strcpy_s(TargetMaps[i].OpenGLLib, sizeof(TargetMaps[i].OpenGLLib), dlg.m_OpenGLLib); - strcpy_s(TitleMaps[i].title, sizeof(TitleMaps[i].title), dlg.m_Title); - if(dlg.m_DXVersion > 1) dlg.m_DXVersion += 5; - TargetMaps[i].dxversion = dlg.m_DXVersion; - TargetMaps[i].coordinates = dlg.m_Coordinates; - TargetMaps[i].flags = 0; - TargetMaps[i].flags2 = 0; - TargetMaps[i].flags3 = 0; - TargetMaps[i].flags4 = 0; - TargetMaps[i].tflags = 0; - if(dlg.m_UnNotify) TargetMaps[i].flags |= UNNOTIFY; - if(dlg.m_Windowize) TargetMaps[i].flags2 |= WINDOWIZE; - if(dlg.m_HookDLLs) TargetMaps[i].flags3 |= HOOKDLLS; - if(dlg.m_HookEnabled) TargetMaps[i].flags3 |= HOOKENABLED; - if(dlg.m_NoBanner) TargetMaps[i].flags2 |= NOBANNER; - if(dlg.m_StartDebug) TargetMaps[i].flags2 |= STARTDEBUG; - if(dlg.m_NoEmulateSurface) { - dlg.m_EmulateSurface = FALSE; - dlg.m_EmulateBuffer = FALSE; - TargetMaps[i].flags &= ~EMULATEFLAGS; - } - if(dlg.m_EmulateSurface) { - dlg.m_NoEmulateSurface = FALSE; - dlg.m_EmulateBuffer = FALSE; - TargetMaps[i].flags &= ~EMULATEFLAGS; - TargetMaps[i].flags |= EMULATESURFACE; - } - if(dlg.m_EmulateBuffer) { - dlg.m_NoEmulateSurface = FALSE; - dlg.m_EmulateSurface = FALSE; - TargetMaps[i].flags &= ~EMULATEFLAGS; - TargetMaps[i].flags |= EMULATEBUFFER; - } - if(dlg.m_HookDI) TargetMaps[i].flags |= HOOKDI; - if(dlg.m_ModifyMouse) TargetMaps[i].flags |= MODIFYMOUSE; - if(dlg.m_OutTrace) TargetMaps[i].tflags |= OUTDDRAWTRACE; - if(dlg.m_OutDebug) TargetMaps[i].tflags |= OUTDEBUG; - if(dlg.m_CursorTrace) TargetMaps[i].tflags |= OUTCURSORTRACE; - if(dlg.m_LogEnabled) TargetMaps[i].tflags |= OUTTRACE; - if(dlg.m_OutWinMessages) TargetMaps[i].tflags |= OUTWINMESSAGES; - if(dlg.m_OutDXTrace) TargetMaps[i].tflags |= OUTPROXYTRACE; - if(dlg.m_DXProxed) TargetMaps[i].tflags |= DXPROXED; - if(dlg.m_AssertDialog) TargetMaps[i].tflags |= ASSERTDIALOG; - if(dlg.m_ImportTable) TargetMaps[i].tflags |= OUTIMPORTTABLE; - if(dlg.m_HandleDC) TargetMaps[i].flags |= HANDLEDC; - if(dlg.m_HandleExceptions) TargetMaps[i].flags |= HANDLEEXCEPTIONS; - if(dlg.m_LimitResources) TargetMaps[i].flags2 |= LIMITRESOURCES; - if(dlg.m_SuppressIME) TargetMaps[i].flags2 |= SUPPRESSIME; - if(dlg.m_SuppressD3DExt) TargetMaps[i].flags3 |= SUPPRESSD3DEXT; - if(dlg.m_SetCompatibility) TargetMaps[i].flags2 |= SETCOMPATIBILITY; - if(dlg.m_SaveCaps) TargetMaps[i].flags3 |= SAVECAPS; - if(dlg.m_SingleProcAffinity) TargetMaps[i].flags3 |= SINGLEPROCAFFINITY; - if(dlg.m_SaveLoad) TargetMaps[i].flags |= SAVELOAD; - if(dlg.m_SlowDown) TargetMaps[i].flags |= SLOWDOWN; - if(dlg.m_BlitFromBackBuffer) TargetMaps[i].flags |= BLITFROMBACKBUFFER; - if(dlg.m_SuppressClipping) TargetMaps[i].flags |= SUPPRESSCLIPPING; - if(dlg.m_DisableGammaRamp) TargetMaps[i].flags2 |= DISABLEGAMMARAMP; - if(dlg.m_AutoRefresh) TargetMaps[i].flags |= AUTOREFRESH; - if(dlg.m_FixWinFrame) TargetMaps[i].flags |= FIXWINFRAME; - if(dlg.m_HideHwCursor) TargetMaps[i].flags |= HIDEHWCURSOR; - if(dlg.m_ShowHwCursor) TargetMaps[i].flags2 |= SHOWHWCURSOR; - if(dlg.m_EnableClipping) TargetMaps[i].flags |= ENABLECLIPPING; - if(dlg.m_CursorClipping) TargetMaps[i].flags |= CLIPCURSOR; - if(dlg.m_VideoToSystemMem) TargetMaps[i].flags |= SWITCHVIDEOMEMORY; - if(dlg.m_FixTextOut) TargetMaps[i].flags |= FIXTEXTOUT; - if(dlg.m_KeepCursorWithin) TargetMaps[i].flags |= KEEPCURSORWITHIN; - if(dlg.m_KeepCursorFixed) TargetMaps[i].flags2 |= KEEPCURSORFIXED; - if(dlg.m_UseRGB565) TargetMaps[i].flags |= USERGB565; - if(dlg.m_SuppressDXErrors) TargetMaps[i].flags |= SUPPRESSDXERRORS; - if(dlg.m_MarkBlit) TargetMaps[i].flags3 |= MARKBLIT; - if(dlg.m_PreventMaximize) TargetMaps[i].flags |= PREVENTMAXIMIZE; - if(dlg.m_ClientRemapping) TargetMaps[i].flags |= CLIENTREMAPPING; - if(dlg.m_MapGDIToPrimary) TargetMaps[i].flags |= MAPGDITOPRIMARY; - if(dlg.m_LockWinPos) TargetMaps[i].flags |= LOCKWINPOS; - if(dlg.m_LockWinStyle) TargetMaps[i].flags |= LOCKWINSTYLE; - if(dlg.m_FixParentWin) TargetMaps[i].flags |= FIXPARENTWIN; - if(dlg.m_ModalStyle) TargetMaps[i].flags2 |= MODALSTYLE; - if(dlg.m_KeepAspectRatio) TargetMaps[i].flags2 |= KEEPASPECTRATIO; - if(dlg.m_ForceWinResize) TargetMaps[i].flags2 |= FORCEWINRESIZE; - if(dlg.m_HookGDI) TargetMaps[i].flags2 |= HOOKGDI; - if(dlg.m_HideMultiMonitor) TargetMaps[i].flags2 |= HIDEMULTIMONITOR; - if(dlg.m_WallpaperMode) TargetMaps[i].flags2 |= WALLPAPERMODE; - if(dlg.m_FixD3DFrame) TargetMaps[i].flags3 |= FIXD3DFRAME; - if(dlg.m_Force16BPP) TargetMaps[i].flags3 |= FORCE16BPP; - if(dlg.m_HookChildWin) TargetMaps[i].flags |= HOOKCHILDWIN; - if(dlg.m_MessageProc) TargetMaps[i].flags |= MESSAGEPROC; - if(dlg.m_FixNCHITTEST) TargetMaps[i].flags2 |= FIXNCHITTEST; - if(dlg.m_RecoverScreenMode) TargetMaps[i].flags2 |= RECOVERSCREENMODE; - if(dlg.m_RefreshOnResize) TargetMaps[i].flags2 |= REFRESHONRESIZE; - if(dlg.m_Init8BPP) TargetMaps[i].flags2 |= INIT8BPP; - if(dlg.m_Init16BPP) TargetMaps[i].flags2 |= INIT16BPP; - if(dlg.m_BackBufAttach) TargetMaps[i].flags2 |= BACKBUFATTACH; - if(dlg.m_HandleAltF4) TargetMaps[i].flags |= HANDLEALTF4; - if(dlg.m_LimitFPS) TargetMaps[i].flags2 |= LIMITFPS; - if(dlg.m_SkipFPS) TargetMaps[i].flags2 |= SKIPFPS; - if(dlg.m_ShowFPS) TargetMaps[i].flags2 |= SHOWFPS; - if(dlg.m_ShowFPSOverlay) TargetMaps[i].flags2 |= SHOWFPSOVERLAY; - if(dlg.m_TimeStretch) TargetMaps[i].flags2 |= TIMESTRETCH; - if(dlg.m_HookOpenGL) TargetMaps[i].flags2 |= HOOKOPENGL; - if(dlg.m_ForceHookOpenGL) TargetMaps[i].flags3 |= FORCEHOOKOPENGL; - if(dlg.m_WireFrame) TargetMaps[i].flags2 |= WIREFRAME; - if(dlg.m_BlackWhite) TargetMaps[i].flags3 |= BLACKWHITE; - if(dlg.m_FakeVersion) TargetMaps[i].flags2 |= FAKEVERSION; - if(dlg.m_FullRectBlt) TargetMaps[i].flags2 |= FULLRECTBLT; - if(dlg.m_NoPaletteUpdate) TargetMaps[i].flags2 |= NOPALETTEUPDATE; - TargetMaps[i].initx = dlg.m_InitX; - TargetMaps[i].inity = dlg.m_InitY; - TargetMaps[i].minx = dlg.m_MinX; - TargetMaps[i].miny = dlg.m_MinY; - TargetMaps[i].maxx = dlg.m_MaxX; - TargetMaps[i].maxy = dlg.m_MaxY; - TargetMaps[i].posx = dlg.m_PosX; - TargetMaps[i].posy = dlg.m_PosY; - TargetMaps[i].sizx = dlg.m_SizX; - TargetMaps[i].sizy = dlg.m_SizY; - TargetMaps[i].MaxFPS = dlg.m_MaxFPS; - TargetMaps[i].InitTS = dlg.m_InitTS-8; - TargetMaps[i].FakeVersionId = dlg.m_FakeVersionId; - strcpy_s(TargetMaps[i].module, sizeof(TargetMaps[i].module), dlg.m_Module); - strcpy_s(TargetMaps[i].OpenGLLib, sizeof(TargetMaps[i].OpenGLLib), dlg.m_OpenGLLib); - strcpy_s(TitleMaps[i].title, sizeof(TitleMaps[i].title), dlg.m_Title); + strncpy(TitleMaps[i].title, dlg.m_Title, 40); + SetTargetFromDlg(&TargetMaps[i], &dlg); CListCtrl& listctrl = GetListCtrl(); listitem.mask = LVIF_TEXT | LVIF_IMAGE; listitem.iItem = i; @@ -1018,127 +1027,8 @@ void CDxwndhostView::OnAdd() return; } if(dlg.DoModal() == IDOK && dlg.m_FilePath.GetLength()){ - strcpy_s(TargetMaps[i].path,sizeof(TargetMaps[i].path),dlg.m_FilePath); - strcpy_s(TargetMaps[i].module,sizeof(TargetMaps[i].module),dlg.m_Module); - strcpy_s(TargetMaps[i].OpenGLLib,sizeof(TargetMaps[i].OpenGLLib),dlg.m_OpenGLLib); - strcpy_s(TitleMaps[i].title, sizeof(TitleMaps[i].title), dlg.m_Title); - if(dlg.m_DXVersion > 1) dlg.m_DXVersion += 5; - TargetMaps[i].dxversion = dlg.m_DXVersion; - TargetMaps[i].coordinates = dlg.m_Coordinates; - TargetMaps[i].flags = 0; - TargetMaps[i].flags2 = 0; - TargetMaps[i].tflags = 0; - if(dlg.m_UnNotify) TargetMaps[i].flags |= UNNOTIFY; - if(dlg.m_Windowize) TargetMaps[i].flags2 |= WINDOWIZE; - if(dlg.m_HookDLLs) TargetMaps[i].flags3 |= HOOKDLLS; - if(dlg.m_HookEnabled) TargetMaps[i].flags3 |= HOOKENABLED; - if(dlg.m_NoBanner) TargetMaps[i].flags2 |= NOBANNER; - if(dlg.m_StartDebug) TargetMaps[i].flags2 |= STARTDEBUG; - if(dlg.m_NoEmulateSurface) { - dlg.m_EmulateSurface = FALSE; - dlg.m_EmulateBuffer = FALSE; - TargetMaps[i].flags &= ~EMULATEFLAGS; - } - if(dlg.m_EmulateSurface) { - dlg.m_NoEmulateSurface = FALSE; - dlg.m_EmulateBuffer = FALSE; - TargetMaps[i].flags &= ~EMULATEFLAGS; - TargetMaps[i].flags |= EMULATESURFACE; - } - if(dlg.m_EmulateBuffer) { - dlg.m_NoEmulateSurface = FALSE; - dlg.m_EmulateSurface = FALSE; - TargetMaps[i].flags &= ~EMULATEFLAGS; - TargetMaps[i].flags |= EMULATEBUFFER; - } - if(dlg.m_HookDI) TargetMaps[i].flags |= HOOKDI; - if(dlg.m_ModifyMouse) TargetMaps[i].flags |= MODIFYMOUSE; - if(dlg.m_OutTrace) TargetMaps[i].tflags |= OUTDDRAWTRACE; - if(dlg.m_OutDebug) TargetMaps[i].tflags |= OUTDEBUG; - if(dlg.m_CursorTrace) TargetMaps[i].tflags |= OUTCURSORTRACE; - if(dlg.m_LogEnabled) TargetMaps[i].tflags |= OUTTRACE; - if(dlg.m_OutWinMessages) TargetMaps[i].tflags |= OUTWINMESSAGES; - if(dlg.m_OutDXTrace) TargetMaps[i].tflags |= OUTPROXYTRACE; - if(dlg.m_DXProxed) TargetMaps[i].tflags |= DXPROXED; - if(dlg.m_AssertDialog) TargetMaps[i].tflags |= ASSERTDIALOG; - if(dlg.m_ImportTable) TargetMaps[i].tflags |= OUTIMPORTTABLE; - if(dlg.m_HandleDC) TargetMaps[i].flags |= HANDLEDC; - if(dlg.m_HandleExceptions) TargetMaps[i].flags |= HANDLEEXCEPTIONS; - if(dlg.m_SuppressIME) TargetMaps[i].flags2 |= SUPPRESSIME; - if(dlg.m_SuppressD3DExt) TargetMaps[i].flags3 |= SUPPRESSD3DEXT; - if(dlg.m_SetCompatibility) TargetMaps[i].flags2 |= SETCOMPATIBILITY; - if(dlg.m_SaveCaps) TargetMaps[i].flags3 |= SAVECAPS; - if(dlg.m_SingleProcAffinity) TargetMaps[i].flags3 |= SINGLEPROCAFFINITY; - if(dlg.m_LimitResources) TargetMaps[i].flags2 |= LIMITRESOURCES; - if(dlg.m_SaveLoad) TargetMaps[i].flags |= SAVELOAD; - if(dlg.m_SlowDown) TargetMaps[i].flags |= SLOWDOWN; - if(dlg.m_BlitFromBackBuffer) TargetMaps[i].flags |= BLITFROMBACKBUFFER; - if(dlg.m_SuppressClipping) TargetMaps[i].flags |= SUPPRESSCLIPPING; - if(dlg.m_DisableGammaRamp) TargetMaps[i].flags2 |= DISABLEGAMMARAMP; - if(dlg.m_AutoRefresh) TargetMaps[i].flags |= AUTOREFRESH; - if(dlg.m_FixWinFrame) TargetMaps[i].flags |= FIXWINFRAME; - if(dlg.m_HideHwCursor) TargetMaps[i].flags |= HIDEHWCURSOR; - if(dlg.m_ShowHwCursor) TargetMaps[i].flags2 |= SHOWHWCURSOR; - if(dlg.m_EnableClipping) TargetMaps[i].flags |= ENABLECLIPPING; - if(dlg.m_CursorClipping) TargetMaps[i].flags |= CLIPCURSOR; - if(dlg.m_VideoToSystemMem) TargetMaps[i].flags |= SWITCHVIDEOMEMORY; - if(dlg.m_FixTextOut) TargetMaps[i].flags |= FIXTEXTOUT; - if(dlg.m_KeepCursorWithin) TargetMaps[i].flags |= KEEPCURSORWITHIN; - if(dlg.m_KeepCursorFixed) TargetMaps[i].flags2 |= KEEPCURSORFIXED; - if(dlg.m_UseRGB565) TargetMaps[i].flags |= USERGB565; - if(dlg.m_SuppressDXErrors) TargetMaps[i].flags |= SUPPRESSDXERRORS; - if(dlg.m_MarkBlit) TargetMaps[i].flags3 |= MARKBLIT; - if(dlg.m_PreventMaximize) TargetMaps[i].flags |= PREVENTMAXIMIZE; - if(dlg.m_ClientRemapping) TargetMaps[i].flags |= CLIENTREMAPPING; - if(dlg.m_MapGDIToPrimary) TargetMaps[i].flags |= MAPGDITOPRIMARY; - if(dlg.m_LockWinPos) TargetMaps[i].flags |= LOCKWINPOS; - if(dlg.m_LockWinStyle) TargetMaps[i].flags |= LOCKWINSTYLE; - if(dlg.m_FixParentWin) TargetMaps[i].flags |= FIXPARENTWIN; - if(dlg.m_ModalStyle) TargetMaps[i].flags2 |= MODALSTYLE; - if(dlg.m_KeepAspectRatio) TargetMaps[i].flags2 |= KEEPASPECTRATIO; - if(dlg.m_ForceWinResize) TargetMaps[i].flags2 |= FORCEWINRESIZE; - if(dlg.m_HookGDI) TargetMaps[i].flags2 |= HOOKGDI; - if(dlg.m_HideMultiMonitor) TargetMaps[i].flags2 |= HIDEMULTIMONITOR; - if(dlg.m_WallpaperMode) TargetMaps[i].flags2 |= WALLPAPERMODE; - if(dlg.m_FixD3DFrame) TargetMaps[i].flags3 |= FIXD3DFRAME; - if(dlg.m_Force16BPP) TargetMaps[i].flags3 |= FORCE16BPP; - if(dlg.m_HookChildWin) TargetMaps[i].flags |= HOOKCHILDWIN; - if(dlg.m_MessageProc) TargetMaps[i].flags |= MESSAGEPROC; - if(dlg.m_FixNCHITTEST) TargetMaps[i].flags2 |= FIXNCHITTEST; - if(dlg.m_RecoverScreenMode) TargetMaps[i].flags2 |= RECOVERSCREENMODE; - if(dlg.m_RefreshOnResize) TargetMaps[i].flags2 |= REFRESHONRESIZE; - if(dlg.m_Init8BPP) TargetMaps[i].flags2 |= INIT8BPP; - if(dlg.m_Init16BPP) TargetMaps[i].flags2 |= INIT16BPP; - if(dlg.m_BackBufAttach) TargetMaps[i].flags2 |= BACKBUFATTACH; - if(dlg.m_HandleAltF4) TargetMaps[i].flags |= HANDLEALTF4; - if(dlg.m_LimitFPS) TargetMaps[i].flags2 |= LIMITFPS; - if(dlg.m_SkipFPS) TargetMaps[i].flags2 |= SKIPFPS; - if(dlg.m_ShowFPS) TargetMaps[i].flags2 |= SHOWFPS; - if(dlg.m_ShowFPSOverlay) TargetMaps[i].flags2 |= SHOWFPSOVERLAY; - if(dlg.m_TimeStretch) TargetMaps[i].flags2 |= TIMESTRETCH; - if(dlg.m_HookOpenGL) TargetMaps[i].flags2 |= HOOKOPENGL; - if(dlg.m_ForceHookOpenGL) TargetMaps[i].flags3 |= FORCEHOOKOPENGL; - if(dlg.m_WireFrame) TargetMaps[i].flags2 |= WIREFRAME; - if(dlg.m_BlackWhite) TargetMaps[i].flags3 |= BLACKWHITE; - if(dlg.m_FakeVersion) TargetMaps[i].flags2 |= FAKEVERSION; - if(dlg.m_FullRectBlt) TargetMaps[i].flags2 |= FULLRECTBLT; - if(dlg.m_NoPaletteUpdate) TargetMaps[i].flags2 |= NOPALETTEUPDATE; - TargetMaps[i].initx = dlg.m_InitX; - TargetMaps[i].inity = dlg.m_InitY; - TargetMaps[i].minx = dlg.m_MinX; - TargetMaps[i].miny = dlg.m_MinY; - TargetMaps[i].maxx = dlg.m_MaxX; - TargetMaps[i].maxy = dlg.m_MaxY; - TargetMaps[i].posx = dlg.m_PosX; - TargetMaps[i].posy = dlg.m_PosY; - TargetMaps[i].sizx = dlg.m_SizX; - TargetMaps[i].sizy = dlg.m_SizY; - TargetMaps[i].MaxFPS = dlg.m_MaxFPS; - TargetMaps[i].FakeVersionId = dlg.m_FakeVersionId; - if (dlg.m_InitTS>=-8 && dlg.m_InitTS<=8) - TargetMaps[i].InitTS = dlg.m_InitTS-8; - else - MessageBoxEx(0, "Bad InitTS", "Warning", MB_OK, NULL); + strncpy(TitleMaps[i].title, dlg.m_Title, 40); + SetTargetFromDlg(&TargetMaps[i], &dlg); CListCtrl& listctrl = GetListCtrl(); listitem.mask = LVIF_TEXT | LVIF_IMAGE; listitem.iItem = i;