From 0d1d1fc6b862454b84411ff3bd6a56562fbfc2e9 Mon Sep 17 00:00:00 2001 From: gho tik Date: Sun, 2 Feb 2014 11:38:46 -0500 Subject: [PATCH] v2_02_56_src Former-commit-id: 16e07a99fe0abe0e86093aae9c3f5d93ab530aa2 --- build/dxwnd.dll | 4 +- build/dxwnd.ini | 961 ++++++++++-------- build/exports/Affari Tuoi.dxw | 26 + build/exports/Agassi Tennis Generation.dxw | 26 + build/exports/LEGO Star Wars.dxw | 26 + .../Legacy of Kain Soul Reaver (GOG).dxw | 26 + build/exports/Syberia 2.dxw | 26 + build/exports/Syberia.dxw | 26 + .../Thief the Dark Project GOLD (GOG).dxw | 26 + build/exports/Thief the Dark Project GOLD.dxw | 26 + build/exports/Total Immersion Racing.dxw | 26 + build/readme-relnotes.txt | 11 +- dll/ddraw.cpp | 60 +- dll/dinput.cpp | 16 +- dll/dxwnd.vs2008.suo | Bin 112640 -> 122368 bytes dll/hd3d.cpp | 57 +- dll/hd3d7.cpp | 748 +++++++++++--- dll/syslibs.h | 6 +- dll/user32.cpp | 31 +- host/dxwndhost.vs2008.suo | Bin 100352 -> 100352 bytes 20 files changed, 1476 insertions(+), 652 deletions(-) create mode 100644 build/exports/Affari Tuoi.dxw create mode 100644 build/exports/Agassi Tennis Generation.dxw create mode 100644 build/exports/LEGO Star Wars.dxw create mode 100644 build/exports/Legacy of Kain Soul Reaver (GOG).dxw create mode 100644 build/exports/Syberia 2.dxw create mode 100644 build/exports/Syberia.dxw create mode 100644 build/exports/Thief the Dark Project GOLD (GOG).dxw create mode 100644 build/exports/Thief the Dark Project GOLD.dxw create mode 100644 build/exports/Total Immersion Racing.dxw diff --git a/build/dxwnd.dll b/build/dxwnd.dll index aa1c284..1357954 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:204b88153c343d4bd1b32eadbb4f2c0267ad6f3147cf813cf591084e27893061 -size 450048 +oid sha256:0ab0518cd95cd490131b9ba49cc94686af2bdc129622f112e8499bc5c386cc42 +size 458240 diff --git a/build/dxwnd.ini b/build/dxwnd.ini index fab5947..5e2a67d 100644 --- a/build/dxwnd.ini +++ b/build/dxwnd.ini @@ -1424,8 +1424,8 @@ maxfps56=0 initts56=0 winver56=0 maxres56=-1 -title57=LEGOŽ Marvel Super Heroes Demo -path57=C:\Program Files (x86)\Warner Bros. Interactive Entertainment\LEGOŽ Marvel Super Heroes Demo\LEGOMarvelDemo.exe +title57=LEGO Star Wars +path57=D:\Games\LEGO Star Wars Game\LegoStarwars.crack.exe module57= opengllib57= ver57=0 @@ -1434,7 +1434,7 @@ flag57=134217762 flagg57=1207959552 flagh57=20 flagi57=4 -tflag57=0 +tflag57=64 initx57=0 inity57=0 minx57=0 @@ -1448,18 +1448,18 @@ sizy57=600 maxfps57=0 initts57=0 winver57=0 -maxres57=0 -title58=L'Elefante a Strisce -path58=D:\Games\L'Elefante a Strisce\Pilots1I.EXE +maxres57=-1 +title58=LEGOŽ Marvel Super Heroes Demo +path58=C:\Program Files (x86)\Warner Bros. Interactive Entertainment\LEGOŽ Marvel Super Heroes Demo\LEGOMarvelDemo.exe module58= opengllib58= ver58=0 coord58=0 flag58=134217762 -flagg58=135266368 +flagg58=1207959552 flagh58=20 -flagi58=0 -tflag58=64 +flagi58=4 +tflag58=0 initx58=0 inity58=0 minx58=0 @@ -1474,17 +1474,17 @@ maxfps58=0 initts58=0 winver58=0 maxres58=0 -title59=Lords of Magic Special Edition -path59=D:\Games\LoM\SIERRA\LOMSE\lomse.exe +title59=L'Elefante a Strisce +path59=D:\Games\L'Elefante a Strisce\Pilots1I.EXE module59= opengllib59= ver59=0 coord59=0 -flag59=402669603 -flagg59=1207959568 -flagh59=6291476 +flag59=134217762 +flagg59=135266368 +flagh59=20 flagi59=0 -tflag59=6418 +tflag59=64 initx59=0 inity59=0 minx59=0 @@ -1499,17 +1499,17 @@ maxfps59=0 initts59=0 winver59=0 maxres59=0 -title60=Lords of the Realm 2 -path60=D:\Games\Lords of the Realm 2\LORDS2.EXE +title60=Lords of Magic Special Edition +path60=D:\Games\LoM\SIERRA\LOMSE\lomse.exe module60= opengllib60= ver60=0 coord60=0 -flag60=134217762 -flagg60=1209008128 -flagh60=65556 -flagi60=4 -tflag60=0 +flag60=402669603 +flagg60=1207959568 +flagh60=6291476 +flagi60=0 +tflag60=6418 initx60=0 inity60=0 minx60=0 @@ -1524,16 +1524,16 @@ maxfps60=0 initts60=0 winver60=0 maxres60=0 -title61=Lost Valley -path61=D:\Games\Lost Valley\lost valley\lost valley data.exe +title61=Lords of the Realm 2 +path61=D:\Games\Lords of the Realm 2\LORDS2.EXE module61= opengllib61= ver61=0 coord61=0 -flag61=679485474 -flagg61=1207959552 -flagh61=-2080374764 -flagi61=0 +flag61=134217762 +flagg61=1209008128 +flagh61=65556 +flagi61=4 tflag61=0 initx61=0 inity61=0 @@ -1549,17 +1549,17 @@ maxfps61=0 initts61=0 winver61=0 maxres61=0 -title62=Mageslayer -path62=D:\Games\MAGE\MAGESLAY.EXE +title62=Lost Valley +path62=D:\Games\Lost Valley\lost valley\lost valley data.exe module62= opengllib62= ver62=0 coord62=0 -flag62=134234146 -flagg62=402653216 -flagh62=8212 -flagi62=1 -tflag62=6210 +flag62=679485474 +flagg62=1207959552 +flagh62=-2080374764 +flagi62=0 +tflag62=0 initx62=0 inity62=0 minx62=0 @@ -1574,17 +1574,17 @@ maxfps62=0 initts62=0 winver62=0 maxres62=0 -title63=Magic & Mayhem -path63=D:\Games\Magic_&_Mayhem\Chaos.exe +title63=Mageslayer +path63=D:\Games\MAGE\MAGESLAY.EXE module63= opengllib63= ver63=0 coord63=0 -flag63=134217762 -flagg63=1207959552 -flagh63=20 -flagi63=4 -tflag63=0 +flag63=134234146 +flagg63=402653216 +flagh63=8212 +flagi63=1 +tflag63=6210 initx63=0 inity63=0 minx63=0 @@ -1599,17 +1599,17 @@ maxfps63=0 initts63=0 winver63=0 maxres63=0 -title64=Martian Gothic Unification -path64=D:\Games\Martian Gothic\martian gothic.exe +title64=Magic & Mayhem +path64=D:\Games\Magic_&_Mayhem\Chaos.exe module64= opengllib64= ver64=0 coord64=0 -flag64=203423776 -flagg64=1476395008 +flag64=134217762 +flagg64=1207959552 flagh64=20 -flagi64=5 -tflag64=6162 +flagi64=4 +tflag64=0 initx64=0 inity64=0 minx64=0 @@ -1624,17 +1624,17 @@ maxfps64=0 initts64=0 winver64=0 maxres64=0 -title65=Millennium Racer Y2K fighters -path65=D:\Games\Millennium Racer\MRacer.exe +title65=Martian Gothic Unification +path65=D:\Games\Martian Gothic\martian gothic.exe module65= opengllib65= ver65=0 coord65=0 -flag65=671105056 -flagg65=1476395024 +flag65=203423776 +flagg65=1476395008 flagh65=20 -flagi65=4 -tflag65=0 +flagi65=5 +tflag65=6162 initx65=0 inity65=0 minx65=0 @@ -1648,17 +1648,17 @@ sizy65=600 maxfps65=0 initts65=0 winver65=0 -maxres65=-1 -title66=Motocross Madness (DEMO) -path66=D:\Games\Motocross Madness Trial\mcm.exe +maxres65=0 +title66=Millennium Racer Y2K fighters +path66=D:\Games\Millennium Racer\MRacer.exe module66= opengllib66= ver66=0 coord66=0 -flag66=134217760 -flagg66=1207959552 +flag66=671105056 +flagg66=1476395024 flagh66=20 -flagi66=0 +flagi66=4 tflag66=0 initx66=0 inity66=0 @@ -1673,18 +1673,18 @@ sizy66=600 maxfps66=0 initts66=0 winver66=0 -maxres66=0 -title67=Nascar Racing 3 -path67=D:\Games\Nascar Racing 3\NASCAR Racing 3.exe +maxres66=-1 +title67=Motocross Madness (DEMO) +path67=D:\Games\Motocross Madness Trial\mcm.exe module67= opengllib67= ver67=0 coord67=0 -flag67=671105056 +flag67=134217760 flagg67=1207959552 flagh67=20 -flagi67=4 -tflag67=6162 +flagi67=0 +tflag67=0 initx67=0 inity67=0 minx67=0 @@ -1699,14 +1699,14 @@ maxfps67=0 initts67=0 winver67=0 maxres67=0 -title68=Need for Speed 2SE -path68=D:\Games\Need for Speed 2SE\NFS2SEN.EXE +title68=Nascar Racing 3 +path68=D:\Games\Nascar Racing 3\NASCAR Racing 3.exe module68= opengllib68= ver68=0 coord68=0 -flag68=134217826 -flagg68=1480589312 +flag68=671105056 +flagg68=1207959552 flagh68=20 flagi68=4 tflag68=6162 @@ -1724,17 +1724,17 @@ maxfps68=0 initts68=0 winver68=0 maxres68=0 -title69=Need for Speed 2SE (3dfx) -path69=D:\Games\Need for Speed 2SE\nfs2sea.exe +title69=Need for Speed 2SE +path69=D:\Games\Need for Speed 2SE\NFS2SEN.EXE module69= opengllib69= ver69=0 coord69=0 -flag69=134217760 -flagg69=1207959552 +flag69=134217826 +flagg69=1480589312 flagh69=20 flagi69=4 -tflag69=6146 +tflag69=6162 initx69=0 inity69=0 minx69=0 @@ -1749,17 +1749,17 @@ maxfps69=0 initts69=0 winver69=0 maxres69=0 -title70=Need for Speed 3 -path70=D:\Games\Need for Speed 3\nfs3.exe +title70=Need for Speed 2SE (3dfx) +path70=D:\Games\Need for Speed 2SE\nfs2sea.exe module70= opengllib70= -ver70=1 +ver70=0 coord70=0 -flag70=134217762 +flag70=134217760 flagg70=1207959552 flagh70=20 flagi70=4 -tflag70=0 +tflag70=6146 initx70=0 inity70=0 minx70=0 @@ -1774,16 +1774,16 @@ maxfps70=0 initts70=0 winver70=0 maxres70=0 -title71=Need For Speed Underground -path71=D:\Games\Need For Speed Underground\speed.exe +title71=Need for Speed 3 +path71=D:\Games\Need for Speed 3\nfs3.exe module71= opengllib71= -ver71=9 +ver71=1 coord71=0 flag71=134217762 flagg71=1207959552 flagh71=20 -flagi71=1028 +flagi71=4 tflag71=0 initx71=0 inity71=0 @@ -1799,8 +1799,8 @@ maxfps71=0 initts71=0 winver71=0 maxres71=0 -title72=Need for Speed Underground 2 -path72=D:\Games\Need for Speed Underground 2\SPEED2.EXE +title72=Need For Speed Underground +path72=D:\Games\Need For Speed Underground\speed.exe module72= opengllib72= ver72=9 @@ -1808,7 +1808,7 @@ coord72=0 flag72=134217762 flagg72=1207959552 flagh72=20 -flagi72=4 +flagi72=1028 tflag72=0 initx72=0 inity72=0 @@ -1824,13 +1824,13 @@ maxfps72=0 initts72=0 winver72=0 maxres72=0 -title73=Neophyte Koplio's Story -path73=D:\Games\Neophyte Koplio's Story\KOPLIO.exe +title73=Need for Speed Underground 2 +path73=D:\Games\Need for Speed Underground 2\SPEED2.EXE module73= opengllib73= -ver73=1 +ver73=9 coord73=0 -flag73=134234146 +flag73=134217762 flagg73=1207959552 flagh73=20 flagi73=4 @@ -1849,14 +1849,14 @@ maxfps73=0 initts73=0 winver73=0 maxres73=0 -title74=NetStorm - Islands at War -path74=D:\Games\NetStorm - Islands at War\Netstorm.exe +title74=Neophyte Koplio's Story +path74=D:\Games\Neophyte Koplio's Story\KOPLIO.exe module74= opengllib74= -ver74=0 +ver74=1 coord74=0 -flag74=679608354 -flagg74=1209008384 +flag74=134234146 +flagg74=1207959552 flagh74=20 flagi74=4 tflag74=0 @@ -1874,17 +1874,17 @@ maxfps74=0 initts74=0 winver74=0 maxres74=0 -title75=O.R.B. Offword Rescue Base -path75=D:\Games\O.R.B\orb.exe +title75=NetStorm - Islands at War +path75=D:\Games\NetStorm - Islands at War\Netstorm.exe module75= opengllib75= ver75=0 -coord75=2 -flag75=134234144 -flagg75=1207959568 +coord75=0 +flag75=679608354 +flagg75=1209008384 flagh75=20 flagi75=4 -tflag75=6162 +tflag75=0 initx75=0 inity75=0 minx75=0 @@ -1898,18 +1898,18 @@ sizy75=600 maxfps75=0 initts75=0 winver75=0 -maxres75=-1 -title76=Pandemonium 2 (GLIDE) -path76=D:\Games\Pandemonium 2\pandy.exe +maxres75=0 +title76=O.R.B. Offword Rescue Base +path76=D:\Games\O.R.B\orb.exe module76= opengllib76= ver76=0 -coord76=0 -flag76=134217762 -flagg76=1207959552 -flagh76=65556 +coord76=2 +flag76=134234144 +flagg76=1207959568 +flagh76=20 flagi76=4 -tflag76=0 +tflag76=6162 initx76=0 inity76=0 minx76=0 @@ -1923,18 +1923,18 @@ sizy76=600 maxfps76=0 initts76=0 winver76=0 -maxres76=0 -title77=Panzer Dragoon -path77=D:\Games\Panzer Dragoon\game\PANZERDG.EXE +maxres76=-1 +title77=Pandemonium 2 (GLIDE) +path77=D:\Games\Pandemonium 2\pandy.exe module77= opengllib77= ver77=0 coord77=0 flag77=134217762 flagg77=1207959552 -flagh77=20 +flagh77=65556 flagi77=4 -tflag77=66 +tflag77=0 initx77=0 inity77=0 minx77=0 @@ -1949,17 +1949,17 @@ maxfps77=0 initts77=0 winver77=0 maxres77=0 -title78=Port Royale 2 -path78=D:\Games\Port Royale 2\PR2.exe +title78=Panzer Dragoon +path78=D:\Games\Panzer Dragoon\game\PANZERDG.EXE module78= opengllib78= -ver78=8 +ver78=0 coord78=0 -flag78=671096866 +flag78=134217762 flagg78=1207959552 -flagh78=65556 +flagh78=20 flagi78=4 -tflag78=0 +tflag78=66 initx78=0 inity78=0 minx78=0 @@ -1973,18 +1973,18 @@ sizy78=600 maxfps78=0 initts78=0 winver78=0 -maxres78=-1 -title79=Praetorians -path79=D:\games\Praetorians\Praetorians.exe +maxres78=0 +title79=Port Royale 2 +path79=D:\Games\Port Royale 2\PR2.exe module79= opengllib79= -ver79=0 -coord79=2 -flag79=134217760 -flagg79=1209008144 -flagh79=22 +ver79=8 +coord79=0 +flag79=671096866 +flagg79=1207959552 +flagh79=65556 flagi79=4 -tflag79=2 +tflag79=0 initx79=0 inity79=0 minx79=0 @@ -1998,18 +1998,18 @@ sizy79=600 maxfps79=0 initts79=0 winver79=0 -maxres79=0 -title80=Praetorians (DEMO) -path80=D:\Games\Praetorians Demo\Praetorians.exe +maxres79=-1 +title80=Praetorians +path80=D:\games\Praetorians\Praetorians.exe module80= opengllib80= ver80=0 -coord80=0 -flag80=150994976 -flagg80=1209008128 -flagh80=65556 +coord80=2 +flag80=134217760 +flagg80=1209008144 +flagh80=22 flagi80=4 -tflag80=6418 +tflag80=2 initx80=0 inity80=0 minx80=0 @@ -2024,17 +2024,17 @@ maxfps80=0 initts80=0 winver80=0 maxres80=0 -title81=Premier Manager 98 -path81=D:\Games\Premier Manager 98\MANAGER.EXE +title81=Praetorians (DEMO) +path81=D:\Games\Praetorians Demo\Praetorians.exe module81= opengllib81= ver81=0 coord81=0 -flag81=671092770 -flagg81=1207959552 -flagh81=16 -flagi81=0 -tflag81=0 +flag81=150994976 +flagg81=1209008128 +flagh81=65556 +flagi81=4 +tflag81=6418 initx81=0 inity81=0 minx81=0 @@ -2049,15 +2049,15 @@ maxfps81=0 initts81=0 winver81=0 maxres81=0 -title82=Primitive Wars -path82=D:\Games\Primitive Wars\Pw.exe +title82=Premier Manager 98 +path82=D:\Games\Premier Manager 98\MANAGER.EXE module82= opengllib82= ver82=0 coord82=0 -flag82=671088674 -flagg82=134217728 -flagh82=20 +flag82=671092770 +flagg82=1207959552 +flagh82=16 flagi82=0 tflag82=0 initx82=0 @@ -2074,17 +2074,17 @@ maxfps82=0 initts82=0 winver82=0 maxres82=0 -title83=Project Eden -path83=D:\Games\Project Eden\Eden.exe +title83=Primitive Wars +path83=D:\Games\Primitive Wars\Pw.exe module83= opengllib83= ver83=0 coord83=0 -flag83=134217763 -flagg83=1207959552 +flag83=671088674 +flagg83=134217728 flagh83=20 -flagi83=4 -tflag83=64 +flagi83=0 +tflag83=0 initx83=0 inity83=0 minx83=0 @@ -2098,18 +2098,18 @@ sizy83=600 maxfps83=0 initts83=0 winver83=0 -maxres83=-1 -title84=Project IGI -path84=D:\Games\Project IGI\pc\IGI.exe +maxres83=0 +title84=Project Eden +path84=D:\Games\Project Eden\Eden.exe module84= opengllib84= ver84=0 coord84=0 -flag84=671105060 -flagg84=-939524096 +flag84=134217763 +flagg84=1207959552 flagh84=20 flagi84=4 -tflag84=66 +tflag84=64 initx84=0 inity84=0 minx84=0 @@ -2123,18 +2123,18 @@ sizy84=600 maxfps84=0 initts84=0 winver84=0 -maxres84=0 -title85=Project Nomads (DEMO) -path85=D:\Games\Project Nomads Demo\bin\win32\nomads.exe +maxres84=-1 +title85=Project IGI +path85=D:\Games\Project IGI\pc\IGI.exe module85= opengllib85= -ver85=8 +ver85=0 coord85=0 -flag85=-1476394974 -flagg85=1207959808 -flagh85=4 -flagi85=0 -tflag85=274 +flag85=671105060 +flagg85=-939524096 +flagh85=20 +flagi85=4 +tflag85=66 initx85=0 inity85=0 minx85=0 @@ -2149,17 +2149,17 @@ maxfps85=0 initts85=0 winver85=0 maxres85=0 -title86=Quake 2 -path86=D:\Games\QUAKE2\quake2.exe +title86=Project Nomads (DEMO) +path86=D:\Games\Project Nomads Demo\bin\win32\nomads.exe module86= opengllib86= -ver86=0 +ver86=8 coord86=0 -flag86=134234114 -flagg86=1208090624 -flagh86=20 -flagi86=4 -tflag86=0 +flag86=-1476394974 +flagg86=1207959808 +flagh86=4 +flagi86=0 +tflag86=274 initx86=0 inity86=0 minx86=0 @@ -2174,14 +2174,14 @@ maxfps86=0 initts86=0 winver86=0 maxres86=0 -title87=Railroad Tycoon II -path87=D:\Games\Railroad.Tycoon.II\RT2.EXE +title87=Quake 2 +path87=D:\Games\QUAKE2\quake2.exe module87= opengllib87= ver87=0 coord87=0 -flag87=134217762 -flagg87=1207959552 +flag87=134234114 +flagg87=1208090624 flagh87=20 flagi87=4 tflag87=0 @@ -2199,17 +2199,17 @@ maxfps87=0 initts87=0 winver87=0 maxres87=0 -title88=Rayman 2 Demo -path88=D:\Games\Rayman2Demo\Rayman2Demo.exe +title88=Railroad Tycoon II +path88=D:\Games\Railroad.Tycoon.II\RT2.EXE module88= opengllib88= -ver88=7 +ver88=0 coord88=0 -flag88=402653217 -flagg88=1208025088 -flagh88=2097172 -flagi88=0 -tflag88=6418 +flag88=134217762 +flagg88=1207959552 +flagh88=20 +flagi88=4 +tflag88=0 initx88=0 inity88=0 minx88=0 @@ -2221,20 +2221,20 @@ posy88=50 sizx88=800 sizy88=600 maxfps88=0 -initts88=4 +initts88=0 winver88=0 maxres88=0 -title89=Serious Sam - The Second Encounter Demo -path89=D:\Games\Serious Sam - The Second Encounter Demo\Bin\SeriousSam.exe +title89=Rayman 2 Demo +path89=D:\Games\Rayman2Demo\Rayman2Demo.exe module89= opengllib89= -ver89=0 +ver89=7 coord89=0 -flag89=671088674 -flagg89=1208156160 -flagh89=20 -flagi89=4 -tflag89=64 +flag89=402653217 +flagg89=1208025088 +flagh89=2097172 +flagi89=0 +tflag89=6418 initx89=0 inity89=0 minx89=0 @@ -2249,17 +2249,17 @@ maxfps89=0 initts89=4 winver89=0 maxres89=0 -title90=Shadows of the Empire (DEMO) -path90=D:\Games\Shadows of the Empire\shadows.exe +title90=Serious Sam - The Second Encounter Demo +path90=D:\Games\Serious Sam - The Second Encounter Demo\Bin\SeriousSam.exe module90= opengllib90= ver90=0 -coord90=2 -flag90=134479906 -flagg90=1207959568 -flagh90=33554452 -flagi90=0 -tflag90=274 +coord90=0 +flag90=671088674 +flagg90=1208156160 +flagh90=20 +flagi90=4 +tflag90=64 initx90=0 inity90=0 minx90=0 @@ -2271,20 +2271,20 @@ posy90=50 sizx90=800 sizy90=600 maxfps90=0 -initts90=0 +initts90=4 winver90=0 maxres90=0 -title91=Sid Meier's Civilization III Complete -path91=D:\Games\Sid Meier's Civilization III Complete\Conquests\Civ3Conquests.exe -module91=jgl +title91=Shadows of the Empire (DEMO) +path91=D:\Games\Shadows of the Empire\shadows.exe +module91= opengllib91= ver91=0 -coord91=0 -flag91=973352994 -flagg91=136462360 -flagh91=2162708 -flagi91=4100 -tflag91=64 +coord91=2 +flag91=134479906 +flagg91=1207959568 +flagh91=33554452 +flagi91=0 +tflag91=274 initx91=0 inity91=0 minx91=0 @@ -2296,20 +2296,20 @@ posy91=50 sizx91=800 sizy91=600 maxfps91=0 -initts91=6 +initts91=0 winver91=0 -maxres91=5 -title92=SimCity 4 Deluxe -path92=D:\Games\SimCity 4 Deluxe\Apps\SimCity 4.exe -module92= +maxres91=0 +title92=Sid Meier's Civilization III Complete +path92=D:\Games\Sid Meier's Civilization III Complete\Conquests\Civ3Conquests.exe +module92=jgl opengllib92= -ver92=7 +ver92=0 coord92=0 -flag92=32 -flagg92=1207959568 -flagh92=20 +flag92=973352994 +flagg92=136462360 +flagh92=2162708 flagi92=4100 -tflag92=8158 +tflag92=64 initx92=0 inity92=0 minx92=0 @@ -2318,23 +2318,23 @@ maxx92=0 maxy92=0 posx92=50 posy92=50 -sizx92=1200 -sizy92=900 +sizx92=800 +sizy92=600 maxfps92=0 -initts92=0 +initts92=6 winver92=0 -maxres92=1 -title93=Star Wars Episode I Racer -path93=D:\Games\Star Wars Episode 1 racer\SWEP1RCR.EXE +maxres92=5 +title93=SimCity 4 Deluxe +path93=D:\Games\SimCity 4 Deluxe\Apps\SimCity 4.exe module93= opengllib93= -ver93=0 +ver93=7 coord93=0 -flag93=679493669 -flagg93=1210056720 -flagh93=8212 -flagi93=20 -tflag93=64 +flag93=32 +flagg93=1207959568 +flagh93=20 +flagi93=4100 +tflag93=8158 initx93=0 inity93=0 minx93=0 @@ -2343,22 +2343,22 @@ maxx93=0 maxy93=0 posx93=50 posy93=50 -sizx93=800 -sizy93=600 +sizx93=1200 +sizy93=900 maxfps93=0 initts93=0 winver93=0 -maxres93=0 -title94=StarCraft -path94=D:\Games\Starcraft\StarCraft.exe +maxres93=1 +title94=Star Wars Episode I Racer +path94=D:\Games\Star Wars Episode 1 racer\SWEP1RCR.EXE module94= opengllib94= ver94=0 coord94=0 -flag94=134217762 -flagg94=134283264 -flagh94=20 -flagi94=8 +flag94=679493669 +flagg94=1210056720 +flagh94=8212 +flagi94=20 tflag94=64 initx94=0 inity94=0 @@ -2374,17 +2374,17 @@ maxfps94=0 initts94=0 winver94=0 maxres94=0 -title95=Starsky & Hutch - GAME -path95=D:\Games\Starsky & Hutch\StarskyPC.exe +title95=StarCraft +path95=D:\Games\Starcraft\StarCraft.exe module95= opengllib95= ver95=0 coord95=0 -flag95=947912739 -flagg95=1207959552 +flag95=134217762 +flagg95=134283264 flagh95=20 -flagi95=4 -tflag95=0 +flagi95=8 +tflag95=64 initx95=0 inity95=0 minx95=0 @@ -2399,13 +2399,13 @@ maxfps95=0 initts95=0 winver95=0 maxres95=0 -title96=Starsky & Hutch - LAUNCHER -path96=D:\Games\Starsky & Hutch\Starsky.exe +title96=Starsky & Hutch - GAME +path96=D:\Games\Starsky & Hutch\StarskyPC.exe module96= opengllib96= ver96=0 coord96=0 -flag96=134217728 +flag96=947912739 flagg96=1207959552 flagh96=20 flagi96=4 @@ -2424,17 +2424,17 @@ maxfps96=0 initts96=0 winver96=0 maxres96=0 -title97=State of Emergency -path97=D:\Games\State of Emergency\KaosPC.cracked.exe +title97=Starsky & Hutch - LAUNCHER +path97=D:\Games\Starsky & Hutch\Starsky.exe module97= opengllib97= -ver97=8 +ver97=0 coord97=0 -flag97=671088676 -flagg97=1208025088 +flag97=134217728 +flagg97=1207959552 flagh97=20 -flagi97=2052 -tflag97=6162 +flagi97=4 +tflag97=0 initx97=0 inity97=0 minx97=0 @@ -2445,21 +2445,21 @@ posx97=50 posy97=50 sizx97=800 sizy97=600 -maxfps97=50 -initts97=2 +maxfps97=0 +initts97=0 winver97=0 maxres97=0 -title98=State of War Warmonger -path98=D:\Games\State of War Warmonger\State of War - Warmonger.exe +title98=State of Emergency +path98=D:\Games\State of Emergency\KaosPC.cracked.exe module98= opengllib98= -ver98=0 +ver98=8 coord98=0 -flag98=134234210 -flagg98=134217728 -flagh98=532 -flagi98=4 -tflag98=0 +flag98=671088676 +flagg98=1208025088 +flagh98=20 +flagi98=2052 +tflag98=6162 initx98=0 inity98=0 minx98=0 @@ -2470,21 +2470,21 @@ posx98=50 posy98=50 sizx98=800 sizy98=600 -maxfps98=0 -initts98=0 +maxfps98=50 +initts98=2 winver98=0 -maxres98=-1 -title99=Still Life (GOG) -path99=D:\Games\Still Life (GOG)\StillLife.exe +maxres98=0 +title99=State of War Warmonger +path99=D:\Games\State of War Warmonger\State of War - Warmonger.exe module99= opengllib99= ver99=0 coord99=0 -flag99=671105058 -flagg99=1207959568 -flagh99=20 +flag99=134234210 +flagg99=134217728 +flagh99=532 flagi99=4 -tflag99=6210 +tflag99=0 initx99=0 inity99=0 minx99=0 @@ -2498,24 +2498,24 @@ sizy99=600 maxfps99=0 initts99=0 winver99=0 -maxres99=5 -title100=Syberia -path100=D:\Games\Syberia\Syberia.exe +maxres99=-1 +title100=Still Life (GOG) +path100=D:\Games\Still Life (GOG)\StillLife.exe module100= opengllib100= ver100=0 coord100=0 -flag100=822116385 -flagg100=1242562576 +flag100=671105058 +flagg100=1207959568 flagh100=20 flagi100=4 -tflag100=6170 -initx100=150 -inity100=150 -minx100=150 -miny100=150 -maxx100=800 -maxy100=600 +tflag100=6210 +initx100=0 +inity100=0 +minx100=0 +miny100=0 +maxx100=0 +maxy100=0 posx100=50 posy100=50 sizx100=800 @@ -2523,24 +2523,24 @@ sizy100=600 maxfps100=0 initts100=0 winver100=0 -maxres100=0 -title101=Take no Prisoners -path101=D:\Games\Take no Prisoners\TNP.EXE +maxres100=5 +title101=Syberia +path101=D:\Games\Syberia\Syberia.exe module101= opengllib101= ver101=0 coord101=0 -flag101=134217762 -flagg101=134217860 +flag101=822116385 +flagg101=1242562576 flagh101=20 -flagi101=512 -tflag101=258 -initx101=0 -inity101=0 -minx101=0 -miny101=0 -maxx101=0 -maxy101=0 +flagi101=4 +tflag101=6170 +initx101=150 +inity101=150 +minx101=150 +miny101=150 +maxx101=800 +maxy101=600 posx101=50 posy101=50 sizx101=800 @@ -2549,17 +2549,17 @@ maxfps101=0 initts101=0 winver101=0 maxres101=0 -title102=The Bard's Tale -path102=D:\Games\The Bard's Tale\The Bard's Tale.exe +title102=Take no Prisoners +path102=D:\Games\Take no Prisoners\TNP.EXE module102= opengllib102= -ver102=9 +ver102=0 coord102=0 -flag102=134217760 -flagg102=134217728 -flagh102=16 -flagi102=1024 -tflag102=6162 +flag102=134217762 +flagg102=134217860 +flagh102=20 +flagi102=512 +tflag102=258 initx102=0 inity102=0 minx102=0 @@ -2574,17 +2574,17 @@ maxfps102=0 initts102=0 winver102=0 maxres102=0 -title103=Tomb Raider 4 (DEMO) -path103=D:\Games\Tomb Raider - The Last Revelation (Demo)\tomb4.exe +title103=The Bard's Tale +path103=D:\Games\The Bard's Tale\The Bard's Tale.exe module103= opengllib103= -ver103=7 +ver103=9 coord103=0 flag103=134217760 -flagg103=1207959552 -flagh103=20 -flagi103=0 -tflag103=258 +flagg103=134217728 +flagh103=16 +flagi103=1024 +tflag103=6162 initx103=0 inity103=0 minx103=0 @@ -2599,17 +2599,17 @@ maxfps103=0 initts103=0 winver103=0 maxres103=0 -title104=Tomb Raider II -path104=D:\Games\Tomb Raider II\Tomb2.exe +title104=Thief the Dark Project GOLD +path104=D:\Games\Thief Gold\THIEF.EXE module104= opengllib104= -ver104=0 +ver104=7 coord104=0 -flag104=671088674 -flagg104=1207959552 -flagh104=20 -flagi104=0 -tflag104=0 +flag104=272 +flagg104=440401936 +flagh104=131612 +flagi104=4 +tflag104=9 initx104=0 inity104=0 minx104=0 @@ -2622,19 +2622,19 @@ sizx104=800 sizy104=600 maxfps104=0 initts104=0 -winver104=0 -maxres104=0 -title105=Tomb Raider II Gold (DEMO) -path105=D:\Games\Tomb Raider II Gold (Demo)\Tomb2.exe +winver104=1 +maxres104=-1 +title105=Thief the Dark Project GOLD (GOG) +path105=D:\Games\Thief Gold (GOG)\THIEF.EXE module105= opengllib105= ver105=0 -coord105=2 -flag105=671088674 -flagg105=1224736784 +coord105=0 +flag105=256 +flagg105=1207959568 flagh105=20 -flagi105=0 -tflag105=258 +flagi105=4 +tflag105=0 initx105=0 inity105=0 minx105=0 @@ -2648,18 +2648,18 @@ sizy105=600 maxfps105=0 initts105=0 winver105=0 -maxres105=0 -title106=Tomb Raider III -path106=D:\Games\Tomb Raider III\tomb3.exe +maxres105=-1 +title106=Tomb Raider 4 (DEMO) +path106=D:\Games\Tomb Raider - The Last Revelation (Demo)\tomb4.exe module106= opengllib106= -ver106=0 -coord106=2 +ver106=7 +coord106=0 flag106=134217760 -flagg106=1241514000 +flagg106=1207959552 flagh106=20 flagi106=0 -tflag106=322 +tflag106=258 initx106=0 inity106=0 minx106=0 @@ -2674,17 +2674,17 @@ maxfps106=0 initts106=0 winver106=0 maxres106=0 -title107=Total Annihilation Kingdoms -path107=D:\Games\Total Annihilation Kingdoms\Kingdoms.exe +title107=Tomb Raider II +path107=D:\Games\Tomb Raider II\Tomb2.exe module107= opengllib107= -ver107=7 +ver107=0 coord107=0 -flag107=671105058 +flag107=671088674 flagg107=1207959552 flagh107=20 -flagi107=4 -tflag107=6162 +flagi107=0 +tflag107=0 initx107=0 inity107=0 minx107=0 @@ -2699,17 +2699,17 @@ maxfps107=0 initts107=0 winver107=0 maxres107=0 -title108=Unreal Tournament -path108=D:\Games\Unreal Tournament\System\UnrealTournament.exe +title108=Tomb Raider II Gold (DEMO) +path108=D:\Games\Tomb Raider II Gold (Demo)\Tomb2.exe module108= opengllib108= ver108=0 -coord108=0 -flag108=-2013265886 -flagg108=1209073680 +coord108=2 +flag108=671088674 +flagg108=1224736784 flagh108=20 -flagi108=2052 -tflag108=4096 +flagi108=0 +tflag108=258 initx108=0 inity108=0 minx108=0 @@ -2718,23 +2718,23 @@ maxx108=0 maxy108=0 posx108=50 posy108=50 -sizx108=1200 -sizy108=900 +sizx108=800 +sizy108=600 maxfps108=0 initts108=0 winver108=0 maxres108=0 -title109=Virtua Fighter 2 (DEMO) -path109=D:\Games\vf2_demo\VF2DEMO.EXE +title109=Tomb Raider III +path109=D:\Games\Tomb Raider III\tomb3.exe module109= opengllib109= ver109=0 -coord109=0 -flag109=939524131 -flagg109=1207959664 +coord109=2 +flag109=134217760 +flagg109=1241514000 flagh109=20 flagi109=0 -tflag109=0 +tflag109=322 initx109=0 inity109=0 minx109=0 @@ -2749,17 +2749,17 @@ maxfps109=0 initts109=0 winver109=0 maxres109=0 -title110=Virtua Fighter PC -path110=D:\Games\Virtua Fighter\VFPC.EXE +title110=Total Annihilation Kingdoms +path110=D:\Games\Total Annihilation Kingdoms\Kingdoms.exe module110= opengllib110= -ver110=0 +ver110=7 coord110=0 -flag110=402653218 -flagg110=1224736784 -flagh110=33562644 -flagi110=0 -tflag110=290 +flag110=671105058 +flagg110=1207959552 +flagh110=20 +flagi110=4 +tflag110=6162 initx110=0 inity110=0 minx110=0 @@ -2773,18 +2773,18 @@ sizy110=600 maxfps110=0 initts110=0 winver110=0 -maxres110=2 -title111=Warcraft 2 Battlenet Ed -path111=D:\Games\Warcraft 2 Battlenet Ed\Warcraft II BNE.exe +maxres110=0 +title111=Unreal Tournament +path111=D:\Games\Unreal Tournament\System\UnrealTournament.exe module111= opengllib111= ver111=0 coord111=0 -flag111=134217762 -flagg111=1210122240 -flagh111=148 -flagi111=12 -tflag111=0 +flag111=-2013265886 +flagg111=1209073680 +flagh111=20 +flagi111=2052 +tflag111=4096 initx111=0 inity111=0 minx111=0 @@ -2793,23 +2793,23 @@ maxx111=0 maxy111=0 posx111=50 posy111=50 -sizx111=800 -sizy111=600 +sizx111=1200 +sizy111=900 maxfps111=0 initts111=0 winver111=0 maxres111=0 -title112=Wargasm -path112=D:\Games\Wargasm\tank.exe +title112=Virtua Fighter 2 (DEMO) +path112=D:\Games\vf2_demo\VF2DEMO.EXE module112= opengllib112= ver112=0 -coord112=2 -flag112=671088672 -flagg112=1207959696 -flagh112=65556 +coord112=0 +flag112=939524131 +flagg112=1207959664 +flagh112=20 flagi112=0 -tflag112=6162 +tflag112=0 initx112=0 inity112=0 minx112=0 @@ -2824,17 +2824,17 @@ maxfps112=0 initts112=0 winver112=0 maxres112=0 -title113=Warlords Battlecry II (DEMO) -path113=D:\Games\Warlords Battlecry II Demo\Battlecry II Demo.exe +title113=Virtua Fighter PC +path113=D:\Games\Virtua Fighter\VFPC.EXE module113= opengllib113= ver113=0 -coord113=2 -flag113=134217762 -flagg113=1207959568 -flagh113=22 +coord113=0 +flag113=402653218 +flagg113=1224736784 +flagh113=33562644 flagi113=0 -tflag113=258 +tflag113=290 initx113=0 inity113=0 minx113=0 @@ -2848,18 +2848,18 @@ sizy113=600 maxfps113=0 initts113=0 winver113=0 -maxres113=0 -title114=Whiteout -path114=D:\Games\Whiteout\Whiteout.exe +maxres113=2 +title114=Warcraft 2 Battlenet Ed +path114=D:\Games\Warcraft 2 Battlenet Ed\Warcraft II BNE.exe module114= opengllib114= ver114=0 coord114=0 -flag114=402653217 -flagg114=1207959552 -flagh114=20 -flagi114=0 -tflag114=66 +flag114=134217762 +flagg114=1210122240 +flagh114=148 +flagi114=12 +tflag114=0 initx114=0 inity114=0 minx114=0 @@ -2868,23 +2868,23 @@ maxx114=0 maxy114=0 posx114=50 posy114=50 -sizx114=640 -sizy114=480 +sizx114=800 +sizy114=600 maxfps114=0 initts114=0 winver114=0 maxres114=0 -title115=Wildfire -path115=D:\Games\Wildfire\Wildfire.exe +title115=Wargasm +path115=D:\Games\Wargasm\tank.exe module115= opengllib115= ver115=0 -coord115=0 -flag115=-1476392958 -flagg115=1210122240 -flagh115=20 -flagi115=12 -tflag115=0 +coord115=2 +flag115=671088672 +flagg115=1207959696 +flagh115=65556 +flagi115=0 +tflag115=6162 initx115=0 inity115=0 minx115=0 @@ -2899,17 +2899,17 @@ maxfps115=0 initts115=0 winver115=0 maxres115=0 -title116=Worms Pinball -path116=D:\Games\Worms Pinball\WPIB.exe +title116=Warlords Battlecry II (DEMO) +path116=D:\Games\Warlords Battlecry II Demo\Battlecry II Demo.exe module116= opengllib116= -ver116=1 -coord116=0 +ver116=0 +coord116=2 flag116=134217762 flagg116=1207959568 -flagh116=20 -flagi116=4 -tflag116=0 +flagh116=22 +flagi116=0 +tflag116=258 initx116=0 inity116=0 minx116=0 @@ -2924,17 +2924,17 @@ maxfps116=0 initts116=0 winver116=0 maxres116=0 -title117=Zanzarah -path117=D:\Games\Zanzarah\System\zanthp.exe +title117=Whiteout +path117=D:\Games\Whiteout\Whiteout.exe module117= opengllib117= ver117=0 coord117=0 -flag117=679477280 +flag117=402653217 flagg117=1207959552 flagh117=20 flagi117=0 -tflag117=0 +tflag117=66 initx117=0 inity117=0 minx117=0 @@ -2943,23 +2943,23 @@ maxx117=0 maxy117=0 posx117=50 posy117=50 -sizx117=800 -sizy117=600 +sizx117=640 +sizy117=480 maxfps117=0 initts117=0 winver117=0 maxres117=0 -title118=Zax the Alien Hunter (DEMO) -path118=D:\Games\ZaxDemo\Zax.exe +title118=Wildfire +path118=D:\Games\Wildfire\Wildfire.exe module118= opengllib118= ver118=0 -coord118=2 -flag118=-2011168734 -flagg118=1209008144 +coord118=0 +flag118=-1476392958 +flagg118=1210122240 flagh118=20 -flagi118=0 -tflag118=258 +flagi118=12 +tflag118=0 initx118=0 inity118=0 minx118=0 @@ -2974,14 +2974,14 @@ maxfps118=0 initts118=0 winver118=0 maxres118=0 -title119=ZPC Zero Population Count -path119=D:\Games\ZPC\ZPC.EXE +title119=Worms Pinball +path119=D:\Games\Worms Pinball\WPIB.exe module119= opengllib119= -ver119=0 +ver119=1 coord119=0 flag119=134217762 -flagg119=1207959552 +flagg119=1207959568 flagh119=20 flagi119=4 tflag119=0 @@ -2999,6 +2999,81 @@ maxfps119=0 initts119=0 winver119=0 maxres119=0 +title120=Zanzarah +path120=D:\Games\Zanzarah\System\zanthp.exe +module120= +opengllib120= +ver120=0 +coord120=0 +flag120=679477280 +flagg120=1207959552 +flagh120=20 +flagi120=0 +tflag120=0 +initx120=0 +inity120=0 +minx120=0 +miny120=0 +maxx120=0 +maxy120=0 +posx120=50 +posy120=50 +sizx120=800 +sizy120=600 +maxfps120=0 +initts120=0 +winver120=0 +maxres120=0 +title121=Zax the Alien Hunter (DEMO) +path121=D:\Games\ZaxDemo\Zax.exe +module121= +opengllib121= +ver121=0 +coord121=2 +flag121=-2011168734 +flagg121=1209008144 +flagh121=20 +flagi121=0 +tflag121=258 +initx121=0 +inity121=0 +minx121=0 +miny121=0 +maxx121=0 +maxy121=0 +posx121=50 +posy121=50 +sizx121=800 +sizy121=600 +maxfps121=0 +initts121=0 +winver121=0 +maxres121=0 +title122=ZPC Zero Population Count +path122=D:\Games\ZPC\ZPC.EXE +module122= +opengllib122= +ver122=0 +coord122=0 +flag122=134217762 +flagg122=1207959552 +flagh122=20 +flagi122=4 +tflag122=0 +initx122=0 +inity122=0 +minx122=0 +miny122=0 +maxx122=0 +maxy122=0 +posx122=50 +posy122=50 +sizx122=800 +sizy122=600 +maxfps122=0 +initts122=0 +winver122=0 +maxres122=0 [window] posx=1035 posy=288 diff --git a/build/exports/Affari Tuoi.dxw b/build/exports/Affari Tuoi.dxw new file mode 100644 index 0000000..0546937 --- /dev/null +++ b/build/exports/Affari Tuoi.dxw @@ -0,0 +1,26 @@ +[target] +title0=Affari Tuoi +path0=D:\Games\affari tuoi\Affari Tuoi\DOND.exe +module0= +opengllib0= +ver0=9 +coord0=0 +flag0=536870914 +flagg0=1207959568 +flagh0=16 +flagi0=4 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=4 diff --git a/build/exports/Agassi Tennis Generation.dxw b/build/exports/Agassi Tennis Generation.dxw new file mode 100644 index 0000000..f189c97 --- /dev/null +++ b/build/exports/Agassi Tennis Generation.dxw @@ -0,0 +1,26 @@ +[target] +title0=Agassi Tennis Generation +path0=D:\Games\Agassi Tennis Generation\AGASSI.exe +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=671096866 +flagg0=1207959552 +flagh0=65556 +flagi0=4 +tflag0=6147 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/LEGO Star Wars.dxw b/build/exports/LEGO Star Wars.dxw new file mode 100644 index 0000000..90e5963 --- /dev/null +++ b/build/exports/LEGO Star Wars.dxw @@ -0,0 +1,26 @@ +[target] +title0=LEGO Star Wars +path0=D:\Games\LEGO Star Wars Game\LegoStarwars.crack.exe +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=134217762 +flagg0=1207959552 +flagh0=20 +flagi0=4 +tflag0=64 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/Legacy of Kain Soul Reaver (GOG).dxw b/build/exports/Legacy of Kain Soul Reaver (GOG).dxw new file mode 100644 index 0000000..ad09e92 --- /dev/null +++ b/build/exports/Legacy of Kain Soul Reaver (GOG).dxw @@ -0,0 +1,26 @@ +[target] +title0=Legacy of Kain Soul Reaver (GOG) +path0=D:\Games\Legacy of Kain Soul Reaver\kain2.exe +module0= +opengllib0= +ver0=7 +coord0=0 +flag0=671088672 +flagg0=134217728 +flagh0=20 +flagi0=1028 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/Syberia 2.dxw b/build/exports/Syberia 2.dxw new file mode 100644 index 0000000..80d639e --- /dev/null +++ b/build/exports/Syberia 2.dxw @@ -0,0 +1,26 @@ +[target] +title0=Syberia 2 +path0=D:\Games\Syberia 2\Syberia2.exe +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=134234147 +flagg0=1207959552 +flagh0=20 +flagi0=4 +tflag0=64 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/Syberia.dxw b/build/exports/Syberia.dxw new file mode 100644 index 0000000..b27650c --- /dev/null +++ b/build/exports/Syberia.dxw @@ -0,0 +1,26 @@ +[target] +title0=Syberia +path0=D:\Games\Syberia\Syberia.exe +module0=Syberia ck2_3d ck2 +opengllib0= +ver0=0 +coord0=2 +flag0=1610694673 +flagg0=1207959576 +flagh0=20 +flagi0=4 +tflag0=6418 +initx0=300 +inity0=300 +minx0=0 +miny0=0 +maxx0=800 +maxy0=600 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/Thief the Dark Project GOLD (GOG).dxw b/build/exports/Thief the Dark Project GOLD (GOG).dxw new file mode 100644 index 0000000..a20eb17 --- /dev/null +++ b/build/exports/Thief the Dark Project GOLD (GOG).dxw @@ -0,0 +1,26 @@ +[target] +title0=Thief the Dark Project GOLD (GOG) +path0=D:\Games\Thief Gold (GOG)\THIEF.EXE +module0= +opengllib0= +ver0=0 +coord0=0 +flag0=256 +flagg0=1207959568 +flagh0=20 +flagi0=4 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/Thief the Dark Project GOLD.dxw b/build/exports/Thief the Dark Project GOLD.dxw new file mode 100644 index 0000000..08bcc64 --- /dev/null +++ b/build/exports/Thief the Dark Project GOLD.dxw @@ -0,0 +1,26 @@ +[target] +title0=Thief the Dark Project GOLD +path0=D:\Games\Thief Gold\THIEF.EXE +module0= +opengllib0= +ver0=7 +coord0=0 +flag0=272 +flagg0=440401936 +flagh0=131612 +flagi0=4 +tflag0=9 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=1 +maxres0=-1 diff --git a/build/exports/Total Immersion Racing.dxw b/build/exports/Total Immersion Racing.dxw new file mode 100644 index 0000000..bd47b53 --- /dev/null +++ b/build/exports/Total Immersion Racing.dxw @@ -0,0 +1,26 @@ +[target] +title0=Total Immersion Racing +path0=D:\Games\TIR\game\Tir.exe +module0= +opengllib0= +ver0=8 +coord0=0 +flag0=134217762 +flagg0=1207959552 +flagh0=20 +flagi0=1028 +tflag0=6147 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index b50554f..e08a50c 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -376,5 +376,14 @@ eliminated "Disable HAL support", no longer necessary some incomplete work on gdi game handling added preliminary, incomplete (not working) glide handling -v2.02.54 +v2.02.55 added "Hide desktop background" video option + +v2.02.56 +hooked RegisterClassA API (useless so far...) +fixed bug in SendMessageW hooking: caused truncated text in window titles and form captions +fixed several d3d1-7 hooks: prevented some d3d games to properly work, i.e. "Thief the Dark Project" +fixed d3d GetDisplayMode to return virtual desktop size - fixed "Affari Tuoi", an italian game. +fixed some log messages + + diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 51bc0fa..dcb6398 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -80,6 +80,7 @@ HRESULT WINAPI extGetPalette(LPDIRECTDRAWSURFACE, LPDIRECTDRAWPALETTE *); HRESULT WINAPI extGetPixelFormat(LPDIRECTDRAWSURFACE, LPDDPIXELFORMAT); HRESULT WINAPI extGetSurfaceDesc1(LPDIRECTDRAWSURFACE lpdds, LPDDSURFACEDESC lpddsd); HRESULT WINAPI extGetSurfaceDesc2(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 lpddsd); +HRESULT WINAPI extGetSurfaceDesc7(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 lpddsd); // STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC2) PURE; HRESULT WINAPI extLock(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, DWORD, HANDLE); HRESULT WINAPI extLockDir(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, DWORD, HANDLE); @@ -189,6 +190,8 @@ GetPalette_Type pGetPalette; GetPixelFormat_Type pGetPixelFormat; GetSurfaceDesc_Type pGetSurfaceDesc1; GetSurfaceDesc2_Type pGetSurfaceDesc4; +GetSurfaceDesc2_Type pGetSurfaceDesc7; + //Initialize IsLost_Type pIsLost; Lock_Type pLock; @@ -424,17 +427,30 @@ static void DescribeSurface(LPDIRECTDRAWSURFACE lpdds, int dxversion, char *labe int dwSize = (dxversion<4)?sizeof(DDSURFACEDESC):sizeof(DDSURFACEDESC2); memset(&ddsd, 0, dwSize); ddsd.dwSize = dwSize; - if(dxversion<4){ + switch (dxversion){ + case 0: + case 1: + case 2: + case 3: if (pGetSurfaceDesc1) res=(*pGetSurfaceDesc1)(lpdds, (LPDDSURFACEDESC)&ddsd); else res=lpdds->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd); - } - else { + break; + case 4: + case 5: + case 6: if (pGetSurfaceDesc4) res=(*pGetSurfaceDesc4)((LPDIRECTDRAWSURFACE2)lpdds, &ddsd); else res=lpdds->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd); + break; + case 7: + if (pGetSurfaceDesc7) + res=(*pGetSurfaceDesc7)((LPDIRECTDRAWSURFACE2)lpdds, &ddsd); + else + res=lpdds->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd); + break; } if(res)return; OutTrace("Surface %s: ddsd=%x dxversion=%d ", label, lpdds, dxversion); @@ -1071,9 +1087,12 @@ static void HookDDSurfacePrim(LPDIRECTDRAWSURFACE *lplpdds, int dxversion) if (dxversion < 4) { SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc1, (void **)&pGetSurfaceDesc1, "GetSurfaceDesc(S1)"); } - else { + if((dxversion >= 4) && (dxversion < 7)) { SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc2, (void **)&pGetSurfaceDesc4, "GetSurfaceDesc(S4)"); } + if(dxversion == 7) { + SetHook((void *)(**(DWORD **)lplpdds + 88), extGetSurfaceDesc7, (void **)&pGetSurfaceDesc7, "GetSurfaceDesc(S7)"); + } // IDirectDrawSurface::SetClipper SetHook((void *)(**(DWORD **)lplpdds + 112), extSetClipper, (void **)&pSetClipper, "SetClipper(S)"); // IDirectDrawSurface::SetColorKey @@ -1545,10 +1564,10 @@ HRESULT WINAPI extQueryInterfaceD(void *lpdd, REFIID riid, LPVOID *obp) dwLocalD3DVersion = 1; break; case 0x6aae1ec1: //Direct3D2 - dwLocalD3DVersion = 5; + dwLocalD3DVersion = 2; break; case 0xbb223240: //Direct3D3 - dwLocalD3DVersion = 6; + dwLocalD3DVersion = 3; break; case 0xf5049e77: //Direct3D7 dwLocalD3DVersion = 7; @@ -1582,8 +1601,8 @@ HRESULT WINAPI extQueryInterfaceD(void *lpdd, REFIID riid, LPVOID *obp) extern void HookDirect3DSession(LPDIRECTDRAW *, int); switch (dwLocalD3DVersion){ case 1: - case 5: - case 6: + case 2: + case 3: case 7: HookDirect3DSession((LPDIRECTDRAW *)obp, dwLocalD3DVersion); break; @@ -1799,7 +1818,7 @@ HRESULT WINAPI extSetDisplayMode1(LPDIRECTDRAW lpdd, HRESULT WINAPI extGetDisplayMode(LPDIRECTDRAW lpdd, LPDDSURFACEDESC lpddsd) { - OutTraceDDRAW("GetDisplayMode: lpdd=%x lpddsd=%s\n", lpdd, lpddsd); + OutTraceDDRAW("GetDisplayMode: lpdd=%x lpddsd=%x\n", lpdd, lpddsd); (*pGetDisplayMode)(lpdd, lpddsd); if(dxw.dwFlags1 & EMULATESURFACE) { @@ -4391,6 +4410,25 @@ HRESULT WINAPI extGetSurfaceDesc2(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 l return DDERR_INVALIDOBJECT; } +HRESULT WINAPI extGetSurfaceDesc7(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 (pGetSurfaceDesc7) return extGetSurfaceDesc((GetSurfaceDesc_Type)pGetSurfaceDesc7, (LPDIRECTDRAWSURFACE)lpdds, (LPDDSURFACEDESC)lpddsd); + break; + default: + OutTraceDW("GetSurfaceDesc: ASSERT - bad dwSize=%d lpdds=%x at %d\n", lpddsd->dwSize, lpdds, __LINE__); + return DDERR_INVALIDOBJECT; + } + OutTraceDW("GetSurfaceDesc: ASSERT - missing hook lpdds=%x dwSize=%d(%s) at %d\n", + lpdds, lpddsd->dwSize, lpddsd->dwSize==sizeof(DDSURFACEDESC)?"DDSURFACEDESC":"DDSURFACEDESC2", __LINE__); + return DDERR_INVALIDOBJECT; +} + HRESULT WINAPI extReleaseP(LPDIRECTDRAWPALETTE lpddPalette) { ULONG ref; @@ -4479,10 +4517,10 @@ HRESULT WINAPI extDDGetGammaRamp(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPDDG HRESULT WINAPI extDDSetGammaRamp(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags, LPDDGAMMARAMP lpgr) { HRESULT ret; - OutTraceDDRAW("GetGammaRamp: dds=%x dwFlags=%x RGB=(%x,%x,%x)\n", lpdds, dwFlags, lpgr->red, lpgr->green, lpgr->blue); + OutTraceDDRAW("SetGammaRamp: dds=%x dwFlags=%x RGB=(%x,%x,%x)\n", lpdds, dwFlags, lpgr->red, lpgr->green, lpgr->blue); if (dxw.dwFlags2 & DISABLEGAMMARAMP) return DD_OK; ret=(*pDDSetGammaRamp)(lpdds, dwFlags, lpgr); - if(ret) OutTraceE("GetGammaRamp: ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); + if(ret) OutTraceE("SetGammaRamp: ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); return ret; } diff --git a/dll/dinput.cpp b/dll/dinput.cpp index 278e5d2..c007538 100644 --- a/dll/dinput.cpp +++ b/dll/dinput.cpp @@ -5,6 +5,7 @@ #include "dxwnd.h" #include "dxwcore.hpp" #include "syslibs.h" +#include "dxhelper.h" typedef HRESULT (WINAPI *QueryInterface_Type)(void *, REFIID, LPVOID *); typedef HRESULT (WINAPI *DirectInputCreate_Type)(HINSTANCE, DWORD, LPDIRECTINPUT *, LPUNKNOWN); @@ -103,7 +104,10 @@ HRESULT WINAPI extDirectInputCreate(HINSTANCE hinst, dwversion); res = (*pDirectInputCreate)(hinst, dwversion, lplpdi, pu); - if(res) return res; + if(res) { + OutTraceE("DirectInputCreate: ERROR err=%x(%s)\n", res, ExplainDDError(res)); + return res; + } SetHook((void *)(**(DWORD **)lplpdi), extQueryInterfaceI, (void **)&pQueryInterfaceI, "QueryInterface(I)"); SetHook((void *)(**(DWORD **)lplpdi + 12), extDICreateDevice, (void **)&pDICreateDevice, "CreateDevice(I)"); SetHook((void *)(**(DWORD **)lplpdi + 16), extDIEnumDevices, (void **)&pDIEnumDevices, "EnumDevices(I)"); @@ -119,10 +123,14 @@ HRESULT WINAPI extDirectInputCreateEx(HINSTANCE hinst, dwversion, riidltf.Data1); res = (*pDirectInputCreateEx)(hinst, dwversion, riidltf, ppvout, pu); - if(res) return res; + if(res) { + OutTraceE("DirectInputCreateEx: ERROR err=%x(%s)\n", res, ExplainDDError(res)); + return res; + } SetHook((void *)(**(DWORD **)ppvout + 12), extDICreateDevice, (void **)&pDICreateDevice, "CreateDevice(I)"); SetHook((void *)(**(DWORD **)ppvout + 16), extDIEnumDevices, (void **)&pDIEnumDevices, "EnumDevices(I)"); - SetHook((void *)(**(DWORD **)ppvout + 36), extDICreateDeviceEx, (void **)pDICreateDeviceEx, "DICreateDeviceEx(I)"); + if(dwversion > 700) + SetHook((void *)(**(DWORD **)ppvout + 36), extDICreateDeviceEx, (void **)&pDICreateDeviceEx, "DICreateDeviceEx(I)"); return 0; } @@ -139,7 +147,7 @@ HRESULT WINAPI extQueryInterfaceI(void * lpdi, REFIID riid, LPVOID *obp) switch(riid.Data1){ case 0x5944E662: //DirectInput2A case 0x5944E663: //DirectInput2W - SetHook((void *)(**(DWORD **)obp + 12), extDICreateDevice, (void **)pDICreateDevice, "CreateDevice(I)"); + SetHook((void *)(**(DWORD **)obp + 12), extDICreateDevice, (void **)&pDICreateDevice, "CreateDevice(I)"); SetHook((void *)(**(DWORD **)obp + 16), extDIEnumDevices, (void **)&pDIEnumDevices, "EnumDevices(I)"); break; } diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index cece195747bca7b34df76ede85c5c227bef4f487..547bfedc0001378e3ad61509fa75ae807d781782 100644 GIT binary patch literal 122368 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⋙I<(YRgadmCZ<_u30@Zo@1&hpK`7r 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 delta 27724 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 d3d9.dll\n", sSourcePath); + OutTraceD3D("HookInit: copy %s -> d3d9.dll\n", sSourcePath); CopyFile(sSourcePath, "d3d9.dll", FALSE); } @@ -198,7 +198,7 @@ void WINAPI voidDebugSetMute(void) BOOL WINAPI voidDisableD3DSpy(void) { - OutTraceD3D("DisableD3DSpy: SUPPRESSED\n"); + OutTraceDW("DisableD3DSpy: SUPPRESSED\n"); return FALSE; } @@ -512,7 +512,7 @@ void* WINAPI extDirect3DCreate8(UINT sdkversion) OutTraceD3D("Direct3DCreate8: sdkversion=%x\n", sdkversion); lpd3d = (*pDirect3DCreate8)(sdkversion); if(!lpd3d) { - OutTraceD3D("Direct3DCreate8: ERROR err=%d\n", GetLastError()); + OutTraceE("Direct3DCreate8: ERROR err=%d\n", GetLastError()); return 0; } dwD3DVersion = 8; @@ -534,7 +534,7 @@ void* WINAPI extDirect3DCreate9(UINT sdkversion) OutTraceD3D("Direct3DCreate9: sdkversion=%x\n", sdkversion); lpd3d = (*pDirect3DCreate9)(sdkversion); if(!lpd3d) { - OutTraceD3D("Direct3DCreate9: ERROR err=%d\n", GetLastError()); + OutTraceE("Direct3DCreate9: ERROR err=%d\n", GetLastError()); return 0; } @@ -558,7 +558,7 @@ HRESULT WINAPI extDirect3DCreate9Ex(UINT sdkversion, IDirect3D9Ex **ppD3D) OutTraceD3D("Direct3DCreate9Ex: sdkversion=%x\n", sdkversion); res = (*pDirect3DCreate9Ex)(sdkversion, ppD3D); if(res) { - OutTraceD3D("Direct3DCreate9Ex: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + OutTraceE("Direct3DCreate9Ex: ERROR res=%x(%s)\n", res, ExplainDDError(res)); return res; } dwD3DVersion = 9; @@ -578,7 +578,7 @@ UINT WINAPI extGetAdapterCount8(void *lpd3d) { UINT res; res=(*pGetAdapterCount8)(lpd3d); - OutTraceDW("GetAdapterCount(8): count=%d\n", res); + OutTraceD3D("GetAdapterCount(8): count=%d\n", res); if(dxw.dwFlags2 & HIDEMULTIMONITOR) { OutTraceDW("GetAdapterCount: HIDEMULTIMONITOR count=1\n"); res=1; @@ -590,7 +590,7 @@ UINT WINAPI extGetAdapterCount9(void *lpd3d) { UINT res; res=(*pGetAdapterCount9)(lpd3d); - OutTraceDW("GetAdapterCount(9): count=%d\n", res); + OutTraceD3D("GetAdapterCount(9): count=%d\n", res); if(dxw.dwFlags2 & HIDEMULTIMONITOR) { OutTraceDW("GetAdapterCount: HIDEMULTIMONITOR count=1\n"); res=1; @@ -638,13 +638,17 @@ HRESULT WINAPI extGetDisplayMode8(void *lpd3d, D3DDISPLAYMODE *pMode) { HRESULT res; res=(*pGetDisplayMode8)(lpd3d, pMode); - OutTraceD3D("DEBUG: GetDisplayMode(8): size=(%dx%d) RefreshRate=%d Format=%d\n", + OutTraceD3D("GetDisplayMode(8): size=(%dx%d) RefreshRate=%d Format=%d\n", pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format); if(dxw.dwFlags2 & KEEPASPECTRATIO){ pMode->Width=dxw.iSizX; pMode->Height=dxw.iSizY; - OutTraceD3D("DEBUG: GetDisplayMode(8): fixed size=(%dx%d)\n", pMode->Width, pMode->Height); } + else{ + pMode->Width = dxw.GetScreenWidth(); + pMode->Height = dxw.GetScreenHeight(); + } + OutTraceDW("GetDisplayMode(8): fixed size=(%dx%d)\n", pMode->Width, pMode->Height); return res; } @@ -652,13 +656,17 @@ HRESULT WINAPI extGetDisplayMode9(void *lpd3d, UINT iSwapChain, D3DDISPLAYMODE * { HRESULT res; res=(*pGetDisplayMode9)(lpd3d, iSwapChain, pMode); - OutTraceD3D("DEBUG: GetDisplayMode(9): SwapChain=%d size=(%dx%d) RefreshRate=%d Format=%d\n", + OutTraceD3D("GetDisplayMode(9): SwapChain=%d size=(%dx%d) RefreshRate=%d Format=%d\n", iSwapChain, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format); if(dxw.dwFlags2 & KEEPASPECTRATIO){ pMode->Width=dxw.iSizX; pMode->Height=dxw.iSizY; - OutTraceD3D("DEBUG: GetDisplayMode(9): fixed size=(%dx%d)\n", pMode->Width, pMode->Height); } + else{ + pMode->Width = dxw.GetScreenWidth(); + pMode->Height = dxw.GetScreenHeight(); + } + OutTraceDW("GetDisplayMode(9): fixed size=(%dx%d)\n", pMode->Width, pMode->Height); return res; } @@ -684,13 +692,17 @@ HRESULT WINAPI extGetAdapterDisplayMode8(void *lpd3d, UINT Adapter, D3DDISPLAYMO { HRESULT res; res=(*pGetAdapterDisplayMode8)(lpd3d, Adapter, pMode); - OutTraceD3D("DEBUG: GetAdapterDisplayMode(8): size=(%dx%d) RefreshRate=%d Format=%d\n", + OutTraceD3D("GetAdapterDisplayMode(8): size=(%dx%d) RefreshRate=%d Format=%d\n", pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format); if(dxw.dwFlags2 & KEEPASPECTRATIO){ pMode->Width=dxw.iSizX; pMode->Height=dxw.iSizY; - OutTraceDW("DEBUG: GetAdapterDisplayMode(8): fixed size=(%dx%d)\n", pMode->Width, pMode->Height); } + else{ + pMode->Width = dxw.GetScreenWidth(); + pMode->Height = dxw.GetScreenHeight(); + } + OutTraceDW("GetAdapterDisplayMode(8): fixed size=(%dx%d)\n", pMode->Width, pMode->Height); return res; } @@ -698,13 +710,17 @@ HRESULT WINAPI extGetAdapterDisplayMode9(void *lpd3d, UINT Adapter, D3DDISPLAYMO { HRESULT res; res=(*pGetAdapterDisplayMode9)(lpd3d, Adapter, pMode); - OutTraceD3D("DEBUG: GetAdapterDisplayMode(9): size=(%dx%d) RefreshRate=%d Format=%d\n", + OutTraceD3D("GetAdapterDisplayMode(9): size=(%dx%d) RefreshRate=%d Format=%d\n", pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format); if(dxw.dwFlags2 & KEEPASPECTRATIO){ pMode->Width=dxw.iSizX; pMode->Height=dxw.iSizY; - OutTraceDW("DEBUG: GetAdapterDisplayMode(9): fixed size=(%dx%d)\n", pMode->Width, pMode->Height); } + else{ + pMode->Width = dxw.GetScreenWidth(); + pMode->Height = dxw.GetScreenHeight(); + } + OutTraceDW("GetAdapterDisplayMode(9): fixed size=(%dx%d)\n", pMode->Width, pMode->Height); return res; } @@ -726,7 +742,7 @@ HRESULT WINAPI extGetAdapterDisplayMode9(void *lpd3d, UINT Adapter, D3DDISPLAYMO //} HRESULT WINAPI extProbe(void *lpd3dd) { - OutTrace("Probe: %x\n", lpd3dd); + OutTraceD3D("Probe: d3dd=%x\n", lpd3dd); return 0; } @@ -762,7 +778,7 @@ HRESULT WINAPI extCreateDevice(void *lpd3d, UINT adapter, D3DDEVTYPE devicetype, OutTraceDW("CreateDevice: updated hfocuswindow=%x pos=(%d,%d) size=(%d,%d)\n", hfocuswindow, workarea.left, workarea.top, workarea.right-workarea.left, workarea.bottom-workarea.top); else - OutTraceDW("CreateDevice: CreateWindowEx ERROR err=%d\n", GetLastError()); + OutTraceE("CreateDevice: CreateWindowEx ERROR err=%d\n", GetLastError()); dxw.SethWnd(hfocuswindow, dxw.GethWnd()); } @@ -848,6 +864,9 @@ HRESULT WINAPI extCreateDeviceEx(void *lpd3d, UINT adapter, D3DDEVTYPE devicetyp D3DDISPLAYMODE mode; int Windowed; + OutTraceD3D("CreateDeviceEx: D3DVersion=%d lpd3d=%x adapter=%x hFocusWnd=%x behavior=%x, size=(%d,%d)\n", + dwD3DVersion, lpd3d, adapter, hfocuswindow, behaviorflags, ppresentparam->BackBufferWidth, ppresentparam->BackBufferHeight); + memcpy(param, ppresentparam, 56); dxw.SethWnd(hfocuswindow); dxw.SetScreenSize(param[0], param[1]); @@ -947,6 +966,8 @@ HRESULT WINAPI extCreateAdditionalSwapChain(void *lpd3d, D3DPRESENT_PARAMETERS * D3DDISPLAYMODE mode; int Windowed; + OutTraceD3D("CreateAdditionalSwapChain: d3d=%x\n", lpd3d); + memcpy(param, pPresentationParameters, (dwD3DVersion == 9)?56:52); dxw.SetScreenSize(param[0], param[1]); AdjustWindowFrame(dxw.GethWnd(), dxw.GetScreenWidth(), dxw.GetScreenHeight()); @@ -1103,7 +1124,7 @@ HRESULT WINAPI extD3D11CreateDevice( //return 0x887a0004; res=(*pD3D11CreateDevice)(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext); if(res){ - OutTraceD3D("D3D11CreateDevice: ret=%x\n", res); + OutTraceE("D3D11CreateDevice: ret=%x\n", res); return res; } SetHook((void *)(*(DWORD *)ppImmediateContext + 148), extRSSetViewports, (void **)&pRSSetViewports, "RSSetViewports(D11)"); diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp index 5824da9..50d38aa 100644 --- a/dll/hd3d7.cpp +++ b/dll/hd3d7.cpp @@ -8,9 +8,8 @@ // exported API -DWORD gD3DVersion; // quick & dirty .... -//#undef OutTraceDW -//#define OutTraceDW OutTrace +//#undef OutTraceD3D +//#define OutTraceD3D OutTrace typedef HRESULT (WINAPI *Direct3DCreateDevice_Type)(GUID FAR *, LPDIRECT3D, LPDIRECTDRAWSURFACE, LPDIRECT3D *, LPUNKNOWN); typedef HRESULT (WINAPI *Direct3DCreate_Type)(UINT, LPDIRECT3D *, LPUNKNOWN); @@ -21,68 +20,125 @@ Direct3DCreate_Type pDirect3DCreate = NULL; HRESULT WINAPI extDirect3DCreateDevice(GUID FAR *, LPDIRECT3D, LPDIRECTDRAWSURFACE, LPDIRECT3D *, LPUNKNOWN); HRESULT WINAPI extDirect3DCreate(UINT, LPDIRECT3D *, LPUNKNOWN); -// IDirect3D interfaces +// IDirect3D-n interfaces +typedef HRESULT (WINAPI *QueryInterfaceD3_Type)(void *, REFIID, LPVOID *); typedef HRESULT (WINAPI *Initialize_Type)(void *); typedef HRESULT (WINAPI *EnumDevices_Type)(void *, LPD3DENUMDEVICESCALLBACK, LPVOID); +typedef HRESULT (WINAPI *EnumDevices7_Type)(void *, LPD3DENUMDEVICESCALLBACK7, LPVOID); typedef HRESULT (WINAPI *CreateLight_Type)(void *, LPDIRECT3DLIGHT *, IUnknown *); typedef HRESULT (WINAPI *CreateMaterial_Type)(void *, LPDIRECT3DMATERIAL *, IUnknown *); -typedef HRESULT (WINAPI *CreateViewport_Type)(void *, LPDIRECT3DVIEWPORT *, IUnknown *); +typedef HRESULT (WINAPI *CreateViewport1_Type)(void *, LPDIRECT3DVIEWPORT *, IUnknown *); +typedef HRESULT (WINAPI *CreateViewport2_Type)(void *, LPDIRECT3DVIEWPORT2 *, IUnknown *); +typedef HRESULT (WINAPI *CreateViewport3_Type)(void *, LPDIRECT3DVIEWPORT3 *, IUnknown *); typedef HRESULT (WINAPI *FindDevice_Type)(void *, LPD3DFINDDEVICESEARCH, LPD3DFINDDEVICERESULT); typedef HRESULT (WINAPI *CreateDevice2_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE, LPDIRECT3DDEVICE2 *); typedef HRESULT (WINAPI *CreateDevice3_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE4, LPDIRECT3DDEVICE3 *, LPUNKNOWN); +typedef HRESULT (WINAPI *CreateDevice7_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE7, LPDIRECT3DDEVICE7 *); -typedef HRESULT (WINAPI *InitializeVP_Type)(void *, LPDIRECT3D); -typedef HRESULT (WINAPI *SetViewport_Type)(void *, LPD3DVIEWPORT); -typedef HRESULT (WINAPI *GetViewport_Type)(void *, LPD3DVIEWPORT); -typedef HRESULT (WINAPI *QueryInterfaceD3_Type)(void *, REFIID, LPVOID *); - -typedef HRESULT (WINAPI *D3DInitialize_Type)(void *, LPDIRECT3D , LPGUID, LPD3DDEVICEDESC); -typedef HRESULT (WINAPI *D3DGetCaps_Type)(void *, LPD3DDEVICEDESC ,LPD3DDEVICEDESC); - -typedef HRESULT (WINAPI *SetRenderState3_Type)(void *, D3DRENDERSTATETYPE, DWORD); -typedef HRESULT (WINAPI *Scene3_Type)(void *); -typedef HRESULT (WINAPI *GetCaps3_Type)(void *, LPD3DDEVICEDESC, LPD3DDEVICEDESC); -typedef HRESULT (WINAPI *SetLightState_Type)(void *, D3DLIGHTSTATETYPE, DWORD); - +QueryInterfaceD3_Type pQueryInterfaceD3 = NULL; Initialize_Type pInitialize = NULL; EnumDevices_Type pEnumDevices = NULL; +EnumDevices7_Type pEnumDevices7 = NULL; CreateLight_Type pCreateLight = NULL; CreateMaterial_Type pCreateMaterial = NULL; -CreateViewport_Type pCreateViewport = NULL; +CreateViewport1_Type pCreateViewport1 = NULL; +CreateViewport2_Type pCreateViewport2 = NULL; +CreateViewport3_Type pCreateViewport3 = NULL; FindDevice_Type pFindDevice = NULL; CreateDevice2_Type pCreateDevice2 = NULL; CreateDevice3_Type pCreateDevice3 = NULL; +CreateDevice7_Type pCreateDevice7 = NULL; -InitializeVP_Type pInitializeVP = NULL; -SetViewport_Type pSetViewport = NULL; -GetViewport_Type pGetViewport = NULL; -QueryInterfaceD3_Type pQueryInterfaceD3 = NULL; +// Direct3DDevice-n interfaces -SetRenderState3_Type pSetRenderState2 = NULL; -SetRenderState3_Type pSetRenderState3 = NULL; +typedef HRESULT (WINAPI *D3DInitialize_Type)(void *, LPDIRECT3D , LPGUID, LPD3DDEVICEDESC); +typedef HRESULT (WINAPI *D3DGetCaps_Type)(void *, LPD3DDEVICEDESC ,LPD3DDEVICEDESC); +typedef HRESULT (WINAPI *D3DGetCaps3_Type)(void *, LPD3DDEVICEDESC, LPD3DDEVICEDESC); +typedef HRESULT (WINAPI *AddViewport1_Type)(void *, LPDIRECT3DVIEWPORT); +typedef HRESULT (WINAPI *AddViewport2_Type)(void *, LPDIRECT3DVIEWPORT2); +typedef HRESULT (WINAPI *AddViewport3_Type)(void *, LPDIRECT3DVIEWPORT3); +typedef HRESULT (WINAPI *Scene3_Type)(void *); // BeginScene, EndScene +typedef HRESULT (WINAPI *SetRenderState3_Type)(void *, D3DRENDERSTATETYPE, DWORD); +typedef HRESULT (WINAPI *GetViewport7_Type)(void *, LPD3DVIEWPORT7); +typedef HRESULT (WINAPI *SetViewport7_Type)(void *, LPD3DVIEWPORT7); +typedef HRESULT (WINAPI *SetLightState_Type)(void *, D3DLIGHTSTATETYPE, DWORD); +typedef HRESULT (WINAPI *GetCurrentViewport2_Type)(void *, LPDIRECT3DVIEWPORT2 *); +typedef HRESULT (WINAPI *SetCurrentViewport2_Type)(void *, LPDIRECT3DVIEWPORT2); +typedef HRESULT (WINAPI *GetCurrentViewport3_Type)(void *, LPDIRECT3DVIEWPORT3 *); +typedef HRESULT (WINAPI *SetCurrentViewport3_Type)(void *, LPDIRECT3DVIEWPORT3); + +D3DInitialize_Type pD3DInitialize = NULL; +D3DGetCaps_Type pD3DGetCaps = NULL; +D3DGetCaps3_Type pGetCaps3 = NULL; +AddViewport1_Type pAddViewport1 = NULL; +AddViewport2_Type pAddViewport2 = NULL; +AddViewport3_Type pAddViewport3 = NULL; Scene3_Type pBeginScene1 = NULL; Scene3_Type pBeginScene2 = NULL; Scene3_Type pBeginScene3 = NULL; Scene3_Type pEndScene1 = NULL; Scene3_Type pEndScene2 = NULL; Scene3_Type pEndScene3 = NULL; - -GetCaps3_Type pGetCaps3 = NULL; - +SetRenderState3_Type pSetRenderState2 = NULL; +SetRenderState3_Type pSetRenderState3 = NULL; +GetViewport7_Type pGetViewport7 = NULL; +SetViewport7_Type pSetViewport7 = NULL; SetLightState_Type pSetLightState3 = NULL; +GetCurrentViewport2_Type pGetCurrentViewport2 = NULL; +SetCurrentViewport2_Type pSetCurrentViewport2 = NULL; +GetCurrentViewport3_Type pGetCurrentViewport3 = NULL; +SetCurrentViewport3_Type pSetCurrentViewport3 = NULL; + +// IDirect3DViewport-n interfaces + +typedef HRESULT (WINAPI *InitializeVP_Type)(void *, LPDIRECT3D); +typedef HRESULT (WINAPI *SetViewport_Type)(void *, LPD3DVIEWPORT); +typedef HRESULT (WINAPI *GetViewport_Type)(void *, LPD3DVIEWPORT); +typedef HRESULT (WINAPI *GetViewport2_Type)(void *, LPD3DVIEWPORT); +typedef HRESULT (WINAPI *SetViewport2_Type)(void *, LPD3DVIEWPORT); +typedef HRESULT (WINAPI *GetViewport3_Type)(void *, LPD3DVIEWPORT); +typedef HRESULT (WINAPI *SetViewport3_Type)(void *, LPD3DVIEWPORT); +typedef HRESULT (WINAPI *GetViewport2_3_Type)(void *, LPD3DVIEWPORT2); +typedef HRESULT (WINAPI *SetViewport2_3_Type)(void *, LPD3DVIEWPORT2); +typedef HRESULT (WINAPI *DeleteViewport1_Type)(void *, LPDIRECT3DVIEWPORT); +typedef HRESULT (WINAPI *NextViewport1_Type)(void *, LPDIRECT3DVIEWPORT, LPDIRECT3DVIEWPORT *, DWORD); +typedef HRESULT (WINAPI *DeleteViewport2_Type)(void *, LPDIRECT3DVIEWPORT2); +typedef HRESULT (WINAPI *NextViewport2_Type)(void *, LPDIRECT3DVIEWPORT2, LPDIRECT3DVIEWPORT2 *, DWORD); + +InitializeVP_Type pInitializeVP = NULL; +SetViewport_Type pSetViewport = NULL; +GetViewport_Type pGetViewport = NULL; +GetViewport2_Type pGetViewport2 = NULL; +SetViewport2_Type pSetViewport2 = NULL; +GetViewport2_3_Type pGetViewport2_3 = NULL; +SetViewport2_3_Type pSetViewport2_3 = NULL; +GetViewport3_Type pGetViewport3 = NULL; +SetViewport3_Type pSetViewport3 = NULL; +DeleteViewport1_Type pDeleteViewport1 = NULL; +NextViewport1_Type pNextViewport1 = NULL; +DeleteViewport2_Type pDeleteViewport2 = NULL; +NextViewport2_Type pNextViewport2 = NULL; + + -D3DInitialize_Type pD3DInitialize = NULL; -D3DGetCaps_Type pD3DGetCaps = NULL; HRESULT WINAPI extInitialize(void *); HRESULT WINAPI extEnumDevices(void *, LPD3DENUMDEVICESCALLBACK, LPVOID); +HRESULT WINAPI extEnumDevices7(void *, LPD3DENUMDEVICESCALLBACK7, LPVOID); HRESULT WINAPI extCreateLight(void *, LPDIRECT3DLIGHT *, IUnknown *); HRESULT WINAPI extCreateMaterial(void *, LPDIRECT3DMATERIAL *, IUnknown *); -HRESULT WINAPI extCreateViewport(void *, LPDIRECT3DVIEWPORT *, IUnknown *); +HRESULT WINAPI extCreateViewport1(void *, LPDIRECT3DVIEWPORT *, IUnknown *); +HRESULT WINAPI extCreateViewport2(void *, LPDIRECT3DVIEWPORT2 *, IUnknown *); +HRESULT WINAPI extCreateViewport3(void *, LPDIRECT3DVIEWPORT3 *, IUnknown *); HRESULT WINAPI extFindDevice(void *, LPD3DFINDDEVICESEARCH, LPD3DFINDDEVICERESULT); HRESULT WINAPI extCreateDevice2(void *, REFCLSID, LPDIRECTDRAWSURFACE, LPDIRECT3DDEVICE2 *); HRESULT WINAPI extCreateDevice3(void *, REFCLSID, LPDIRECTDRAWSURFACE4, LPDIRECT3DDEVICE3 *, LPUNKNOWN); +HRESULT WINAPI extCreateDevice7(void *, REFCLSID, LPDIRECTDRAWSURFACE7, LPDIRECT3DDEVICE7 *); +HRESULT WINAPI extDeleteViewport1(void *, LPDIRECT3DVIEWPORT); +HRESULT WINAPI extNextViewport1(void *, LPDIRECT3DVIEWPORT, LPDIRECT3DVIEWPORT *, DWORD); +HRESULT WINAPI extDeleteViewport2(void *, LPDIRECT3DVIEWPORT2); +HRESULT WINAPI extNextViewport2(void *, LPDIRECT3DVIEWPORT2, LPDIRECT3DVIEWPORT2 *, DWORD); HRESULT WINAPI extInitializeVP(void *, LPDIRECT3D); HRESULT WINAPI extSetViewport(void *, LPD3DVIEWPORT); @@ -102,6 +158,21 @@ HRESULT WINAPI extBeginScene3(void *); HRESULT WINAPI extEndScene3(void *); HRESULT WINAPI extGetCaps3(void *, LPD3DDEVICEDESC, LPD3DDEVICEDESC); HRESULT WINAPI extSetLightState3(void *d3dd, D3DLIGHTSTATETYPE d3dls, DWORD t); +HRESULT WINAPI extSetViewport3(void *, LPD3DVIEWPORT); +HRESULT WINAPI extGetViewport3(void *, LPD3DVIEWPORT); +HRESULT WINAPI extAddViewport1(void *, LPDIRECT3DVIEWPORT); +HRESULT WINAPI extAddViewport2(void *, LPDIRECT3DVIEWPORT2); +HRESULT WINAPI extAddViewport3(void *, LPDIRECT3DVIEWPORT3); +HRESULT WINAPI extGetViewport2(void *, LPD3DVIEWPORT); +HRESULT WINAPI extSetViewport2(void *, LPD3DVIEWPORT); +HRESULT WINAPI extGetViewport2_3(void *, LPD3DVIEWPORT2); +HRESULT WINAPI extSetViewport2_3(void *, LPD3DVIEWPORT2); +HRESULT WINAPI extSetCurrentViewport2(void *, LPDIRECT3DVIEWPORT2); +HRESULT WINAPI extGetCurrentViewport2(void *, LPDIRECT3DVIEWPORT2 *); +HRESULT WINAPI extSetCurrentViewport3(void *, LPDIRECT3DVIEWPORT3); +HRESULT WINAPI extGetCurrentViewport3(void *, LPDIRECT3DVIEWPORT3 *); +HRESULT WINAPI extSetViewport7(void *, LPD3DVIEWPORT7); +HRESULT WINAPI extGetViewport7(void *, LPD3DVIEWPORT7); extern char *ExplainDDError(DWORD); @@ -111,8 +182,6 @@ int HookDirect3D7(HMODULE module, int version){ LPDIRECT3D lpd3d=NULL; HRESULT res; - gD3DVersion = version; - switch(version){ case 0: case 1: @@ -153,18 +222,131 @@ FARPROC Remap_d3d7_ProcAddress(LPCSTR proc, HMODULE hModule) { if (!strcmp(proc,"Direct3DCreate") && !pDirect3DCreate){ pDirect3DCreate=(Direct3DCreate_Type)(*pGetProcAddress)(hModule, proc); - OutTraceDW("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), pDirect3DCreate); + OutTraceD3D("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), pDirect3DCreate); return (FARPROC)extDirect3DCreate; } if (!strcmp(proc,"Direct3DCreateDevice") && !pDirect3DCreateDevice){ pDirect3DCreateDevice=(Direct3DCreateDevice_Type)(*pGetProcAddress)(hModule, proc); - OutTraceDW("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), pDirect3DCreateDevice); + OutTraceD3D("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), pDirect3DCreateDevice); return (FARPROC)extDirect3DCreateDevice; } // NULL -> keep the original call address return NULL; } +void HookDirect3DSession(LPDIRECTDRAW *lplpdd, int d3dversion) +{ + OutTraceD3D("HookDirect3DSession: d3d=%x d3dversion=%d\n", *lplpdd, d3dversion); + + switch(d3dversion){ + case 1: + SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)"); + SetHook((void *)(**(DWORD **)lplpdd + 12), extInitialize, (void **)&pInitialize, "Initialize(1)"); + SetHook((void *)(**(DWORD **)lplpdd + 16), extEnumDevices, (void **)&pEnumDevices, "EnumDevices"); + SetHook((void *)(**(DWORD **)lplpdd + 20), extCreateLight, (void **)&pCreateLight, "CreateLight"); + SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); + SetHook((void *)(**(DWORD **)lplpdd + 28), extCreateViewport1, (void **)&pCreateViewport1, "CreateViewport(1)"); + SetHook((void *)(**(DWORD **)lplpdd + 32), extFindDevice, (void **)&pFindDevice, "FindDevice"); + break; + case 2: + SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)"); + SetHook((void *)(**(DWORD **)lplpdd + 12), extEnumDevices, (void **)&pEnumDevices, "EnumDevices(2)"); + SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateLight, (void **)&pCreateLight, "CreateLight"); + SetHook((void *)(**(DWORD **)lplpdd + 20), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); + SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateViewport2, (void **)&pCreateViewport2, "CreateViewport(2)"); + SetHook((void *)(**(DWORD **)lplpdd + 28), extFindDevice, (void **)&pFindDevice, "FindDevice"); + SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice2, (void **)&pCreateDevice2, "CreateDevice(D3D2)"); + break; + case 3: + SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)"); + SetHook((void *)(**(DWORD **)lplpdd + 12), extEnumDevices, (void **)&pEnumDevices, "EnumDevices(3)"); + SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateLight, (void **)&pCreateLight, "CreateLight"); + SetHook((void *)(**(DWORD **)lplpdd + 20), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); + SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateViewport3, (void **)&pCreateViewport3, "CreateViewport(3)"); + SetHook((void *)(**(DWORD **)lplpdd + 28), extFindDevice, (void **)&pFindDevice, "FindDevice"); + SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice3, (void **)&pCreateDevice3, "CreateDevice(D3D3)"); + break; + case 7: + SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)"); + SetHook((void *)(**(DWORD **)lplpdd + 12), extEnumDevices7, (void **)&pEnumDevices7, "EnumDevices(7)"); + SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice7, (void **)&pCreateDevice7, "CreateDevice(D3D7)"); + break; + } +} + + +void HookDirect3DDevice(void **lpd3ddev, int d3dversion) +{ + OutTraceD3D("HookDirect3DDevice: d3ddev=%x d3dversion=%d\n", lpd3ddev, d3dversion); + + switch(d3dversion){ + case 1: + //SetHook((void *)(**(DWORD **)lpd3ddev + 16), extGetCaps1, (void **)&pGetCaps1, "GetCaps(1)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 36), extAddViewport1, (void **)&pAddViewport1, "AddViewport(1)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 40), extDeleteViewport1, (void **)&pDeleteViewport1, "DeleteViewport(1)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 44), extNextViewport1, (void **)&pNextViewport1, "NextViewport(1)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 76), extBeginScene1, (void **)&pBeginScene1, "BeginScene(1)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 80), extEndScene1, (void **)&pEndScene1, "EndScene(1)"); + break; + case 2: + //SetHook((void *)(**(DWORD **)lpd3ddev + 12), extGetCaps2, (void **)&pGetCaps2, "GetCaps(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 24), extAddViewport2, (void **)&pAddViewport2, "AddViewport(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 28), extDeleteViewport2, (void **)&pDeleteViewport2, "DeleteViewport(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 32), extNextViewport2, (void **)&pNextViewport2, "NextViewport(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 40), extBeginScene2, (void **)&pBeginScene2, "BeginScene(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 44), extEndScene2, (void **)&pEndScene2, "EndScene(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 52), extSetCurrentViewport2, (void **)&pSetCurrentViewport2, "SetCurrentViewport(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 56), extGetCurrentViewport2, (void **)&pGetCurrentViewport2, "GetCurrentViewport(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 92), extSetRenderState2, (void **)&pSetRenderState2, "SetRenderState(2)"); + if(pSetRenderState2){ + if(dxw.dwFlags2 & WIREFRAME)(*pSetRenderState2)(*lpd3ddev, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); + if(dxw.dwFlags4 & DISABLEFOGGING) (*pSetRenderState2)(*lpd3ddev, D3DRENDERSTATE_FOGENABLE, FALSE); + } + break; + case 3: + SetHook((void *)(**(DWORD **)lpd3ddev + 12), extGetCaps3, (void **)&pGetCaps3, "GetCaps(3)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 20), extAddViewport3, (void **)&pAddViewport3, "AddViewport(3)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 36), extBeginScene3, (void **)&pBeginScene3, "BeginScene(3)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 40), extEndScene3, (void **)&pEndScene3, "EndScene(3)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 48), extSetCurrentViewport3, (void **)&pSetCurrentViewport3, "SetCurrentViewport(3)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 52), extGetCurrentViewport3, (void **)&pGetCurrentViewport3, "GetCurrentViewport(3)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 88), extSetRenderState3, (void **)&pSetRenderState3, "SetRenderState(3)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 96), extSetLightState3, (void **)&pSetLightState3, "SetLightState(3)"); + if(pSetRenderState3){ + if(dxw.dwFlags2 & WIREFRAME)(*pSetRenderState3)(*lpd3ddev, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); + if(dxw.dwFlags4 & DISABLEFOGGING) (*pSetRenderState3)(*lpd3ddev, D3DRENDERSTATE_FOGENABLE, FALSE); + } + break; + case 7: + SetHook((void *)(**(DWORD **)lpd3ddev + 52), extSetViewport7, (void **)&pSetViewport7, "SetViewport(7)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 60), extGetViewport7, (void **)&pGetViewport7, "GetViewport(7)"); + break; + } +} + +HRESULT WINAPI extDirect3DCreate(UINT SDKVersion, LPDIRECT3D *lplpd3d, LPUNKNOWN pUnkOuter) +{ + HRESULT res; + UINT d3dversion; + + OutTraceD3D("Direct3DCreate: SDKVersion=%x UnkOuter=%x\n", SDKVersion, pUnkOuter); + res=(*pDirect3DCreate)(SDKVersion, lplpd3d, pUnkOuter); + + if(res) { + OutTraceE("Direct3DCreate ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + + d3dversion = 1; + if(SDKVersion >= 0x0500) d3dversion = 2; + if(SDKVersion >= 0x0600) d3dversion = 3; + if(SDKVersion >= 0x0700) d3dversion = 7; + + HookDirect3DSession((LPDIRECTDRAW *)lplpd3d, d3dversion); + OutTraceD3D("Direct3DCreate: d3d=%x\n", *lplpd3d); + return res; +} + HRESULT WINAPI extDirect3DCreateDevice(GUID FAR *lpGUID, LPDIRECT3D lpd3ddevice, LPDIRECTDRAWSURFACE surf, LPDIRECT3D *lplpd3ddevice, LPUNKNOWN pUnkOuter) { HRESULT res; @@ -174,112 +356,49 @@ HRESULT WINAPI extDirect3DCreateDevice(GUID FAR *lpGUID, LPDIRECT3D lpd3ddevice, res=(*pDirect3DCreateDevice)(lpGUID, lpd3ddevice, surf, lplpd3ddevice, pUnkOuter); if(res) OutTraceE("Direct3DCreateDevice ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); else OutTraceD3D("Direct3DCreateDevice: d3ddevice=%x\n", *lplpd3ddevice); + + switch(lpGUID->Data1){ + case 0x64108800: // IID_IDirect3DDevice + HookDirect3DDevice((void **)lplpd3ddevice, 1); + break; + case 0x93281501: // IID_IDirect3DDevice2 + HookDirect3DDevice((void **)lplpd3ddevice, 2); + break; + case 0xb0ab3b60: // IID_IDirect3DDevice3 + HookDirect3DDevice((void **)lplpd3ddevice, 3); + break; + case 0xf5049e79: // IID_IDirect3DDevice7 + HookDirect3DDevice((void **)lplpd3ddevice, 7); + break; + } return res; } -void HookDirect3DSession(LPDIRECTDRAW *lplpdd, int dxversion) +void HookViewport(LPDIRECT3DVIEWPORT *lpViewport, int d3dversion) { - OutTraceDW("HookDirect3DSession: d3d=%x d3dversion=%d\n", *lplpdd, dxversion); + OutTraceD3D("HookViewport: Viewport=%x d3dversion=%d\n", *lpViewport, d3dversion); - gD3DVersion = dxversion; - - switch(dxversion){ + switch(d3dversion){ case 1: - SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)"); - SetHook((void *)(**(DWORD **)lplpdd + 12), extInitialize, (void **)&pInitialize, "Initialize"); - SetHook((void *)(**(DWORD **)lplpdd + 16), extEnumDevices, (void **)&pEnumDevices, "EnumDevices"); - SetHook((void *)(**(DWORD **)lplpdd + 20), extCreateLight, (void **)&pCreateLight, "CreateLight"); - SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); - SetHook((void *)(**(DWORD **)lplpdd + 28), extCreateViewport, (void **)&pCreateViewport, "CreateViewport"); - SetHook((void *)(**(DWORD **)lplpdd + 32), extFindDevice, (void **)&pFindDevice, "FindDevice"); - break; - case 5: - SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)"); - SetHook((void *)(**(DWORD **)lplpdd + 12), extEnumDevices, (void **)&pEnumDevices, "EnumDevices"); - SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateLight, (void **)&pCreateLight, "CreateLight"); - SetHook((void *)(**(DWORD **)lplpdd + 20), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); - SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateViewport, (void **)&pCreateViewport, "CreateViewport"); - SetHook((void *)(**(DWORD **)lplpdd + 28), extFindDevice, (void **)&pFindDevice, "FindDevice"); - SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice2, (void **)&pCreateDevice2, "CreateDevice(D3D2)"); - break; - case 6: - SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)"); - SetHook((void *)(**(DWORD **)lplpdd + 12), extEnumDevices, (void **)&pEnumDevices, "EnumDevices"); - SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateLight, (void **)&pCreateLight, "CreateLight"); - SetHook((void *)(**(DWORD **)lplpdd + 20), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); - SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateViewport, (void **)&pCreateViewport, "CreateViewport"); - SetHook((void *)(**(DWORD **)lplpdd + 28), extFindDevice, (void **)&pFindDevice, "FindDevice"); - SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice3, (void **)&pCreateDevice3, "CreateDevice(D3D3)"); - break; - } -} - - -void HookDirect3DDevice(void **lpd3ddev, int dxversion) -{ - OutTraceDW("HookDirect3DDevice: d3ddev=%x d3dversion=%d\n", lpd3ddev, dxversion); - - gD3DVersion = dxversion; - - switch(dxversion){ - case 1: - //SetHook((void *)(**(DWORD **)lpd3ddev + 16), extGetCaps1, (void **)&pGetCaps1, "GetCaps(1)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 76), extBeginScene1, (void **)&pBeginScene1, "BeginScene(1)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 80), extEndScene1, (void **)&pEndScene1, "EndScene(1)"); + SetHook((void *)(**(DWORD **)lpViewport + 12), extInitializeVP, (void **)&pInitializeVP, "Initialize(VP1)"); + SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport, (void **)&pGetViewport, "GetViewport(1)"); + SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport, (void **)&pSetViewport, "SetViewport(1)"); break; case 2: - //SetHook((void *)(**(DWORD **)lpd3ddev + 12), extGetCaps2, (void **)&pGetCaps2, "GetCaps(2)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 40), extBeginScene2, (void **)&pBeginScene2, "BeginScene(2)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 44), extEndScene2, (void **)&pEndScene2, "EndScene(2)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 92), extSetRenderState2, (void **)&pSetRenderState2, "SetRenderState(2)"); - if(pSetRenderState2){ - if(dxw.dwFlags2 & WIREFRAME)(*pSetRenderState2)(*lpd3ddev, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); - if(dxw.dwFlags4 & DISABLEFOGGING) (*pSetRenderState2)(*lpd3ddev, D3DRENDERSTATE_FOGENABLE, FALSE); - } + SetHook((void *)(**(DWORD **)lpViewport + 12), extInitializeVP, (void **)&pInitializeVP, "Initialize(VP2)"); + SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport, (void **)&pGetViewport, "GetViewport(2)"); + SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport, (void **)&pSetViewport, "SetViewport(2)"); + SetHook((void *)(**(DWORD **)lpViewport + 64), extGetViewport2_3, (void **)&pGetViewport2_3, "GetViewport2(2)"); + SetHook((void *)(**(DWORD **)lpViewport + 68), extSetViewport2_3, (void **)&pSetViewport2_3, "SetViewport2(2)"); break; case 3: - SetHook((void *)(**(DWORD **)lpd3ddev + 12), extGetCaps3, (void **)&pGetCaps3, "GetCaps(3)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 36), extBeginScene3, (void **)&pBeginScene3, "BeginScene(3)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 40), extEndScene3, (void **)&pEndScene3, "EndScene(3)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 88), extSetRenderState3, (void **)&pSetRenderState3, "SetRenderState(3)"); - SetHook((void *)(**(DWORD **)lpd3ddev + 96), extSetLightState3, (void **)&pSetLightState3, "SetLightState(3)"); - if(pSetRenderState3){ - if(dxw.dwFlags2 & WIREFRAME)(*pSetRenderState3)(*lpd3ddev, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); - if(dxw.dwFlags4 & DISABLEFOGGING) (*pSetRenderState3)(*lpd3ddev, D3DRENDERSTATE_FOGENABLE, FALSE); - } + SetHook((void *)(**(DWORD **)lpViewport + 12), extInitializeVP, (void **)&pInitializeVP, "Initialize(VP3)"); + SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport, (void **)&pGetViewport, "GetViewport(3)"); + SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport, (void **)&pSetViewport, "SetViewport(3)"); + SetHook((void *)(**(DWORD **)lpViewport + 64), extGetViewport2_3, (void **)&pGetViewport2_3, "GetViewport2(3)"); + SetHook((void *)(**(DWORD **)lpViewport + 68), extSetViewport2_3, (void **)&pSetViewport2_3, "SetViewport2(3)"); break; - } -} - -HRESULT WINAPI extDirect3DCreate(UINT SDKVersion, LPDIRECT3D *lplpd3d, LPUNKNOWN pUnkOuter) -{ - HRESULT res; - - OutTraceD3D("Direct3DCreate: SDKVersion=%x UnkOuter=%x\n", SDKVersion, pUnkOuter); - res=(*pDirect3DCreate)(SDKVersion, lplpd3d, pUnkOuter); - - if(res) { - OutTraceE("Direct3DCreate ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - return res; - } - - HookDirect3DSession((LPDIRECTDRAW *)lplpd3d, SDKVersion); - OutTraceD3D("Direct3DCreate: d3d=%x\n", *lplpd3d); - return res; -} - -void HookViewport(LPDIRECT3DVIEWPORT *lpViewport, int dxversion) -{ - OutTraceDW("HookViewport: Viewport=%x d3dversion=%d\n", *lpViewport, dxversion); - - switch(dxversion){ - case 1: - case 5: - case 6: case 7: - SetHook((void *)(**(DWORD **)lpViewport + 12), extInitializeVP, (void **)&pInitializeVP, "Initialize(VP)"); - SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport, (void **)&pGetViewport, "GetViewport"); - SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport, (void **)&pSetViewport, "SetViewport"); break; } } @@ -294,28 +413,38 @@ HRESULT WINAPI extQueryInterfaceD3(void *lpd3d, REFIID riid, LPVOID *ppvObj) res=(*pQueryInterfaceD3)(lpd3d, riid, ppvObj); switch(riid.Data1){ case 0x3BBA0080: d3dversion=1; break; - case 0x6aae1ec1: d3dversion=5; break; - case 0xbb223240: d3dversion=6; break; + case 0x6aae1ec1: d3dversion=2; break; + case 0xbb223240: d3dversion=3; break; case 0xf5049e77: d3dversion=7; break; } - if(d3dversion) OutTraceDW("QueryInterface(D3): hooking version=%d\n", d3dversion); + if(d3dversion) OutTraceD3D("QueryInterface(D3): hooking version=%d\n", d3dversion); switch(d3dversion){ case 1: SetHook((void *)(**(DWORD **)ppvObj + 12), extInitialize, (void **)&pInitialize, "Initialize"); SetHook((void *)(**(DWORD **)ppvObj + 16), extEnumDevices, (void **)&pEnumDevices, "EnumDevices"); SetHook((void *)(**(DWORD **)ppvObj + 20), extCreateLight, (void **)&pCreateLight, "CreateLight"); SetHook((void *)(**(DWORD **)ppvObj + 24), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); - SetHook((void *)(**(DWORD **)ppvObj + 28), extCreateViewport, (void **)&pCreateViewport, "CreateViewport"); + SetHook((void *)(**(DWORD **)ppvObj + 28), extCreateViewport1, (void **)&pCreateViewport1, "CreateViewport(1)"); SetHook((void *)(**(DWORD **)ppvObj + 32), extFindDevice, (void **)&pFindDevice, "FindDevice"); break; - case 5: - case 6: + case 2: SetHook((void *)(**(DWORD **)ppvObj + 12), extEnumDevices, (void **)&pEnumDevices, "EnumDevices"); SetHook((void *)(**(DWORD **)ppvObj + 16), extCreateLight, (void **)&pCreateLight, "CreateLight"); SetHook((void *)(**(DWORD **)ppvObj + 20), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); - SetHook((void *)(**(DWORD **)ppvObj + 24), extCreateViewport, (void **)&pCreateViewport, "CreateViewport"); + SetHook((void *)(**(DWORD **)ppvObj + 24), extCreateViewport2, (void **)&pCreateViewport2, "CreateViewport(2)"); SetHook((void *)(**(DWORD **)ppvObj + 28), extFindDevice, (void **)&pFindDevice, "FindDevice"); break; + case 3: + SetHook((void *)(**(DWORD **)ppvObj + 12), extEnumDevices, (void **)&pEnumDevices, "EnumDevices"); + SetHook((void *)(**(DWORD **)ppvObj + 16), extCreateLight, (void **)&pCreateLight, "CreateLight"); + SetHook((void *)(**(DWORD **)ppvObj + 20), extCreateMaterial, (void **)&pCreateMaterial, "CreateMaterial"); + SetHook((void *)(**(DWORD **)ppvObj + 24), extCreateViewport3, (void **)&pCreateViewport3, "CreateViewport(3)"); + SetHook((void *)(**(DWORD **)ppvObj + 28), extFindDevice, (void **)&pFindDevice, "FindDevice"); + break; + case 7: + SetHook((void *)(**(DWORD **)ppvObj + 12), extEnumDevices7, (void **)&pEnumDevices7, "EnumDevices(7)"); + SetHook((void *)(**(DWORD **)ppvObj + 32), extCreateDevice7, (void **)&pCreateDevice7, "CreateDevice(D3D7)"); + break; } return res; } @@ -336,29 +465,38 @@ typedef struct { LPVOID arg; } CallbackArg; +typedef struct { + LPD3DENUMDEVICESCALLBACK7 *cb; + LPVOID arg; +} CallbackArg7; + static void DumpD3DDevideDesc(LPD3DDEVICEDESC d3, char *label) { if(IsTraceD3D){ - OutTrace("EnumDevices: CALLBACK dev=%s Size=%d Flags=%x ", label, d3->dwSize, d3->dwFlags); - if(d3->dwFlags & D3DDD_COLORMODEL) OutTrace("ColorModel=%x ", d3->dcmColorModel); - if(d3->dwFlags & D3DDD_DEVCAPS) OutTrace("DevCaps=%x ", d3->dwDevCaps); - if(d3->dwFlags & D3DDD_TRANSFORMCAPS) OutTrace("TransformCaps=%x ", d3->dtcTransformCaps.dwCaps); - if(d3->dwFlags & D3DDD_LIGHTINGCAPS) OutTrace("LightingCaps=%x ", d3->dlcLightingCaps); - if(d3->dwFlags & D3DDD_BCLIPPING) OutTrace("Clipping=%x ", d3->bClipping); - if(d3->dwFlags & D3DDD_LINECAPS) OutTrace("LineCaps=%x ", d3->dpcLineCaps); - if(d3->dwFlags & D3DDD_TRICAPS) OutTrace("TriCaps=%x ", d3->dpcTriCaps); - if(d3->dwFlags & D3DDD_DEVICERENDERBITDEPTH) OutTrace("DeviceRenderBitDepth=%d ", d3->dwDeviceRenderBitDepth); - if(d3->dwFlags & D3DDD_DEVICEZBUFFERBITDEPTH) OutTrace("DeviceZBufferBitDepth=%d ", d3->dwDeviceZBufferBitDepth); - if(d3->dwFlags & D3DDD_MAXBUFFERSIZE) OutTrace("MaxBufferSize=%d ", d3->dwMaxBufferSize); - if(d3->dwFlags & D3DDD_MAXVERTEXCOUNT) OutTrace("MaxVertexCount=%d ", d3->dwMaxVertexCount); - OutTrace("\n"); + if(d3){ + OutTrace("EnumDevices: CALLBACK dev=%s Size=%d Flags=%x ", label, d3->dwSize, d3->dwFlags); + if(d3->dwFlags & D3DDD_COLORMODEL) OutTrace("ColorModel=%x ", d3->dcmColorModel); + if(d3->dwFlags & D3DDD_DEVCAPS) OutTrace("DevCaps=%x ", d3->dwDevCaps); + if(d3->dwFlags & D3DDD_TRANSFORMCAPS) OutTrace("TransformCaps=%x ", d3->dtcTransformCaps.dwCaps); + if(d3->dwFlags & D3DDD_LIGHTINGCAPS) OutTrace("LightingCaps=%x ", d3->dlcLightingCaps); + if(d3->dwFlags & D3DDD_BCLIPPING) OutTrace("Clipping=%x ", d3->bClipping); + if(d3->dwFlags & D3DDD_LINECAPS) OutTrace("LineCaps=%x ", d3->dpcLineCaps); + if(d3->dwFlags & D3DDD_TRICAPS) OutTrace("TriCaps=%x ", d3->dpcTriCaps); + if(d3->dwFlags & D3DDD_DEVICERENDERBITDEPTH) OutTrace("DeviceRenderBitDepth=%d ", d3->dwDeviceRenderBitDepth); + if(d3->dwFlags & D3DDD_DEVICEZBUFFERBITDEPTH) OutTrace("DeviceZBufferBitDepth=%d ", d3->dwDeviceZBufferBitDepth); + if(d3->dwFlags & D3DDD_MAXBUFFERSIZE) OutTrace("MaxBufferSize=%d ", d3->dwMaxBufferSize); + if(d3->dwFlags & D3DDD_MAXVERTEXCOUNT) OutTrace("MaxVertexCount=%d ", d3->dwMaxVertexCount); + OutTrace("\n"); + } + else + OutTrace("EnumDevices: CALLBACK dev=%s ddesc=NULL\n", label); } } HRESULT WINAPI extDeviceProxy(GUID FAR *lpGuid, LPSTR lpDeviceDescription, LPSTR lpDeviceName, LPD3DDEVICEDESC lpd3ddd1, LPD3DDEVICEDESC lpd3ddd2, LPVOID arg) { HRESULT res; - OutTraceDW("EnumDevices: CALLBACK GUID=%x(%s) DeviceDescription=\"%s\", DeviceName=\"%s\", arg=%x\n", lpGuid->Data1, ExplainGUID(lpGuid), lpDeviceDescription, lpDeviceName, ((CallbackArg *)arg)->arg); + OutTraceD3D("EnumDevices: CALLBACK GUID=%x(%s) DeviceDescription=\"%s\", DeviceName=\"%s\", arg=%x\n", lpGuid->Data1, ExplainGUID(lpGuid), lpDeviceDescription, lpDeviceName, ((CallbackArg *)arg)->arg); DumpD3DDevideDesc(lpd3ddd1, "HWDEV"); DumpD3DDevideDesc(lpd3ddd2, "SWDEV"); if(dxw.dwFlags4 & NOPOWER2FIX){ @@ -374,7 +512,26 @@ HRESULT WINAPI extDeviceProxy(GUID FAR *lpGuid, LPSTR lpDeviceDescription, LPSTR else { res = (*(((CallbackArg *)arg)->cb))(lpGuid, lpDeviceDescription, lpDeviceName, lpd3ddd1, lpd3ddd2, ((CallbackArg *)arg)->arg); } - OutTraceDW("EnumDevices: CALLBACK ret=%x\n", res); + OutTraceD3D("EnumDevices: CALLBACK ret=%x\n", res); + return res; +} + +HRESULT WINAPI extDeviceProxy7(LPSTR lpDeviceDescription, LPSTR lpDeviceName, LPD3DDEVICEDESC7 lpd3ddd, LPVOID arg) +{ + HRESULT res; + OutTraceD3D("EnumDevices(D3D7): CALLBACK DeviceDescription=\"%s\", DeviceName=\"%s\", arg=%x\n", lpDeviceDescription, lpDeviceName, ((CallbackArg *)arg)->arg); + DumpD3DDevideDesc((LPD3DDEVICEDESC)lpd3ddd, "DEV"); + if(dxw.dwFlags4 & NOPOWER2FIX){ + D3DDEVICEDESC7 lpd3dddfix; + if(lpd3ddd) memcpy(&lpd3dddfix, lpd3ddd, sizeof(D3DDEVICEDESC7)); + lpd3dddfix.dpcLineCaps.dwTextureCaps|=D3DPTEXTURECAPS_NONPOW2CONDITIONAL|D3DPTEXTURECAPS_POW2; + lpd3dddfix.dpcTriCaps.dwTextureCaps|=D3DPTEXTURECAPS_NONPOW2CONDITIONAL|D3DPTEXTURECAPS_POW2; + res = (*(((CallbackArg7 *)arg)->cb))(lpDeviceDescription, lpDeviceName, lpd3ddd?&lpd3dddfix:NULL, ((CallbackArg7 *)arg)->arg); + } + else { + res = (*(((CallbackArg7 *)arg)->cb))(lpDeviceDescription, lpDeviceName, lpd3ddd, ((CallbackArg7 *)arg)->arg); + } + OutTraceD3D("EnumDevices: CALLBACK ret=%x\n", res); return res; } @@ -392,6 +549,20 @@ HRESULT WINAPI extEnumDevices(void *lpd3d, LPD3DENUMDEVICESCALLBACK cb, LPVOID a return res; } +HRESULT WINAPI extEnumDevices7(void *lpd3d, LPD3DENUMDEVICESCALLBACK7 cb, LPVOID arg) +{ + HRESULT res; + CallbackArg7 Arg; + + OutTraceD3D("EnumDevices: d3d=%x arg=%x\n", lpd3d, arg); + Arg.cb= &cb; + Arg.arg=arg; + res=(*pEnumDevices7)(lpd3d, (LPD3DENUMDEVICESCALLBACK7)extDeviceProxy7, (LPVOID)&Arg); + if(res) OutTraceE("EnumDevices ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("EnumDevices: OK\n"); + return res; +} + HRESULT WINAPI extCreateLight(void *lpd3d, LPDIRECT3DLIGHT *lpLight, IUnknown *p0) { HRESULT res; @@ -414,18 +585,42 @@ HRESULT WINAPI extCreateMaterial(void *lpd3d, LPDIRECT3DMATERIAL *lpMaterial, IU return res; } -HRESULT WINAPI extCreateViewport(void *lpd3d, LPDIRECT3DVIEWPORT *lpViewport, IUnknown *p0) +HRESULT WINAPI extCreateViewport1(void *lpd3d, LPDIRECT3DVIEWPORT *lpViewport, IUnknown *p0) { HRESULT res; - OutTraceD3D("CreateViewport: d3d=%x\n", lpd3d); - res=(*pCreateViewport)(lpd3d, lpViewport, p0); + OutTraceD3D("CreateViewport(1): d3d=%x\n", lpd3d); + res=(*pCreateViewport1)(lpd3d, lpViewport, p0); if(res) OutTraceE("CreateViewport ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); else OutTraceD3D("CreateViewport: Viewport=%x\n", *lpViewport); - HookViewport(lpViewport, gD3DVersion); + HookViewport(lpViewport, 1); return res; } - + +HRESULT WINAPI extCreateViewport2(void *lpd3d, LPDIRECT3DVIEWPORT2 *lpViewport, IUnknown *p0) +{ + HRESULT res; + + OutTraceD3D("CreateViewport(2): d3d=%x\n", lpd3d); + res=(*pCreateViewport2)(lpd3d, lpViewport, p0); + if(res) OutTraceE("CreateViewport(2) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("CreateViewport(2): Viewport=%x\n", *lpViewport); + HookViewport((LPDIRECT3DVIEWPORT *)lpViewport, 2); + return res; +} + +HRESULT WINAPI extCreateViewport3(void *lpd3d, LPDIRECT3DVIEWPORT3 *lpViewport, IUnknown *p0) +{ + HRESULT res; + + OutTraceD3D("CreateViewport(3): d3d=%x\n", lpd3d); + res=(*pCreateViewport3)(lpd3d, lpViewport, p0); + if(res) OutTraceE("CreateViewport(3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("CreateViewport(3): Viewport=%x\n", *lpViewport); + HookViewport((LPDIRECT3DVIEWPORT *)lpViewport, 3); + return res; +} + HRESULT WINAPI extFindDevice(void *lpd3d, LPD3DFINDDEVICESEARCH p1, LPD3DFINDDEVICERESULT p2) { HRESULT res; @@ -447,7 +642,7 @@ HRESULT WINAPI extSetViewport(void *lpvp, LPD3DVIEWPORT vpd) HRESULT res; OutTraceD3D("SetViewport: viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d) scale=(%fx%f) maxXYZ=(%f,%f,%f) minZ=%f\n", - lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwHeight, vpd->dwWidth, vpd->dvScaleX, vpd->dvScaleY, + lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight, vpd->dvScaleX, vpd->dvScaleY, vpd->dvMaxX, vpd->dvMaxY, vpd->dvMaxZ, vpd->dvMinZ); res=(*pSetViewport)(lpvp, vpd); if(res) OutTraceE("SetViewport ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); @@ -463,7 +658,7 @@ HRESULT WINAPI extGetViewport(void *lpvp, LPD3DVIEWPORT vpd) res=(*pGetViewport)(lpvp, vpd); if(res) OutTraceE("GetViewport ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); else OutTraceD3D("GetViewport: OK size=%d pos=(%d,%d) dim=(%dx%d) scale=(%fx%f) maxXYZ=(%f,%f,%f) minZ=%f\n", - vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwHeight, vpd->dwWidth, vpd->dvScaleX, vpd->dvScaleY, + vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight, vpd->dvScaleX, vpd->dvScaleY, vpd->dvMaxX, vpd->dvMaxY, vpd->dvMaxZ, vpd->dvMinZ); return res; } @@ -525,7 +720,23 @@ HRESULT WINAPI extCreateDevice3(void *lpd3d, REFCLSID Guid, LPDIRECTDRAWSURFACE4 return res; } - HookDirect3DDevice((void **)lplpd3dd, 3); + HookDirect3DDevice((void **)lplpd3dd, 3); + + return res; +} + +HRESULT WINAPI extCreateDevice7(void *lpd3d, REFCLSID Guid, LPDIRECTDRAWSURFACE7 lpdds, LPDIRECT3DDEVICE7 *lplpd3dd) +{ + HRESULT res; + + OutTraceD3D("CreateDevice(D3D7): d3d=%x GUID=%x(%s) lpdds=%x\n", lpd3d, Guid.Data1, ExplainGUID((GUID *)&Guid), lpdds); + res=(*pCreateDevice7)(lpd3d, Guid, lpdds, lplpd3dd); + if(res) { + OutTraceE("CreateDevice(D3D7) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + + HookDirect3DDevice((void **)lplpd3dd, 7); return res; } @@ -596,11 +807,11 @@ HRESULT WINAPI extSetRenderState2(void *d3dd, D3DRENDERSTATETYPE State, DWORD Va DWORD OldValue; OldValue = Value; Value = D3DCMP_ALWAYS; - OutTraceDW("SetRenderState: FIXED State=ZFUNC Value=%s->D3DCMP_ALWAYS\n", ExplainRenderstateValue(OldValue)); + OutTraceD3D("SetRenderState: FIXED State=ZFUNC Value=%s->D3DCMP_ALWAYS\n", ExplainRenderstateValue(OldValue)); } if((dxw.dwFlags2 & WIREFRAME) && (State == D3DRENDERSTATE_FILLMODE)){ Value = D3DFILL_WIREFRAME; - OutTraceDW("SetRenderState: FIXED State=FILLMODE Value=D3DFILL_WIREFRAME\n"); + OutTraceD3D("SetRenderState: FIXED State=FILLMODE Value=D3DFILL_WIREFRAME\n"); } res=(*pSetRenderState2)(d3dd, State, Value); if(res) OutTraceE("SetRenderState(2): res=%x(%s)\n", res, ExplainDDError(res)); @@ -615,14 +826,14 @@ HRESULT WINAPI extSetRenderState3(void *d3dd, D3DRENDERSTATETYPE State, DWORD Va DWORD OldValue; OldValue = Value; Value = D3DCMP_ALWAYS; - OutTraceDW("SetRenderState: FIXED State=ZFUNC Value=%s->D3DCMP_ALWAYS\n", ExplainRenderstateValue(OldValue)); + OutTraceD3D("SetRenderState: FIXED State=ZFUNC Value=%s->D3DCMP_ALWAYS\n", ExplainRenderstateValue(OldValue)); } if((dxw.dwFlags2 & WIREFRAME) && (State == D3DRENDERSTATE_FILLMODE)){ Value = D3DFILL_WIREFRAME; - OutTraceDW("SetRenderState: FIXED State=FILLMODE Value=D3DFILL_WIREFRAME\n"); + OutTraceD3D("SetRenderState: FIXED State=FILLMODE Value=D3DFILL_WIREFRAME\n"); } if((dxw.dwFlags4 & DISABLEFOGGING) && (State == D3DRENDERSTATE_FOGENABLE)){ - OutTraceDW("SetRenderState: FIXED State=FOGENABLE Value=FALSE\n"); + OutTraceD3D("SetRenderState: FIXED State=FOGENABLE Value=FALSE\n"); Value = FALSE; } res=(*pSetRenderState3)(d3dd, State, Value); @@ -656,7 +867,7 @@ HRESULT WINAPI extBeginScene2(void *d3dd) d3dRect.y1 = vpd.dwY; d3dRect.x2 = vpd.dwX + vpd.dwWidth; d3dRect.y2 = vpd.dwY + vpd.dwHeight; - OutTraceDW("d3dRect=(%d,%d)-(%d,%d)\n", d3dRect.x1, d3dRect.y1, d3dRect.x2, d3dRect.y2); + OutTraceD3D("d3dRect=(%d,%d)-(%d,%d)\n", d3dRect.x1, d3dRect.y1, d3dRect.x2, d3dRect.y2); vp->Clear(1, &d3dRect, D3DCLEAR_ZBUFFER); } } @@ -682,7 +893,7 @@ HRESULT WINAPI extBeginScene3(void *d3dd) d3dRect.y1 = vpd.dwY; d3dRect.x2 = vpd.dwX + vpd.dwWidth; d3dRect.y2 = vpd.dwY + vpd.dwHeight; - OutTraceDW("d3dRect=(%d,%d)-(%d,%d)\n", d3dRect.x1, d3dRect.y1, d3dRect.x2, d3dRect.y2); + OutTraceD3D("d3dRect=(%d,%d)-(%d,%d)\n", d3dRect.x1, d3dRect.y1, d3dRect.x2, d3dRect.y2); if(dxw.dwFlags4 & ZBUFFERCLEAN )vp->Clear2(1, &d3dRect, D3DCLEAR_ZBUFFER, 0, 1.0, 0); if(dxw.dwFlags4 & ZBUFFER0CLEAN)vp->Clear2(1, &d3dRect, D3DCLEAR_ZBUFFER, 0, 0.0, 0); } @@ -752,3 +963,208 @@ HRESULT WINAPI extSetLightState3(void *d3dd, D3DLIGHTSTATETYPE d3dls, DWORD t) if(res) OutTraceE("SetLightState(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); return res; } + +HRESULT WINAPI extSetViewport2(void *d3dd, LPD3DVIEWPORT lpd3dvp) +{ + HRESULT res; + OutTraceD3D("SetViewport(2): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pSetViewport2)(d3dd, lpd3dvp); + if(res) OutTraceE("SetViewport(2): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extGetViewport2(void *d3dd, LPD3DVIEWPORT lpd3dvp) +{ + HRESULT res; + OutTraceD3D("GetViewport(2): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pGetViewport2)(d3dd, lpd3dvp); + if(res) OutTraceE("GetViewport(2): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extSetViewport3(void *d3dd, LPD3DVIEWPORT lpd3dvp) +{ + HRESULT res; + OutTraceD3D("SetViewport(3): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pSetViewport3)(d3dd, lpd3dvp); + if(res) OutTraceE("SetViewport(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extGetViewport3(void *d3dd, LPD3DVIEWPORT lpd3dvp) +{ + HRESULT res; + OutTraceD3D("GetViewport(3): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pGetViewport3)(d3dd, lpd3dvp); + if(res) OutTraceE("GetViewport(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extSetViewport7(void *d3dd, LPD3DVIEWPORT7 lpd3dvp) +{ + HRESULT res; + OutTraceD3D("SetViewport(7): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pSetViewport7)(d3dd, lpd3dvp); + if(res) OutTraceE("SetViewport(7): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extGetViewport7(void *d3dd, LPD3DVIEWPORT7 lpd3dvp) +{ + HRESULT res; + OutTraceD3D("GetViewport(7): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pGetViewport7)(d3dd, lpd3dvp); + if(res) OutTraceE("GetViewport(7): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extAddViewport1(void *d3dd, LPDIRECT3DVIEWPORT lpd3dvp) +{ + HRESULT res; + OutTraceD3D("AddViewport(1): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pAddViewport1)(d3dd, lpd3dvp); + if(res) { + OutTraceE("AddViewport(1): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; + } + HookViewport(&lpd3dvp, 1); + return res; +} + +HRESULT WINAPI extAddViewport2(void *d3dd, LPDIRECT3DVIEWPORT2 lpd3dvp) +{ + HRESULT res; + OutTraceD3D("AddViewport(2): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pAddViewport2)(d3dd, lpd3dvp); + if(res) { + OutTraceE("AddViewport(2): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; + } + HookViewport((LPDIRECT3DVIEWPORT *)&lpd3dvp, 2); + return res; +} + +HRESULT WINAPI extAddViewport3(void *d3dd, LPDIRECT3DVIEWPORT3 lpd3dvp) +{ + HRESULT res; + OutTraceD3D("AddViewport(3): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); + res=(*pAddViewport3)(d3dd, lpd3dvp); + if(res) { + OutTraceE("AddViewport(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; + } + HookViewport((LPDIRECT3DVIEWPORT *)&lpd3dvp, 3); + return res; +} + +HRESULT WINAPI extSetViewport2_3(void *lpvp, LPD3DVIEWPORT2 vpd) +{ + HRESULT res; + + OutTraceD3D("SetViewport2(VP3): viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d)\n", + lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight); + res=(*pSetViewport2_3)(lpvp, vpd); + if(res) OutTraceE("SetViewport2(VP3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("SetViewport2(VP3): OK\n"); + return res; +} + +HRESULT WINAPI extGetViewport2_3(void *lpvp, LPD3DVIEWPORT2 vpd) +{ + HRESULT res; + + OutTraceD3D("GetViewport2(VP3): viewport=%x viewportd=%x\n", lpvp, vpd); + res=(*pGetViewport2_3)(lpvp, vpd); + if(res) OutTraceE("GetViewport2(VP3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("GetViewport2(VP3): OK size=%d pos=(%d,%d) dim=(%dx%d)\n", + vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight); + return res; +} + +HRESULT WINAPI extGetCurrentViewport2(void *d3dd, LPDIRECT3DVIEWPORT2 *lpd3dvp) +{ + HRESULT res; + OutTraceD3D("GetCurrentViewport(D3DD2): d3dd=%x viewportd=%x\n", d3dd, lpd3dvp); + res=(*pGetCurrentViewport2)(d3dd, lpd3dvp); + if(res) { + OutTraceE("GetCurrentViewport(D3DD2) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + HookViewport((LPDIRECT3DVIEWPORT *)lpd3dvp, 2); + return res; +} + +HRESULT WINAPI extSetCurrentViewport2(void *d3dd, LPDIRECT3DVIEWPORT2 lpd3dvp) +{ + HRESULT res; + + OutTraceD3D("SetCurrentViewport(D3DD2): d3dd=%x viewportd=%x\n", d3dd, lpd3dvp); + res=(*pSetCurrentViewport2)(d3dd, lpd3dvp); + if(res) OutTraceE("SetCurrentViewport(D3DD2) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("SetCurrentViewport(D3DD2): OK\n"); + return res; +} + +HRESULT WINAPI extGetCurrentViewport3(void *d3dd, LPDIRECT3DVIEWPORT3 *lpd3dvp) +{ + HRESULT res; + OutTraceD3D("GetCurrentViewport(D3DD3): d3dd=%x viewportd=%x\n", d3dd, lpd3dvp); + res=(*pGetCurrentViewport3)(d3dd, lpd3dvp); + if(res) { + OutTraceE("GetCurrentViewport(D3DD3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + HookViewport((LPDIRECT3DVIEWPORT *)lpd3dvp, 3); + return res; +} + +HRESULT WINAPI extSetCurrentViewport3(void *lpvp, LPDIRECT3DVIEWPORT3 vpd) +{ + HRESULT res; + + OutTraceD3D("SetCurrentViewport(D3DD3): viewport=%x\n", lpvp, vpd); + res=(*pSetCurrentViewport3)(lpvp, vpd); + if(res) OutTraceE("SetCurrentViewport(D3DD3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("SetCurrentViewport(D3DD3): OK\n"); + return res; +} + +HRESULT WINAPI extDeleteViewport1(void *d3dd, LPDIRECT3DVIEWPORT lpd3dvp) +{ + HRESULT res; + OutTraceD3D("DeletetViewport(D3DD1): d3dd=%x viewport=%x\n", d3dd, lpd3dvp); + res=(*pDeleteViewport1)(d3dd, lpd3dvp); + if(res) OutTraceE("DeletetViewport(D3DD1) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("DeletetViewport(D3DD1): OK\n"); + return res; +} + +HRESULT WINAPI extNextViewport1(void *d3dd, LPDIRECT3DVIEWPORT lpd3dvp, LPDIRECT3DVIEWPORT *vpnext, DWORD dw) +{ + HRESULT res; + OutTraceD3D("NextViewport(D3DD1): d3dd=%x viewport=%x dw=%x\n", d3dd, lpd3dvp); + res=(*pNextViewport1)(d3dd, lpd3dvp, vpnext, dw); + if(res) OutTraceE("NextViewport(D3DD1) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("NextViewport(D3DD1): next=%x\n", *vpnext); + return res; +} + +HRESULT WINAPI extDeleteViewport2(void *d3dd, LPDIRECT3DVIEWPORT2 lpd3dvp) +{ + HRESULT res; + OutTraceD3D("DeletetViewport(D3DD2): d3dd=%x viewport=%x\n", d3dd, lpd3dvp); + res=(*pDeleteViewport2)(d3dd, lpd3dvp); + if(res) OutTraceE("DeletetViewport(D3DD2) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("DeletetViewport(D3DD2): OK\n"); + return res; +} + +HRESULT WINAPI extNextViewport2(void *d3dd, LPDIRECT3DVIEWPORT2 lpd3dvp, LPDIRECT3DVIEWPORT2 *vpnext, DWORD dw) +{ + HRESULT res; + OutTraceD3D("NextViewport(D3DD2): d3dd=%x viewport=%x dw=%x\n", d3dd, lpd3dvp); + res=(*pNextViewport2)(d3dd, lpd3dvp, vpnext, dw); + if(res) OutTraceE("NextViewport(D3DD2) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("NextViewport(D3DD2): next=%x\n", *vpnext); + return res; +} diff --git a/dll/syslibs.h b/dll/syslibs.h index bd95e6b..086fb8a 100644 --- a/dll/syslibs.h +++ b/dll/syslibs.h @@ -168,6 +168,7 @@ typedef int (WINAPI *MapWindowPoints_Type)(HWND, HWND, LPPOINT, UINT); typedef BOOL (WINAPI *MoveWindow_Type)(HWND, int, int, int, int, BOOL); typedef BOOL (WINAPI *PeekMessage_Type)(LPMSG, HWND, UINT, UINT, UINT); typedef ATOM (WINAPI *RegisterClassExA_Type)(WNDCLASSEX *); +typedef ATOM (WINAPI *RegisterClassA_Type)(WNDCLASS *); typedef int (WINAPI *GDIReleaseDC_Type)(HWND, HDC); typedef BOOL (WINAPI *ScreenToClient_Type)(HWND, LPPOINT); typedef LRESULT (WINAPI *SendMessage_Type)(HWND, UINT, WPARAM, LPARAM); @@ -365,6 +366,7 @@ DXWEXTERN MapWindowPoints_Type pMapWindowPoints DXWINITIALIZED; DXWEXTERN MoveWindow_Type pMoveWindow DXWINITIALIZED; DXWEXTERN PeekMessage_Type pPeekMessage DXWINITIALIZED; DXWEXTERN RegisterClassExA_Type pRegisterClassExA DXWINITIALIZED; +DXWEXTERN RegisterClassA_Type pRegisterClassA DXWINITIALIZED; DXWEXTERN GDIReleaseDC_Type pGDIReleaseDC DXWINITIALIZED; DXWEXTERN ScreenToClient_Type pScreenToClient DXWINITIALIZED; DXWEXTERN SendMessage_Type pSendMessageA DXWINITIALIZED; @@ -564,10 +566,12 @@ extern int WINAPI extMapWindowPoints(HWND, HWND, LPPOINT, UINT); extern BOOL WINAPI extMoveWindow(HWND, int, int, int, int, BOOL); extern BOOL WINAPI extPeekMessage(LPMSG, HWND, UINT, UINT, UINT); extern ATOM WINAPI extRegisterClassExA(WNDCLASSEXA *); +extern ATOM WINAPI extRegisterClassA(WNDCLASSA *); extern int WINAPI extDDReleaseDC(HWND, HDC); extern int WINAPI extGDIReleaseDC(HWND, HDC); extern BOOL WINAPI extScreenToClient(HWND, LPPOINT); -extern LRESULT WINAPI extSendMessage(HWND, UINT, WPARAM, LPARAM); +extern LRESULT WINAPI extSendMessageA(HWND, UINT, WPARAM, LPARAM); +extern LRESULT WINAPI extSendMessageW(HWND, UINT, WPARAM, LPARAM); extern HCURSOR WINAPI extSetCursor(HCURSOR); extern BOOL WINAPI extSetCursorPos(int, int); extern UINT_PTR WINAPI extSetTimer(HWND, UINT_PTR, UINT, TIMERPROC); diff --git a/dll/user32.cpp b/dll/user32.cpp index a824a69..b721eaf 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -32,6 +32,7 @@ static HookEntry_Type Hooks[]={ {"CreateWindowExA", (FARPROC)CreateWindowExA, (FARPROC *)&pCreateWindowExA, (FARPROC)extCreateWindowExA}, {"CreateWindowExW", (FARPROC)CreateWindowExW, (FARPROC *)&pCreateWindowExW, (FARPROC)extCreateWindowExW}, {"RegisterClassExA", (FARPROC)RegisterClassExA, (FARPROC *)&pRegisterClassExA, (FARPROC)extRegisterClassExA}, + {"RegisterClassA", (FARPROC)RegisterClassA, (FARPROC *)&pRegisterClassA, (FARPROC)extRegisterClassA}, {"GetSystemMetrics", (FARPROC)GetSystemMetrics, (FARPROC *)&pGetSystemMetrics, (FARPROC)extGetSystemMetrics}, {"GetDesktopWindow", (FARPROC)GetDesktopWindow, (FARPROC *)&pGetDesktopWindow, (FARPROC)extGetDesktopWindow}, {"TabbedTextOutA", (FARPROC)TabbedTextOutA, (FARPROC *)&pTabbedTextOutA, (FARPROC)extTabbedTextOutA}, @@ -102,8 +103,8 @@ static HookEntry_Type PeekAllHooks[]={ static HookEntry_Type MouseHooks[]={ {"GetCursorPos", (FARPROC)GetCursorPos, (FARPROC *)&pGetCursorPos, (FARPROC)extGetCursorPos}, {"SetCursor", (FARPROC)SetCursor, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, - {"SendMessageA", (FARPROC)SendMessageA, (FARPROC *)&pSendMessageA, (FARPROC)extSendMessage}, // ??? - {"SendMessageW", (FARPROC)SendMessageW, (FARPROC *)&pSendMessageW, (FARPROC)extSendMessage}, // ??? + {"SendMessageA", (FARPROC)SendMessageA, (FARPROC *)&pSendMessageA, (FARPROC)extSendMessageA}, + {"SendMessageW", (FARPROC)SendMessageW, (FARPROC *)&pSendMessageW, (FARPROC)extSendMessageW}, //{"SetPhysicalCursorPos", NULL, (FARPROC *)&pSetCursor, (FARPROC)extSetCursor}, // ??? {0, NULL, 0, 0} // terminator }; @@ -677,7 +678,7 @@ HDWP WINAPI extDeferWindowPos(HDWP hWinPosInfo, HWND hwnd, HWND hWndInsertAfter, return res; } -LRESULT WINAPI extSendMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) +LRESULT WINAPI extSendMessage(SendMessage_Type pSendMessage, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) { LRESULT ret; OutTraceW("SendMessage: hwnd=%x WinMsg=[0x%x]%s(%x,%x)\n", @@ -718,11 +719,21 @@ LRESULT WINAPI extSendMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) break; } } - ret=(*pSendMessageA)(hwnd, Msg, wParam, lParam); + ret=(*pSendMessage)(hwnd, Msg, wParam, lParam); OutTraceW("SendMessage: lresult=%x\n", ret); return ret; } +LRESULT WINAPI extSendMessageA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + return extSendMessage(pSendMessageA, hwnd, Msg, wParam, lParam); +} + +LRESULT WINAPI extSendMessageW(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + return extSendMessage(pSendMessageW, hwnd, Msg, wParam, lParam); +} + HCURSOR WINAPI extSetCursor(HCURSOR hCursor) { HCURSOR ret; @@ -1030,11 +1041,19 @@ int WINAPI extGetSystemMetrics(int nindex) ATOM WINAPI extRegisterClassExA(WNDCLASSEX *lpwcx) { - OutTraceDW("RegisterClassEx: PROXED ClassName=%s style=%x(%s)\n", - lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style)); + OutTraceDW("RegisterClassEx: PROXED ClassName=%s style=%x(%s) WndProc=%x cbClsExtra=%d cbWndExtra=%d hInstance=%x\n", + lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style), lpwcx->lpfnWndProc, lpwcx->cbClsExtra, lpwcx->cbWndExtra, lpwcx->hInstance); return (*pRegisterClassExA)(lpwcx); } +ATOM WINAPI extRegisterClassA(WNDCLASS *lpwcx) +{ + // referenced by Syberia, together with RegisterClassExA + OutTraceDW("RegisterClass: PROXED ClassName=%s style=%x(%s) WndProc=%x cbClsExtra=%d cbWndExtra=%d hInstance=%x\n", + lpwcx->lpszClassName, lpwcx->style, ExplainStyle(lpwcx->style), lpwcx->lpfnWndProc, lpwcx->cbClsExtra, lpwcx->cbWndExtra, lpwcx->hInstance); + return (*pRegisterClassA)(lpwcx); +} + static HWND WINAPI extCreateWindowCommon( LPCTSTR ApiName, BOOL WideChar, diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index a5e1d6a0480df9af4b3e49ca009308064118015a..70653fa58bf5882ecea0d08631402b837a78f2dd 100644 GIT binary patch delta 8500 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 GD*hK42r>Eq