From 3ecf3a3a1f796e539f9cfed56837a6f033fdc241 Mon Sep 17 00:00:00 2001 From: gho tik Date: Sat, 19 Jan 2013 11:16:54 -0500 Subject: [PATCH] v2_02_04_src Former-commit-id: 1367b767e90df1e072467161f9db16af667aed54 --- Include/dxwnd.h | 10 +- build/dxwnd.dll | 4 +- build/dxwnd.exe | 4 +- build/dxwnd.ini | 3402 ---------------------------------- build/readme-relnotes.txt | 7 + dll/dxhook.cpp | 916 ++++----- dll/dxhook.h | 12 +- dll/dxwcore.cpp | 157 +- dll/dxwcore.hpp | 23 +- dll/dxwnd.cpp | 8 +- dll/dxwnd.def | 1 + dll/dxwnd.ncb | Bin 0 -> 11264 bytes dll/dxwnd.vcproj | 389 ---- dll/dxwnd.ws2008.suo | Bin 57856 -> 80896 bytes dll/glhook.cpp | 30 +- dll/glhook.h | 2 +- dll/hd3d.cpp | 16 +- dll/hddproxy.cpp | 124 +- dll/hddraw.cpp | 211 +-- dll/hdinput.cpp | 10 +- dll/syslibs.cpp | 484 ++--- dll/syslibs.h | 421 +++-- host/Resource.h | 16 +- host/StatusDialog.cpp | 32 +- host/StatusDialog.h | 1 + host/TargetDlg.cpp | 20 +- host/TargetDlg.h | 8 +- host/TimeSliderDialog.h | 29 + host/TimeSliderDlg.cpp | 106 ++ host/dxwndhost.aps | Bin 139320 -> 141004 bytes host/dxwndhost.rc | 200 +- host/dxwndhost.sln | 20 - host/dxwndhost.suo | Bin 413696 -> 0 bytes host/dxwndhost.vs2008.suo | Bin 16896 -> 39424 bytes host/dxwndhost.vs2008.vcproj | 8 + host/dxwndhostView.cpp | 42 + host/dxwndhostView.h | 1 + 37 files changed, 1468 insertions(+), 5246 deletions(-) delete mode 100644 build/dxwnd.ini create mode 100644 dll/dxwnd.ncb delete mode 100644 dll/dxwnd.vcproj create mode 100644 host/TimeSliderDialog.h create mode 100644 host/TimeSliderDlg.cpp delete mode 100644 host/dxwndhost.sln delete mode 100644 host/dxwndhost.suo diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 6c84583..e2270d4 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -61,6 +61,10 @@ #define SHOWFPS 0x00004000 // shows FPS value to status win / log #define HIDEMULTIMONITOR 0x00008000 // hide multimonitor configurations: GetAdapterCount returns 1. #define TIMESTRETCH 0x00010000 // make system time stretchable +#define HOOKOPENGL 0x00020000 // Hook OpenGL calls +#define WALLPAPERMODE 0x00040000 // mouse events are discarded (good for screensaver-like) +#define SHOWHWCURSOR 0x00080000 // mouse events are discarded (good for screensaver-like) +#define HOOKGDI 0x00100000 // Hook GDI functions // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general @@ -80,6 +84,7 @@ typedef struct TARGETMAP { char path[MAX_PATH]; char module[60+1]; + char OpenGLLib[20+1]; int dxversion; int flags; int flags2; @@ -95,6 +100,7 @@ typedef struct TARGETMAP short sizx; short sizy; short MaxFPS; + short InitTS; }TARGETMAP; typedef struct @@ -109,6 +115,7 @@ typedef struct DWORD dwPid; BOOL isLogging; DWORD FPSCount; + int iTimeShift; } DXWNDSTATUS; extern DXWNDSTATUS DxWndStatus; @@ -119,12 +126,13 @@ int EndHook(void); void GetDllVersion(char *); int GetHookStatus(DXWNDSTATUS *); void SetHookStatus(DXWNDSTATUS *); +int GetTimeShift(); int HookInit(TARGETMAP *, HWND); void *SetHook(void *, void *); void SetHook(void *, void *, void **, char *); void OutTrace(const char *, ...); -void *HookAPI(const char *, void *, const char *, void *); +void *HookAPI(const char *, char *, void *, const char *, void *); void AdjustWindowFrame(HWND, DWORD, DWORD); LRESULT CALLBACK extWindowProc(HWND, UINT, WPARAM, LPARAM); diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 0ac9a44..1f0d515 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9c184ea18b592accf84a23876799143c8e5c16761512624d25c595298e34470 -size 260608 +oid sha256:df99818897624e2426ed40251d25c8c8f8a50e5174746aed2c5c1be3dbfcd4a4 +size 262144 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index dd705f6..140ea66 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f3ff1ef480c67937ed3848ce26c7612704b0017f3c49fd597915d2273bfff76f -size 484352 +oid sha256:63d93b8775f8106a4ed846e49768c1ff2203c049656866b84a8f046d1c9864d9 +size 488448 diff --git a/build/dxwnd.ini b/build/dxwnd.ini deleted file mode 100644 index 63ad082..0000000 --- a/build/dxwnd.ini +++ /dev/null @@ -1,3402 +0,0 @@ -[target] -title0=1602 A.D. -path0=C:\Games\1602 A.D\1602.exe -module0= -ver0=0 -flag0=679608354 -flagg0=0 -tflag0=0 -initx0=0 -inity0=0 -minx0=0 -miny0=0 -maxx0=0 -maxy0=0 -posx0=50 -posy0=50 -sizx0=800 -sizy0=600 -title1=7th Legion -path1=D:\Games\7th_Legion\LEGION.EXE -module1= -ver1=0 -flag1=402669607 -flagg1=2064 -tflag1=13 -initx1=0 -inity1=0 -minx1=0 -miny1=0 -maxx1=0 -maxy1=0 -posx1=50 -posy1=50 -sizx1=800 -sizy1=600 -title2=A10 Cuba -path2=D:\Games\A10\A10Cuba.exe -module2= -ver2=0 -flag2=34 -flagg2=0 -tflag2=0 -initx2=0 -inity2=0 -minx2=0 -miny2=0 -maxx2=0 -maxy2=0 -posx2=50 -posy2=50 -sizx2=800 -sizy2=600 -title3=Achtung Spitfire -path3=C:\Games\Achtung Spitfire\ASP95.EXE -module3= -ver3=0 -flag3=536870946 -flagg3=0 -tflag3=70 -initx3=0 -inity3=0 -minx3=0 -miny3=0 -maxx3=0 -maxy3=0 -posx3=50 -posy3=50 -sizx3=800 -sizy3=600 -title4=Actua Soccer 3 -path4=C:\Games\ActuaSoccer3\ActuaSoccer3\Soccer3.exe -module4= -ver4=0 -flag4=671088928 -flagg4=256 -tflag4=0 -initx4=0 -inity4=0 -minx4=0 -miny4=0 -maxx4=0 -maxy4=0 -posx4=50 -posy4=50 -sizx4=800 -sizy4=600 -title5=AfterLife -path5=d:\Games\ALIFE\ALIFE.EXE -module5= -ver5=1 -flag5=134217762 -flagg5=32 -tflag5=3 -initx5=0 -inity5=0 -minx5=0 -miny5=0 -maxx5=0 -maxy5=0 -posx5=50 -posy5=50 -sizx5=800 -sizy5=600 -title6=Age of Empires -path6=D:\Games\Age of Empires\EMPIRES.EXE -module6= -ver6=0 -flag6=268436006 -flagg6=16 -tflag6=3 -initx6=0 -inity6=0 -minx6=0 -miny6=0 -maxx6=0 -maxy6=0 -posx6=50 -posy6=50 -sizx6=800 -sizy6=600 -title7=Airline Tycoon Evolution -path7=C:\Games\Airline.Tycoon.Evolution.UV.Carlows\AT.EXE -module7= -ver7=0 -flag7=32 -flagg7=0 -tflag7=2 -initx7=0 -inity7=0 -minx7=0 -miny7=0 -maxx7=0 -maxy7=0 -posx7=50 -posy7=50 -sizx7=800 -sizy7=600 -title8=Alien Cabal 95 -path8=C:\Games\Alien_cabal\ACabal95.exe -module8= -ver8=0 -flag8=67108896 -flagg8=0 -tflag8=2 -initx8=0 -inity8=0 -minx8=0 -miny8=0 -maxx8=0 -maxy8=0 -posx8=50 -posy8=50 -sizx8=800 -sizy8=600 -title9=Alien vs. Predator -path9=C:\Games\Alien vs Predator\AvP.exe -module9= -ver9=0 -flag9=8224 -flagg9=0 -tflag9=130 -initx9=0 -inity9=0 -minx9=0 -miny9=0 -maxx9=0 -maxy9=0 -posx9=50 -posy9=50 -sizx9=800 -sizy9=600 -title10=Aliens Nations Demo -path10=C:\Games\aademo\Bin\AA.exe -module10= -ver10=0 -flag10=134217762 -flagg10=0 -tflag10=0 -initx10=0 -inity10=0 -minx10=0 -miny10=0 -maxx10=0 -maxy10=0 -posx10=0 -posy10=0 -sizx10=800 -sizy10=600 -title11=America -path11=D:\Games\America\america.exe -module11= -ver11=0 -flag11=134234150 -flagg11=16 -tflag11=0 -initx11=0 -inity11=0 -minx11=0 -miny11=0 -maxx11=0 -maxy11=0 -posx11=50 -posy11=50 -sizx11=800 -sizy11=600 -title12=Ancient Evil -path12=C:\Games\Ancient Evil\RPG.EXE -module12=DDW16.DLL -ver12=1 -flag12=-2013249497 -flagg12=0 -tflag12=2 -initx12=0 -inity12=0 -minx12=0 -miny12=0 -maxx12=0 -maxy12=0 -posx12=50 -posy12=50 -sizx12=800 -sizy12=600 -title13=Ancient Evil Demo -path13=C:\Games\Ancient Evil Curse of the Snake Cult\aecsc-demo.exe -module13= -ver13=1 -flag13=134242336 -flagg13=0 -tflag13=0 -initx13=0 -inity13=0 -minx13=0 -miny13=0 -maxx13=0 -maxy13=0 -posx13=50 -posy13=50 -sizx13=800 -sizy13=600 -title14=Armymen -path14=C:\Games\armymen\Armymen.exe -module14= -ver14=0 -flag14=134218274 -flagg14=1 -tflag14=0 -initx14=0 -inity14=0 -minx14=0 -miny14=0 -maxx14=0 -maxy14=0 -posx14=50 -posy14=50 -sizx14=800 -sizy14=600 -title15=ArmyMen 2 -path15=C:\Games\army2\ArmyMen2.exe -module15= -ver15=0 -flag15=402653730 -flagg15=0 -tflag15=0 -initx15=0 -inity15=0 -minx15=0 -miny15=0 -maxx15=0 -maxy15=0 -posx15=50 -posy15=50 -sizx15=800 -sizy15=600 -title16=Atomic Bomberman -path16=C:\Games\Atomic Bomberman\BM95.EXE -module16= -ver16=0 -flag16=2 -flagg16=0 -tflag16=0 -initx16=0 -inity16=0 -minx16=0 -miny16=0 -maxx16=0 -maxy16=0 -posx16=50 -posy16=50 -sizx16=800 -sizy16=600 -title17=Axis & Allies Iron Blitz Edition -path17=C:\Games\Axis & Allies Iron Blitz Edition\Axis & Allies\AxisAllies.exe -module17= -ver17=0 -flag17=-2147483614 -flagg17=0 -tflag17=0 -initx17=0 -inity17=0 -minx17=0 -miny17=0 -maxx17=0 -maxy17=0 -posx17=50 -posy17=50 -sizx17=800 -sizy17=600 -title18=Baldies -path18=C:\Games\Baldies for Win95\baldies.exe -module18= -ver18=0 -flag18=537010210 -flagg18=0 -tflag18=0 -initx18=0 -inity18=0 -minx18=0 -miny18=0 -maxx18=0 -maxy18=0 -posx18=50 -posy18=50 -sizx18=800 -sizy18=600 -title19=Battle Arena Toshinden 2 (BAD!!) -path19=C:\Games\Battle Arena Toshinden 2\tsd2\T2.EXE -module19= -ver19=1 -flag19=8388640 -flagg19=0 -tflag19=258 -initx19=0 -inity19=0 -minx19=0 -miny19=0 -maxx19=0 -maxy19=0 -posx19=50 -posy19=50 -sizx19=800 -sizy19=600 -title20=Beasts & Bumpkins -path20=C:\Games\Beasts and Bumpkins\BEASTS.EXE -module20= -ver20=0 -flag20=2105890 -flagg20=0 -tflag20=2 -initx20=0 -inity20=0 -minx20=0 -miny20=0 -maxx20=0 -maxy20=0 -posx20=50 -posy20=50 -sizx20=800 -sizy20=600 -title21=Beats of Rage -path21=C:\Games\BOR\BeatsOfRage.exe -module21= -ver21=0 -flag21=537002018 -flagg21=0 -tflag21=0 -initx21=0 -inity21=0 -minx21=0 -miny21=0 -maxx21=0 -maxy21=0 -posx21=50 -posy21=50 -sizx21=800 -sizy21=600 -title22=Beyond Good & Evil Demo -path22=C:\Games\Beyond Good & Evil\BGE.exe -module22= -ver22=0 -flag22=0 -flagg22=0 -tflag22=0 -initx22=0 -inity22=0 -minx22=0 -miny22=0 -maxx22=0 -maxy22=0 -posx22=50 -posy22=50 -sizx22=800 -sizy22=600 -title23=Black Moon Lune Noire -path23=C:\Games\Black Moon\Lune noire\Engine.exe -module23= -ver23=0 -flag23=262179 -flagg23=0 -tflag23=0 -initx23=0 -inity23=0 -minx23=0 -miny23=0 -maxx23=0 -maxy23=0 -posx23=50 -posy23=50 -sizx23=800 -sizy23=600 -title24=Blood Omen Legacy of Kain -path24=C:\Games\Blood Omen\KAIN.EXE -module24= -ver24=0 -flag24=49190 -flagg24=0 -tflag24=0 -initx24=0 -inity24=0 -minx24=0 -miny24=0 -maxx24=0 -maxy24=0 -posx24=50 -posy24=50 -sizx24=800 -sizy24=600 -title25=Bonkheads -path25=C:\Games\Bonkheads\Bonkheads.exe -module25= -ver25=0 -flag25=262690 -flagg25=16 -tflag25=78 -initx25=0 -inity25=0 -minx25=0 -miny25=0 -maxx25=0 -maxy25=0 -posx25=50 -posy25=50 -sizx25=800 -sizy25=600 -title26=Bubble Bobble 2 -path26=C:\Games\bubble2\BOBO2.EXE -module26= -ver26=0 -flag26=34 -flagg26=0 -tflag26=0 -initx26=0 -inity26=0 -minx26=0 -miny26=0 -maxx26=0 -maxy26=0 -posx26=50 -posy26=50 -sizx26=800 -sizy26=600 -title27=Bug! -path27=C:\Games\Bug\BUG!.EXE -module27= -ver27=0 -flag27=134225954 -flagg27=32 -tflag27=2 -initx27=0 -inity27=0 -minx27=0 -miny27=0 -maxx27=0 -maxy27=0 -posx27=0 -posy27=0 -sizx27=800 -sizy27=600 -title28=Caesar III -path28=C:\Games\Caesar III\c3.exe -module28= -ver28=0 -flag28=-2147475422 -flagg28=0 -tflag28=0 -initx28=0 -inity28=0 -minx28=0 -miny28=0 -maxx28=0 -maxy28=0 -posx28=50 -posy28=50 -sizx28=800 -sizy28=600 -title29=Championship Manager 99-00 -path29=C:\Games\CM9900\cm9900.exe -module29= -ver29=0 -flag29=10306 -flagg29=0 -tflag29=0 -initx29=0 -inity29=0 -minx29=0 -miny29=0 -maxx29=0 -maxy29=0 -posx29=50 -posy29=50 -sizx29=800 -sizy29=600 -title30=Civilization Call to Power -path30=C:\Games\civctp\Civilization_Call_To_Power\ctp_program\ctp\civctp.exe -module30= -ver30=0 -flag30=545267746 -flagg30=0 -tflag30=0 -initx30=0 -inity30=0 -minx30=0 -miny30=0 -maxx30=0 -maxy30=0 -posx30=50 -posy30=50 -sizx30=800 -sizy30=600 -title31=Claw -path31=C:\Games\claw\clawexe.exe -module31= -ver31=0 -flag31=24610 -flagg31=0 -tflag31=0 -initx31=0 -inity31=0 -minx31=0 -miny31=0 -maxx31=0 -maxy31=0 -posx31=50 -posy31=50 -sizx31=800 -sizy31=600 -title32=Commando's Behind Enemy Lines Demo -path32=C:\Games\Commando's Behind Enemy Lines Demo\COMANDOS\Comandos.exe -module32= -ver32=0 -flag32=1744838944 -flagg32=0 -tflag32=64 -initx32=0 -inity32=0 -minx32=0 -miny32=0 -maxx32=0 -maxy32=0 -posx32=50 -posy32=50 -sizx32=800 -sizy32=600 -title33=Commandos II: Men of Courage -path33=C:\Games\Commandos II\comm2.exe -module33= -ver33=0 -flag33=-1207951008 -flagg33=0 -tflag33=0 -initx33=0 -inity33=0 -minx33=0 -miny33=0 -maxx33=0 -maxy33=0 -posx33=50 -posy33=50 -sizx33=800 -sizy33=600 -title34=Crazy Taxy -path34=C:\Games\Crazy_Taxi\Crazy Taxi PC Version\crazy_taxi_pc.exe -module34= -ver34=8 -flag34=536870945 -flagg34=0 -tflag34=0 -initx34=0 -inity34=0 -minx34=0 -miny34=0 -maxx34=0 -maxy34=0 -posx34=50 -posy34=50 -sizx34=800 -sizy34=600 -title35=Crush! Deluxe -path35=C:\Games\Crush! Deluxe\CRUSHD.EXE -module35= -ver35=0 -flag35=134492706 -flagg35=0 -tflag35=0 -initx35=0 -inity35=0 -minx35=0 -miny35=0 -maxx35=0 -maxy35=0 -posx35=50 -posy35=50 -sizx35=800 -sizy35=600 -title36=Cybermercs -path36=C:\Games\cybermercs\cybermercs.exe -module36= -ver36=0 -flag36=134234146 -flagg36=16 -tflag36=0 -initx36=0 -inity36=0 -minx36=0 -miny36=0 -maxx36=0 -maxy36=0 -posx36=50 -posy36=50 -sizx36=800 -sizy36=600 -title37=Darius Gaiden -path37=C:\Games\Darius_gaiden\DARIUS.EXE -module37= -ver37=0 -flag37=536870946 -flagg37=0 -tflag37=0 -initx37=0 -inity37=0 -minx37=0 -miny37=0 -maxx37=0 -maxy37=0 -posx37=50 -posy37=50 -sizx37=800 -sizy37=600 -title38=Dark Colony the Council Wars -path38=C:\Games\darkcolony_council\dc\DC16.EXE -module38= -ver38=0 -flag38=268435462 -flagg38=0 -tflag38=0 -initx38=0 -inity38=0 -minx38=0 -miny38=0 -maxx38=0 -maxy38=0 -posx38=50 -posy38=50 -sizx38=800 -sizy38=600 -title39=Darkstone -path39=C:\Games\darkstone\Darkstone.exe -module39= -ver39=0 -flag39=134234148 -flagg39=0 -tflag39=0 -initx39=0 -inity39=0 -minx39=0 -miny39=0 -maxx39=0 -maxy39=0 -posx39=50 -posy39=50 -sizx39=800 -sizy39=600 -title40=Dave Mirra Freestyle BMX Demo -path40=C:\Games\Dave Mirra Freestyle BMX\NgBMXDemo.exe -module40= -ver40=0 -flag40=8224 -flagg40=0 -tflag40=0 -initx40=0 -inity40=0 -minx40=0 -miny40=0 -maxx40=0 -maxy40=0 -posx40=50 -posy40=50 -sizx40=800 -sizy40=600 -title41=Daytona USA Deluxe -path41=C:\Games\Daytona USA Deluxe\DAYTONA USA Deluxe.exe -module41= -ver41=0 -flag41=402661410 -flagg41=0 -tflag41=0 -initx41=0 -inity41=0 -minx41=0 -miny41=0 -maxx41=0 -maxy41=0 -posx41=50 -posy41=50 -sizx41=800 -sizy41=600 -title42=Deadlock 2 -path42=C:\Games\deadlock2\DEADLOCK.EXE -module42= -ver42=0 -flag42=-2012995550 -flagg42=0 -tflag42=0 -initx42=0 -inity42=0 -minx42=0 -miny42=0 -maxx42=0 -maxy42=0 -posx42=50 -posy42=50 -sizx42=800 -sizy42=600 -title43=Deeper Dungeons 95 -path43=C:\Games\Keeper95\Deeper95.exe -module43= -ver43=0 -flag43=268460070 -flagg43=0 -tflag43=0 -initx43=0 -inity43=0 -minx43=0 -miny43=0 -maxx43=0 -maxy43=0 -posx43=50 -posy43=50 -sizx43=800 -sizy43=600 -title44=Delta Force -path44=C:\Games\Delta Force\Df.exe -module44= -ver44=0 -flag44=34 -flagg44=0 -tflag44=0 -initx44=0 -inity44=0 -minx44=0 -miny44=0 -maxx44=0 -maxy44=0 -posx44=50 -posy44=50 -sizx44=800 -sizy44=600 -title45=Dementia -path45=C:\Games\dementia\program\CRUX.EXE -h -module45= -ver45=0 -flag45=536887330 -flagg45=0 -tflag45=2 -initx45=0 -inity45=0 -minx45=0 -miny45=0 -maxx45=0 -maxy45=0 -posx45=50 -posy45=50 -sizx45=800 -sizy45=600 -title46=Dethkarz -path46=D:\Games\DethKarz\Dethkarz.exe -module46= -ver46=0 -flag46=0 -flagg46=0 -tflag46=0 -initx46=0 -inity46=0 -minx46=0 -miny46=0 -maxx46=0 -maxy46=0 -posx46=50 -posy46=50 -sizx46=800 -sizy46=600 -title47=Devil Inside -path47=C:\Games\Devil Inside\Devil.exe -module47= -ver47=0 -flag47=32 -flagg47=0 -tflag47=0 -initx47=0 -inity47=0 -minx47=0 -miny47=0 -maxx47=0 -maxy47=0 -posx47=50 -posy47=50 -sizx47=800 -sizy47=600 -title48=Diablo -path48=D:\Games\Diablo\Diablo.exe -module48= -ver48=1 -flag48=134234150 -flagg48=16 -tflag48=3 -initx48=0 -inity48=0 -minx48=0 -miny48=0 -maxx48=0 -maxy48=0 -posx48=50 -posy48=50 -sizx48=800 -sizy48=600 -title49=Dink Smallwood (BAD) -path49=C:\Games\Dink SmallWood\Dink.exe -module49= -ver49=0 -flag49=546 -flagg49=0 -tflag49=258 -initx49=0 -inity49=0 -minx49=0 -miny49=0 -maxx49=0 -maxy49=0 -posx49=50 -posy49=50 -sizx49=800 -sizy49=600 -title50=Drakan -path50=C:\Games\Drakan\drakan.exe -module50= -ver50=0 -flag50=536887328 -flagg50=0 -tflag50=0 -initx50=0 -inity50=0 -minx50=0 -miny50=0 -maxx50=0 -maxy50=0 -posx50=50 -posy50=50 -sizx50=800 -sizy50=600 -title51=Dungeon Keeper 95 -path51=D:\Games\Keeper95\KEEPER95.EXE -module51= -ver51=0 -flag51=24614 -flagg51=0 -tflag51=64 -initx51=0 -inity51=0 -minx51=0 -miny51=0 -maxx51=0 -maxy51=0 -posx51=50 -posy51=50 -sizx51=800 -sizy51=600 -title52=Dungeon Keeper II -path52=C:\Games\Dungeon Keeper II\DKII.exe -module52= -ver52=0 -flag52=34 -flagg52=0 -tflag52=82 -initx52=0 -inity52=0 -minx52=0 -miny52=0 -maxx52=0 -maxy52=0 -posx52=50 -posy52=50 -sizx52=800 -sizy52=600 -title53=Emergency Fighters for life -path53=D:\Games\Emergency\EMERGY.EXE -module53= -ver53=0 -flag53=134283811 -flagg53=18 -tflag53=3 -initx53=0 -inity53=0 -minx53=0 -miny53=0 -maxx53=0 -maxy53=0 -posx53=50 -posy53=50 -sizx53=800 -sizy53=600 -title54=Enemy Infestation -path54=C:\Games\Enemy Infestation (1998)\Ei.exe -module54= -ver54=0 -flag54=38 -flagg54=0 -tflag54=0 -initx54=0 -inity54=0 -minx54=0 -miny54=0 -maxx54=0 -maxy54=0 -posx54=50 -posy54=50 -sizx54=800 -sizy54=600 -title55=Evil Genius -path55=D:\Games\Evil Genius\ReleaseExe\EvilGenius_Cracked.exe -module55= -ver55=9 -flag55=2053 -flagg55=80 -tflag55=0 -initx55=0 -inity55=0 -minx55=0 -miny55=0 -maxx55=0 -maxy55=0 -posx55=50 -posy55=50 -sizx55=800 -sizy55=600 -title56=Expendable -path56=C:\Games\eXpendable\go.exe -nocputest -module56= -ver56=0 -flag56=402653280 -flagg56=1 -tflag56=2 -initx56=0 -inity56=0 -minx56=0 -miny56=0 -maxx56=0 -maxy56=0 -posx56=50 -posy56=50 -sizx56=800 -sizy56=600 -title57=Fallen Heaven (BAD) -path57=C:\Games\falhaven\Exe\FALLEN.EXE -module57= -ver57=0 -flag57=679485962 -flagg57=32 -tflag57=0 -initx57=0 -inity57=0 -minx57=0 -miny57=0 -maxx57=0 -maxy57=0 -posx57=0 -posy57=0 -sizx57=800 -sizy57=600 -title58=Fallout -path58=D:\Games\Fallout\FALLOUTW.EXE -module58= -ver58=1 -flag58=134217734 -flagg58=16 -tflag58=0 -initx58=0 -inity58=0 -minx58=0 -miny58=0 -maxx58=0 -maxy58=0 -posx58=50 -posy58=50 -sizx58=800 -sizy58=600 -title59=FreakOut -path59=C:\Games\Freak Out - Extreme Freeride\FreakOut.exe -module59= -ver59=9 -flag59=0 -flagg59=0 -tflag59=2 -initx59=0 -inity59=0 -minx59=0 -miny59=0 -maxx59=0 -maxy59=0 -posx59=50 -posy59=50 -sizx59=800 -sizy59=600 -title60=Funtracks -path60=C:\Games\Funtracks\Fun_win.exe -module60= -ver60=1 -flag60=2 -flagg60=0 -tflag60=258 -initx60=0 -inity60=0 -minx60=0 -miny60=0 -maxx60=0 -maxy60=0 -posx60=50 -posy60=50 -sizx60=800 -sizy60=600 -title61=Galapagos -path61=C:\Games\Galapagos\GALA.EXE -module61= -ver61=0 -flag61=134217760 -flagg61=0 -tflag61=0 -initx61=0 -inity61=0 -minx61=0 -miny61=0 -maxx61=0 -maxy61=0 -posx61=50 -posy61=50 -sizx61=800 -sizy61=600 -title62=Gangsters -path62=C:\Games\Gangsters\gangsters.exe -module62= -ver62=0 -flag62=134217762 -flagg62=0 -tflag62=2 -initx62=0 -inity62=0 -minx62=0 -miny62=0 -maxx62=0 -maxy62=0 -posx62=100 -posy62=100 -sizx62=800 -sizy62=600 -title63=GeneRally -path63=C:\Games\generally105\GeneRally.exe -module63= -ver63=0 -flag63=34 -flagg63=0 -tflag63=0 -initx63=0 -inity63=0 -minx63=0 -miny63=0 -maxx63=0 -maxy63=0 -posx63=50 -posy63=50 -sizx63=800 -sizy63=600 -title64=Get Medieval -path64=C:\Games\Get Medieval\MEDIEVAL.EXE -module64= -ver64=0 -flag64=34 -flagg64=2 -tflag64=0 -initx64=0 -inity64=0 -minx64=0 -miny64=0 -maxx64=0 -maxy64=0 -posx64=0 -posy64=0 -sizx64=800 -sizy64=600 -title65=Gift -path65=C:\Games\Gift\Gift.exe -module65= -ver65=0 -flag65=4196384 -flagg65=0 -tflag65=34 -initx65=0 -inity65=0 -minx65=0 -miny65=0 -maxx65=0 -maxy65=0 -posx65=0 -posy65=0 -sizx65=0 -sizy65=0 -title66=Golden Age of Racing -path66=C:\Games\Golden Age of Racing\GAOR.exe -module66= -ver66=0 -flag66=34 -flagg66=0 -tflag66=0 -initx66=0 -inity66=0 -minx66=0 -miny66=0 -maxx66=0 -maxy66=0 -posx66=50 -posy66=50 -sizx66=800 -sizy66=600 -title67=Gp500 for Win2K -path67=C:\Games\gp500\gp500_win2k.exe -module67= -ver67=1 -flag67=545677860 -flagg67=0 -tflag67=2 -initx67=0 -inity67=0 -minx67=0 -miny67=0 -maxx67=0 -maxy67=0 -posx67=50 -posy67=50 -sizx67=800 -sizy67=600 -title68=G-Police -path68=C:\Games\gpolice\GPOLICE.EXE -module68= -ver68=0 -flag68=67125286 -flagg68=0 -tflag68=2 -initx68=0 -inity68=0 -minx68=0 -miny68=0 -maxx68=0 -maxy68=0 -posx68=50 -posy68=50 -sizx68=800 -sizy68=600 -title69=Grand Prix Legends -path69=C:\Games\grand prix legends\gpl\gpl.exe -module69= -ver69=7 -flag69=134217760 -flagg69=4 -tflag69=0 -initx69=0 -inity69=0 -minx69=0 -miny69=0 -maxx69=0 -maxy69=0 -posx69=50 -posy69=50 -sizx69=0 -sizy69=0 -title70=Grim Fandango Demo -path70=C:\Games\GrimWebDemo\grimdemo.exe -module70= -ver70=0 -flag70=34 -flagg70=0 -tflag70=258 -initx70=0 -inity70=0 -minx70=0 -miny70=0 -maxx70=0 -maxy70=0 -posx70=50 -posy70=50 -sizx70=800 -sizy70=600 -title71=Heart of Darkness -path71=C:\Games\Heart_of_Darkness\HODWin32.exe -module71= -ver71=0 -flag71=8226 -flagg71=0 -tflag71=0 -initx71=0 -inity71=0 -minx71=0 -miny71=0 -maxx71=0 -maxy71=0 -posx71=50 -posy71=50 -sizx71=800 -sizy71=600 -title72=Heavy Metal FAKK 2 -path72=C:\Games\Heavy Metal - FAKK2\fakk2.exe -module72= -ver72=0 -flag72=33554464 -flagg72=64 -tflag72=2 -initx72=0 -inity72=0 -minx72=0 -miny72=0 -maxx72=0 -maxy72=0 -posx72=50 -posy72=50 -sizx72=800 -sizy72=600 -title73=HellCopter -path73=C:\Games\hellcop\HCopter.exe -module73= -ver73=0 -flag73=-2013249500 -flagg73=256 -tflag73=0 -initx73=0 -inity73=0 -minx73=0 -miny73=0 -maxx73=0 -maxy73=0 -posx73=50 -posy73=50 -sizx73=800 -sizy73=600 -title74=Heroes of Might & Magic III Demo -path74=C:\Games\Heroes III Demo\h3demo.exe -module74= -ver74=1 -flag74=134234146 -flagg74=0 -tflag74=2 -initx74=0 -inity74=0 -minx74=0 -miny74=0 -maxx74=0 -maxy74=0 -posx74=50 -posy74=50 -sizx74=800 -sizy74=600 -title75=hover -path75=C:\Games\hover\hoverX.exe -module75= -ver75=0 -flag75=8224 -flagg75=0 -tflag75=0 -initx75=0 -inity75=0 -minx75=0 -miny75=0 -maxx75=0 -maxy75=0 -posx75=50 -posy75=50 -sizx75=800 -sizy75=600 -title76=Hyperblade -path76=D:\Games\Hyperblade\HYPERX.EXE -module76= -ver76=0 -flag76=675 -flagg76=4114 -tflag76=2 -initx76=0 -inity76=0 -minx76=0 -miny76=0 -maxx76=0 -maxy76=0 -posx76=50 -posy76=50 -sizx76=800 -sizy76=600 -title77=Idinaloq -path77=C:\Games\idina101\idinaloq.exe -module77= -ver77=0 -flag77=32 -flagg77=0 -tflag77=0 -initx77=0 -inity77=0 -minx77=0 -miny77=0 -maxx77=0 -maxy77=0 -posx77=50 -posy77=50 -sizx77=800 -sizy77=600 -title78=Immanis -path78=C:\Games\Immanis CD release\immanis.exe -module78= -ver78=0 -flag78=24611 -flagg78=0 -tflag78=0 -initx78=0 -inity78=0 -minx78=0 -miny78=0 -maxx78=0 -maxy78=0 -posx78=50 -posy78=50 -sizx78=800 -sizy78=600 -title79=Immanis (v2) -path79=C:\Games\Immanis CD release\immanis_v2.exe -module79= -ver79=0 -flag79=268460067 -flagg79=0 -tflag79=0 -initx79=0 -inity79=0 -minx79=0 -miny79=0 -maxx79=0 -maxy79=0 -posx79=50 -posy79=50 -sizx79=800 -sizy79=600 -title80=In the Hunt -path80=C:\Games\In The Hunt\e8.exe -module80= -ver80=0 -flag80=2 -flagg80=0 -tflag80=0 -initx80=0 -inity80=0 -minx80=0 -miny80=0 -maxx80=0 -maxy80=0 -posx80=50 -posy80=50 -sizx80=800 -sizy80=600 -title81=International Superstar Soccer 3 -path81=C:\Games\ISS_3\iss3.exe -module81= -ver81=8 -flag81=545267715 -flagg81=0 -tflag81=0 -initx81=0 -inity81=0 -minx81=0 -miny81=0 -maxx81=0 -maxy81=0 -posx81=50 -posy81=50 -sizx81=800 -sizy81=600 -title82=Jet Moto -path82=M:\JETMOTO.EXE -module82= -ver82=0 -flag82=139298 -flagg82=0 -tflag82=0 -initx82=0 -inity82=0 -minx82=0 -miny82=0 -maxx82=0 -maxy82=0 -posx82=50 -posy82=50 -sizx82=800 -sizy82=600 -title83=Kiss Psyco Cyrcus -path83=C:\Games\Psycho\client.exe -module83=d3d.ren -ver83=7 -flag83=537018404 -flagg83=0 -tflag83=0 -initx83=0 -inity83=0 -minx83=0 -miny83=0 -maxx83=0 -maxy83=0 -posx83=50 -posy83=50 -sizx83=800 -sizy83=600 -title84=Krazy Ivan -path84=C:\Games\Krazy Ivan\KRAZY.EXE -module84= -ver84=0 -flag84=536870914 -flagg84=0 -tflag84=0 -initx84=0 -inity84=0 -minx84=0 -miny84=0 -maxx84=0 -maxy84=0 -posx84=50 -posy84=50 -sizx84=800 -sizy84=600 -title85=Last Bronx -path85=C:\Games\Last_Bronx\LB.EXE -module85= -ver85=0 -flag85=40994 -flagg85=0 -tflag85=64 -initx85=0 -inity85=0 -minx85=0 -miny85=0 -maxx85=0 -maxy85=0 -posx85=50 -posy85=50 -sizx85=800 -sizy85=600 -title86=Lionheart -path86=C:\Games\Lionheart Demo\Lionheart.exe -module86= -ver86=0 -flag86=-2147483612 -flagg86=0 -tflag86=0 -initx86=0 -inity86=0 -minx86=0 -miny86=0 -maxx86=0 -maxy86=0 -posx86=50 -posy86=50 -sizx86=800 -sizy86=600 -title87=M.A.X. 2 -path87=C:\Games\MAX 2\MAX_2\MAX2\MAX2.EXE -module87= -ver87=0 -flag87=34 -flagg87=0 -tflag87=0 -initx87=0 -inity87=0 -minx87=0 -miny87=0 -maxx87=0 -maxy87=0 -posx87=50 -posy87=50 -sizx87=800 -sizy87=600 -title88=M1 Tank Platoon 2 -path88=C:\Games\M1 Tank Platoon 2\M1TP2.exe -module88= -ver88=8 -flag88=34 -flagg88=0 -tflag88=0 -initx88=0 -inity88=0 -minx88=0 -miny88=0 -maxx88=0 -maxy88=0 -posx88=50 -posy88=50 -sizx88=800 -sizy88=600 -title89=Mario Worlds (stripped PE) -path89=C:\Games\Mario Worlds\Mario Worlds.exe -module89= -ver89=1 -flag89=2 -flagg89=1 -tflag89=386 -initx89=0 -inity89=0 -minx89=0 -miny89=0 -maxx89=0 -maxy89=0 -posx89=50 -posy89=50 -sizx89=800 -sizy89=600 -title90=Masters of Orion 2 -path90=C:\Games\Orion2\Orion95.exe -module90= -ver90=0 -flag90=34 -flagg90=0 -tflag90=0 -initx90=0 -inity90=0 -minx90=0 -miny90=0 -maxx90=0 -maxy90=0 -posx90=50 -posy90=50 -sizx90=800 -sizy90=600 -title91=Microsoft Flight Simulator 98 -path91=C:\Games\Flight Simulator 98\FLTSIM98.EXE -module91= -ver91=0 -flag91=288 -flagg91=0 -tflag91=0 -initx91=0 -inity91=0 -minx91=0 -miny91=0 -maxx91=0 -maxy91=0 -posx91=50 -posy91=50 -sizx91=800 -sizy91=600 -title92=Microsoft Midtown Madness -path92=C:\Games\Midtown Madness\midtown.exe -module92= -ver92=0 -flag92=8192 -flagg92=0 -tflag92=2 -initx92=0 -inity92=0 -minx92=0 -miny92=0 -maxx92=0 -maxy92=0 -posx92=50 -posy92=50 -sizx92=800 -sizy92=600 -title93=Microsoft Midtown Madness Trial (BAD) -path93=C:\Games\Midtown Madness Trial\midtrial.exe -module93= -ver93=0 -flag93=2 -flagg93=0 -tflag93=0 -initx93=0 -inity93=0 -minx93=0 -miny93=0 -maxx93=0 -maxy93=0 -posx93=0 -posy93=0 -sizx93=800 -sizy93=600 -title94=Microsoft Motocross Madness 2 (BAD!!) -path94=C:\Games\Motocross Madness 2\MCM2.cracked.EXE -module94= -ver94=7 -flag94=201326664 -flagg94=1 -tflag94=82 -initx94=0 -inity94=0 -minx94=0 -miny94=0 -maxx94=0 -maxy94=0 -posx94=50 -posy94=50 -sizx94=800 -sizy94=600 -title95=Microsoft Motocross Madness Trial (BAD) -path95=C:\Games\Motocross Madness Trial\mcm.exe -module95= -ver95=1 -flag95=134225952 -flagg95=0 -tflag95=130 -initx95=0 -inity95=0 -minx95=0 -miny95=0 -maxx95=0 -maxy95=0 -posx95=50 -posy95=50 -sizx95=0 -sizy95=0 -title96=Mission Force Cyberstorm (BAD ?) -path96=C:\Games\SIERRA\CSTORM\CSTORM.EXE -module96= -ver96=0 -flag96=33562658 -flagg96=0 -tflag96=0 -initx96=0 -inity96=0 -minx96=0 -miny96=0 -maxx96=0 -maxy96=0 -posx96=50 -posy96=50 -sizx96=0 -sizy96=0 -title97=Monopoly 3D -path97=C:\Games\Monopoly (Edition 3D)\Monopoly.exe -module97= -ver97=0 -flag97=134244388 -flagg97=0 -tflag97=2 -initx97=0 -inity97=0 -minx97=0 -miny97=0 -maxx97=0 -maxy97=0 -posx97=50 -posy97=50 -sizx97=800 -sizy97=600 -title98=Monster Truck Madness 2 -path98=C:\Games\Monster Truck Madness 2\Monster.EXE -module98= -ver98=1 -flag98=34 -flagg98=1 -tflag98=0 -initx98=0 -inity98=0 -minx98=0 -miny98=0 -maxx98=0 -maxy98=0 -posx98=50 -posy98=50 -sizx98=800 -sizy98=600 -title99=Necrodrome -path99=C:\Games\Necrodome\NECRO95.EXE -module99= -ver99=0 -flag99=268435495 -flagg99=256 -tflag99=0 -initx99=0 -inity99=0 -minx99=0 -miny99=0 -maxx99=0 -maxy99=0 -posx99=50 -posy99=50 -sizx99=800 -sizy99=600 -title100=Need For Speed - Porsche 2000 -path100=C:\Games\Need For Speed - Porsche 2000\Porsche.exe -module100= -ver100=7 -flag100=0 -flagg100=0 -tflag100=258 -initx100=0 -inity100=0 -minx100=0 -miny100=0 -maxx100=0 -maxy100=0 -posx100=50 -posy100=50 -sizx100=800 -sizy100=600 -title101=Netstorm Islands at War -path101=C:\Games\Netstorm\Netstorm.exe -module101= -ver101=0 -flag101=2 -flagg101=0 -tflag101=0 -initx101=0 -inity101=0 -minx101=0 -miny101=0 -maxx101=0 -maxy101=0 -posx101=50 -posy101=50 -sizx101=800 -sizy101=600 -title102=Nox -path102=C:\Games\Nox2\Game.exe -module102= -ver102=0 -flag102=939540515 -flagg102=0 -tflag102=386 -initx102=0 -inity102=0 -minx102=0 -miny102=0 -maxx102=0 -maxy102=0 -posx102=50 -posy102=50 -sizx102=800 -sizy102=600 -title103=Pacific General -path103=C:\Games\Pacific General\PACGEN.EXE -module103= -ver103=0 -flag103=8226 -flagg103=0 -tflag103=2 -initx103=0 -inity103=0 -minx103=0 -miny103=0 -maxx103=0 -maxy103=0 -posx103=50 -posy103=50 -sizx103=800 -sizy103=600 -title104=Project Nomads Demo (BAD) -path104=C:\Games\Project Nomads Demo\bin\win32\nomads.exe -module104= -ver104=8 -flag104=-1476394912 -flagg104=256 -tflag104=258 -initx104=0 -inity104=0 -minx104=0 -miny104=0 -maxx104=0 -maxy104=0 -posx104=50 -posy104=50 -sizx104=800 -sizy104=600 -title105=Puzzle Bubble -path105=C:\Games\Puzzle Bubble\PB.EXE -module105= -ver105=0 -flag105=34 -flagg105=0 -tflag105=0 -initx105=0 -inity105=0 -minx105=0 -miny105=0 -maxx105=0 -maxy105=0 -posx105=50 -posy105=50 -sizx105=800 -sizy105=600 -title106=Raiden II -path106=C:\Games\Raiden II\Raiden II\RAIDENII.EXE -module106= -ver106=0 -flag106=34 -flagg106=0 -tflag106=0 -initx106=0 -inity106=0 -minx106=0 -miny106=0 -maxx106=0 -maxy106=0 -posx106=50 -posy106=50 -sizx106=800 -sizy106=600 -title107=Railroad Tycoon II -path107=C:\Games\Railroad.Tycoon.II\RT2.EXE -module107= -ver107=1 -flag107=134225954 -flagg107=0 -tflag107=0 -initx107=0 -inity107=0 -minx107=0 -miny107=0 -maxx107=0 -maxy107=0 -posx107=50 -posy107=50 -sizx107=800 -sizy107=600 -title108=Rally Championship 2000 -path108=C:\Games\Rally Championship 2000\RAL.EXE -module108= -ver108=0 -flag108=67108864 -flagg108=0 -tflag108=2 -initx108=0 -inity108=0 -minx108=0 -miny108=0 -maxx108=0 -maxy108=0 -posx108=50 -posy108=50 -sizx108=800 -sizy108=600 -title109=Rebel Moon Rising -path109=C:\Games\Rebel Moon Rising\Rmr.exe -module109= -ver109=0 -flag109=0 -flagg109=0 -tflag109=0 -initx109=0 -inity109=0 -minx109=0 -miny109=0 -maxx109=0 -maxy109=0 -posx109=50 -posy109=50 -sizx109=800 -sizy109=600 -title110=Redline - Gang Warfare 2066 -path110=C:\Games\Redline - Gang Warfare 2066\redline.exe -module110= -ver110=0 -flag110=32 -flagg110=0 -tflag110=386 -initx110=0 -inity110=0 -minx110=0 -miny110=0 -maxx110=0 -maxy110=0 -posx110=50 -posy110=50 -sizx110=800 -sizy110=600 -title111=Resident Evil -path111=C:\Games\Resident Evil\residentevil.patched.exe -module111= -ver111=1 -flag111=134217827 -flagg111=0 -tflag111=2 -initx111=0 -inity111=0 -minx111=0 -miny111=0 -maxx111=0 -maxy111=0 -posx111=50 -posy111=50 -sizx111=800 -sizy111=600 -title112=Re-Volt -path112=C:\Games\Re-Volt\REVOLT.EXE -module112= -ver112=0 -flag112=134217792 -flagg112=0 -tflag112=0 -initx112=0 -inity112=0 -minx112=0 -miny112=0 -maxx112=0 -maxy112=0 -posx112=50 -posy112=50 -sizx112=800 -sizy112=600 -title113=Road Rash -path113=D:\Games\Road Rash\ROADRASH\ROADRASH.EXE -module113= -ver113=0 -flag113=134217730 -flagg113=0 -tflag113=387 -initx113=0 -inity113=0 -minx113=0 -miny113=0 -maxx113=0 -maxy113=0 -posx113=50 -posy113=50 -sizx113=800 -sizy113=600 -title114=Road Rash Demo -path114=D:\Games\RoadRash DEMO\DEMORASH.EXE -module114= -ver114=0 -flag114=134218242 -flagg114=0 -tflag114=259 -initx114=0 -inity114=0 -minx114=0 -miny114=0 -maxx114=0 -maxy114=0 -posx114=50 -posy114=50 -sizx114=800 -sizy114=600 -title115=RollerCoaster Tycoon 2 Mini Game -path115=C:\Games\RollerCoaster Tycoon 2 Mini Game\rct2.exe -module115= -ver115=1 -flag115=536870946 -flagg115=0 -tflag115=0 -initx115=0 -inity115=0 -minx115=0 -miny115=0 -maxx115=0 -maxy115=0 -posx115=0 -posy115=0 -sizx115=800 -sizy115=600 -title116=Sega Rally 2 Championship -path116=C:\Games\Sega Rally 2 Championship\SEGA RALLY 2.exe -module116= -ver116=1 -flag116=268435488 -flagg116=2 -tflag116=0 -initx116=0 -inity116=0 -minx116=0 -miny116=0 -maxx116=0 -maxy116=0 -posx116=0 -posy116=0 -sizx116=800 -sizy116=600 -title117=Shadow Master (TBD) -path117=C:\Games\Shadow Master\rmg.exe -module117= -ver117=1 -flag117=32 -flagg117=256 -tflag117=450 -initx117=0 -inity117=0 -minx117=0 -miny117=0 -maxx117=0 -maxy117=0 -posx117=50 -posy117=50 -sizx117=800 -sizy117=600 -title118=Sid Meier's SimGolf Demo -path118=C:\Games\Sid Meier's SimGolf Demo\golf.exe -module118=jgl.dll -ver118=0 -flag118=33554434 -flagg118=0 -tflag118=2 -initx118=0 -inity118=0 -minx118=0 -miny118=0 -maxx118=0 -maxy118=0 -posx118=50 -posy118=50 -sizx118=800 -sizy118=600 -title119=SleepWalker -path119=C:\Games\SleepWalker\Sleepy.exe -module119= -ver119=0 -flag119=301989954 -flagg119=0 -tflag119=198 -initx119=0 -inity119=0 -minx119=0 -miny119=0 -maxx119=0 -maxy119=0 -posx119=50 -posy119=50 -sizx119=800 -sizy119=600 -title120=SnowBoard Racer -path120=C:\Games\Snowboard Racer\SnowBoard.exe -module120= -ver120=0 -flag120=268443681 -flagg120=0 -tflag120=0 -initx120=0 -inity120=0 -minx120=0 -miny120=0 -maxx120=0 -maxy120=0 -posx120=50 -posy120=50 -sizx120=800 -sizy120=600 -title121=Solaris (~BAD) -path121=c:\Games\Solaris\solaris.exe -module121= -ver121=7 -flag121=973078627 -flagg121=1 -tflag121=2 -initx121=0 -inity121=0 -minx121=0 -miny121=0 -maxx121=0 -maxy121=0 -posx121=50 -posy121=50 -sizx121=800 -sizy121=600 -title122=Sonic 3 -path122=C:\Games\Sonic 3 + Sonic et Knuckles\Sonic 3\SONIC3K.EXE -module122= -ver122=1 -flag122=546 -flagg122=0 -tflag122=0 -initx122=0 -inity122=0 -minx122=0 -miny122=0 -maxx122=0 -maxy122=0 -posx122=50 -posy122=50 -sizx122=800 -sizy122=600 -title123=Sonic 3D Blast -path123=C:\Games\Sonic3D\pcsonic.exe -module123= -ver123=0 -flag123=134217762 -flagg123=0 -tflag123=0 -initx123=0 -inity123=0 -minx123=0 -miny123=0 -maxx123=0 -maxy123=0 -posx123=50 -posy123=50 -sizx123=800 -sizy123=600 -title124=Sonic R -path124=C:\Games\SonicR\sonicr.exe -module124= -ver124=0 -flag124=8288 -flagg124=0 -tflag124=0 -initx124=0 -inity124=0 -minx124=0 -miny124=0 -maxx124=0 -maxy124=0 -posx124=50 -posy124=50 -sizx124=800 -sizy124=600 -title125=Soulbringer -path125=C:\Games\SoulBringer\SoulbringeVCnoeax.exe -module125= -ver125=0 -flag125=143024174 -flagg125=0 -tflag125=0 -initx125=0 -inity125=0 -minx125=0 -miny125=0 -maxx125=0 -maxy125=0 -posx125=50 -posy125=50 -sizx125=800 -sizy125=600 -title126=Speedboat Attack (BAD) -path126=C:\Games\Speedboat Attack\SBOAT.EXE -module126= -ver126=0 -flag126=541073954 -flagg126=0 -tflag126=2 -initx126=0 -inity126=0 -minx126=0 -miny126=0 -maxx126=0 -maxy126=0 -posx126=50 -posy126=50 -sizx126=800 -sizy126=600 -title127=Star Wars Episode 1 Racer -path127=C:\Games\sw racer\SWEP1RCR.EXE -module127= -ver127=0 -flag127=142606368 -flagg127=0 -tflag127=0 -initx127=0 -inity127=0 -minx127=0 -miny127=0 -maxx127=0 -maxy127=0 -posx127=50 -posy127=50 -sizx127=800 -sizy127=600 -title128=Star Wars: Jedi Knight -path128=C:\Games\Jedi Knight\Jedi Knight\JK.EXE -module128= -ver128=0 -flag128=8226 -flagg128=0 -tflag128=0 -initx128=0 -inity128=0 -minx128=0 -miny128=0 -maxx128=0 -maxy128=0 -posx128=50 -posy128=50 -sizx128=800 -sizy128=600 -title129=Star Wars: the Gungan Frontier -path129=C:\Games\sw the gungan frontier\Gungan Frontier.exe -module129= -ver129=1 -flag129=402915362 -flagg129=512 -tflag129=0 -initx129=0 -inity129=0 -minx129=0 -miny129=0 -maxx129=0 -maxy129=0 -posx129=0 -posy129=0 -sizx129=800 -sizy129=600 -title130=Starship Troopers -path130=C:\Games\Starship Troopers - Terran Ascendancy\stta\StarshipTroopers.exe -module130= -ver130=1 -flag130=32 -flagg130=0 -tflag130=0 -initx130=0 -inity130=0 -minx130=0 -miny130=0 -maxx130=0 -maxy130=0 -posx130=50 -posy130=50 -sizx130=800 -sizy130=600 -title131=Starshot Space Circus -path131=D:\SpaceCircus.exe -module131= -ver131=0 -flag131=66 -flagg131=0 -tflag131=0 -initx131=0 -inity131=0 -minx131=0 -miny131=0 -maxx131=0 -maxy131=0 -posx131=50 -posy131=50 -sizx131=800 -sizy131=600 -title132=Stronghold Demo -path132=C:\Games\Firefly Studios' Stronghold - Demo\Stronghold Demo.exe -module132= -ver132=0 -flag132=98 -flagg132=0 -tflag132=0 -initx132=0 -inity132=0 -minx132=0 -miny132=0 -maxx132=0 -maxy132=0 -posx132=50 -posy132=50 -sizx132=800 -sizy132=600 -title133=Sub Culture -path133=C:\Games\Sub Culture\sc.exe -module133= -ver133=0 -flag133=66 -flagg133=256 -tflag133=10 -initx133=50 -inity133=50 -minx133=50 -miny133=50 -maxx133=800 -maxy133=600 -posx133=50 -posy133=50 -sizx133=800 -sizy133=600 -title134=Superbike 2001 -path134=C:\Games\Superbike 2001\Sbk2001.exe -module134= -ver134=1 -flag134=536887332 -flagg134=0 -tflag134=0 -initx134=0 -inity134=0 -minx134=0 -miny134=0 -maxx134=0 -maxy134=0 -posx134=50 -posy134=50 -sizx134=800 -sizy134=600 -title135=Syberia 2 Demo -path135=C:\Games\Syberia 2 Demo\Syberia2Demo.exe -module135= -ver135=8 -flag135=536887332 -flagg135=0 -tflag135=0 -initx135=0 -inity135=0 -minx135=0 -miny135=0 -maxx135=0 -maxy135=0 -posx135=50 -posy135=50 -sizx135=800 -sizy135=600 -title136=Syberia Demo -path136=C:\Games\SyberiaDemo\SyberiaDemo.exe -module136= -ver136=1 -flag136=536887332 -flagg136=0 -tflag136=0 -initx136=0 -inity136=0 -minx136=0 -miny136=0 -maxx136=0 -maxy136=0 -posx136=50 -posy136=50 -sizx136=800 -sizy136=600 -title137=System Shock 2 (BAD!!!) -path137=C:\Games\Sys Shock II\Shock2.exe -module137= -ver137=1 -flag137=0 -flagg137=64 -tflag137=0 -initx137=0 -inity137=0 -minx137=0 -miny137=0 -maxx137=0 -maxy137=0 -posx137=50 -posy137=50 -sizx137=800 -sizy137=600 -title138=Test Drive 4 -path138=D:\Games\Test Drive 4\td4.EXE -module138= -ver138=0 -flag138=-2013265886 -flagg138=16 -tflag138=3 -initx138=0 -inity138=0 -minx138=0 -miny138=0 -maxx138=0 -maxy138=0 -posx138=50 -posy138=50 -sizx138=800 -sizy138=600 -title139=The Nations Demo -path139=C:\Games\The Nations Demo\bin\Game.exe -module139= -ver139=1 -flag139=402661920 -flagg139=256 -tflag139=0 -initx139=0 -inity139=0 -minx139=0 -miny139=0 -maxx139=0 -maxy139=0 -posx139=50 -posy139=50 -sizx139=800 -sizy139=600 -title140=The Sims -path140=C:\Games\The Sims\Sims.exe -module140= -ver140=0 -flag140=134226976 -flagg140=0 -tflag140=2 -initx140=0 -inity140=0 -minx140=0 -miny140=0 -maxx140=0 -maxy140=0 -posx140=50 -posy140=50 -sizx140=800 -sizy140=600 -title141=Thief the Dark Project (FRE) -path141=C:\Games\thief\game\thieffixed.exe -module141= -ver141=1 -flag141=16390 -flagg141=0 -tflag141=0 -initx141=0 -inity141=0 -minx141=0 -miny141=0 -maxx141=0 -maxy141=0 -posx141=50 -posy141=50 -sizx141=800 -sizy141=600 -title142=TinTin: Prisoners of the Sun -path142=C:\Games\tintin\TINTINW.EXE -module142= -ver142=0 -flag142=34 -flagg142=0 -tflag142=2 -initx142=0 -inity142=0 -minx142=0 -miny142=0 -maxx142=0 -maxy142=0 -posx142=50 -posy142=50 -sizx142=800 -sizy142=600 -title143=Tintoy (BAD gfx) -path143=C:\Games\Tintoy\Tintoy.exe -module143= -ver143=0 -flag143=546 -flagg143=256 -tflag143=258 -initx143=0 -inity143=0 -minx143=0 -miny143=0 -maxx143=0 -maxy143=0 -posx143=50 -posy143=50 -sizx143=800 -sizy143=600 -title144=Tomb Raider - Anniversary -path144=C:\Games\Tomb Raider - Anniversary\tra.exe -module144= -ver144=9 -flag144=0 -flagg144=256 -tflag144=2 -initx144=0 -inity144=0 -minx144=0 -miny144=0 -maxx144=0 -maxy144=0 -posx144=50 -posy144=50 -sizx144=800 -sizy144=600 -title145=Tomb Raider 2 the Golden Mask -path145=D:\Games\TR2 Golden Mask\T2GOLD.EXE -module145= -ver145=0 -flag145=570688034 -flagg145=0 -tflag145=258 -initx145=0 -inity145=0 -minx145=0 -miny145=0 -maxx145=0 -maxy145=0 -posx145=50 -posy145=50 -sizx145=800 -sizy145=600 -title146=Tomb Raider 3 Demo -path146=C:\Games\Tomb Raider 3 - The Lost Artifact Demo\tr3gold.exe -module146= -ver146=1 -flag146=369098848 -flagg146=0 -tflag146=258 -initx146=0 -inity146=0 -minx146=0 -miny146=0 -maxx146=0 -maxy146=0 -posx146=50 -posy146=50 -sizx146=800 -sizy146=600 -title147=Tomb Raider 4 Demo -path147=C:\Games\Tomb Raider 4 - The Last Revelation (Demo)\tomb4.patched.exe -module147= -ver147=0 -flag147=234881056 -flagg147=16 -tflag147=258 -initx147=0 -inity147=0 -minx147=0 -miny147=0 -maxx147=0 -maxy147=0 -posx147=50 -posy147=50 -sizx147=800 -sizy147=600 -title148=Total Annihilation Kingdoms -path148=D:\Games\Total Annihilation Kingdoms\Kingdoms.exe -module148= -ver148=0 -flag148=134234146 -flagg148=0 -tflag148=0 -initx148=0 -inity148=0 -minx148=0 -miny148=0 -maxx148=0 -maxy148=0 -posx148=50 -posy148=50 -sizx148=800 -sizy148=600 -title149=Ultim@te Race Pro -path149=C:\Games\Ultim@te race pro\Ultim@te Race Pro.exe -module149= -ver149=0 -flag149=570425440 -flagg149=256 -tflag149=0 -initx149=0 -inity149=0 -minx149=0 -miny149=0 -maxx149=0 -maxy149=0 -posx149=50 -posy149=50 -sizx149=800 -sizy149=600 -title150=Uprising - Join or Die -path150=D:\Games\Uprising\uprising.exe -module150= -ver150=0 -flag150=-2013265882 -flagg150=18 -tflag150=0 -initx150=0 -inity150=0 -minx150=0 -miny150=0 -maxx150=0 -maxy150=0 -posx150=50 -posy150=50 -sizx150=800 -sizy150=600 -title151=Warcraft 2 Battlenet Edition -path151=D:\Games\Warcraft 2\Warcraft II BNE.exe -module151= -ver151=0 -flag151=24610 -flagg151=65552 -tflag151=1 -initx151=0 -inity151=0 -minx151=0 -miny151=0 -maxx151=0 -maxy151=0 -posx151=50 -posy151=50 -sizx151=800 -sizy151=600 -title152=WarHammer Rites of War -path152=C:\Games\Rites of War\RoW.exe -module152= -ver152=0 -flag152=134217760 -flagg152=128 -tflag152=0 -initx152=0 -inity152=0 -minx152=0 -miny152=0 -maxx152=0 -maxy152=0 -posx152=50 -posy152=50 -sizx152=800 -sizy152=600 -title153=Warlords 3 -path153=D:\Games\WARLORDS3\Darklord.exe -module153= -ver153=0 -flag153=134218274 -flagg153=32 -tflag153=2 -initx153=0 -inity153=0 -minx153=0 -miny153=0 -maxx153=0 -maxy153=0 -posx153=50 -posy153=50 -sizx153=640 -sizy153=480 -title154=WarTorn -path154=C:\Games\WarTorn\W.exe -module154= -ver154=0 -flag154=32 -flagg154=0 -tflag154=0 -initx154=0 -inity154=0 -minx154=0 -miny154=0 -maxx154=0 -maxy154=0 -posx154=50 -posy154=50 -sizx154=800 -sizy154=600 -title155=WarWind -path155=C:\Games\WarWind\WW.EXE -module155= -ver155=0 -flag155=16418 -flagg155=16 -tflag155=0 -initx155=0 -inity155=0 -minx155=0 -miny155=0 -maxx155=0 -maxy155=0 -posx155=50 -posy155=50 -sizx155=800 -sizy155=600 -title156=Worms Armageddon Demo (BAD!!!) -path156=C:\Games\Worms Armageddon Demo\WaDemo.exe -module156= -ver156=1 -flag156=939524099 -flagg156=8 -tflag156=2 -initx156=0 -inity156=0 -minx156=0 -miny156=0 -maxx156=0 -maxy156=0 -posx156=0 -posy156=0 -sizx156=0 -sizy156=0 -title157=Worms World Party -path157=D:\Games\Worms World Party\wwp.exe -module157= -ver157=1 -flag157=8388610 -flagg157=0 -tflag157=0 -initx157=0 -inity157=0 -minx157=0 -miny157=0 -maxx157=0 -maxy157=0 -posx157=50 -posy157=50 -sizx157=800 -sizy157=600 -title158=Worms World Party Demo (BAD) -path158=C:\Games\WWP Demo\wwp.exe -module158=MFC42.DLL ltkrn10N.dll -ver158=1 -flag158=406847491 -flagg158=8 -tflag158=2 -initx158=0 -inity158=0 -minx158=0 -miny158=0 -maxx158=0 -maxy158=0 -posx158=0 -posy158=0 -sizx158=0 -sizy158=0 -title159=X-Com Enforcer -path159=C:\Games\X-Com Enforcer\System\xcom.exe -module159= -ver159=1 -flag159=32 -flagg159=0 -tflag159=0 -initx159=0 -inity159=0 -minx159=0 -miny159=0 -maxx159=0 -maxy159=0 -posx159=0 -posy159=0 -sizx159=800 -sizy159=600 -title160=X-Com Interceptor -path160=C:\Games\X-Com_Interceptor\X-COM Interceptor\Interceptor.exe -module160= -ver160=0 -flag160=16418 -flagg160=0 -tflag160=0 -initx160=0 -inity160=0 -minx160=0 -miny160=0 -maxx160=0 -maxy160=0 -posx160=50 -posy160=50 -sizx160=800 -sizy160=600 -title161=Z Steel Soldiers -path161=C:\Games\ZSteelSoldiers\Bin\z2.exe -module161= -ver161=8 -flag161=805462020 -flagg161=0 -tflag161=0 -initx161=0 -inity161=0 -minx161=0 -miny161=0 -maxx161=0 -maxy161=0 -posx161=50 -posy161=50 -sizx161=800 -sizy161=600 -title162=Zax Alien Hunter -path162=C:\Games\ZaxDemo\Zax.exe -module162= -ver162=0 -flag162=-1476386784 -flagg162=0 -tflag162=0 -initx162=0 -inity162=0 -minx162=0 -miny162=0 -maxx162=0 -maxy162=0 -posx162=50 -posy162=50 -sizx162=800 -sizy162=600 -title163=Zero Critical (BAD) -path163=C:\Games\zero_critical_-_satin_rift\ZEROCR.EXE -module163= -ver163=0 -flag163=679477858 -flagg163=8 -tflag163=0 -initx163=0 -inity163=0 -minx163=0 -miny163=0 -maxx163=0 -maxy163=0 -posx163=0 -posy163=0 -sizx163=800 -sizy163=600 -title164=Zero Population Count -path164=C:\Games\ZPC\ZPC.EXE -module164= -ver164=0 -flag164=1073741859 -flagg164=0 -tflag164=0 -initx164=0 -inity164=0 -minx164=0 -miny164=0 -maxx164=0 -maxy164=0 -posx164=0 -posy164=0 -sizx164=800 -sizy164=600 -title165=Zero Zone -path165=D:\ZZone\ZeroZone.exe -module165= -ver165=0 -flag165=34 -flagg165=0 -tflag165=0 -initx165=0 -inity165=0 -minx165=0 -miny165=0 -maxx165=0 -maxy165=0 -posx165=50 -posy165=50 -sizx165=800 -sizy165=600 -title166=Zeus Poseidon -path166=C:\Games\Zeus-Poseidon\Zeus.exe -module166= -ver166=0 -flag166=34 -flagg166=0 -tflag166=0 -initx166=0 -inity166=0 -minx166=0 -miny166=0 -maxx166=0 -maxy166=0 -posx166=50 -posy166=50 -sizx166=800 -sizy166=600 -title167=Zoo Tycoon -path167=C:\Games\Zoo Tycoon\zoo.exe -module167= -ver167=0 -flag167=-2013265886 -flagg167=0 -tflag167=0 -initx167=0 -inity167=0 -minx167=0 -miny167=0 -maxx167=0 -maxy167=0 -posx167=50 -posy167=50 -sizx167=800 -sizy167=600 -title168=Soldiers at War -path168=D:\Games\Soldiers at War\SAW_Game.exe -module168= -ver168=0 -flag168=671359010 -flagg168=64 -tflag168=0 -initx168=0 -inity168=0 -minx168=0 -miny168=0 -maxx168=0 -maxy168=0 -posx168=50 -posy168=50 -sizx168=640 -sizy168=480 -title169=Halo Combat Evolved -path169=D:\Games\Halo Combat Evolved\halo.exe -module169= -ver169=9 -flag169=570425377 -flagg169=0 -tflag169=479 -initx169=0 -inity169=0 -minx169=0 -miny169=0 -maxx169=0 -maxy169=0 -posx169=50 -posy169=50 -sizx169=800 -sizy169=600 -title170=Jedi Knight II Jedi Outcast -path170=D:\Games\Jedi Knight II Jedi Outcast\GameData\jk2sp.exe -module170= -ver170=0 -flag170=0 -flagg170=512 -tflag170=267 -initx170=0 -inity170=0 -minx170=0 -miny170=0 -maxx170=0 -maxy170=0 -posx170=50 -posy170=50 -sizx170=800 -sizy170=600 -title171=Incoming Forces -path171=D:\Games\Incoming Forces\forces.exe -module171= -ver171=8 -flag171=134217760 -flagg171=0 -tflag171=3 -initx171=0 -inity171=0 -minx171=0 -miny171=0 -maxx171=0 -maxy171=0 -posx171=50 -posy171=50 -sizx171=800 -sizy171=600 -title172=Doom 64 Absolution -path172=D:\Games\Doom 64\Bin\Absolution.exe -module172= -ver172=8 -flag172=0 -flagg172=0 -tflag172=259 -initx172=0 -inity172=0 -minx172=0 -miny172=0 -maxx172=0 -maxy172=0 -posx172=50 -posy172=50 -sizx172=800 -sizy172=600 -title173=lithtech.exe -path173=D:\Games\NOLF Technology Demo\lithtech.exe -module173= -ver173=7 -flag173=0 -flagg173=512 -tflag173=259 -initx173=0 -inity173=0 -minx173=0 -miny173=0 -maxx173=0 -maxy173=0 -posx173=50 -posy173=50 -sizx173=800 -sizy173=600 -title174=Half-Life Uplink Demo -path174=D:\Games\Half-Life Uplink\hldemo.exe -module174= -ver174=1 -flag174=1073741826 -flagg174=512 -tflag174=3 -initx174=0 -inity174=0 -minx174=0 -miny174=0 -maxx174=0 -maxy174=0 -posx174=50 -posy174=50 -sizx174=640 -sizy174=480 -title175=Daikatana -path175=D:\Games\Daikatana\daikatana.exe -module175=OpenGL32.dll -ver175=9 -flag175=514 -flagg175=513 -tflag175=387 -initx175=0 -inity175=0 -minx175=0 -miny175=0 -maxx175=0 -maxy175=0 -posx175=50 -posy175=50 -sizx175=800 -sizy175=600 -title176=Half-Life Blue-Shift (d3d) -path176=D:\Games\Half-Life Blue-Shift\bshift.exe -module176= -ver176=10 -flag176=1073741826 -flagg176=513 -tflag176=259 -initx176=0 -inity176=0 -minx176=0 -miny176=0 -maxx176=0 -maxy176=0 -posx176=50 -posy176=50 -sizx176=640 -sizy176=480 -title177=Moto Racer Demo -path177=D:\Games\Moto Racer Demo\PlayDemo.exe -module177= -ver177=0 -flag177=167903267 -flagg177=192 -tflag177=14 -initx177=0 -inity177=0 -minx177=0 -miny177=0 -maxx177=0 -maxy177=0 -posx177=50 -posy177=50 -sizx177=800 -sizy177=600 -title178=Quake 2 -path178=D:\Games\QUAKE2\quake2.exe -module178= -ver178=10 -flag178=167772672 -flagg178=1 -tflag178=387 -initx178=0 -inity178=0 -minx178=0 -miny178=0 -maxx178=0 -maxy178=0 -posx178=50 -posy178=50 -sizx178=800 -sizy178=600 -title179=Quake 3 Arena -path179=D:\Games\Q3A\quake3.exe -module179= -ver179=10 -flag179=0 -flagg179=513 -tflag179=0 -initx179=0 -inity179=0 -minx179=0 -miny179=0 -maxx179=0 -maxy179=0 -posx179=50 -posy179=50 -sizx179=800 -sizy179=600 -title180=Sentinel Returns -path180=D:\Games\Sentinel Returns\Sentinel.exe -module180= -ver180=1 -flag180=3 -flagg180=0 -tflag180=0 -initx180=0 -inity180=0 -minx180=0 -miny180=0 -maxx180=0 -maxy180=0 -posx180=50 -posy180=50 -sizx180=800 -sizy180=600 -title181=Sin, Wages of (sw renderer) -path181=D:\Games\sin\sin.exe -module181=ref_gl.dll ref_soft.dll -ver181=10 -flag181=402670082 -flagg181=769 -tflag181=387 -initx181=0 -inity181=0 -minx181=0 -miny181=0 -maxx181=0 -maxy181=0 -posx181=50 -posy181=50 -sizx181=800 -sizy181=600 -title182=Star trek Klingon Honor Guard -path182=D:\Games\Star trek Klingon Honor Guard\System\Khg.exe -module182=OGIDrv.dll -ver182=10 -flag182=0 -flagg182=513 -tflag182=386 -initx182=0 -inity182=0 -minx182=0 -miny182=0 -maxx182=0 -maxy182=0 -posx182=50 -posy182=50 -sizx182=800 -sizy182=600 -title183=American McGee's Alice Demo -path183=D:\Games\American McGee's Alice Demo\alice.exe -module183= -ver183=10 -flag183=268435458 -flagg183=0 -tflag183=0 -initx183=0 -inity183=0 -minx183=0 -miny183=0 -maxx183=0 -maxy183=0 -posx183=50 -posy183=50 -sizx183=800 -sizy183=600 -title184=Hexen II (opengl) -path184=D:\Games\Hexen II\glh2.exe -module184= -ver184=10 -flag184=2 -flagg184=1 -tflag184=387 -initx184=0 -inity184=0 -minx184=0 -miny184=0 -maxx184=0 -maxy184=0 -posx184=50 -posy184=50 -sizx184=800 -sizy184=600 -title185=Hexen II (software) -path185=D:\Games\Hexen II\h2.exe -module185= -ver185=10 -flag185=671088642 -flagg185=4096 -tflag185=0 -initx185=0 -inity185=0 -minx185=0 -miny185=0 -maxx185=0 -maxy185=0 -posx185=50 -posy185=50 -sizx185=800 -sizy185=600 -title186=Star Wars Jedi Knight Jedi Academy -path186=D:\Games\Star_Wars_Jedi_Knight_Jedi_Academy\GameData\jasp.exe -module186= -ver186=10 -flag186=0 -flagg186=65536 -tflag186=3 -initx186=0 -inity186=0 -minx186=0 -miny186=0 -maxx186=0 -maxy186=0 -posx186=50 -posy186=50 -sizx186=800 -sizy186=600 -title187=Dungeon Keeper 2 GOG release -path187=D:\Games\Dungeon Keeper 2 GOG release\DKII.EXE -module187= -ver187=0 -flag187=134217762 -flagg187=0 -tflag187=0 -initx187=0 -inity187=0 -minx187=0 -miny187=0 -maxx187=0 -maxy187=0 -posx187=50 -posy187=50 -sizx187=800 -sizy187=600 -maxfps0=0 -maxfps1=0 -maxfps2=0 -maxfps3=0 -maxfps4=0 -maxfps5=0 -maxfps6=0 -maxfps7=0 -maxfps8=0 -maxfps9=0 -maxfps10=0 -maxfps11=0 -maxfps12=0 -maxfps13=0 -maxfps14=0 -maxfps15=0 -maxfps16=0 -maxfps17=0 -maxfps18=0 -maxfps19=0 -maxfps20=0 -maxfps21=0 -maxfps22=0 -maxfps23=0 -maxfps24=0 -maxfps25=0 -maxfps26=0 -maxfps27=0 -maxfps28=0 -maxfps29=0 -maxfps30=0 -maxfps31=0 -maxfps32=0 -maxfps33=0 -maxfps34=0 -maxfps35=0 -maxfps36=0 -maxfps37=0 -maxfps38=0 -maxfps39=0 -maxfps40=0 -maxfps41=0 -maxfps42=0 -maxfps43=0 -maxfps44=0 -maxfps45=0 -maxfps46=0 -maxfps47=0 -maxfps48=0 -maxfps49=0 -maxfps50=0 -maxfps51=0 -maxfps52=0 -maxfps53=0 -maxfps54=0 -maxfps55=0 -maxfps56=0 -maxfps57=0 -maxfps58=0 -maxfps59=0 -maxfps60=0 -maxfps61=0 -maxfps62=0 -maxfps63=0 -maxfps64=0 -maxfps65=0 -maxfps66=0 -maxfps67=0 -maxfps68=0 -maxfps69=0 -maxfps70=0 -maxfps71=0 -maxfps72=0 -maxfps73=0 -maxfps74=0 -maxfps75=0 -maxfps76=20 -maxfps77=0 -maxfps78=0 -maxfps79=0 -maxfps80=0 -maxfps81=0 -maxfps82=0 -maxfps83=0 -maxfps84=0 -maxfps85=0 -maxfps86=0 -maxfps87=0 -maxfps88=0 -maxfps89=0 -maxfps90=0 -maxfps91=0 -maxfps92=0 -maxfps93=0 -maxfps94=0 -maxfps95=0 -maxfps96=0 -maxfps97=0 -maxfps98=0 -maxfps99=0 -maxfps100=0 -maxfps101=0 -maxfps102=0 -maxfps103=0 -maxfps104=0 -maxfps105=0 -maxfps106=0 -maxfps107=0 -maxfps108=0 -maxfps109=0 -maxfps110=0 -maxfps111=0 -maxfps112=0 -maxfps113=0 -maxfps114=0 -maxfps115=0 -maxfps116=0 -maxfps117=0 -maxfps118=0 -maxfps119=0 -maxfps120=0 -maxfps121=0 -maxfps122=0 -maxfps123=0 -maxfps124=0 -maxfps125=0 -maxfps126=0 -maxfps127=0 -maxfps128=0 -maxfps129=0 -maxfps130=0 -maxfps131=0 -maxfps132=0 -maxfps133=0 -maxfps134=0 -maxfps135=0 -maxfps136=0 -maxfps137=0 -maxfps138=0 -maxfps139=0 -maxfps140=0 -maxfps141=0 -maxfps142=0 -maxfps143=0 -maxfps144=0 -maxfps145=0 -maxfps146=0 -maxfps147=0 -maxfps148=0 -maxfps149=0 -maxfps150=0 -maxfps151=0 -maxfps152=0 -maxfps153=0 -maxfps154=0 -maxfps155=0 -maxfps156=0 -maxfps157=0 -maxfps158=0 -maxfps159=0 -maxfps160=0 -maxfps161=0 -maxfps162=0 -maxfps163=0 -maxfps164=0 -maxfps165=0 -maxfps166=0 -maxfps167=0 -maxfps168=0 -maxfps169=0 -maxfps170=0 -maxfps171=0 -maxfps172=0 -maxfps173=0 -maxfps174=0 -maxfps175=0 -maxfps176=0 -maxfps177=0 -maxfps178=0 -maxfps179=0 -maxfps180=0 -maxfps181=0 -maxfps182=0 -maxfps183=0 -maxfps184=0 -maxfps185=200 -maxfps186=0 -maxfps187=0 -title188=Total Soccer 2000 -path188=D:\Games\Total Soccer 2000\Total Soccer 2000\SOCCERDX.EXE -module188= -ver188=1 -flag188=2 -flagg188=4096 -tflag188=0 -initx188=0 -inity188=0 -minx188=0 -miny188=0 -maxx188=0 -maxy188=0 -posx188=50 -posy188=50 -sizx188=800 -maxfps188=20 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index d22ad0e..7a206ec 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -6,3 +6,10 @@ Hide Multi Monitor configuration flag - used for "Dream Acquarium" on multimonit v2.2.02 preliminary time stretching: so far applies to GetTickCount() only, and is controlled by Alt-F5 / F6 keys. Fixed bug in GDI BitBlt call: stretching must be made on screen DC only, or it's made twice. + +v2.02.03/04: +code cleanup - see syslib calls hooking +new configuration flags: Hook GDI and Hook OpenGL +OpenGL custom library field +API hooking fix with module specification +Time stratching by keyboard control (Alt F5/F6) and/or Time Slider dialog \ No newline at end of file diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 9781c34..723f6fa 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -9,179 +9,19 @@ #include "dxwcore.hpp" #include "dxhook.h" #include "glhook.h" +#define DXWDECLARATIONS 1 #include "syslibs.h" +#undef DXWDECLARATIONS #include "dxhelper.h" dxwCore dxw; -extern BOOL MakeWindowTransparent(HWND, unsigned char); - extern void InitScreenParameters(); -int WINAPI extGetDeviceCaps(HDC, int); -BOOL WINAPI extGetCursorPos(LPPOINT); -BOOL WINAPI extSetCursorPos(int, int); -HCURSOR WINAPI extSetCursor(HCURSOR); -BOOL WINAPI extClipCursor(RECT *); -BOOL WINAPI extGetClipCursor(LPRECT); -HRESULT WINAPI extGDIGetDisplayMode(HDC, int); -//BOOL WINAPI extColorCorrectPalette(HDC, HPALETTE, DWORD, DWORD); -int WINAPI extGetSystemMetrics(int); -extern HFONT WINAPI extCreateFont(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCTSTR); -extern HFONT WINAPI extCreateFontIndirect(const LOGFONT*); -extern int WINAPI extFillRect(HDC, const RECT *, HBRUSH); -extern int WINAPI extDrawFocusRect(HDC, const RECT *); -extern BOOL WINAPI extRectangle(HDC, int, int, int, int); -extern LONG WINAPI extSetWindowLong(HWND, int, LONG); -extern LONG WINAPI extGetWindowLong(HWND, int); -extern BOOL WINAPI extSetWindowPos(HWND, HWND, int, int, int, int, UINT); -extern HDWP WINAPI extDeferWindowPos(HDWP, HWND, HWND, int, int, int, int, UINT); -extern LRESULT WINAPI extCallWindowProc(WNDPROC, HWND, UINT, WPARAM, LPARAM); -extern BOOL WINAPI extScaleWindowExtEx(HDC, int, int, int, int, LPSIZE); -//extern HRGN WINAPI extCreateRectRgn(int, int, int, int); -extern LRESULT WINAPI extDefWindowProc(HWND, UINT, WPARAM, LPARAM); -extern LONG WINAPI extChangeDisplaySettings(DEVMODE *, DWORD); -extern LONG WINAPI extChangeDisplaySettingsEx(LPCTSTR, DEVMODE *, HWND, DWORD, LPVOID); -extern LONG WINAPI extEnumDisplaySettings(LPCTSTR, DWORD, DEVMODE *); -extern BOOL WINAPI extSetWindowPlacement(const WINDOWPLACEMENT*); -extern HDC WINAPI extGDICreateCompatibleDC(HDC); -extern HDC WINAPI extDDCreateCompatibleDC(HDC); -extern BOOL WINAPI extGDIDeleteDC(HDC); -extern BOOL WINAPI extDDDeleteDC(HDC); -extern HDC WINAPI extGDIGetDC(HWND); -extern HDC WINAPI extDDGetDC(HWND); -extern HDC WINAPI extGDIGetWindowDC(HWND); -extern HDC WINAPI extDDGetWindowDC(HWND); -extern int WINAPI extGDIReleaseDC(HWND, HDC); -extern int WINAPI extDDReleaseDC(HWND, HDC); -extern BOOL WINAPI extGDIBitBlt(HDC, int, int, int, int, HDC, int, int, DWORD); -extern BOOL WINAPI extGDIPatBlt(HDC, int, int, int, int, DWORD); -extern BOOL WINAPI extDDBitBlt(HDC, int, int, int, int, HDC, int, int, DWORD); -extern BOOL WINAPI extGDIStretchBlt(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); -extern BOOL WINAPI extDDStretchBlt(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); -extern HDC WINAPI extGDICreateDC(LPSTR, LPSTR, LPSTR, CONST DEVMODE *); -extern HDC WINAPI extDDCreateDC(LPSTR, LPSTR, LPSTR, CONST DEVMODE *); -extern int WINAPI extGDISaveDC(HDC); -extern BOOL WINAPI extGDIRestoreDC(HDC, int); -extern HDC WINAPI extBeginPaint(HWND, LPPAINTSTRUCT); -extern BOOL WINAPI extEndPaint(HWND, const PAINTSTRUCT *); - -extern HMODULE WINAPI extLoadLibraryA(LPCTSTR); -extern HMODULE WINAPI extLoadLibraryExA(LPCTSTR, HANDLE, DWORD); -extern BOOL WINAPI extGetClipCursor(LPRECT); -extern BOOL WINAPI extClipCursor(LPRECT); -extern BOOL WINAPI extScreenToClient(HWND, LPPOINT); -extern BOOL WINAPI extClientToScreen(HWND, LPPOINT); -extern BOOL WINAPI extGetClientRect(HWND, LPRECT); -extern BOOL WINAPI extGetWindowRect(HWND, LPRECT); -extern int WINAPI extMapWindowPoints(HWND, HWND, LPPOINT, UINT); -extern BOOL WINAPI extPeekMessage(LPMSG, HWND, UINT, UINT, UINT); -extern BOOL WINAPI extGetMessage(LPMSG, HWND, UINT, UINT); -extern LRESULT WINAPI extDispatchMessage(LPMSG); -extern FARPROC WINAPI extGetProcAddress(HMODULE, LPCSTR); -//extern BOOL WINAPI extGetUpdateRect(HWND, LPRECT, BOOL); - -// GHO: pro Diablo -HWND WINAPI extCreateWindowExA(DWORD, LPCTSTR, LPCTSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID); -HWND WINAPI extGetDesktopWindow(void); -BOOL WINAPI extShowWindow(HWND, int); -BOOL WINAPI extTextOutA(HDC, int, int, LPCTSTR, int); -ATOM WINAPI extRegisterClassExA(WNDCLASSEXA *); - -// GHO: pro GC&C Tiberian Sun -extern HWND WINAPI extCreateDialogIndirectParam(HINSTANCE, LPCDLGTEMPLATE, HWND, DLGPROC, LPARAM); -extern HWND WINAPI extCreateDialogParam(HINSTANCE, LPCSTR, HWND, DLGPROC, LPARAM); - -extern HWND WINAPI extSetCapture(HWND); -extern BOOL WINAPI extReleaseCapture(void); -extern BOOL WINAPI extDDInvalidateRect(HWND, RECT *, BOOL); -extern BOOL WINAPI extInvalidateRect(HWND, RECT *, BOOL); -extern BOOL WINAPI extInvalidateRgn(HWND, HRGN, BOOL); - -extern HPALETTE WINAPI extGDICreatePalette(CONST LOGPALETTE *); -extern HPALETTE WINAPI extSelectPalette(HDC, HPALETTE, BOOL); -extern UINT WINAPI extRealizePalette(HDC); -extern UINT WINAPI extGetSystemPaletteEntries(HDC, UINT, UINT, LPPALETTEENTRY); -extern BOOL WINAPI extMoveWindow(HWND, int, int, int, int, BOOL); -extern LPTOP_LEVEL_EXCEPTION_FILTER WINAPI extSetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER); -extern BOOL WINAPI extGetDiskFreeSpaceA(LPCSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); -extern BOOL WINAPI extSetDeviceGammaRamp(HDC, LPVOID); -extern BOOL WINAPI extGetDeviceGammaRamp(HDC, LPVOID); -extern LRESULT WINAPI extSendMessage(HWND, UINT, WPARAM, LPARAM); -extern DWORD WINAPI extGetTickCount(void); - extern HANDLE hTraceMutex; -GetDeviceCaps_Type pGetDeviceCaps; -GetCursorPos_Type pGetCursorPos=0; -SetCursorPos_Type pSetCursorPos=0; -SetCursor_Type pSetCursor=0; -ClipCursor_Type pClipCursor=0; -GetClipCursor_Type pGetClipCursor=0; -TextOut_Type pTextOutA=0; -FillRect_Type pFillRect; -DrawFocusRect_Type pDrawFocusRect; -Rectangle_Type pRectangle; -GDIGetDisplayMode_Type pGDIGetDisplayMode; -//ColorCorrectPalette_Type pColorCorrectPalette; -GetSystemMetrics_Type pGetSystemMetrics; -// GHO: pro Diablo -CreateWindowExA_Type pCreateWindowExA; -GetDesktopWindow_Type pGetDesktopWindow; -ShowWindow_Type pShowWindow; -SetTextColor_Type pSetTextColor; -SetBkColor_Type pSetBkColor; -CreateFont_Type pCreateFont; -CreateFontIndirect_Type pCreateFontIndirect; -SetWindowLong_Type pSetWindowLong; -GetWindowLong_Type pGetWindowLong; -SetWindowPos_Type pSetWindowPos; -DeferWindowPos_Type pDeferWindowPos; -CallWindowProc_Type pCallWindowProc; -ScaleWindowExtEx_Type pScaleWindowExtEx; -//CreateRectRgn_Type pCreateRectRgn; -DefWindowProc_Type pDefWindowProc; -ChangeDisplaySettings_Type pChangeDisplaySettings; -ChangeDisplaySettingsEx_Type pChangeDisplaySettingsEx; -EnumDisplaySettings_Type pEnumDisplaySettings = NULL; -SetWindowPlacement_Type pSetWindowPlacement; -CreateCompatibleDC_Type pCreateCompatibleDC; -DeleteDC_Type pDeleteDC; -extern GDIGetDC_Type pGDIGetDC; -extern GDIGetDC_Type pGDIGetWindowDC; -extern GDIReleaseDC_Type pGDIReleaseDC; -extern CreateDC_Type pCreateDC; -BitBlt_Type pBitBlt; -PatBlt_Type pPatBlt; -StretchBlt_Type pStretchtBlt; -extern InvalidateRgn_Type pInvalidateRgn; -GetTickCount_Type pGetTickCount; - -LoadLibraryA_Type pLoadLibraryA; -LoadLibraryExA_Type pLoadLibraryExA; -//GetClipCursor_Type pGetClipCursor; -RegisterClassExA_Type pRegisterClassExA; -ScreenToClient_Type pScreenToClient = NULL; -ClientToScreen_Type pClientToScreen = NULL; -GetClientRect_Type pGetClientRect = NULL; -GetWindowRect_Type pGetWindowRect = NULL; -MapWindowPoints_Type pMapWindowPoints = NULL; - -PeekMessage_Type pPeekMessage; -GetMessage_Type pGetMessage; -DispatchMessage_Type pDispatchMessage; -GetProcAddress_Type pGetProcAddress; -SetDeviceGammaRamp_Type pSetDeviceGammaRamp; -GetDeviceGammaRamp_Type pGetDeviceGammaRamp; -SendMessage_Type pSendMessage; - CRITICAL_SECTION TraceCS; -extern COLORREF WINAPI extSetTextColor(HDC, COLORREF); -extern COLORREF WINAPI extSetBkColor(HDC, COLORREF); - -short iPosX, iPosY, iSizX, iSizY; - static char *FlagNames[32]={ "UNNOTIFY", "EMULATESURFACE", "CLIPCURSOR", "RESETPRIMARY", "HOOKDI", "MODIFYMOUSE", "HANDLEEXCEPTIONS", "SAVELOAD", @@ -197,9 +37,9 @@ static char *Flag2Names[32]={ "RECOVERSCREENMODE", "REFRESHONRESIZE", "BACKBUFATTACH", "MODALSTYLE", "KEEPASPECTRATIO", "INIT8BPP", "FORCEWINRESIZE", "INIT16BPP", "KEEPCURSORFIXED", "DISABLEGAMMARAMP", "DIFFERENTIALMOUSE", "FIXNCHITTEST", - "LIMITFPS", "SKIPFPS", "SHOWFPS", "", - "", "", "", "", - "", "", "", "", + "LIMITFPS", "SKIPFPS", "SHOWFPS", "HIDEMULTIMONITOR", + "TIMESTRETCH", "HOOKOPENGL", "WALLPAPERMODE", "SHOWHWCURSOR", + "HOOKGDI", "", "", "", "", "", "", "", "", "", "", "", }; @@ -346,180 +186,6 @@ void DumpImportTable(char *module) return; } - -void *HookAPIbyAddr(const char *module, void *apiproc, void *hookproc) -{ - DWORD base; - PIMAGE_NT_HEADERS pnth; - PIMAGE_IMPORT_DESCRIPTOR pidesc; - DWORD rva; - PSTR impmodule; - PIMAGE_THUNK_DATA ptaddr; - DWORD oldprotect; - void *org; - - if(!apiproc) { // check - char *sMsg="HookAPIbyAddr: NULL api ptr\n"; - OutTraceE(sMsg); - if (IsAssertEnabled) MessageBox(0, sMsg, "HookAPIbyAddr", MB_OK | MB_ICONEXCLAMATION); - return 0; - } - - base = (DWORD)GetModuleHandle(NULL); - if(!base) { - OutTraceD("HookAPIbyAddr: GetModuleHandle failed, error=%d\n",GetLastError()); - return 0; - } - - __try{ - pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); - if(!pnth) { - OutTraceE("HookAPIbyAddr: ERROR no pnth at %d\n", __LINE__); - return 0; - } - rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - if(!rva) { - OutTraceE("HookAPIbyAddr: ERROR no rva at %d\n", __LINE__); - return 0; - } - pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); - - while(pidesc->FirstThunk){ - impmodule = (PSTR)(base + pidesc->Name); - if(!lstrcmpi(module, impmodule)) break; - pidesc ++; - } - if(!pidesc->FirstThunk) { - OutTraceD("HookAPIbyAddr: PE unreferenced module=%s\n", module); - return 0; - } - ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); - while(ptaddr->u1.Function){ - if(ptaddr->u1.Function == (DWORD)apiproc) break; - ptaddr ++; - } - if(!ptaddr->u1.Function) return 0; - - org = (void *)ptaddr->u1.Function; - if(org == hookproc) return 0; // already hooked - - if(!VirtualProtect(&ptaddr->u1.Function, 4, PAGE_EXECUTE_READWRITE, &oldprotect)) { - OutTraceD("HookAPIbyAddr: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - ptaddr->u1.Function = (DWORD)hookproc; - if(!VirtualProtect(&ptaddr->u1.Function, 4, oldprotect, &oldprotect)) { - OutTraceD("HookAPIbyAddr: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - if (!FlushInstructionCache(GetCurrentProcess(), &ptaddr->u1.Function, 4)) { - OutTraceD("HookAPIbyAddr: FlushInstructionCache error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - //OutTraceD("HookAPIbyAddr hook=%s.%x address=%x->%x\n", module, apiproc, org, hookproc); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - OutTraceD("HookAPIbyAddr: EXCEPTION hook=%s:%x Hook Failed.\n", module, apiproc); - org = 0; - } -#ifdef TRYBOTHMODULES - } -#endif - return org; -} - - -void *HookAPIbyName(const char *module, const char *api, void *hookproc) -{ - DWORD base; - PIMAGE_NT_HEADERS pnth; - PIMAGE_IMPORT_DESCRIPTOR pidesc; - DWORD rva; - PSTR impmodule; - PIMAGE_THUNK_DATA ptaddr; - PIMAGE_THUNK_DATA ptname; - PIMAGE_IMPORT_BY_NAME piname; - DWORD oldprotect; - void *org; - - if(!*api) { // check - char *sMsg="HookAPIbyName: NULL api name\n"; - OutTraceE(sMsg); - if (IsAssertEnabled) MessageBox(0, sMsg, "HookAPIbyName", MB_OK | MB_ICONEXCLAMATION); - return 0; - } - - base = (DWORD)GetModuleHandle(NULL); - if(!base) { - OutTraceD("HookAPIbyName: GetModuleHandle failed, error=%d\n",GetLastError()); - return 0; - } - __try{ - pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); - if(!pnth) { - OutTraceE("HookAPIbyName: ERROR no pnth at %d\n", __LINE__); - return 0; - } - rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - if(!rva) { - OutTraceE("HookAPIbyName: ERROR no rva at %d\n", __LINE__); - return 0; - } - pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); - - while(pidesc->FirstThunk){ - impmodule = (PSTR)(base + pidesc->Name); - if(!lstrcmpi(module, impmodule)) break; - pidesc ++; - } - if(!pidesc->FirstThunk) { - if (IsDebug) OutTraceD("HookAPIbyName: PE unreferenced module=%s\n", module); - return 0; - } - if(!pidesc->OriginalFirstThunk) { - OutTraceD("HookAPIbyName: no PE OFTs - stripped module=%s\n", module); - return 0; - } - ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); - ptname = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk); - - while(ptaddr->u1.Function){ - if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){ - piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); - if(!lstrcmpi(api, (char *)piname->Name)) break; - } - ptaddr ++; - ptname ++; - } - if(!ptaddr->u1.Function) return 0; - - org = (void *)ptaddr->u1.Function; - if(org == hookproc) return 0; // already hooked - - if(!VirtualProtect(&ptaddr->u1.Function, 4, PAGE_EXECUTE_READWRITE, &oldprotect)) { - OutTraceD("HookAPIbyName: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - ptaddr->u1.Function = (DWORD)hookproc; - if(!VirtualProtect(&ptaddr->u1.Function, 4, oldprotect, &oldprotect)) { - OutTraceD("HookAPIbyName: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - if (!FlushInstructionCache(GetCurrentProcess(), &ptaddr->u1.Function, 4)) { - OutTraceD("HookAPIbyName: FlushInstructionCache error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - //OutTraceD("HookAPIbyName hook=%s.%s address=%x->%x\n", module, api, org, hookproc); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - OutTraceD("HookAPIbyName: EXCEPTION hook=%s:%s Hook Failed.\n", module, api); - org = 0; - } - return org; -} - void SetHook(void *target, void *hookproc, void **hookedproc, char *hookname) { void *tmp; @@ -547,6 +213,103 @@ void SetHook(void *target, void *hookproc, void **hookedproc, char *hookname) *hookedproc = tmp; } +void *HookAPI(const char *module, char *dll, void *apiproc, const char *apiname, void *hookproc) +{ + DWORD base; + PIMAGE_NT_HEADERS pnth; + PIMAGE_IMPORT_DESCRIPTOR pidesc; + DWORD rva; + PSTR impmodule; + PIMAGE_THUNK_DATA ptaddr; + PIMAGE_THUNK_DATA ptname; + PIMAGE_IMPORT_BY_NAME piname; + DWORD oldprotect; + void *org; + + if(!*apiname) { // check + char *sMsg="HookAPI: NULL api name\n"; + OutTraceE(sMsg); + if (IsAssertEnabled) MessageBox(0, sMsg, "HookAPI", MB_OK | MB_ICONEXCLAMATION); + return 0; + } + + base = (DWORD)GetModuleHandle(module); + if(!base) { + OutTraceD("HookAPI: GetModuleHandle failed, error=%d\n",GetLastError()); + return 0; + } + __try{ + pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); + if(!pnth) { + OutTraceE("HookAPI: ERROR no pnth at %d\n", __LINE__); + return 0; + } + rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + if(!rva) { + OutTraceE("HookAPI: ERROR no rva at %d\n", __LINE__); + return 0; + } + pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); + + while(pidesc->FirstThunk){ + impmodule = (PSTR)(base + pidesc->Name); + if(!lstrcmpi(dll, impmodule)) break; + pidesc ++; + } + if(!pidesc->FirstThunk) { + if (IsDebug) OutTraceD("HookAPI: PE unreferenced dll=%s\n", dll); + return 0; + } + + ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); + ptname = (pidesc->OriginalFirstThunk) ? (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk) : NULL; + + if((apiproc==NULL) && (ptname==NULL)){ + if (IsDebug) OutTraceD("HookAPI: unreacheable api=%s dll=%s\n", apiname, dll); + return 0; + } + + while(ptaddr->u1.Function){ + if (ptname){ + if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){ + piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); + if(!lstrcmpi(apiname, (char *)piname->Name)) break; + } + } + if (apiproc){ + if(ptaddr->u1.Function == (DWORD)apiproc) break; + } + ptaddr ++; + if (ptname) ptname ++; + } + if(!ptaddr->u1.Function) return 0; + + org = (void *)ptaddr->u1.Function; + if(org == hookproc) return 0; // already hooked + + if(!VirtualProtect(&ptaddr->u1.Function, 4, PAGE_EXECUTE_READWRITE, &oldprotect)) { + OutTraceD("HookAPI: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); + return 0; + } + ptaddr->u1.Function = (DWORD)hookproc; + if(!VirtualProtect(&ptaddr->u1.Function, 4, oldprotect, &oldprotect)) { + OutTraceD("HookAPI: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); + return 0; + } + if (!FlushInstructionCache(GetCurrentProcess(), &ptaddr->u1.Function, 4)) { + OutTraceD("HookAPI: FlushInstructionCache error %d at %d\n", GetLastError(), __LINE__); + return 0; + } + //OutTraceD("HookAPI hook=%s.%s address=%x->%x\n", module, apiname, org, hookproc); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + OutTraceD("HookAPI: EXCEPTION hook=%s:%s Hook Failed.\n", dll, apiname); + org = 0; + } + return org; +} + // v.2.1.80: unified positioning logic into CalculateWindowPos routine // now taking in account for window menus (see "Alien Cabal") @@ -557,14 +320,14 @@ void CalculateWindowPos(HWND hwnd, DWORD width, DWORD height, LPWINDOWPOS wp) int MaxX, MaxY; HMENU hMenu; - rect.left = iPosX; - rect.top = iPosY; - MaxX = iSizX; - MaxY = iSizY; + rect.left = dxw.iPosX; + rect.top = dxw.iPosX; + MaxX = dxw.iSizX; + MaxY = dxw.iSizY; if (!MaxX) MaxX = width; if (!MaxY) MaxY = height; - rect.right = iPosX+MaxX; - rect.bottom = iPosY+MaxY; + rect.right = dxw.iPosX+MaxX; + rect.bottom = dxw.iPosX+MaxY; dwStyle=(*pGetWindowLong)(hwnd, GWL_STYLE); hMenu = GetMenu(hwnd); @@ -637,7 +400,8 @@ void AdjustWindowFrame(HWND hwnd, DWORD width, DWORD height) // fixing cursor view and clipping region - if (dxw.dwFlags1 & HIDEHWCURSOR) while (ShowCursor(0) >= 0); + if (dxw.dwFlags1 & HIDEHWCURSOR) while ((*pShowCursor)(0) >= 0); + if (dxw.dwFlags2 & SHOWHWCURSOR) while((*pShowCursor)(1) < 0); if (dxw.dwFlags1 & CLIPCURSOR) { OutTraceD("AdjustWindowFrame: setting clip region\n"); dxw.SetClipCursor(); @@ -668,7 +432,6 @@ INT_PTR CALLBACK extDialogWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPA pWindowProc=WhndGetWindowProc(hwnd); if(pWindowProc) return(*pWindowProc)(hwnd, message, wparam, lparam); - //OutTraceD("ASSERT: DialogWinMsg pWindowProc=NULL !!!\n"); char *sMsg="ASSERT: DialogWinMsg pWindowProc=NULL !!!\n"; OutTraceD(sMsg); if (IsAssertEnabled) MessageBox(0, sMsg, "WindowProc", MB_OK | MB_ICONEXCLAMATION); @@ -737,10 +500,7 @@ static void dx_TogglePositionLock(HWND hwnd) (*pClientToScreen)(hwnd,&p); dxw.dwFlags1 |= LOCKWINPOS; OutTraceD("Toggle position lock ON\n"); - iPosX=(short)p.x; - iPosY=(short)p.y; - iSizX=(short)(rect.right-rect.left); - iSizY=(short)(rect.bottom-rect.top); + dxw.InitWindowPos(p.x, p.y, rect.right-rect.left, rect.bottom-rect.top); } } @@ -758,7 +518,6 @@ void dx_ToggleDC() LRESULT LastCursorPos; - LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { POINT prev, curr; @@ -772,6 +531,25 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp // v2.1.93: adjust clipping region OutTraceW("WindowProc: WinMsg=[0x%x]%s(%x,%x)\n", message, ExplainWinMessage(message), wparam, lparam); + +#if 0 + if(dxw.dwFlags2 & WALLPAPERMODE) { + static int t=0; + if ((*pGetTickCount)() - t > 100){ + //if (GetTopWindow(NULL)==hwnd){ + { + (*pSetWindowPos)(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE); + t = (*pGetTickCount)(); + } + } + //if ((message >= WM_MOUSEFIRST) && (message <= WM_MOUSELAST)) return 0; + //if (message == WM_WINDOWPOSCHANGED) { + // t=0; + // return 0; + //} + } +#endif + switch(message){ case WM_NCHITTEST: if((dxw.dwFlags2 & FIXNCHITTEST) && (dxw.dwFlags1 & MODIFYMOUSE)){ // mouse processing @@ -806,12 +584,13 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp dxwFixWindowPos("WindowProc", hwnd, lparam); break; case WM_ENTERSIZEMOVE: - while(ShowCursor(1) < 0); + while((*pShowCursor)(1) < 0); if(dxw.dwFlags1 & CLIPCURSOR) dxw.EraseClipCursor(); if(dxw.dwFlags1 & ENABLECLIPPING) (*pClipCursor)(NULL); break; case WM_EXITSIZEMOVE: - if (dxw.dwFlags1 & HIDEHWCURSOR) while(ShowCursor(0) >= 0); + if (dxw.dwFlags1 & HIDEHWCURSOR) while((*pShowCursor)(0) >= 0); + if (dxw.dwFlags2 & SHOWHWCURSOR) while((*pShowCursor)(1) < 0); if(dxw.dwFlags1 & ENABLECLIPPING) extClipCursor(lpClipRegion); if(dxw.dwFlags2 & REFRESHONRESIZE) dxw.ScreenRefresh(); break; @@ -830,7 +609,7 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp // This message is posted to the window that contains the cursor. // If a window has captured the mouse, this message is not posted. // V2.1.90: on nonclient areas the cursor is always shown. - while(ShowCursor(1) < 0); + while((*pShowCursor)(1) < 0); break; case WM_MOUSEMOVE: prev.x = LOWORD(lparam); @@ -838,12 +617,12 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp if (dxw.dwFlags1 & HIDEHWCURSOR) { (*pGetClientRect)(hwnd, &rect); if(prev.x >= 0 && prev.x < rect.right && prev.y >= 0 && prev.y < rect.bottom) - while(ShowCursor(0) >= 0); + while((*pShowCursor)(0) >= 0); else - while(ShowCursor(1) < 0); + while((*pShowCursor)(1) < 0); } else { - while(ShowCursor(1) < 0); + while((*pShowCursor)(1) < 0); } if(dxw.dwFlags1 & MODIFYMOUSE){ // mouse processing // scale mouse coordinates @@ -874,7 +653,6 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp } break; case WM_SETFOCUS: - //if (dxw.dwFlags1 & CLIPCURSOR) if (ClipCursorToggleState) dxw.SetClipCursor(); if (dxw.dwFlags1 & ENABLECLIPPING) extClipCursor(lpClipRegion); break; case WM_KILLFOCUS: @@ -882,11 +660,8 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp if (dxw.dwFlags1 & ENABLECLIPPING) (*pClipCursor)(NULL); break; case WM_CLOSE: - //if (dxw.dwFlags1 & HANDLECOSEICON) { - { - OutTraceD("WindowProc: WM_CLOSE - terminating process\n"); - TerminateProcess(GetCurrentProcess(),0); - } + OutTraceD("WindowProc: WM_CLOSE - terminating process\n"); + TerminateProcess(GetCurrentProcess(),0); break; case WM_SYSKEYDOWN: OutTraceW("event WM_SYSKEYDOWN wparam=%x lparam=%x\n", wparam, lparam); @@ -916,23 +691,14 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp } break; case VK_F5: - //case '+': - if ((dxw.dwFlags2 & TIMESTRETCH) && (dxw.TimeShift < 4)) { - dxw.TimeShift++; - if(dxw.TimeShift > 0) - OutTrace("Time Stretch: speed %dx slow\n", 1 << dxw.TimeShift); - else - OutTrace("Time Stretch: speed %dx quick\n", 1 << (-dxw.TimeShift)); - } - break; case VK_F6: - //case '-': - if ((dxw.dwFlags2 & TIMESTRETCH) && (dxw.TimeShift > -4)) { - dxw.TimeShift--; - if(dxw.TimeShift > 0) - OutTrace("Time Stretch: speed %dx slow\n", 1 << dxw.TimeShift); - else - OutTrace("Time Stretch: speed %dx quick\n", 1 << (-dxw.TimeShift)); + if (dxw.dwFlags2 & TIMESTRETCH) { + char *sTSCaption[9]={"x16","x8","x4","x2","x1",":2",":4",":8",":16"}; + if (wparam == VK_F5 && (dxw.TimeShift < 4)) dxw.TimeShift++; + if (wparam == VK_F6 && (dxw.TimeShift > -4)) dxw.TimeShift--; + OutTrace("Time Stretch: shift=%d speed=%s\n", dxw.TimeShift, sTSCaption[dxw.TimeShift+4]); + DxWndStatus.iTimeShift=dxw.TimeShift; + SetHookStatus(&DxWndStatus); } break; default: @@ -981,37 +747,21 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp return (*pDefWindowProc)(hwnd, message, wparam, lparam); } -void *HookAPI(const char *module, void *apiproc, const char *apiname, void *hookproc) -{ - void *hookaddr; - //OutTraceD("Hooking %s:%s addr=%x\n", module, apiname, apiproc); - hookaddr=NULL; - if (apiproc) - hookaddr=HookAPIbyAddr(module, apiproc, hookproc); - //else - if(!hookaddr) - hookaddr=HookAPIbyName(module, apiname, hookproc); - - if (hookaddr) OutTraceD("Hooked %s:%s %x->%x\n", module, apiname, apiproc, hookproc); - return hookaddr; -} - void HookSysLibsInit() { pLoadLibraryA = LoadLibrary; pGetProcAddress = (GetProcAddress_Type)GetProcAddress; - pCreateCompatibleDC=CreateCompatibleDC; - pDeleteDC=DeleteDC; + pGDICreateCompatibleDC=CreateCompatibleDC; + pGDIDeleteDC=DeleteDC; pGDIGetDC=GetDC; pGDIGetWindowDC=GetWindowDC; pGDIReleaseDC=ReleaseDC; - pCreateDC=CreateDC; - pBitBlt=BitBlt; - pStretchBlt=StretchBlt; + pGDICreateDC=CreateDC; + pGDIBitBlt=BitBlt; + pGDIStretchBlt=StretchBlt; pBeginPaint=BeginPaint; pEndPaint=EndPaint; pInvalidateRect=InvalidateRect; - pInvalidateRgn=InvalidateRgn; pScreenToClient = ScreenToClient; pClientToScreen = ClientToScreen; pGetClientRect = GetClientRect; @@ -1023,26 +773,24 @@ void HookSysLibsInit() pFillRect = FillRect; pPeekMessage = PeekMessage; pGetMessage = GetMessage; - pDispatchMessage = (DispatchMessage_Type)DispatchMessage; pDefWindowProc = DefWindowProc; - pGetDeviceCaps = GetDeviceCaps; - pTextOutA = TextOutA; - pScaleWindowExtEx = ScaleWindowExtEx; + pGDIGetDeviceCaps = GetDeviceCaps; + pGDITextOutA = TextOutA; + pGDIScaleWindowExtEx = ScaleWindowExtEx; pCreateWindowExA = CreateWindowExA; pRegisterClassExA = (RegisterClassExA_Type)RegisterClassExA; - pRectangle = Rectangle; + pGDIRectangle = Rectangle; pSetWindowPos=SetWindowPos; - pDeferWindowPos=DeferWindowPos; + pGDIDeferWindowPos=DeferWindowPos; pSetWindowLong=SetWindowLongA; pGetWindowLong=GetWindowLongA; pCallWindowProc=CallWindowProcA; pShowWindow=ShowWindow; - pSetTextColor = SetTextColor; - pSetBkColor = SetBkColor; - pCreateFont = CreateFont; - pCreateFontIndirect = CreateFontIndirect; + pGDISetTextColor = SetTextColor; + pGDISetBkColor = SetBkColor; + pGDICreateFont = CreateFont; + pGDICreateFontIndirect = CreateFontIndirect; pGetSystemMetrics = GetSystemMetrics; - //pColorCorrectPalette = ColorCorrectPalette; pGetCursorPos = GetCursorPos; pSetCursorPos = SetCursorPos; pSetCursor = SetCursor; @@ -1050,222 +798,225 @@ void HookSysLibsInit() pCreateDialogParam=CreateDialogParamA; pMoveWindow=MoveWindow; pGetDesktopWindow=GetDesktopWindow; + pShowCursor=ShowCursor; pGetTickCount=GetTickCount; + pSleep=Sleep; + pSleepEx=SleepEx; + pGetSystemTime=GetSystemTime; + pGetLocalTime=GetLocalTime; + pSetTimer=SetTimer; +} + +void HookGDILib(char *module) +{ + void *tmp; + + if(dxw.dwFlags1 & MAPGDITOPRIMARY){ + tmp = HookAPI(module, "GDI32.dll", CreateCompatibleDC, "CreateCompatibleDC", extDDCreateCompatibleDC); + if(tmp) pGDICreateCompatibleDC = (CreateCompatibleDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", DeleteDC, "DeleteDC", extDDDeleteDC); + if(tmp) pGDIDeleteDC = (DeleteDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", CreateDCA, "CreateDCA", extDDCreateDC); + if(tmp) pGDICreateDC = (CreateDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", BitBlt, "BitBlt", extDDBitBlt); + if(tmp) pGDIBitBlt = (BitBlt_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", StretchBlt, "StretchBlt", extDDStretchBlt); + if(tmp) pGDIStretchBlt = (StretchBlt_Type)tmp; + } + else { + tmp = HookAPI(module, "GDI32.dll", CreateCompatibleDC, "CreateCompatibleDC", extGDICreateCompatibleDC); + if(tmp) pGDICreateCompatibleDC = (CreateCompatibleDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", DeleteDC, "DeleteDC", extGDIDeleteDC); + if(tmp) pGDIDeleteDC = (DeleteDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", CreateDCA, "CreateDCA", extGDICreateDC); + if(tmp) pGDICreateDC = (CreateDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", BitBlt, "BitBlt", extGDIBitBlt); + if(tmp) pGDIBitBlt = (BitBlt_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", StretchBlt, "StretchBlt", extGDIStretchBlt); + if(tmp) pGDIStretchBlt = (StretchBlt_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", PatBlt, "PatBlt", extGDIPatBlt); + if(tmp) pGDIPatBlt = (PatBlt_Type)tmp; + } + tmp = HookAPI(module, "GDI32.dll", GetDeviceCaps, "GetDeviceCaps", extGetDeviceCaps); // GHO: added for caesar3 + if(tmp) pGDIGetDeviceCaps = (GetDeviceCaps_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", TextOutA, "TextOutA", extTextOutA); + if(tmp) pGDITextOutA = (TextOut_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", ScaleWindowExtEx, "ScaleWindowExtEx", extScaleWindowExtEx); + if(tmp) pGDIScaleWindowExtEx = (ScaleWindowExtEx_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", Rectangle, "Rectangle", extRectangle); + if(tmp) pGDIRectangle = (Rectangle_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", SaveDC, "SaveDC", extGDISaveDC); + if(tmp) pGDISaveDC = (SaveDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", RestoreDC, "RestoreDC", extGDIRestoreDC); + if(tmp) pGDIRestoreDC = (RestoreDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", CreatePalette, "CreatePalette", extGDICreatePalette); + if(tmp) pGDICreatePalette = (GDICreatePalette_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", SelectPalette, "SelectPalette", extSelectPalette); + if(tmp) pGDISelectPalette = (SelectPalette_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", RealizePalette, "RealizePalette", extRealizePalette); + if(tmp) pGDIRealizePalette = (RealizePalette_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", GetSystemPaletteEntries, "GetSystemPaletteEntries", extGetSystemPaletteEntries); + if(tmp) pGDIGetSystemPaletteEntries = (GetSystemPaletteEntries_Type)tmp; + if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC)){ + tmp = HookAPI(module, "GDI32.dll", SetTextColor, "SetTextColor", extSetTextColor); + if(tmp) pGDISetTextColor = (SetTextColor_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", SetBkColor, "SetBkColor", extSetBkColor); + if(tmp) pGDISetBkColor = (SetBkColor_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", CreateFont, "CreateFont", extCreateFont); + if(tmp) pGDICreateFont = (CreateFont_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", CreateFontIndirectA, "CreateFontIndirectA", extCreateFontIndirect); + if(tmp) pGDICreateFontIndirect = (CreateFontIndirect_Type)tmp; + } + + if(dxw.dwFlags2 & DISABLEGAMMARAMP){ + tmp = HookAPI(module, "GDI32.dll", SetDeviceGammaRamp, "SetDeviceGammaRamp", extSetDeviceGammaRamp); + if(tmp) pGDISetDeviceGammaRamp = (SetDeviceGammaRamp_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", GetDeviceGammaRamp, "GetDeviceGammaRamp", extGetDeviceGammaRamp); + if(tmp) pGDIGetDeviceGammaRamp = (GetDeviceGammaRamp_Type)tmp; + } } void HookSysLibs(char *module) { void *tmp; - tmp = HookAPI("KERNEL32.dll", GetProcAddress, "GetProcAddress", extGetProcAddress); + tmp = HookAPI(module, "kernel32.dll", GetProcAddress, "GetProcAddress", extGetProcAddress); if(tmp) pGetProcAddress = (GetProcAddress_Type)tmp; - - tmp = HookAPI("kernel32.dll", LoadLibraryA, "LoadLibraryA", extLoadLibraryA); + tmp = HookAPI(module, "kernel32.dll", LoadLibraryA, "LoadLibraryA", extLoadLibraryA); if(tmp) pLoadLibraryA = (LoadLibraryA_Type)tmp; - tmp = HookAPI("kernel32.dll", LoadLibraryExA, "LoadLibraryExA", extLoadLibraryExA); + tmp = HookAPI(module, "kernel32.dll", LoadLibraryExA, "LoadLibraryExA", extLoadLibraryExA); if(tmp) pLoadLibraryExA = (LoadLibraryExA_Type)tmp; - tmp = HookAPI("user32.dll", BeginPaint, "BeginPaint", extBeginPaint); + tmp = HookAPI(module, "user32.dll", BeginPaint, "BeginPaint", extBeginPaint); if(tmp) pBeginPaint = (BeginPaint_Type)tmp; - tmp = HookAPI("user32.dll", EndPaint, "EndPaint", extEndPaint); + tmp = HookAPI(module, "user32.dll", EndPaint, "EndPaint", extEndPaint); if(tmp) pEndPaint = (EndPaint_Type)tmp; + tmp = HookAPI(module, "user32.dll", ShowCursor, "ShowCursor", extShowCursor); + if(tmp) pShowCursor = (ShowCursor_Type)tmp; if(dxw.dwFlags1 & MAPGDITOPRIMARY){ - tmp = HookAPI("GDI32.dll", CreateCompatibleDC, "CreateCompatibleDC", extDDCreateCompatibleDC); - if(tmp) pCreateCompatibleDC = (CreateCompatibleDC_Type)tmp; - tmp = HookAPI("GDI32.dll", DeleteDC, "DeleteDC", extDDDeleteDC); - if(tmp) pDeleteDC = (DeleteDC_Type)tmp; - tmp = HookAPI("user32.dll", GetDC, "GetDC", extDDGetDC); + tmp = HookAPI(module, "user32.dll", GetDC, "GetDC", extDDGetDC); if(tmp) pGDIGetDC = (GDIGetDC_Type)tmp; - tmp = HookAPI("user32.dll", GetWindowDC, "GetWindowDC", extDDGetWindowDC); + tmp = HookAPI(module, "user32.dll", GetWindowDC, "GetWindowDC", extDDGetWindowDC); if(tmp) pGDIGetWindowDC = (GDIGetDC_Type)tmp; - tmp = HookAPI("user32.dll", ReleaseDC, "ReleaseDC", extDDReleaseDC); + tmp = HookAPI(module, "user32.dll", ReleaseDC, "ReleaseDC", extDDReleaseDC); if(tmp) pGDIReleaseDC = (GDIReleaseDC_Type)tmp; - tmp = HookAPI("GDI32.dll", CreateDCA, "CreateDCA", extDDCreateDC); - if(tmp) pCreateDC = (CreateDC_Type)tmp; - tmp = HookAPI("GDI32.dll", BitBlt, "BitBlt", extDDBitBlt); - if(tmp) pBitBlt = (BitBlt_Type)tmp; - tmp = HookAPI("GDI32.dll", StretchBlt, "StretchBlt", extDDStretchBlt); - if(tmp) pStretchBlt = (StretchBlt_Type)tmp; - tmp = HookAPI("user32.dll", InvalidateRect, "InvalidateRect", extDDInvalidateRect); + tmp = HookAPI(module, "user32.dll", InvalidateRect, "InvalidateRect", extDDInvalidateRect); if(tmp) pInvalidateRect = (InvalidateRect_Type)tmp; } else{ - tmp = HookAPI("GDI32.dll", CreateCompatibleDC, "CreateCompatibleDC", extGDICreateCompatibleDC); - if(tmp) pCreateCompatibleDC = (CreateCompatibleDC_Type)tmp; - tmp = HookAPI("GDI32.dll", DeleteDC, "DeleteDC", extGDIDeleteDC); - if(tmp) pDeleteDC = (DeleteDC_Type)tmp; - tmp = HookAPI("user32.dll", GetDC, "GetDC", extGDIGetDC); + tmp = HookAPI(module, "user32.dll", GetDC, "GetDC", extGDIGetDC); if(tmp) pGDIGetDC = (GDIGetDC_Type)tmp; - tmp = HookAPI("user32.dll", GetWindowDC, "GetWindowDC", extGDIGetWindowDC); + tmp = HookAPI(module, "user32.dll", GetWindowDC, "GetWindowDC", extGDIGetWindowDC); if(tmp) pGDIGetWindowDC = (GDIGetDC_Type)tmp; - tmp = HookAPI("user32.dll", ReleaseDC, "ReleaseDC", extGDIReleaseDC); + tmp = HookAPI(module, "user32.dll", ReleaseDC, "ReleaseDC", extGDIReleaseDC); if(tmp) pGDIReleaseDC = (GDIReleaseDC_Type)tmp; - tmp = HookAPI("GDI32.dll", CreateDCA, "CreateDCA", extGDICreateDC); - if(tmp) pCreateDC = (CreateDC_Type)tmp; - tmp = HookAPI("GDI32.dll", BitBlt, "BitBlt", extGDIBitBlt); - if(tmp) pBitBlt = (BitBlt_Type)tmp; - tmp = HookAPI("GDI32.dll", StretchBlt, "StretchBlt", extGDIStretchBlt); - if(tmp) pStretchBlt = (StretchBlt_Type)tmp; - tmp = HookAPI("GDI32.dll", PatBlt, "PatBlt", extGDIPatBlt); - if(tmp) pPatBlt = (PatBlt_Type)tmp; - tmp = HookAPI("user32.dll", InvalidateRect, "InvalidateRect", extInvalidateRect); + tmp = HookAPI(module, "user32.dll", InvalidateRect, "InvalidateRect", extInvalidateRect); if(tmp) pInvalidateRect = (InvalidateRect_Type)tmp; - //tmp = HookAPI("user32.dll", InvalidateRgn, "InvalidateRgn", extInvalidateRgn); - //if(tmp) pInvalidateRgn = (InvalidateRgn_Type)tmp; } if (dxw.dwFlags1 & CLIENTREMAPPING){ - tmp = HookAPI("user32.dll", ScreenToClient, "ScreenToClient", extScreenToClient); + tmp = HookAPI(module, "user32.dll", ScreenToClient, "ScreenToClient", extScreenToClient); if(tmp) pScreenToClient = (ScreenToClient_Type)tmp; - tmp = HookAPI("user32.dll", ClientToScreen, "ClientToScreen", extClientToScreen); + tmp = HookAPI(module, "user32.dll", ClientToScreen, "ClientToScreen", extClientToScreen); if(tmp) pClientToScreen = (ClientToScreen_Type)tmp; - tmp = HookAPI("user32.dll", GetClientRect, "GetClientRect", extGetClientRect); + tmp = HookAPI(module, "user32.dll", GetClientRect, "GetClientRect", extGetClientRect); if(tmp) pGetClientRect = (GetClientRect_Type)tmp; - tmp = HookAPI("user32.dll", GetWindowRect, "GetWindowRect", extGetWindowRect); + tmp = HookAPI(module, "user32.dll", GetWindowRect, "GetWindowRect", extGetWindowRect); if(tmp) pGetWindowRect = (GetWindowRect_Type)tmp; - tmp = HookAPI("user32.dll", MapWindowPoints, "MapWindowPoints", extMapWindowPoints); + tmp = HookAPI(module, "user32.dll", MapWindowPoints, "MapWindowPoints", extMapWindowPoints); if(tmp) pMapWindowPoints = (MapWindowPoints_Type)tmp; } // get / change display settings - tmp = HookAPI("user32.dll", ChangeDisplaySettingsA, "ChangeDisplaySettingsA", extChangeDisplaySettings); + tmp = HookAPI(module, "user32.dll", ChangeDisplaySettingsA, "ChangeDisplaySettingsA", extChangeDisplaySettings); if(tmp) pChangeDisplaySettings = (ChangeDisplaySettings_Type)tmp; - tmp = HookAPI("user32.dll", ChangeDisplaySettingsExA, "ChangeDisplaySettingsExA", extChangeDisplaySettingsEx); + tmp = HookAPI(module, "user32.dll", ChangeDisplaySettingsExA, "ChangeDisplaySettingsExA", extChangeDisplaySettingsEx); if(tmp) pChangeDisplaySettingsEx = (ChangeDisplaySettingsEx_Type)tmp; - tmp = HookAPI("user32.dll", EnumDisplaySettingsA, "EnumDisplaySettingsA", extEnumDisplaySettings); + tmp = HookAPI(module, "user32.dll", EnumDisplaySettingsA, "EnumDisplaySettingsA", extEnumDisplaySettings); if(tmp) pEnumDisplaySettings = (EnumDisplaySettings_Type)tmp; // handle cursor clipping - tmp = HookAPI("user32.dll", GetClipCursor, "GetClipCursor", extGetClipCursor); + tmp = HookAPI(module, "user32.dll", GetClipCursor, "GetClipCursor", extGetClipCursor); if(tmp) pGetClipCursor = (GetClipCursor_Type)tmp; - tmp = HookAPI("user32.dll", ClipCursor, "ClipCursor", extClipCursor); + tmp = HookAPI(module, "user32.dll", ClipCursor, "ClipCursor", extClipCursor); if(tmp) pClipCursor = (ClipCursor_Type)tmp; - tmp = HookAPI("user32.dll", FillRect, "FillRect", extFillRect); + tmp = HookAPI(module, "user32.dll", FillRect, "FillRect", extFillRect); if(tmp) pFillRect = (FillRect_Type)tmp; if (dxw.dwFlags1 & MESSAGEPROC) { - tmp = HookAPI("user32.dll", PeekMessageA, "PeekMessageA", extPeekMessage); // added for GPL + tmp = HookAPI(module, "user32.dll", PeekMessageA, "PeekMessageA", extPeekMessage); // added for GPL if(tmp) pPeekMessage = (PeekMessage_Type)tmp; - tmp = HookAPI("user32.dll", GetMessageA, "GetMessageA", extGetMessage); // added for GPL + tmp = HookAPI(module, "user32.dll", GetMessageA, "GetMessageA", extGetMessage); // added for GPL if(tmp) pGetMessage = (GetMessage_Type)tmp; - //tmp = HookAPI("user32.dll", DispatchMessageA, "DispatchMessageA", extDispatchMessage); // added for GPL - //if(tmp) pDispatchMessage = (DispatchMessage_Type)tmp; } - tmp = HookAPI("user32.dll", DefWindowProcA, "DefWindowProcA", extDefWindowProc); // added for WarWind background erase + tmp = HookAPI(module, "user32.dll", DefWindowProcA, "DefWindowProcA", extDefWindowProc); // added for WarWind background erase if(tmp) pDefWindowProc = (DefWindowProc_Type)tmp; - tmp = HookAPI("GDI32.dll", GetDeviceCaps, "GetDeviceCaps", extGetDeviceCaps); // GHO: added for caesar3 - if(tmp) pGetDeviceCaps = (GetDeviceCaps_Type)tmp; - tmp = HookAPI("GDI32.dll", TextOutA, "TextOutA", extTextOutA); - if(tmp) pTextOutA = (TextOut_Type)tmp; - tmp = HookAPI("GDI32.dll", ScaleWindowExtEx, "ScaleWindowExtEx", extScaleWindowExtEx); - if(tmp) pScaleWindowExtEx = (ScaleWindowExtEx_Type)tmp; - tmp = HookAPI("user32.dll", CreateWindowExA, "CreateWindowExA", extCreateWindowExA); + tmp = HookAPI(module, "user32.dll", CreateWindowExA, "CreateWindowExA", extCreateWindowExA); if(tmp) pCreateWindowExA = (CreateWindowExA_Type)tmp; - tmp = HookAPI("user32.dll", RegisterClassExA, "RegisterClassExA", extRegisterClassExA); + tmp = HookAPI(module, "user32.dll", RegisterClassExA, "RegisterClassExA", extRegisterClassExA); if(tmp) pRegisterClassExA = (RegisterClassExA_Type)tmp; - tmp = HookAPI("GDI32.dll", Rectangle, "Rectangle", extRectangle); - if(tmp) pRectangle = (Rectangle_Type)tmp; if (dxw.dwFlags1 & (PREVENTMAXIMIZE|FIXWINFRAME|LOCKWINPOS|LOCKWINSTYLE)){ - tmp = HookAPI("user32.dll", ShowWindow, "ShowWindow", extShowWindow); + tmp = HookAPI(module, "user32.dll", ShowWindow, "ShowWindow", extShowWindow); if(tmp) pShowWindow = (ShowWindow_Type)tmp; - tmp = HookAPI("user32.dll", SetWindowLongA, "SetWindowLongA", extSetWindowLong); + tmp = HookAPI(module, "user32.dll", SetWindowLongA, "SetWindowLongA", extSetWindowLong); if(tmp) pSetWindowLong = (SetWindowLong_Type)tmp; - tmp = HookAPI("user32.dll", GetWindowLongA, "GetWindowLongA", extGetWindowLong); + tmp = HookAPI(module, "user32.dll", GetWindowLongA, "GetWindowLongA", extGetWindowLong); if(tmp) pGetWindowLong = (GetWindowLong_Type)tmp; - tmp = HookAPI("user32.dll", SetWindowPos, "SetWindowPos", extSetWindowPos); + tmp = HookAPI(module, "user32.dll", SetWindowPos, "SetWindowPos", extSetWindowPos); if(tmp) pSetWindowPos = (SetWindowPos_Type)tmp; - tmp = HookAPI("user32.dll", DeferWindowPos, "DeferWindowPos", extDeferWindowPos); - if(tmp) pDeferWindowPos = (DeferWindowPos_Type)tmp; - tmp = HookAPI("user32.dll", CallWindowProcA, "CallWindowProcA", extCallWindowProc); + tmp = HookAPI(module, "user32.dll", DeferWindowPos, "DeferWindowPos", extDeferWindowPos); + if(tmp) pGDIDeferWindowPos = (DeferWindowPos_Type)tmp; + tmp = HookAPI(module, "user32.dll", CallWindowProcA, "CallWindowProcA", extCallWindowProc); if(tmp) pCallWindowProc = (CallWindowProc_Type)tmp; - - //tmp = HookAPI("user32.dll", SetWindowPlacement, "SetWindowPlacement", extSetWindowPlacement); - //if(tmp) pSetWindowPlacement = (SetWindowPlacement_Type)tmp; } - if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC)){ - tmp = HookAPI("GDI32.dll", SetTextColor, "SetTextColor", extSetTextColor); - if(tmp) pSetTextColor = (SetTextColor_Type)tmp; - tmp = HookAPI("GDI32.dll", SetBkColor, "SetBkColor", extSetBkColor); - if(tmp) pSetBkColor = (SetBkColor_Type)tmp; - tmp = HookAPI("GDI32.dll", CreateFont, "CreateFont", extCreateFont); - if(tmp) pCreateFont = (CreateFont_Type)tmp; - tmp = HookAPI("GDI32.dll", CreateFontIndirectA, "CreateFontIndirectA", extCreateFontIndirect); - if(tmp) pCreateFontIndirect = (CreateFontIndirect_Type)tmp; - } - tmp = HookAPI("user32.dll", GetSystemMetrics, "GetSystemMetrics", extGetSystemMetrics); + tmp = HookAPI(module, "user32.dll", GetSystemMetrics, "GetSystemMetrics", extGetSystemMetrics); if(tmp) pGetSystemMetrics = (GetSystemMetrics_Type)tmp; - //tmp = HookAPI("GDI32.dll", ColorCorrectPalette, "ColorCorrectPalette", extColorCorrectPalette); - //if(tmp) pColorCorrectPalette = (ColorCorrectPalette_Type)tmp; - // ATTEMPT TO FIX WORMS SERIES PROBLEMS - tmp = HookAPI("user32.dll", GetDesktopWindow, "GetDesktopWindow", extGetDesktopWindow); + tmp = HookAPI(module, "user32.dll", GetDesktopWindow, "GetDesktopWindow", extGetDesktopWindow); if(tmp) pGetDesktopWindow = (GetDesktopWindow_Type)tmp; if(dxw.dwFlags1 & MODIFYMOUSE){ - tmp = HookAPI("user32.dll", GetCursorPos, "GetCursorPos", extGetCursorPos); + tmp = HookAPI(module, "user32.dll", GetCursorPos, "GetCursorPos", extGetCursorPos); if(tmp) pGetCursorPos = (GetCursorPos_Type)tmp; - //tmp = HookAPI("user32.dll", GetPhysicalCursorPos, "", extGetCursorPos); - tmp = HookAPI("user32.dll", SetCursor, "SetCursor", extSetCursor); + //tmp = HookAPI(module, "user32.dll", GetPhysicalCursorPos, "", extGetCursorPos); + tmp = HookAPI(module, "user32.dll", SetCursor, "SetCursor", extSetCursor); if(tmp) pSetCursor = (SetCursor_Type)tmp; - //tmp = HookAPI("user32.dll", SetPhysicalCursorPos, "", extSetCursorPos); - tmp = HookAPI("user32.dll", SendMessageA, "SendMessageA", extSendMessage); + //tmp = HookAPI(module, "user32.dll", SetPhysicalCursorPos, "", extSetCursorPos); + tmp = HookAPI(module, "user32.dll", SendMessageA, "SendMessageA", extSendMessage); if(tmp) pSendMessage = (SendMessage_Type)tmp; } + if((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED)){ - tmp = HookAPI("user32.dll", SetCursorPos, "SetCursorPos", extSetCursorPos); + tmp = HookAPI(module, "user32.dll", SetCursorPos, "SetCursorPos", extSetCursorPos); if(tmp) pSetCursorPos = (SetCursorPos_Type)tmp; } - if(1){ - tmp = HookAPI("GDI32.dll", SaveDC, "SaveDC", extGDISaveDC); - if(tmp) pGDISaveDC = (SaveDC_Type)tmp; - tmp = HookAPI("GDI32.dll", RestoreDC, "RestoreDC", extGDIRestoreDC); - if(tmp) pGDIRestoreDC = (RestoreDC_Type)tmp; - - tmp = HookAPI("user32.dll", CreateDialogIndirectParamA, "CreateDialogIndirectParamA", extCreateDialogIndirectParam); - if(tmp) pCreateDialogIndirectParam = (CreateDialogIndirectParam_Type)tmp; - tmp = HookAPI("user32.dll", CreateDialogParamA, "CreateDialogParamA", extCreateDialogParam); - if(tmp) pCreateDialogParam = (CreateDialogParam_Type)tmp; - } - - if(1){ - tmp = HookAPI("GDI32.dll", CreatePalette, "CreatePalette", extGDICreatePalette); - if(tmp) pGDICreatePalette = (GDICreatePalette_Type)tmp; - tmp = HookAPI("GDI32.dll", SelectPalette, "SelectPalette", extSelectPalette); - if(tmp) pSelectPalette = (SelectPalette_Type)tmp; - tmp = HookAPI("GDI32.dll", RealizePalette, "RealizePalette", extRealizePalette); - if(tmp) pRealizePalette = (RealizePalette_Type)tmp; - tmp = HookAPI("GDI32.dll", GetSystemPaletteEntries, "GetSystemPaletteEntries", extGetSystemPaletteEntries); - if(tmp) pGetSystemPaletteEntries = (GetSystemPaletteEntries_Type)tmp; - } - - // just in case you would have to inhibit mouse capture - if(0){ - tmp = HookAPI("user32.dll", SetCapture, "SetCapture", extSetCapture); - tmp = HookAPI("user32.dll", ReleaseCapture, "ReleaseCapture", extReleaseCapture); - } - - if(1){ - tmp = HookAPI("USER32.dll", MoveWindow, "MoveWindow", extMoveWindow); - if(tmp) pMoveWindow = (MoveWindow_Type)tmp; - } - - if(dxw.dwFlags2 & DISABLEGAMMARAMP){ - tmp = HookAPI("GDI32.dll", SetDeviceGammaRamp, "SetDeviceGammaRamp", extSetDeviceGammaRamp); - if(tmp) pSetDeviceGammaRamp = (SetDeviceGammaRamp_Type)tmp; - tmp = HookAPI("GDI32.dll", GetDeviceGammaRamp, "GetDeviceGammaRamp", extGetDeviceGammaRamp); - if(tmp) pGetDeviceGammaRamp = (GetDeviceGammaRamp_Type)tmp; - } + tmp = HookAPI(module, "user32.dll", CreateDialogIndirectParamA, "CreateDialogIndirectParamA", extCreateDialogIndirectParam); + if(tmp) pCreateDialogIndirectParam = (CreateDialogIndirectParam_Type)tmp; + tmp = HookAPI(module, "user32.dll", CreateDialogParamA, "CreateDialogParamA", extCreateDialogParam); + if(tmp) pCreateDialogParam = (CreateDialogParam_Type)tmp; + tmp = HookAPI(module, "user32.dll", MoveWindow, "MoveWindow", extMoveWindow); + if(tmp) pMoveWindow = (MoveWindow_Type)tmp; #define TRAPLOWRESOURCES 0 if(TRAPLOWRESOURCES){ - tmp = HookAPI("kernel32.dll", GetDiskFreeSpaceA, "GetDiskFreeSpaceA", extGetDiskFreeSpaceA); + tmp = HookAPI(module, "kernel32.dll", GetDiskFreeSpaceA, "GetDiskFreeSpaceA", extGetDiskFreeSpaceA); if(tmp) pGetDiskFreeSpaceA = (GetDiskFreeSpaceA_Type)tmp; } if(dxw.dwFlags2 & TIMESTRETCH){ - tmp = HookAPI("kernel32.dll", GetTickCount, "GetTickCount", extGetTickCount); + tmp = HookAPI(module, "kernel32.dll", GetTickCount, "GetTickCount", extGetTickCount); if(tmp) pGetTickCount = (GetTickCount_Type)tmp; + tmp = HookAPI(module, "kernel32.dll", GetLocalTime, "GetLocalTime", extGetLocalTime); + if(tmp) pGetLocalTime = (GetLocalTime_Type)tmp; + tmp = HookAPI(module, "kernel32.dll", GetSystemTime, "GetSystemTime", extGetSystemTime); + if(tmp) pGetSystemTime = (GetSystemTime_Type)tmp; + tmp = HookAPI(module, "kernel32.dll", Sleep, "Sleep", extSleep); + if(tmp) pSleep = (Sleep_Type)tmp; + tmp = HookAPI(module, "kernel32.dll", SleepEx, "SleepEx", extSleepEx); + if(tmp) pSleepEx = (SleepEx_Type)tmp; + tmp = HookAPI(module, "user32.dll", SetTimer, "SetTimer", extSetTimer); + if(tmp) pSetTimer = (SetTimer_Type)tmp; } return; } @@ -1335,10 +1086,10 @@ void HookExceptionHandler(void) pSetUnhandledExceptionFilter = SetUnhandledExceptionFilter; //v2.1.75 override default exception handler, if any.... LONG WINAPI myUnhandledExceptionFilter(LPEXCEPTION_POINTERS); - tmp = HookAPI("KERNEL32.dll", UnhandledExceptionFilter, "UnhandledExceptionFilter", myUnhandledExceptionFilter); + tmp = HookAPI(NULL, "KERNEL32.dll", UnhandledExceptionFilter, "UnhandledExceptionFilter", myUnhandledExceptionFilter); // so far, no need to save the previous handler. //if(tmp) pUnhandledExceptionFilter = (UnhandledExceptionFilter_Type)tmp; - tmp = HookAPI("KERNEL32.dll", SetUnhandledExceptionFilter, "SetUnhandledExceptionFilter", extSetUnhandledExceptionFilter); + tmp = HookAPI(NULL, "KERNEL32.dll", SetUnhandledExceptionFilter, "SetUnhandledExceptionFilter", extSetUnhandledExceptionFilter); //tmp = HookAPI("KERNEL32.dll", SetUnhandledExceptionFilter, "SetUnhandledExceptionFilter", myUnhandledExceptionFilter); if(tmp) pSetUnhandledExceptionFilter = (SetUnhandledExceptionFilter_Type)tmp; @@ -1350,11 +1101,12 @@ void HookExceptionHandler(void) void HookModule(char *module, int dxversion) { HookSysLibs(module); - if(dxw.dwFlags1 & HOOKDI) HookDirectInput(dxversion); - HookDirectDraw(dxversion); - HookDirect3D(dxversion); - HookOle32(dxversion); // unfinished business - HookOpenGLLibs(dxversion, module); // unfinished business + if(dxw.dwFlags2 & HOOKGDI) HookGDILib(module); + if(dxw.dwFlags1 & HOOKDI) HookDirectInput(module, dxversion); + HookDirectDraw(module, dxversion); + HookDirect3D(module, dxversion); + HookOle32(module, dxversion); // unfinished business + if(dxw.dwFlags2 & HOOKOPENGL) HookOpenGLLibs(module, dxw.CustomOpenGLLib); } int HookInit(TARGETMAP *target, HWND hwnd) @@ -1391,14 +1143,14 @@ int HookInit(TARGETMAP *target, HWND hwnd) if (dxw.dwTFlags & OUTIMPORTTABLE) DumpImportTable(NULL); if (dxw.dwTFlags & DXPROXED){ - HookDDProxy(dxw.dwTargetDDVersion); + HookDDProxy(NULL, dxw.dwTargetDDVersion); return 0; } // make InitPosition used for both DInput and DDraw InitPosition(target->initx, target->inity, target->minx, target->miny, target->maxx, target->maxy); - InitWindowPos(target->posx, target->posy, target->sizx, target->sizy); + dxw.InitWindowPos(target->posx, target->posy, target->sizx, target->sizy); HookSysLibsInit(); // this just once... @@ -1406,6 +1158,7 @@ int HookInit(TARGETMAP *target, HWND hwnd) sModule=strtok(dxw.gsModules," "); while (sModule) { OutTraceD("HookInit: hooking additional module=%s\n", sModule); + if (dxw.dwTFlags & OUTIMPORTTABLE) DumpImportTable(sModule); HookModule(sModule, dxw.dwTargetDDVersion); sModule=strtok(NULL," "); } @@ -1414,9 +1167,9 @@ int HookInit(TARGETMAP *target, HWND hwnd) InitScreenParameters(); - if (IsDebug) OutTraceD("MoveWindow: target pos=(%d,%d) size=(%d,%d)\n", iPosX, iPosY, iSizX, iSizY); + if (IsDebug) OutTraceD("MoveWindow: target pos=(%d,%d) size=(%d,%d)\n", dxw.iPosX, dxw.iPosX, dxw.iSizX, dxw.iSizY); if(dxw.dwFlags1 & FIXPARENTWIN){ - CalculateWindowPos(hwnd, iSizX, iSizY, &wp); + CalculateWindowPos(hwnd, dxw.iSizX, dxw.iSizY, &wp); if (IsDebug) OutTraceD("MoveWindow: dxw.hParentWnd=%x pos=(%d,%d) size=(%d,%d)\n", dxw.hParentWnd, wp.x, wp.y, wp.cx, wp.cy); res=(*pMoveWindow)(dxw.hParentWnd, wp.x, wp.y, wp.cx, wp.cy, FALSE); if(!res) OutTraceE("MoveWindow ERROR: dxw.hParentWnd=%x err=%d at %d\n", dxw.hParentWnd, GetLastError(), __LINE__); @@ -1425,34 +1178,6 @@ int HookInit(TARGETMAP *target, HWND hwnd) return 0; } -// Currently un-hooked - -HRESULT WINAPI extGDIGetDisplayMode(HDC dev, int mode) -{ - HRESULT res; - - //GHO: TO BE COMPLETED !!!! - - OutTraceD("GDIGetDisplayMode, mode=%x\n", mode); - - res=(*pGDIGetDisplayMode)(dev, mode); - if((dxw.dwFlags1 & EMULATESURFACE) && (dxw.VirtualPixelFormat.dwRGBBitCount == 8)){ - //lpddsd->ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; - //lpddsd->ddpfPixelFormat.dwRGBBitCount = 8; - //lpddsd->ddsCaps.dwCaps |= DDSCAPS_PALETTE; - } - else - if((dxw.dwFlags1 & EMULATESURFACE) && (dxw.VirtualPixelFormat.dwRGBBitCount == 16)){ - //lpddsd->ddpfPixelFormat.dwRGBBitCount = 16; - } - //OutTraceD("GetDisplayMode: returning WxH=(%dx%d), PixelFormat Flags=%x, RGBBitCount=%d, Caps=%x\n", - // lpddsd->dwWidth, lpddsd->dwHeight, - // lpddsd->ddpfPixelFormat.dwFlags, - // lpddsd->ddpfPixelFormat.dwRGBBitCount, - // lpddsd->ddsCaps.dwCaps); - return res; -} - HWND WINAPI extGetDesktopWindow(void) { // V2.1.73: correct ??? @@ -1470,21 +1195,6 @@ HWND WINAPI extGetDesktopWindow(void) } } -//BOOL WINAPI extColorCorrectPalette(HDC hDC, HPALETTE hPalette, DWORD dwFirstEntry, DWORD dwNumOfEntries -//) -//{ -// OutTraceD("extColorCorrectPalette: first=%d numentries=%d\n", dwFirstEntry, dwNumOfEntries); -// return(1); -//} - -void InitWindowPos(int x, int y, int w, int h) -{ - iPosX = x; - iPosY = y; - iSizX = w; - iSizY = h; -} - LPCSTR ProcToString(LPCSTR proc) { static char sBuf[24+1]; diff --git a/dll/dxhook.h b/dll/dxhook.h index 529b21d..8c3d789 100644 --- a/dll/dxhook.h +++ b/dll/dxhook.h @@ -1,8 +1,8 @@ -int HookDirectDraw(int); -int HookDDProxy(int); -int HookDirect3D(int); -int HookOle32(int); -int HookDirectInput(int); +int HookDirectDraw(char *, int); +int HookDDProxy(char *, int); +int HookDirect3D(char *, int); +int HookOle32(char *, int); +int HookDirectInput(char *, int); void InitPosition(int, int, int, int, int, int); -void InitWindowPos(int, int, int, int); +//void InitWindowPos(int, int, int, int); extern LPCSTR ProcToString(LPCSTR proc); diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index 88477b0..e51b646 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -2,8 +2,9 @@ #include "dxwcore.hpp" #include "syslibs.h" -extern GetCursorPos_Type pGetCursorPos; -extern ClientToScreen_Type pClientToScreen; +/* ------------------------------------------------------------------ */ +// Constructor, destructor, initialization.... +/* ------------------------------------------------------------------ */ dxwCore::dxwCore() { @@ -17,6 +18,11 @@ dxwCore::dxwCore() bActive = TRUE; bDInputAbs = 0; TimeShift = 0; + lpDDSPrimHDC = NULL; + //IsWithinDDraw = FALSE; + IsGDIPalette = FALSE; + + memset(PrimSurfaces, 0, sizeof(PrimSurfaces)); // preserved syslibs pointers pClientToScreen=ClientToScreen; @@ -38,10 +44,95 @@ void dxwCore::InitTarget(TARGETMAP *target) dwTFlags = target->tflags; gsModules = target->module; MaxFPS = target->MaxFPS; + CustomOpenGLLib = target->OpenGLLib; + if(!strlen(CustomOpenGLLib)) CustomOpenGLLib=NULL; // bounds control dwTargetDDVersion = target->dxversion; if(dwTargetDDVersion<0) dwTargetDDVersion=0; if(dwTargetDDVersion>10) dwTargetDDVersion=10; + TimeShift = target->InitTS; + if(TimeShift < -4) TimeShift = -4; + if(TimeShift > 4) TimeShift = 4; +} + +/* ------------------------------------------------------------------ */ +// Primary surfaces auxiliary functions +/* ------------------------------------------------------------------ */ + +void dxwCore::MarkPrimarySurface(LPDIRECTDRAWSURFACE ps) +{ + int i; + // OutTraceD("PRIMARYSURFACE add %x\n",ps); + for (i=0;iiTimeShift; + TimeShift=GetTimeShift(); if (TimeShift > 0) dwTick >>= TimeShift; if (TimeShift < 0) dwTick <<= -TimeShift; dwLastFakeTick += dwTick; dwLastRealTick = dwNextRealTick; return dwLastFakeTick; +} + +DWORD dxwCore::StretchTime(DWORD dwTimer) +{ + //extern DXWNDSTATUS *pStatus; + //TimeShift=pStatus->iTimeShift; + TimeShift=GetTimeShift(); + if (TimeShift > 0) dwTimer <<= TimeShift; + if (TimeShift < 0) dwTimer >>= -TimeShift; + return dwTimer; +} + +void dxwCore::GetSystemTime(LPSYSTEMTIME lpSystemTime) +{ + DWORD dwTick; + DWORD dwCurrentTick; + FILETIME CurrFileTime; + static DWORD dwStartTick=0; + static DWORD dwUpdateTick=0; + static FILETIME StartFileTime; + extern DXWNDSTATUS *pStatus; + + //TimeShift=pStatus->iTimeShift; + if(dwStartTick==0) { + SYSTEMTIME StartingTime; + // first time through, initialize & return true time + dwStartTick = (*pGetTickCount)(); + (*pGetSystemTime)(&StartingTime); + SystemTimeToFileTime(&StartingTime, &StartFileTime); + *lpSystemTime = StartingTime; + } + else { + dwCurrentTick=(*pGetTickCount)(); + dwTick=(dwCurrentTick-dwStartTick); + TimeShift=GetTimeShift(); + if (TimeShift > 0) dwTick >>= TimeShift; + if (TimeShift < 0) dwTick <<= -TimeShift; + // From MSDN: Contains a 64-bit value representing the number of + // 100-nanosecond intervals since January 1, 1601 (UTC). + // So, since 1mSec = 10.000 * 100nSec, you still have to multiply by 10.000. + CurrFileTime.dwHighDateTime = StartFileTime.dwHighDateTime; // wrong !!!! + CurrFileTime.dwLowDateTime = StartFileTime.dwLowDateTime + (10000 * dwTick); // wrong !!!! + FileTimeToSystemTime(&CurrFileTime, lpSystemTime); + // reset to avoid time jumps on TimeShift changes... + StartFileTime = CurrFileTime; + dwStartTick = dwCurrentTick; + } } \ No newline at end of file diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index c13085c..7bc7b0c 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -1,6 +1,8 @@ #include #include "syslibs.h" +#define DDSQLEN 0x10 + class dxwCore { // Construction/destruction @@ -12,6 +14,7 @@ public: public: // methods void InitTarget(TARGETMAP *); void SethWnd(HWND hwnd) {hWnd=hwnd;} + void InitWindowPos(int, int, int, int); HWND GethWnd(void) {return hWnd;} void SetScreenSize(void) {dwScreenWidth=800; dwScreenHeight=600;} void SetScreenSize(int x, int y) {if(x)dwScreenWidth=x; if(y)dwScreenHeight=y;} @@ -29,8 +32,17 @@ public: // methods RECT MapWindowRect(LPRECT lpRect); RECT MapWindowRect(void); void ScreenRefresh(void); - BOOL HandleFPS(); + BOOL HandleFPS(void); DWORD GetTickCount(void); + void MarkPrimarySurface(LPDIRECTDRAWSURFACE); + void UnmarkPrimarySurface(LPDIRECTDRAWSURFACE); + BOOL IsAPrimarySurface(LPDIRECTDRAWSURFACE); + LPDIRECTDRAWSURFACE GetPrimarySurface(void); + void SetPrimarySurface(void); + void ResetPrimarySurface(void); + void GetSystemTime(LPSYSTEMTIME lpSystemTime); + DWORD StretchTime(DWORD); + public: // simple data variables DDPIXELFORMAT ActualPixelFormat; @@ -50,6 +62,14 @@ public: // simple data variables DWORD MaxFPS; char *gsModules; int TimeShift; + LPDIRECTDRAWSURFACE lpDDSPrimHDC; + short iPosX; + short iPosY; + short iSizX; + short iSizY; + //BOOL IsWithinDDraw; // flag to avoid double intervention at ddraw & GDI level + BOOL IsGDIPalette; + char *CustomOpenGLLib; // Implementation protected: @@ -57,6 +77,7 @@ protected: DWORD dwScreenHeight; BOOL FullScreen; HWND hWnd; + DWORD PrimSurfaces[DDSQLEN+1]; ClientToScreen_Type pClientToScreen; ClipCursor_Type pClipCursor; GetClientRect_Type pGetClientRect; diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index bd15af3..b73389d 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -23,7 +23,7 @@ along with this program. If not, see . #include #include "dxwnd.h" -#define VERSION "2.02.02" +#define VERSION "2.02.04" LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam); @@ -125,6 +125,11 @@ void SetHookStatus(DXWNDSTATUS *s) *pStatus=*s; } +int GetTimeShift() +{ + return pStatus->iTimeShift; +} + LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam) { char name[MAX_PATH]; @@ -166,6 +171,7 @@ LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam) pStatus->IsFullScreen=FALSE; pStatus->hWnd=hwnd; pStatus->dwPid=GetProcessId(GetCurrentProcess()); + pStatus->iTimeShift=pMapping[i].InitTS; DxWndStatus = *pStatus; HookInit(&pMapping[i], hwnd); } diff --git a/dll/dxwnd.def b/dll/dxwnd.def index c3ea5ad..c8da73a 100644 --- a/dll/dxwnd.def +++ b/dll/dxwnd.def @@ -5,3 +5,4 @@ EXPORTS EndHook @3 GetDllVersion @4 GetHookStatus @5 + SetHookStatus @6 diff --git a/dll/dxwnd.ncb b/dll/dxwnd.ncb new file mode 100644 index 0000000000000000000000000000000000000000..ca6a39674f7436b78a630d223e27f07ae6ee43b3 GIT binary patch literal 11264 zcmeI$Jqp4w9Eai5Pf*-d9I_W`yQr%~+=@a64gfeZrG3}-ot00Q|IICz26dw!OVjxoAk-mkNo zo`O|!yxkZ7WM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dll/dxwnd.ws2008.suo b/dll/dxwnd.ws2008.suo index fd81a23bd3c33534b1d0ca3946832e4cd9d495fe..3e8602a6f162c77056b1c83ca27372b37108c2ff 100644 GIT binary patch delta 17360 zcmd6v349dg-N$Fb?q(M-ge2sEKz0Km0YXSZI0A$-;T8x)E~5~V%~6&Fl8uCOxuGor z=4tDN716f#dKIG87Cs+CJy7aFYw<+UzF4gnR#7<$yuaVfe>RH;MGED8@VC!@zVpoU zJTvpmbNpxGswY~lI$_(Eo))HQnhqHuQq#EYgwCEjcg}>GwhG3s!r$n-!(w#XVr;1R zRy*_+>i6MEX${!?0ki~K3N3?{Lo1=pPykvDHQIa;k!Sxt>xW-Fr?H}p$SrDt(^t5Acn4Y8d#YZ;{ac$Do6ShpX%7rppPjKj+k;19o zUg<%#S}T8>$*fY-@ivpg9C|qR*<1ESOtGW5bJqmP@rWtTwn#%7JTrg0DJs8Rregyx z@w;tQMC53k;K+bW(^1cD(668*9QE9JF2;HX(3yGj2o|>jmv55lBPb*i4ULoLTeVO!n=6Xyo6Z2N|ls%?VO{{ z(dx8XtyC-4#%a}veOkR%rg^bl#uR#A-W4^hE*9sK{d&p=YTM+P0BpZz!g$#R2`doB{iB7A z6~@g8_=!h+t+1Z3$8iV3O~Tj)7Ynq+Wv;krsnM7yfHin?)?Big@`{wOh%m* zc1~CY*kRZV*PxAA>3YNFu^GbH-$uY@7$S^^T?d<|GE-O{??;{_+#ryd-U)ji;_bqQ z!rmz9ekCjy?AOAYg$)MVC+sC*%ayaSvgc&tznnRBwWY;nK3{QJ!{X|)j52RI zl4*`1)%89f?g34Ddb-uqH2Ft8dkxx5XQ>05Ko_Z3 zN(k#NthX?p*I?M}i}Qr_hn*qmCJ5t66vG~l_{NZQ6D6IWj5}vR^#a#RLKbp6>;;JL z6gD6B21)k|E1ep#W>LE`^n}G)zSf}4z*u9AFRLrMdP=p0_@`;F|D0Wic~cn6ebU0! zEt8`I;j$+Rv6H(Ik|EY28tMu$bce{;C#FISY@}oiybKJylw?Lx^Bg|Ttp0WmxQ@i;!tPeKf@v*RLUZ4N^W z$04#L=yQnS6hy{w+KjX_h{-(ASz%!SWb7YW(LhKP#x9_5at0}qGRSlz7aosW?^3HJV%ujreI=K zl8_Ln)k=`hLw2*VK8%=U%!2NR&Co22_C8^62;(h#Q|!|cb4)rT>7pGicOnKhLq}mL zusan9bPHtR-C=WQ&k&Xko438Muo&1IVe|Ri>}YD9o)c!{OkbUtIm9rU2F{9f>D^m8 zv3Z+Yq5X8gBh2SK4l&DG54C~KkSeSccABs}VSMO@37aI0tzfdS8Nzt?W(zA3<_4Qb z#`fzI$Sb!%5-t`7q%{azDU4l+(eEI>RT#UR+a%piVa)GdVJ`^dEa{-I_YfQH*A4g& zfyX3acd$={eIbl%r7wkDgU*guYaJ9J9bZpjyfW#+MhWASo-eFi7)G9eRw3{vfk>w< z7Peei4%iA|8$;4<683#zjY#(cVcUgm1iMSv1HuZx9yA!P{~m#(0QXA5{lb8>r-eNy z%mem3Y&+r?h4G@$W_VfH5ZJE>`%u_qu#bd&PR9Gs%c!}~m=M_zbDNj{3rQF$3`lDa zo1ud+FYH)h$-+2e?kX%@*le)g!fq0_6fCe<;0l54fmaIKC@dFjldvC!upbM%OV|{o z`>8O@B#aYb!+b*Q{fNzODmdyog2V0r<=z_E^i2g zs4t-&&1)mKkBAC9jf%I5oFlMDAxl``%|Qd0gyj;q|ad!F+lT-@E=JPAo#|alxs*Hb3NQ zPL5c=K~3>L*q(zeT?*F4{7ust|FN*$4H0crR9sBRK+vEq=DY}bRN|2PTEA;dRII^< z_25i}9Xzv&ho*{MAu&1Um>%@a4BHWtd7!(5{XtkN*dAdo&lE`a%qs%l7RH&*--LZB zjP3q}u-14YS%_}@a!&!DSAiRu`Geyl#E!BuA)VUYxr8o0SL_$)<~Abw#hfs~_tzC-nFWFCw^xXgQ;3 z)tnQR+iuq*9Dk$+7e6;|c?fuAqHLW7!ghn$FEEUQ$ht%0AqLL4$+|#3 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 W7T+r%Z8vpWW!vE2HJE>P;`~2N!&IsO delta 2586 zcmb7GZA_C_6uzf@-`CQXw$c|UrE{&8T9s)*Bz#I0#~7d#f<%-bY|FAa&1ADUbVN~c zpJdUVEZ6N9Mz_SwOr-zBWL3ywm>(GTXNe)WNn$eH)L`Z`p*#02^@AT1@0+Lh+;i^7 zx#ygFPP-pS-NX8WxgKDQ324p6n2rdAFcpu-HQuR)lW?eA8qldA2_`!9eX<~?4!uzs zk+xb!7qnRaynPY$G(FglyQC3A36V4-j(tD7F(4T*W{|K`u1$f`nUbJQ!UuAbqLN^* z4jYxlb#5ZX0rRO}Fiq!B?;|WE_@{Y`sb50KCA>mdN?1ndB4`TI9?|nkn~snAK#i8A zdPw5RtUte`ueCFIW#>?Mcw5u_P>u|cwljRxk%bP=^$dfIGq8qJu* zo$AMsj`!6);K7dcFEM8KX0IY&1n65usAR?TTcv%KY&pi$_oFUjCB`y*!Y6LrGT}sb zrvJ%cUuF%DltM-%a~}Bc>{JeKD*}~|`oWQsNoR`iH1i`_kR#UQ;_%e`#Ed`|D3N#? z%;R}RDCX`WaPqo^;N~#^7w`7d@EB1MXQje~xzm&00xxzr*J(bUbY8|GYn~!p(QCqo z*}EWs9WD}D^B^yJ-(`Y`!;e16q2F-Xhz*AF$nGNEZvq>C-vox}=)6E0|J_UH<@%wC zk2@d(zj(Bflypb(&uFhF8p{s?w#Am}?Tlf(Vm&B)t~qfVRj6tCIs^vpEr3EX%7B*= zV$BM)p@dx_3lB;liR(1+V_BdXz{_JMkRXGfm0?*lSlDC2!}VrtGXx^5hZJzrjZDcK z%O`1Mz<*cQ!%InCG+cQhl@A!f!SDD;0hvzh~no%;1d1 znhSK&GKw;Mu%S%aM?|!!#g;;mmdps@H+%J5$$^JFxDd=>a4@gnlfuf@>F z!zHjosIHx_^7fL1po+U>Fi0Y=VXU)}LWew7Ds)nLvja+aBP2YkCije9+MI7d*X>O& zY&Gp@EjE=GvwHo#7TXrer*E-#`WXA>Xn_?&;r^)FaZ4BJQ3pCLCOo$Zld9lM~k>k1~dOEi-PW)7uKNKb3)Vt_8Vnek#dO4qp#{{tVfUT@d{y62RZCL zpPkJ%7GMll*wZRE1yz?YiETtZ@4&MtcYc2%iuHA6>oU$r>Hk7py4613BdtPgk6T z{hzHAf+s2zWv0g!gpqj|>lZ~4@5VFv_YP=!HtC9&nFi^JoUElOdJB#fv_LD)a}0uF z%uT(hg7XQUY2K1)o`{~6L@z*idDXzdN}Hn9dfk&Z*H`US19Z83LIYtrp@4v+r&Xy$ z5I0W;a$h5&n(#WIhEPkWBdjH?Bh(W@glz;|Gq@)4f2Mb^!1V!fJ|t`>gb5vl9fXev z(QAV@QnB?`Ff!(fx<*<7PUFsBK8=hAp$7LJD5h9c_$eQ}N^h*u|02!?GukG&mL%Yv zflJjgrMT%dgW;=9P@Wt`C$C;ep?VlE$)Q5taJ=&_BauBa7FK>D4GS6W8mp1Z$c%H7 jOXL^{il|1_@?jU80e>>aX@h@)89#~*JX9arW+3n%Y!}z0 diff --git a/dll/glhook.cpp b/dll/glhook.cpp index 03e7268..47dbc64 100644 --- a/dll/glhook.cpp +++ b/dll/glhook.cpp @@ -8,10 +8,6 @@ glViewport_Type pglViewport; glScissor_Type pglScissor; glGetIntegerv_Type pglGetIntegerv; -//extern GLenum WINAPI glGetError(); - -extern short iPosX, iPosY, iSizX, iSizY; - void WINAPI extglViewport(GLint x, GLint y, GLsizei width, GLsizei height) { RECT client; @@ -44,21 +40,6 @@ void WINAPI extglGetIntegerv(GLenum pname, GLint *params) { (*pglGetIntegerv)(pname, params); OutTraceD("glGetIntegerv: pname=%d\n", pname); -// if(glGetError()!=GL_NO_ERROR) OutTraceE("glGetIntegerv: ERROR %d at %d\n", glGetError(), __LINE__); -#if 0 - if (pname==GL_VIEWPORT){ - OutTraceD("glGetIntegerv: pname=GL_VIEWPORT real viewport=(%d,%d)-(%d,%d)\n", - params[0], params[1], params[2], params[3]); - //params[0]=(GLboolean)iPosX; - //params[1]=(GLboolean)iPosY; - params[0]=(GLint)0; - params[1]=(GLint)0; - params[2]=(GLint)iSizX; - params[3]=(GLint)iSizY; - OutTraceD("glGetIntegerv: pname=GL_VIEWPORT remapped viewport=(%d,%d)-(%d,%d)\n", - params[0], params[1], params[2], params[3]); - } -#endif } FARPROC Remap_gl_ProcAddress(LPCSTR proc, HMODULE hModule) @@ -82,19 +63,18 @@ FARPROC Remap_gl_ProcAddress(LPCSTR proc, HMODULE hModule) return NULL; } -void HookOpenGLLibs(int dxversion, char *module) +void HookOpenGLLibs(char *module, char *customlib) { void *tmp; char *DefOpenGLModule="OpenGL32.dll"; - if (dxversion!=10) return; - if (!module) module=DefOpenGLModule; + if (!customlib) customlib=DefOpenGLModule; - tmp = HookAPI(module, NULL, "glViewport", extglViewport); + tmp = HookAPI(module, customlib, NULL, "glViewport", extglViewport); if(tmp) pglViewport = (glViewport_Type)tmp; - tmp = HookAPI(module, NULL, "glScissor", extglScissor); + tmp = HookAPI(module, customlib, NULL, "glScissor", extglScissor); if(tmp) pglScissor = (glScissor_Type)tmp; - tmp = HookAPI(module, NULL, "glGetIntegerv", extglGetIntegerv); + tmp = HookAPI(module, customlib, NULL, "glGetIntegerv", extglGetIntegerv); if(tmp) pglGetIntegerv = (glGetIntegerv_Type)tmp; return; diff --git a/dll/glhook.h b/dll/glhook.h index 38d37d2..304a081 100644 --- a/dll/glhook.h +++ b/dll/glhook.h @@ -1,7 +1,7 @@ #include "gl.h" extern FARPROC Remap_gl_ProcAddress(LPCSTR, HMODULE); -extern void HookOpenGLLibs(int, char *); +extern void HookOpenGLLibs(char *, char *); typedef void (WINAPI *glViewport_Type)(GLint, GLint, GLsizei, GLsizei); typedef void (WINAPI *glScissor_Type)(GLint, GLint, GLsizei, GLsizei); diff --git a/dll/hd3d.cpp b/dll/hd3d.cpp index 1bf3a27..485bd9c 100644 --- a/dll/hd3d.cpp +++ b/dll/hd3d.cpp @@ -33,16 +33,16 @@ GetAdapterDisplayMode_Type pGetAdapterDisplayMode; GetDisplayMode_Type pGetDisplayMode; DWORD dwD3DVersion; -int HookDirect3D(int version){ +int HookDirect3D(char *module, int version){ HINSTANCE hinst; void *tmp; LPDIRECT3D9 lpd3d; switch(version){ case 0: - tmp = HookAPI("d3d8.dll", NULL, "Direct3DCreate8", extDirect3DCreate8); + tmp = HookAPI(module, "d3d8.dll", NULL, "Direct3DCreate8", extDirect3DCreate8); if(tmp) pDirect3DCreate8 = (Direct3DCreate8_Type)tmp; - tmp = HookAPI("d3d9.dll", NULL, "Direct3DCreate9", extDirect3DCreate9); + tmp = HookAPI(module, "d3d9.dll", NULL, "Direct3DCreate9", extDirect3DCreate9); if(tmp) pDirect3DCreate9 = (Direct3DCreate9_Type)tmp; break; case 8: @@ -126,13 +126,12 @@ HRESULT WINAPI extReset(void *pd3dd, D3DPRESENT_PARAMETERS* pPresentationParamet HRESULT WINAPI extGetDisplayMode(void *lpd3d, D3DDISPLAYMODE *pMode) { HRESULT res; - extern short iSizX, iSizY; res=(*pGetDisplayMode)(lpd3d, pMode); OutTraceD("DEBUG: GetDisplayMode: size=(%dx%d) RefreshRate=%d Format=%d\n", pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format); if(dxw.dwFlags2 & KEEPASPECTRATIO){ - pMode->Width=iSizX; - pMode->Height=iSizY; + pMode->Width=dxw.iSizX; + pMode->Height=dxw.iSizY; OutTraceD("DEBUG: GetDisplayMode: fixed size=(%dx%d)\n", pMode->Width, pMode->Height); } return res; @@ -159,13 +158,12 @@ HRESULT WINAPI extEnumAdapterModes9(void *lpd3d, UINT Adapter, D3DFORMAT Format, HRESULT WINAPI extGetAdapterDisplayMode(void *lpd3d, UINT Adapter, D3DDISPLAYMODE *pMode) { HRESULT res; - extern short iSizX, iSizY; res=(*pGetAdapterDisplayMode)(lpd3d, Adapter, pMode); OutTraceD("DEBUG: GetAdapterDisplayMode: size=(%dx%d) RefreshRate=%d Format=%d\n", pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format); if(dxw.dwFlags2 & KEEPASPECTRATIO){ - pMode->Width=iSizX; - pMode->Height=iSizY; + pMode->Width=dxw.iSizX; + pMode->Height=dxw.iSizY; OutTraceD("DEBUG: GetDisplayMode: fixed size=(%dx%d)\n", pMode->Width, pMode->Height); } return res; diff --git a/dll/hddproxy.cpp b/dll/hddproxy.cpp index 0875768..a970e45 100644 --- a/dll/hddproxy.cpp +++ b/dll/hddproxy.cpp @@ -169,11 +169,11 @@ extern GDIGetDC_Type pGDIGetDC; extern GDIGetDC_Type pGDIGetWindowDC; extern GDIReleaseDC_Type pGDIReleaseDC; extern CreateDC_Type pGDICreateDC; -extern CreateCompatibleDC_Type pCreateCompatibleDC; -extern BitBlt_Type pBitBlt; -extern PatBlt_Type pPatBlt; -extern StretchBlt_Type pStretchBlt; -extern DeleteDC_Type pDeleteDC; +extern CreateCompatibleDC_Type pGDICreateCompatibleDC; +extern BitBlt_Type pGDIBitBlt; +extern PatBlt_Type pGDIPatBlt; +extern StretchBlt_Type pGDIStretchBlt; +extern DeleteDC_Type pGDIDeleteDC; SaveDC_Type pSaveDC; RestoreDC_Type pRestoreDC; extern BeginPaint_Type pBeginPaint; @@ -273,7 +273,7 @@ FARPROC WINAPI extGetProcAddressProxy(HMODULE hModule, LPCSTR proc) // // ------------------------------------------------------------------------------------------ // -int HookDDProxy(int dxVersion) +int HookDDProxy(char *module, int dxVersion) { HINSTANCE hinst; void *tmp; @@ -283,60 +283,60 @@ int HookDDProxy(int dxVersion) dxw.dwFlags1 |= OUTDDRAWTRACE; - pCreateCompatibleDC=CreateCompatibleDC; + pGDICreateCompatibleDC=CreateCompatibleDC; pGDIGetDC=GetDC; pGDIGetWindowDC=GetWindowDC; pGDIReleaseDC=ReleaseDC; - pCreateDC=CreateDC; - pBitBlt=BitBlt; - pPatBlt=PatBlt; - pStretchBlt=StretchBlt; - pDeleteDC=DeleteDC; + pGDICreateDC=CreateDC; + pGDIBitBlt=BitBlt; + pGDIPatBlt=PatBlt; + pGDIStretchBlt=StretchBlt; + pGDIDeleteDC=DeleteDC; pSaveDC=SaveDC; pRestoreDC=RestoreDC; - pSelectPalette=SelectPalette; - tmp = HookAPI("GDI32.dll", CreateCompatibleDC, "CreateCompatibleDC", extCreateCompatibleDCProxy); - if(tmp) pCreateCompatibleDC = (CreateCompatibleDC_Type)tmp; - tmp = HookAPI("user32.dll", GetDC, "GetDC", extGDIGetDCProxy); + pGDISelectPalette=SelectPalette; + tmp = HookAPI(module, "GDI32.dll", CreateCompatibleDC, "CreateCompatibleDC", extCreateCompatibleDCProxy); + if(tmp) pGDICreateCompatibleDC = (CreateCompatibleDC_Type)tmp; + tmp = HookAPI(module, "user32.dll", GetDC, "GetDC", extGDIGetDCProxy); if(tmp) pGDIGetDC = (GDIGetDC_Type)tmp; - tmp = HookAPI("user32.dll", GetWindowDC, "GetWindowDC", extGetWindowDCProxy); + tmp = HookAPI(module, "user32.dll", GetWindowDC, "GetWindowDC", extGetWindowDCProxy); if(tmp) pGDIGetWindowDC = (GDIGetDC_Type)tmp; - tmp = HookAPI("user32.dll", ReleaseDC, "ReleaseDC", extGDIReleaseDCProxy); + tmp = HookAPI(module, "user32.dll", ReleaseDC, "ReleaseDC", extGDIReleaseDCProxy); if(tmp) pGDIReleaseDC = (GDIReleaseDC_Type)tmp; - tmp = HookAPI("GDI32.dll", CreateDCA, "CreateDCA", extCreateDCProxy); - if(tmp) pCreateDC = (CreateDC_Type)tmp; - tmp = HookAPI("GDI32.dll", BitBlt, "BitBlt", extBitBltProxy); - if(tmp) pBitBlt = (BitBlt_Type)tmp; - tmp = HookAPI("GDI32.dll", StretchBlt, "StretchBlt", extStretchBltProxy); - if(tmp) pStretchBlt = (StretchBlt_Type)tmp; - tmp = HookAPI("GDI32.dll", PatBlt, "PatBlt", extPatBltProxy); - if(tmp) pPatBlt = (PatBlt_Type)tmp; - tmp = HookAPI("GDI32.dll", DeleteDC, "DeleteDC", extDeleteDCProxy); - if(tmp) pDeleteDC = (DeleteDC_Type)tmp; - tmp = HookAPI("GDI32.dll", SaveDC, "SaveDC", extSaveDCProxy); + tmp = HookAPI(module, "GDI32.dll", CreateDCA, "CreateDCA", extCreateDCProxy); + if(tmp) pGDICreateDC = (CreateDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", BitBlt, "BitBlt", extBitBltProxy); + if(tmp) pGDIBitBlt = (BitBlt_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", StretchBlt, "StretchBlt", extStretchBltProxy); + if(tmp) pGDIStretchBlt = (StretchBlt_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", PatBlt, "PatBlt", extPatBltProxy); + if(tmp) pGDIPatBlt = (PatBlt_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", DeleteDC, "DeleteDC", extDeleteDCProxy); + if(tmp) pGDIDeleteDC = (DeleteDC_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", SaveDC, "SaveDC", extSaveDCProxy); if(tmp) pGDISaveDC = (SaveDC_Type)tmp; - tmp = HookAPI("GDI32.dll", RestoreDC, "RestoreDC", extRestoreDCProxy); + tmp = HookAPI(module, "GDI32.dll", RestoreDC, "RestoreDC", extRestoreDCProxy); if(tmp) pGDIRestoreDC = (RestoreDC_Type)tmp; - tmp = HookAPI("GDI32.dll", SelectPalette, "SelectPalette", extSelectPaletteProxy); - if(tmp) pSelectPalette = (SelectPalette_Type)tmp; - tmp = HookAPI("GDI32.dll", RealizePalette, "RealizePalette", extRealizePaletteProxy); - if(tmp) pRealizePalette = (RealizePalette_Type)tmp; - tmp = HookAPI("GDI32.dll", GetSystemPaletteEntries, "GetSystemPaletteEntries", extGetSystemPaletteEntriesProxy); - if(tmp) pGetSystemPaletteEntries = (GetSystemPaletteEntries_Type)tmp; - tmp = HookAPI("user32.dll", BeginPaint, "BeginPaint", extBeginPaintProxy); + tmp = HookAPI(module, "GDI32.dll", SelectPalette, "SelectPalette", extSelectPaletteProxy); + if(tmp) pGDISelectPalette = (SelectPalette_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", RealizePalette, "RealizePalette", extRealizePaletteProxy); + if(tmp) pGDIRealizePalette = (RealizePalette_Type)tmp; + tmp = HookAPI(module, "GDI32.dll", GetSystemPaletteEntries, "GetSystemPaletteEntries", extGetSystemPaletteEntriesProxy); + if(tmp) pGDIGetSystemPaletteEntries = (GetSystemPaletteEntries_Type)tmp; + tmp = HookAPI(module, "user32.dll", BeginPaint, "BeginPaint", extBeginPaintProxy); if(tmp) pBeginPaint = (BeginPaint_Type)tmp; pGetProcAddress = (GetProcAddress_Type)GetProcAddress; - tmp = HookAPI("KERNEL32.dll", GetProcAddress, "GetProcAddress", extGetProcAddressProxy); + tmp = HookAPI(module, "KERNEL32.dll", GetProcAddress, "GetProcAddress", extGetProcAddressProxy); if(tmp) pGetProcAddress = (GetProcAddress_Type)tmp; switch(dxVersion){ case 0: // automatic - tmp = HookAPI("ddraw.dll", NULL, "DirectDrawCreate", extDirectDrawCreateProxy); + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawCreate", extDirectDrawCreateProxy); if(tmp) pDirectDrawCreate = (DirectDrawCreate_Type)tmp; - tmp = HookAPI("ddraw.dll", NULL, "DirectDrawCreateEx", extDirectDrawCreateExProxy); + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawCreateEx", extDirectDrawCreateExProxy); if(tmp) pDirectDrawCreateEx = (DirectDrawCreateEx_Type)tmp; - tmp = HookAPI("ddraw.dll", NULL, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); if(tmp) pDirectDrawEnumerate = (DirectDrawEnumerate_Type)tmp; - tmp = HookAPI("ddraw.dll", NULL, "DirectDrawEnumerateExA", extDirectDrawEnumerateExProxy); + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawEnumerateExA", extDirectDrawEnumerateExProxy); if(tmp) pDirectDrawEnumerateEx = (DirectDrawEnumerateEx_Type)tmp; break; case 1: @@ -352,8 +352,8 @@ int HookDDProxy(int dxVersion) if(pDirectDrawCreate){ LPDIRECTDRAW lpdd; BOOL res; - HookAPI("ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreateProxy); - HookAPI("ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); + HookAPI(module, "ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreateProxy); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); res=extDirectDrawCreateProxy(0, &lpdd, 0); if (res){ OutTraceP("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res)); @@ -372,9 +372,9 @@ int HookDDProxy(int dxVersion) if(pDirectDrawCreate){ LPDIRECTDRAW lpdd; BOOL res; - HookAPI("ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreateProxy); - HookAPI("ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); - HookAPI("ddraw.dll", pDirectDrawEnumerateEx, "DirectDrawEnumerateExA", extDirectDrawEnumerateExProxy); + HookAPI(module, "ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreateProxy); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerateEx, "DirectDrawEnumerateExA", extDirectDrawEnumerateExProxy); res=extDirectDrawCreateProxy(0, &lpdd, 0); if (res){ OutTraceP("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res)); @@ -386,7 +386,7 @@ int HookDDProxy(int dxVersion) if(pDirectDrawCreateEx){ LPDIRECTDRAW lpdd; BOOL res; - HookAPI("ddraw.dll", pDirectDrawCreateEx, "DirectDrawCreateEx", extDirectDrawCreateExProxy); + HookAPI(module, "ddraw.dll", pDirectDrawCreateEx, "DirectDrawCreateEx", extDirectDrawCreateExProxy); res=extDirectDrawCreateExProxy(0, &lpdd, dd7, 0); if (res) OutTraceP("DirectDrawCreateEx: ERROR res=%x(%s)\n", res, ExplainDDError(res)); lpdd->Release(); @@ -1868,11 +1868,11 @@ extern GDIGetDC_Type pGDIGetDC; //GDIGetDC_Type pGDIGetWinDC; extern GDIReleaseDC_Type pGDIReleaseDC; extern CreateDC_Type pGDICreateDC; -extern CreateCompatibleDC_Type pCreateCompatibleDC; -extern BitBlt_Type pBitBlt; -extern PatBlt_Type pPatBlt; -extern StretchBlt_Type pStretchBlt; -extern DeleteDC_Type pDeleteDC; +extern CreateCompatibleDC_Type pGDICreateCompatibleDC; +extern BitBlt_Type pGDIBitBlt; +extern PatBlt_Type pGDIPatBlt; +extern StretchBlt_Type pGDIStretchBlt; +extern DeleteDC_Type pGDIDeleteDC; extern SaveDC_Type pSaveDC; extern RestoreDC_Type pRestoreDC; @@ -1907,7 +1907,7 @@ HDC WINAPI extCreateDCProxy(LPSTR Driver, LPSTR Device, LPSTR Output, CONST DEVM OutTraceP("GDI.CreateDC: PROXED Driver=%s Device=%s Output=%s InitData=%x\n", Driver?Driver:"(NULL)", Device?Device:"(NULL)", Output?Output:"(NULL)", InitData); - RetHDC=(*pCreateDC)(Driver, Device, Output, InitData); + RetHDC=(*pGDICreateDC)(Driver, Device, Output, InitData); if(RetHDC) OutTraceP("GDI.CreateDC: returning HDC=%x\n", RetHDC); else @@ -1919,7 +1919,7 @@ HDC WINAPI extCreateCompatibleDCProxy(HDC hdc) { HDC RetHdc; OutTraceP("GDI.CreateCompatibleDC: PROXED hdc=%x\n", hdc); - RetHdc=(*pCreateCompatibleDC)(hdc); + RetHdc=(*pGDICreateCompatibleDC)(hdc); if(RetHdc) OutTraceP("GDI.CreateCompatibleDC: returning HDC=%x\n", RetHdc); else @@ -1934,7 +1934,7 @@ BOOL WINAPI extBitBltProxy(HDC hdcDest, int nXDest, int nYDest, int nWidth, int OutTraceP("GDI.BitBlt: PROXED HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d hdcSrc=%x nXSrc=%d nYSrc=%d dwRop=%x(%s)\n", hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop, ExplainROP(dwRop)); - res=(*pBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); + res=(*pGDIBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); if(!res) OutTraceP("GDI.BitBlt: ERROR err=%d\n", GetLastError()); return res; } @@ -1946,7 +1946,7 @@ BOOL WINAPI extPatBltProxy(HDC hdcDest, int nXDest, int nYDest, int nWidth, int OutTraceP("GDI.PatBlt: PROXED HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d dwRop=%x(%s)\n", hdcDest, nXDest, nYDest, nWidth, nHeight, dwRop, ExplainROP(dwRop)); - res=(*pPatBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, dwRop); + res=(*pGDIPatBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, dwRop); if(!res) OutTraceP("GDI.PatBlt: ERROR err=%d\n", GetLastError()); return res; } @@ -1959,7 +1959,7 @@ BOOL WINAPI extStretchBltProxy(HDC hdcDest, int nXDest, int nYDest, int nWidth, OutTraceP("GDI.StretchBlt: PROXED HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d hdcSrc=%x nXSrc=%d nYSrc=%d nWSrc=%d nHSrc=%d dwRop=%x(%s)\n", hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop, ExplainROP(dwRop)); - res=(*pStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop); + res=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop); if(!res) OutTraceP("GDI.StretchBlt: ERROR err=%d\n", GetLastError()); return res; } @@ -1969,7 +1969,7 @@ BOOL WINAPI extDeleteDCProxy(HDC hdc) BOOL res; OutTraceP("GDI.DeleteDC: PROXED hdc=%x\n", hdc); - res=(*pDeleteDC)(hdc); + res=(*pGDIDeleteDC)(hdc); if(!res) OutTraceP("GDI.DeleteDC: ERROR err=%d\n", GetLastError()); return res; } @@ -1996,7 +1996,7 @@ HPALETTE WINAPI extSelectPaletteProxy(HDC hdc, HPALETTE hpal, BOOL bForceBackgro { HPALETTE ret; - ret=(*pSelectPalette)(hdc, hpal, bForceBackground); + ret=(*pGDISelectPalette)(hdc, hpal, bForceBackground); OutTraceP("GDI.SelectPalette: PROXED hdc=%x hpal=%x ForceBackground=%x ret=%x\n", hdc, hpal, bForceBackground, ret); return ret; } @@ -2005,7 +2005,7 @@ UINT WINAPI extRealizePaletteProxy(HDC hdc) { UINT ret; - ret=(*pRealizePalette)(hdc); + ret=(*pGDIRealizePalette)(hdc); OutTraceP("GDI.RealizePalette: PROXED hdc=%x ret=%x\n", hdc, ret); return ret; } @@ -2014,7 +2014,7 @@ UINT WINAPI extGetSystemPaletteEntriesProxy(HDC hdc, UINT iStartIndex, UINT nEnt { UINT ret; - ret=(*pGetSystemPaletteEntries)(hdc, iStartIndex, nEntries, lppe); + ret=(*pGDIGetSystemPaletteEntries)(hdc, iStartIndex, nEntries, lppe); OutTrace("GDI.GetSystemPaletteEntries: PROXED hdc=%x start=%d num=%d ret=%d\n", hdc, iStartIndex, nEntries, ret); if(!ret) OutTrace("GDI.GetSystemPaletteEntries: ERROR err=%d\n", GetLastError()); return ret; diff --git a/dll/hddraw.cpp b/dll/hddraw.cpp index 3a2e390..2193ac5 100644 --- a/dll/hddraw.cpp +++ b/dll/hddraw.cpp @@ -94,14 +94,6 @@ HDC WINAPI extGDIGetDC(HWND); HDC WINAPI extGDIGetWindowDC(HWND); int WINAPI extGDIReleaseDC(HWND, HDC); -extern short iPosX, iPosY, iSizX, iSizY; - -/* ------ */ -GDIGetDC_Type pGDIGetDC; -GDIGetDC_Type pGDIGetWindowDC; -GDIReleaseDC_Type pGDIReleaseDC; -/* ------ */ - /* DirectDraw APIs */ DirectDrawCreate_Type pDirectDrawCreate; DirectDrawCreateEx_Type pDirectDrawCreateEx; @@ -215,7 +207,6 @@ SetEntries_Type pSetEntries; #define MAXBACKBUFFERS 4 -//LPDIRECTDRAWSURFACE lpDDSHDC=NULL, lpDDSEmu_Prim=NULL, lpDDSEmu_Back=NULL; LPDIRECTDRAWSURFACE lpDDSEmu_Prim=NULL, lpDDSEmu_Back=NULL; LPDIRECTDRAWSURFACE lpDDSBack=NULL; LPDIRECTDRAWCLIPPER lpDDC=NULL; @@ -479,7 +470,7 @@ void FixPixelFormat(int ColorDepth, DDPIXELFORMAT *pf) // ------------------------------------------------------------------------------------- static void HookDDSession(LPDIRECTDRAW *, int); -CoCreateInstance_Type pCoCreateInstance=NULL; +//CoCreateInstance_Type pCoCreateInstance=NULL; HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID FAR* ppv) { @@ -526,18 +517,18 @@ HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, return res; } -int HookOle32(int version) +int HookOle32(char *module, int version) { // used by Axis & Allies .... void *tmp; //return 0; OutTraceD("HookOle32 version=%d\n", version); //GHO - tmp = HookAPI("ole32.dll", NULL, "CoCreateInstance", extCoCreateInstance); + tmp = HookAPI(module, "ole32.dll", NULL, "CoCreateInstance", extCoCreateInstance); if(tmp) pCoCreateInstance = (CoCreateInstance_Type)tmp; return 0; } -int HookDirectDraw(int version) +int HookDirectDraw(char *module, int version) { HINSTANCE hinst; void *tmp; @@ -546,13 +537,13 @@ int HookDirectDraw(int version) OutTraceD("HookDirectDraw version=%d\n", version); //GHO switch(version){ case 0: // automatic - tmp = HookAPI("ddraw.dll", NULL, "DirectDrawCreate", extDirectDrawCreate); + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawCreate", extDirectDrawCreate); if(tmp) pDirectDrawCreate = (DirectDrawCreate_Type)tmp; - tmp = HookAPI("ddraw.dll", NULL, "DirectDrawCreateEx", extDirectDrawCreateEx); + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawCreateEx", extDirectDrawCreateEx); if(tmp) pDirectDrawCreateEx = (DirectDrawCreateEx_Type)tmp; - tmp = HookAPI("ddraw.dll", NULL, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); if(tmp) pDirectDrawEnumerate = (DirectDrawEnumerate_Type)tmp; - tmp = HookAPI("ddraw.dll", NULL, "DirectDrawEnumerateExA", extDirectDrawEnumerateExProxy); + tmp = HookAPI(module, "ddraw.dll", NULL, "DirectDrawEnumerateExA", extDirectDrawEnumerateExProxy); if(tmp) pDirectDrawEnumerateEx = (DirectDrawEnumerateEx_Type)tmp; break; case 1: @@ -568,8 +559,8 @@ int HookDirectDraw(int version) if(pDirectDrawCreate){ LPDIRECTDRAW lpdd; BOOL res; - HookAPI("ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreate); - HookAPI("ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); + HookAPI(module, "ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreate); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); res=extDirectDrawCreate(0, &lpdd, 0); if (res){ OutTraceE("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res)); @@ -588,9 +579,9 @@ int HookDirectDraw(int version) if(pDirectDrawCreate){ LPDIRECTDRAW lpdd; BOOL res; - HookAPI("ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreateProxy); - HookAPI("ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); - HookAPI("ddraw.dll", pDirectDrawEnumerateEx, "DirectDrawEnumerateExA", extDirectDrawEnumerateExProxy); + HookAPI(module, "ddraw.dll", pDirectDrawCreate, "DirectDrawCreate", extDirectDrawCreateProxy); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerate, "DirectDrawEnumerateA", extDirectDrawEnumerateProxy); + HookAPI(module, "ddraw.dll", pDirectDrawEnumerateEx, "DirectDrawEnumerateExA", extDirectDrawEnumerateExProxy); res=extDirectDrawCreate(0, &lpdd, 0); if (res) OutTraceE("DirectDrawCreate: ERROR res=%x(%s)\n", res, ExplainDDError(res)); lpdd->Release(); @@ -600,7 +591,7 @@ int HookDirectDraw(int version) if(pDirectDrawCreateEx){ LPDIRECTDRAW lpdd; BOOL res; - HookAPI("ddraw.dll", pDirectDrawCreateEx, "DirectDrawCreateEx", extDirectDrawCreateEx); + HookAPI(module, "ddraw.dll", pDirectDrawCreateEx, "DirectDrawCreateEx", extDirectDrawCreateEx); res=extDirectDrawCreateEx(0, &lpdd, dd7, 0); if (res) OutTraceE("DirectDrawCreateEx: ERROR res=%x(%s)\n", res, ExplainDDError(res)); lpdd->Release(); @@ -612,70 +603,6 @@ int HookDirectDraw(int version) return 0; } -/* ------------------------------------------------------------------ */ -// Primary surfaces auxiliary functions -/* ------------------------------------------------------------------ */ - -#define DDSQLEN 0x10 -static DWORD PrimSurfaces[DDSQLEN+1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -void MarkPrimarySurface(LPDIRECTDRAWSURFACE ps) -{ - int i; - // OutTraceD("PRIMARYSURFACE add %x\n",ps); - for (i=0;idwCaps, ExplainDDSCaps(lpddsc->dwCaps)); @@ -2314,8 +2241,8 @@ HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, BOOL ToPrim, FromPrim, ToScreen, FromScreen; //CkArg arg; - ToPrim=IsAPrimarySurface(lpdds); - FromPrim=IsAPrimarySurface(lpddssrc); + ToPrim=dxw.IsAPrimarySurface(lpdds); + FromPrim=dxw.IsAPrimarySurface(lpddssrc); ToScreen=ToPrim && !(dxw.dwFlags1 & EMULATESURFACE); FromScreen=FromPrim && !(dxw.dwFlags1 & EMULATESURFACE); @@ -2551,7 +2478,7 @@ HRESULT WINAPI extFlip(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, BOOL IsPrim; HRESULT res; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("Flip: lpdds=%x%s, src=%x, flags=%x(%s)\n", lpdds, IsPrim?"(PRIM)":"", lpddssrc, dwflags, ExplainFlipFlags(dwflags)); @@ -2635,8 +2562,8 @@ HRESULT WINAPI extBltFast(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, HRESULT ret; BOOL ToPrim, FromPrim; - ToPrim=IsAPrimarySurface(lpdds); - FromPrim=IsAPrimarySurface(lpddssrc); + ToPrim=dxw.IsAPrimarySurface(lpdds); + FromPrim=dxw.IsAPrimarySurface(lpddssrc); CleanRect(&lpsrcrect,__LINE__); @@ -2770,8 +2697,9 @@ HRESULT WINAPI extSetPalette(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpdd PALETTEENTRY *lpentries; BOOL isPrim; HRESULT res; - - isPrim=IsAPrimarySurface(lpdds); + + dxw.IsGDIPalette=FALSE; + isPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("SetPalette: lpdds=%x%s lpddp=%x\n", lpdds, isPrim?"(PRIM)":"", lpddp); if(!(dxw.dwFlags1 & EMULATESURFACE) || !isPrim) { @@ -2782,11 +2710,11 @@ HRESULT WINAPI extSetPalette(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpdd OutTraceD("SetPalette: DEBUG emulating palette\n"); lpDDP = lpddp; - if (lpDDSBack) { - res=(*pSetPalette)(lpDDSBack, lpddp); - if(res) OutTraceE("SetPalette: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - } - // add a reference to simulate whot would happen in reality.... + //if (lpDDSBack) { GHOGHO + // res=(*pSetPalette)(lpDDSBack, lpddp); + // if(res) OutTraceE("SetPalette: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + //} + // add a reference to simulate what would happen in reality.... lpdds->AddRef(); if(lpddp){ @@ -2803,14 +2731,16 @@ HRESULT WINAPI extSetEntries(LPDIRECTDRAWPALETTE lpddp, DWORD dwflags, DWORD dws { HRESULT res; + dxw.IsGDIPalette=FALSE; OutTraceD("SetEntries: dwFlags=%x, start=%d, count=%d\n", //GHO: added trace infos dwflags, dwstart, dwcount); res = (*pSetEntries)(lpddp, dwflags, dwstart, dwcount, lpentries); if(res) OutTraceE("SetEntries: ERROR res=%x(%s)\n", res, ExplainDDError(res)); - if(!(dxw.dwFlags1 & EMULATESURFACE) || lpDDP != lpddp) + if(!(dxw.dwFlags1 & EMULATESURFACE) || lpDDP != lpddp){ return res; + } if ((dwstart + dwcount > 256) || (dwstart<0)){ dwcount=256; @@ -2831,7 +2761,7 @@ HRESULT WINAPI extSetClipper(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpdd { HRESULT res; BOOL isPrim; - isPrim=IsAPrimarySurface(lpdds); + isPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("SetClipper: lpdds=%x%s lpddc=%x\n", lpdds, isPrim?"(PRIM)":"", lpddc); // v2.1.84: SUPPRESSCLIPPING flag - improves "Monopoly Edition 3D" where continuous @@ -2861,7 +2791,7 @@ HRESULT WINAPI extLock(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDIRECTDRAWSUR HRESULT res; BOOL IsPrim; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); if(IsTraceD){ OutTrace("Lock: lpdds=%x%s flags=%x(%s) lpdds2=%x", @@ -2893,7 +2823,7 @@ HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRAWSURFAC RECT screen, rect; BOOL IsPrim; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); if ((dxversion == 4) && lprect) CleanRect(&lprect,__LINE__); @@ -2976,16 +2906,13 @@ ReleaseDC with Unlock, returning the surface memory ptr (???) as HDC and avoiding the consistency check performed by surface::GetDC (why should it bother if the screen is 32BPP and the surface is not??? */ -HDC PrimSurfaceHDC = 0; -LPDIRECTDRAWSURFACE lpDDSPrimHDC=NULL; - HRESULT WINAPI extGetDC(LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC) { HRESULT res; BOOL IsPrim; RECT client; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("GetDC: lpdss=%x%s\n",lpdds, IsPrim?"(PRIM)":""); res=(*pGetDC)(lpdds,pHDC); if(res){ @@ -3006,8 +2933,7 @@ HRESULT WINAPI extGetDC(LPDIRECTDRAWSURFACE lpdds, HDC FAR *pHDC) // when getting DC from primary surface, save hdc and lpdds // for later possible use in GDI BitBlt wrapper function if (IsPrim){ - if (*pHDC) PrimSurfaceHDC=*pHDC; - lpDDSPrimHDC=lpdds; + dxw.lpDDSPrimHDC=lpdds; } // tricky part to allog GDI to operate on top of a directdraw surface's HDI. @@ -3126,7 +3052,7 @@ HRESULT WINAPI extReleaseDC(LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc) OutTraceE("ReleaseDC: RevBlt ERROR res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__); break; } - if(IsAPrimarySurface(lpdds)){ + if(dxw.IsAPrimarySurface(lpdds)){ res=sBlt("ReleaseDC", lpdds, NULL, lpdds, NULL, 0, NULL, FALSE); if (res) OutTraceE("ReleaseDC: Blt ERROR res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__); } @@ -3341,7 +3267,7 @@ HRESULT WINAPI extGetPixelFormat(LPDIRECTDRAWSURFACE lpdds, LPDDPIXELFORMAT p) DWORD res; BOOL IsPrim; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("GetPixelFormat: lpdds=%x%s\n", lpdds, IsPrim?"(PRIM)":""); res=(*pGetPixelFormat)(lpdds, p); if(res){ @@ -3383,7 +3309,7 @@ HRESULT WINAPI extReleaseS(LPDIRECTDRAWSURFACE lpdds) BOOL IsClosed; OutTraceD("Release(S): DEBUG - lpdds=%x\n", lpdds); - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); // handling of service closed surfaces IsClosed=0; @@ -3401,7 +3327,7 @@ HRESULT WINAPI extReleaseS(LPDIRECTDRAWSURFACE lpdds) // when releasing primary surface, erase clipping region if(IsPrim && (dxw.dwFlags1 & CLIPCURSOR)) dxw.EraseClipCursor(); // if primary, clean primay surface list - if(IsPrim) UnmarkPrimarySurface(lpdds); + if(IsPrim) dxw.UnmarkPrimarySurface(lpdds); // service surfaces cleanup if(lpdds==lpDDSBack) { OutTraceD("Release(S): Clearing lpDDSBack pointer\n"); @@ -3416,14 +3342,9 @@ HRESULT WINAPI extReleaseS(LPDIRECTDRAWSURFACE lpdds) OutTraceD("Release(S): Clearing lpDDSEmu_Back pointer\n"); lpDDSEmu_Back=NULL; } - //if(lpdds==lpDDSHDC) { - // OutTraceD("Release(S): Clearing lpDDSHDC pointer\n"); - // lpDDSHDC=NULL; - //} - if(lpdds==lpDDSPrimHDC) { + if(lpdds==dxw.lpDDSPrimHDC) { OutTraceD("Release(S): Clearing lpDDSPrimHDC pointer\n"); - lpDDSPrimHDC=NULL; - PrimSurfaceHDC=0; + dxw.ResetPrimarySurface(); } } } @@ -3434,7 +3355,7 @@ HRESULT WINAPI extSetColorKey(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORK { HRESULT res; BOOL IsPrim; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); if(IsTraceD){ OutTrace("SetColorKey: lpdds=%x%s flags=%x(%s) ", lpdds, (IsPrim ? "(PRIM)" : ""), flags, ExplainColorKeyFlag(flags)); @@ -3454,7 +3375,7 @@ HRESULT WINAPI extGetColorKey(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORK { HRESULT res; BOOL IsPrim; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("GetColorKey(S): lpdds=%x%s flags=%x(%s)\n", lpdds, (IsPrim ? "(PRIM)" : ""), flags, ExplainColorKeyFlag(flags)); res=(*pGetColorKey)(lpdds, flags, lpDDColorKey); @@ -3471,7 +3392,7 @@ HRESULT WINAPI extEnumAttachedSurfaces(LPDIRECTDRAWSURFACE lpdds, LPVOID lpConte HRESULT res; BOOL IsPrim; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("EnumAttachedSurfaces: lpdds=%x%s Context=%x Callback=%x\n", lpdds, (IsPrim ? "(PRIM)":""), lpContext, lpEnumSurfacesCallback); @@ -3517,7 +3438,7 @@ HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURF // just remember this for further handling in the Flip operation. // But beware: this holds to BACKBUFFER surfaces only, and NOT for attached ZBUFFERS or similar! - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("AddAttachedSurface: lpdds=%x%s lpddsadd=%x\n", lpdds, IsPrim?"(PRIM)":"", lpddsadd); res=(*pAddAttachedSurface)(lpdds, lpddsadd); if (res) { @@ -3575,7 +3496,7 @@ HRESULT WINAPI extGetCapsS(int dxInterface, GetCapsS_Type pGetCapsS, LPDIRECTDRA { HRESULT res; BOOL IsPrim; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); OutTraceD("GetCaps(S%d): lpdds=%x%s, lpcaps=%x\n", dxInterface, lpdds, IsPrim?"(PRIM)":"", caps); res=(*pGetCapsS)(lpdds, caps); if(res) @@ -3734,7 +3655,7 @@ HRESULT WINAPI extGetSurfaceDesc(GetSurfaceDesc_Type pGetSurfaceDesc, LPDIRECTDR { HRESULT res; BOOL IsPrim; - IsPrim=IsAPrimarySurface(lpdds); + IsPrim=dxw.IsAPrimarySurface(lpdds); if (!pGetSurfaceDesc) { OutTraceE("GetSurfaceDesc: ERROR no hooked function\n"); diff --git a/dll/hdinput.cpp b/dll/hdinput.cpp index 0df0472..80f0b71 100644 --- a/dll/hdinput.cpp +++ b/dll/hdinput.cpp @@ -46,7 +46,7 @@ int iCurMinY; int iCurMaxX; int iCurMaxY; -int HookDirectInput(int version) +int HookDirectInput(char *module, int version) { HINSTANCE hinst; void *tmp; @@ -54,13 +54,13 @@ int HookDirectInput(int version) const GUID di7 = {0x9A4CB684,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE}; const GUID di8 = {0xBF798030,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00}; - tmp = HookAPI("dinput.dll", NULL, "DirectInputCreateA", extDirectInputCreate); + tmp = HookAPI(module, "dinput.dll", NULL, "DirectInputCreateA", extDirectInputCreate); if(tmp) pDirectInputCreate = (DirectInputCreate_Type)tmp; - tmp = HookAPI("dinput.dll", NULL, "DirectInputCreateW", extDirectInputCreate); + tmp = HookAPI(module, "dinput.dll", NULL, "DirectInputCreateW", extDirectInputCreate); if(tmp) pDirectInputCreate = (DirectInputCreate_Type)tmp; - tmp = HookAPI("dinput.dll", NULL, "DirectInputCreateEx", extDirectInputCreateEx); + tmp = HookAPI(module, "dinput.dll", NULL, "DirectInputCreateEx", extDirectInputCreateEx); if(tmp) pDirectInputCreateEx = (DirectInputCreateEx_Type)tmp; - tmp = HookAPI("dinput8.dll", NULL, "DirectInput8Create", extDirectInput8Create); + tmp = HookAPI(module, "dinput8.dll", NULL, "DirectInput8Create", extDirectInput8Create); if(tmp) pDirectInputCreateEx = (DirectInputCreateEx_Type)tmp; if(!pDirectInputCreate && !pDirectInputCreateEx){ if(version < 8){ diff --git a/dll/syslibs.cpp b/dll/syslibs.cpp index d9a744f..4853ec9 100644 --- a/dll/syslibs.cpp +++ b/dll/syslibs.cpp @@ -15,64 +15,27 @@ #define WINDOWDC 0xFFFFFFFF -extern GDIGetDC_Type pGDIGetDC; -extern GDIGetDC_Type pGDIGetWindowDC; -extern GDIReleaseDC_Type pGDIReleaseDC; extern DWORD PaletteEntries[256]; -extern HDC PrimSurfaceHDC; -extern LPDIRECTDRAWSURFACE lpDDSPrimHDC; extern LPDIRECTDRAW lpDD; extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); extern GetDC_Type pGetDC; extern ReleaseDC_Type pReleaseDC; -extern SetCursor_Type pSetCursor; DEVMODE SetDevMode; DEVMODE *pSetDevMode=NULL; -extern short iPosX, iPosY, iSizX, iSizY; extern void do_slow(int); -extern LPDIRECTDRAWSURFACE GetPrimarySurface(void); +//extern LPDIRECTDRAWSURFACE GetPrimarySurface(void); extern HRESULT WINAPI extBlt(LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX); extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL); -static SetLayeredWindowAttributes_Type pSetLayeredWindowAttributes = NULL; -#ifndef WS_EX_LAYERED -#define WS_EX_LAYERED 0x00080000 -#define LWA_COLORKEY 0x00000001 -#define LWA_ALPHA 0x00000002 -#endif -// Diablo: end -//extern char *ExplainShowCmd(int); - extern DirectDrawEnumerate_Type pDirectDrawEnumerate; extern DirectDrawEnumerateEx_Type pDirectDrawEnumerateEx; extern LRESULT CALLBACK extChildWindowProc(HWND, UINT, WPARAM, LPARAM); extern INT_PTR CALLBACK extDialogWindowProc(HWND, UINT, WPARAM, LPARAM); -GDIChoosePixelFormat_Type pGDIChoosePixelFormat; -GDIGetPixelFormat_Type pGDIGetPixelFormat; -GDISetPixelFormat_Type pGDISetPixelFormat; -CreateDC_Type pCreateDC; -StretchBlt_Type pStretchBlt; -SaveDC_Type pGDISaveDC; -RestoreDC_Type pGDIRestoreDC; -CreateDialogParam_Type pCreateDialogParam; -CreateDialogIndirectParam_Type pCreateDialogIndirectParam; -BeginPaint_Type pBeginPaint; -EndPaint_Type pEndPaint; -InvalidateRect_Type pInvalidateRect; -InvalidateRgn_Type pInvalidateRgn; -GDICreatePalette_Type pGDICreatePalette; -SelectPalette_Type pSelectPalette; -RealizePalette_Type pRealizePalette; -GetSystemPaletteEntries_Type pGetSystemPaletteEntries; -MoveWindow_Type pMoveWindow; -SetUnhandledExceptionFilter_Type pSetUnhandledExceptionFilter; -GetDiskFreeSpaceA_Type pGetDiskFreeSpaceA; - /* ------------------------------------------------------------------ */ static POINT FixMessagePt(HWND hwnd, POINT point) @@ -254,10 +217,10 @@ HWND WINAPI extCreateWindowExA( else { // invalid parent coordinates: use initial placement, but leave the size. // should also fix the window style and compensate for borders here? - x=iPosX; - y=iPosY; - nWidth=iSizX; - nHeight=iSizY; + x=dxw.iPosX; + y=dxw.iPosY; + nWidth=dxw.iSizX; + nHeight=dxw.iSizY; OutTraceD("CreateWindowEx: renewed BIG win pos=(%d,%d) size=(%d,%d)\n", x, y, nWidth, nHeight); } dxw.SetFullScreen(TRUE); @@ -344,7 +307,7 @@ COLORREF WINAPI extSetTextColor(HDC hdc, COLORREF crColor) if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC) && (dxw.VirtualPixelFormat.dwRGBBitCount==8)) crColor=GetMatchingColor(crColor); - res=(*pSetTextColor)(hdc, crColor); + res=(*pGDISetTextColor)(hdc, crColor); OutTraceD("SetTextColor: color=%x res=%x%s\n", crColor, res, (res==CLR_INVALID)?"(CLR_INVALID)":""); return res; } @@ -356,7 +319,7 @@ COLORREF WINAPI extSetBkColor(HDC hdc, COLORREF crColor) if ((dxw.dwFlags1 & EMULATESURFACE) && (dxw.dwFlags1 & HANDLEDC) && (dxw.VirtualPixelFormat.dwRGBBitCount==8)) crColor=GetMatchingColor(crColor); - res=(*pSetBkColor)(hdc, crColor); + res=(*pGDISetBkColor)(hdc, crColor); OutTraceD("SetBkColor: color=%x res=%x%s\n", crColor, res, (res==CLR_INVALID)?"(CLR_INVALID)":""); return res; } @@ -602,7 +565,7 @@ BOOL WINAPI extTextOutA(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int nXStart=anchor.x; nYStart=anchor.y; } - return (*pTextOutA)(hdc, nXStart, nYStart, lpString, cchString); + return (*pGDITextOutA)(hdc, nXStart, nYStart, lpString, cchString); } BOOL WINAPI extRectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) @@ -621,7 +584,7 @@ BOOL WINAPI extRectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, i nRightRect=anchor.x; nBottomRect=anchor.y; } - return (*pRectangle)(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); + return (*pGDIRectangle)(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); } int WINAPI extFillRect(HDC hdc, const RECT *lprc, HBRUSH hbr) @@ -645,34 +608,13 @@ int WINAPI extFillRect(HDC hdc, const RECT *lprc, HBRUSH hbr) return (*pFillRect)(hdc, &rc, hbr); } -int WINAPI extDrawFocusRect(HDC hdc, const RECT *lprc) -{ - RECT rc; - OutTraceD("DrawFocusRect: hdc=%x xy=(%d,%d)-(%d,%d)\n", hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); - memcpy(&rc, lprc, sizeof(rc)); - if (dxw.dwFlags1 & FIXTEXTOUT) { - POINT anchor; - anchor.x=rc.left; - anchor.y=rc.top; - (*pClientToScreen)(dxw.GethWnd(), &anchor); - rc.left=anchor.x; - rc.top=anchor.y; - anchor.x=rc.right; - anchor.y=rc.bottom; - (*pClientToScreen)(dxw.GethWnd(), &anchor); - rc.right=anchor.x; - rc.bottom=anchor.y; - } - return (*pDrawFocusRect)(hdc, &rc); -} - HFONT WINAPI extCreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCTSTR lpszFace) { OutTraceD("CreateFont: h=%d w=%d face=\"%s\"\n", nHeight, nWidth, lpszFace); - return (*pCreateFont)(nHeight, nWidth, nEscapement, nOrientation, fnWeight, + return (*pGDICreateFont)(nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision, fdwClipPrecision, NONANTIALIASED_QUALITY, fdwPitchAndFamily, lpszFace); @@ -687,7 +629,7 @@ HFONT WINAPI extCreateFontIndirect(const LOGFONT* lplf) OutTraceD("CreateFontIndirect: h=%d w=%d face=\"%s\"\n", lplf->lfHeight, lplf->lfWidth, lplf->lfFaceName); memcpy((char *)&lf, (char *)lplf, sizeof(LOGFONT)); lf.lfQuality=NONANTIALIASED_QUALITY; - retHFont=((*pCreateFontIndirect)(&lf)); + retHFont=((*pGDICreateFontIndirect)(&lf)); if(retHFont) OutTraceD("CreateFontIndirect: hfont=%x\n", retHFont); else @@ -812,8 +754,8 @@ BOOL WINAPI extSetWindowPos(HWND hwnd, HWND hWndInsertAfter, int X, int Y, int c if (dxw.dwFlags1 & PREVENTMAXIMIZE){ int UpdFlag =0; int MaxX, MaxY; - MaxX = iSizX; - MaxY = iSizY; + MaxX = dxw.iSizX; + MaxY = dxw.iSizY; if (!MaxX) MaxX = dxw.GetScreenWidth(); if (!MaxY) MaxY = dxw.GetScreenHeight(); if(cx>MaxX) { cx=MaxX; UpdFlag=1; } @@ -847,7 +789,7 @@ HDWP WINAPI extDeferWindowPos(HDWP hWinPosInfo, HWND hwnd, HWND hWndInsertAfter, if ((hwnd != dxw.GethWnd()) || !dxw.IsFullScreen()){ // just proxy - res=(*pDeferWindowPos)(hWinPosInfo, hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags); + res=(*pGDIDeferWindowPos)(hWinPosInfo, hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags); if(!res)OutTraceE("SetWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } @@ -859,8 +801,8 @@ HDWP WINAPI extDeferWindowPos(HDWP hWinPosInfo, HWND hwnd, HWND hWndInsertAfter, if (dxw.dwFlags1 & PREVENTMAXIMIZE){ int UpdFlag =0; int MaxX, MaxY; - MaxX = iSizX; - MaxY = iSizY; + MaxX = dxw.iSizX; + MaxY = dxw.iSizY; if (!MaxX) MaxX = dxw.GetScreenWidth(); if (!MaxY) MaxY = dxw.GetScreenHeight(); if(cx>MaxX) { cx=MaxX; UpdFlag=1; } @@ -880,7 +822,7 @@ HDWP WINAPI extDeferWindowPos(HDWP hWinPosInfo, HWND hwnd, HWND hWndInsertAfter, cx=rect.right; cy=rect.bottom; OutTraceD("SetWindowPos: main form hwnd=%x fixed size=(%d,%d)\n", hwnd, cx, cy); - res=(*pDeferWindowPos)(hWinPosInfo, hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags); + res=(*pGDIDeferWindowPos)(hWinPosInfo, hwnd, hWndInsertAfter, X, Y, cx, cy, uFlags); if(!res)OutTraceE("DeferWindowPos: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } @@ -890,8 +832,8 @@ void dxwFixWindowPos(char *ApiName, HWND hwnd, LPARAM lParam) LPWINDOWPOS wp; int MaxX, MaxY; wp = (LPWINDOWPOS)lParam; - MaxX = iSizX; - MaxY = iSizY; + MaxX = dxw.iSizX; + MaxY = dxw.iSizY; if (!MaxX) MaxX = dxw.GetScreenWidth(); if (!MaxY) MaxY = dxw.GetScreenHeight(); static int iLastCX, iLastCY; @@ -986,10 +928,10 @@ void dxwFixMinMaxInfo(char *ApiName, HWND hwnd, LPARAM lParam) lpmmi=(LPMINMAXINFO)lParam; OutTraceD("%s: GOT MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); - lpmmi->ptMaxPosition.x=iPosX; - lpmmi->ptMaxPosition.y=iPosY; - lpmmi->ptMaxSize.x = iSizX ? iSizX : dxw.GetScreenWidth(); - lpmmi->ptMaxSize.y = iSizY ? iSizY : dxw.GetScreenHeight(); + lpmmi->ptMaxPosition.x=dxw.iPosX; + lpmmi->ptMaxPosition.y=dxw.iPosY; + lpmmi->ptMaxSize.x = dxw.iSizX ? dxw.iSizX : dxw.GetScreenWidth(); + lpmmi->ptMaxSize.y = dxw.iSizY ? dxw.iSizY : dxw.GetScreenHeight(); OutTraceD("%s: SET LOCKWINPOS MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); } @@ -1129,7 +1071,7 @@ int WINAPI extGetDeviceCaps(HDC hdc, int nindex) { DWORD res; - res = (*pGetDeviceCaps)(hdc, nindex); + res = (*pGDIGetDeviceCaps)(hdc, nindex); OutTraceD("GetDeviceCaps: hdc=%x index=%x(%s) res=%x\n", hdc, nindex, ExplainDeviceCaps(nindex), res); @@ -1255,65 +1197,9 @@ BOOL WINAPI extScaleWindowExtEx(HDC hdc, int Xnum, int Xdenom, int Ynum, int Yde if ((dxw.dwFlags1 & LOCKWINPOS) && dxw.IsFullScreen()) return 1; - return (*pScaleWindowExtEx)(hdc, Xnum, Xdenom, Ynum, Ydenom, lpSize); + return (*pGDIScaleWindowExtEx)(hdc, Xnum, Xdenom, Ynum, Ydenom, lpSize); } -/* ---- pixel color management ----*/ - -int WINAPI extGDIChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd) -{ - int ret; - - OutTraceD("GDIChoosePixelFormat: hdc=%x, pfd=%x\n", hdc, ppfd); - OutTraceD("GDIChoosePixelFormat: Version=%x Flags-%x PixelType=%x ColorBits=%x RedBits=%x RedShift=%x " - "GreenBits=%x BlueBits=%x BlueShift=%x AlphaBits=%x AlphaShift=%x", - ppfd->nVersion, ppfd->dwFlags, ppfd->iPixelType, ppfd->cColorBits, ppfd->cRedBits, ppfd->cRedShift, - ppfd->cGreenBits, ppfd->cGreenShift, ppfd->cBlueBits, ppfd->cBlueShift, ppfd->cAlphaBits, ppfd->cAlphaShift); - /* - ppfd->cAccumBits, ppfd->cAccumRedBits, ppfd->cAccumGreenBits, ppfd->cAccumBlueBits, ppfd->cAccumAlphaBits, - ppfd->cDepthBits, ppfd->cStencilBits, ppfd->cAuxBuffers, ppfd->iLayerType, ppfd->bReserved, - ppfd->dwLayerMask, ppfd->dwVisibleMask, ppfd->dwDamageMask - */ - - ret= (*pGDIChoosePixelFormat)(hdc, ppfd); - OutTraceD("GDIChoosePixelFormat: ret=%d\n",ret); - return ret; -} - -int WINAPI extGDIGetPixelFormat(HDC hdc) -{ - OutTraceD("GDIGetPixelFormat: hdc=%x\n", hdc); - return (*pGDIGetPixelFormat)(hdc); -} - -BOOL WINAPI extGDISetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd) -{ - OutTraceD("GDISetPixelFormat: hdc=%x\n", hdc); - -#if 0 - if(dxw.dwFlags1 & EMULATESURFACE){ - // set VirtualScr view - VirtualScr.dwRGBBitCount=ppfd->cColorBits; - VirtualScr.dwFlags=ppfd->dwFlags; - VirtualScr.dwRBitMask=(2^ppfd->cRedBits - 1)<cRedShift; - VirtualScr.dwGBitMask=(2^ppfd->cGreenBits - 1)<cGreenShift; - VirtualScr.dwBBitMask=(2^ppfd->cBlueBits - 1)<cBlueShift; - VirtualScr.dwRGBAlphaBitMask=(2^ppfd->cAlphaBits - 1)<cAlphaShift; - OutTraceD("GDISetPixelFormat: RGBA colorbits=%d mask=(%x,%x,%x,%x)\n", - VirtualScr.dwRGBBitCount, VirtualScr.dwRBitMask, VirtualScr.dwGBitMask, VirtualScr.dwBBitMask, VirtualScr.dwRGBAlphaBitMask); - return 0; - } -#endif - - return (*pGDISetPixelFormat)(hdc, iPixelFormat, ppfd); -} - -//HRGN WINAPI extCreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) -//{ -// OutTraceD("CreateRectRgn: (%d,%d)-(%d,%d)\n", nLeftRect, nTopRect, nRightRect, nBottomRect); -// return (*pCreateRectRgn)(nLeftRect, nTopRect, nRightRect, nBottomRect); -//} - LONG WINAPI MyChangeDisplaySettings(char *fname, DEVMODE *lpDevMode, DWORD dwflags) { HRESULT res; @@ -1428,7 +1314,6 @@ BOOL WINAPI extClientToScreen(HWND whnd, LPPOINT lppoint) return 1; else return (*pClientToScreen)(whnd, lppoint); -// return 1; } BOOL WINAPI extScreenToClient(HWND whnd, LPPOINT lppoint) @@ -1437,7 +1322,6 @@ BOOL WINAPI extScreenToClient(HWND whnd, LPPOINT lppoint) return 1; else return (*pScreenToClient)(whnd, lppoint); -// return 1; } BOOL WINAPI extGetClientRect(HWND hwnd, LPRECT lpRect) @@ -1587,38 +1471,6 @@ BOOL WINAPI extGetMessage(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgF return res; } -LRESULT WINAPI extDispatchMessage(LPMSG lpMsg) -{ - BOOL res; - DWORD Message; -#if WORKONCOPY - static MSG MsgCopy; - MsgCopy=*lpMsg; - MsgCopy.pt=FixMessagePt(dxw.GethWnd(), MsgCopy.pt); - Message=MsgCopy.message & 0xFFFF; - if((Message <= WM_MOUSELAST) && (Message >= WM_MOUSEFIRST)){ - MsgCopy.lParam = MAKELPARAM(MsgCopy.pt.x, MsgCopy.pt.y); - OutTraceC("PeekMessage: fixed lparam/pt=(%d,%d)\n", MsgCopy.pt.x, MsgCopy.pt.y); - } - res=(*pDispatchMessage)(&MsgCopy); - OutTraceW("DispatchMessage: lpmsg=%x msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", - lpMsg, MsgCopy.message, ExplainWinMessage(MsgCopy.message & 0xFFFF), - MsgCopy.wParam, MsgCopy.lParam, MsgCopy.pt.x, MsgCopy.pt.y, res); -#else - lpMsg->pt=FixMessagePt(dxw.GethWnd(), lpMsg->pt); - Message=lpMsg->message & 0xFFFF; - if((Message <= WM_MOUSELAST) && (Message >= WM_MOUSEFIRST)){ - lpMsg->lParam = MAKELPARAM(lpMsg->pt.x, lpMsg->pt.y); - OutTraceC("PeekMessage: fixed lparam/pt=(%d,%d)\n", lpMsg->pt.x, lpMsg->pt.y); - } - res=(*pDispatchMessage)(lpMsg); - OutTraceW("DispatchMessage: lpmsg=%x msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", - lpMsg, lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), - lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); -#endif - return res; -} - // intercept GetProcAddress to initialize DirectDraw hook pointers. // This is necessary in "The Sims" game, that loads DirectDraw dinamically @@ -1667,6 +1519,11 @@ HMODULE WINAPI extLoadLibraryA(LPCTSTR lpFileName) break; } } + // handle custom OpenGL library + if(!lstrcmpi(lpName,dxw.CustomOpenGLLib)){ + idx=SYSLIBIDX_OPENGL; + SysLibs[idx]=ret; + } if(idx==SYSLIBIDX_MAX) { OutTraceD("LoadLibraryA: hook %s\n", lpFileName); HookModule((char *)lpFileName, 0); @@ -1702,7 +1559,7 @@ extern DirectDrawCreateEx_Type pDirectDrawCreateEx; extern HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); extern HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *); extern GetProcAddress_Type pGetProcAddress; -extern HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID FAR*); +//extern HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID FAR*); int WINAPI extIsDebuggerPresent(void) { @@ -1775,6 +1632,7 @@ FARPROC WINAPI extGetProcAddress(HMODULE hModule, LPCSTR proc) break; case SYSLIBIDX_OPENGL: //default: + if(!(dxw.dwFlags2 & HOOKOPENGL)) break; if (remap=Remap_gl_ProcAddress(proc, hModule)) return remap; } } @@ -1837,6 +1695,7 @@ HDC WINAPI extGDIGetDC(HWND hwnd) { HDC ret; HWND lochwnd; + OutTraceD("GDI.GetDC: hwnd=%x\n", hwnd); lochwnd=hwnd; if (dxw.IsFullScreen() && ((hwnd==0) || (hwnd==(*pGetDesktopWindow)()))) { @@ -1910,11 +1769,11 @@ HDC WINAPI extGDICreateDC(LPSTR Driver, LPSTR Device, LPSTR Output, CONST DEVMOD if (!Driver || !strncmp(Driver,"DISPLAY",7)) { OutTraceD("GDI.CreateDC: returning window surface DC\n"); WinHDC=(*pGDIGetDC)(dxw.GethWnd()); - RetHDC=(*pCreateCompatibleDC)(WinHDC); + RetHDC=(*pGDICreateCompatibleDC)(WinHDC); (*pGDIReleaseDC)(dxw.GethWnd(), WinHDC); } else{ - RetHDC=(*pCreateDC)(Driver, Device, Output, InitData); + RetHDC=(*pGDICreateDC)(Driver, Device, Output, InitData); } if(RetHDC) OutTraceD("GDI.CreateDC: returning HDC=%x\n", RetHDC); @@ -1926,20 +1785,24 @@ HDC WINAPI extGDICreateDC(LPSTR Driver, LPSTR Device, LPSTR Output, CONST DEVMOD HDC WINAPI extGDICreateCompatibleDC(HDC hdc) { HDC RetHdc, SrcHdc; - extern HDC PrimSurfaceHDC; - extern LPDIRECTDRAWSURFACE lpDDSHDC, lpDDSPrimHDC; + extern LPDIRECTDRAWSURFACE lpDDSHDC; extern GetDC_Type pGetDC; + DWORD LastError; OutTraceD("GDI.CreateCompatibleDC: hdc=%x\n", hdc); if(hdc==0){ SrcHdc=(*pGDIGetDC)(dxw.GethWnd()); OutTraceD("GDI.CreateCompatibleDC: duplicating win HDC hWnd=%x\n", dxw.GethWnd()); } - RetHdc=(*pCreateCompatibleDC)(hdc); - if(RetHdc) + + // eliminated error message for errorcode 0. + SetLastError(0); + RetHdc=(*pGDICreateCompatibleDC)(hdc); + LastError=GetLastError(); + if(!LastError) OutTraceD("GDI.CreateCompatibleDC: returning HDC=%x\n", RetHdc); else - OutTraceE("GDI.CreateCompatibleDC ERROR: err=%d at %d\n", GetLastError(), __LINE__); + OutTraceE("GDI.CreateCompatibleDC ERROR: err=%d at %d\n", LastError, __LINE__); return RetHdc; } @@ -1962,10 +1825,10 @@ BOOL WINAPI extGDIBitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nH nWDest= nWidth; nHDest= nHeight; dxw.MapRect(&nXDest, &nYDest, &nWDest, &nHDest); - res=(*pStretchBlt)(hdcDest, nXDest, nYDest, nWDest, nHDest, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, dwRop); + res=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWDest, nHDest, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, dwRop); } else { - res=(*pBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); + res=(*pGDIBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); } if(!res) OutTraceE("GDI.BitBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); @@ -1984,10 +1847,10 @@ BOOL WINAPI extGDIPatBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nH if (dxw.IsFullScreen() && (OBJ_DC == GetObjectType(hdcDest))){ int nWDest, nHDest; dxw.MapRect(&nXDest, &nYDest, &nWDest, &nHDest); - res=(*pPatBlt)(hdcDest, nXDest, nYDest, nWDest, nHDest, dwRop); + res=(*pGDIPatBlt)(hdcDest, nXDest, nYDest, nWDest, nHDest, dwRop); } else { - res=(*pPatBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, dwRop); + res=(*pGDIPatBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, dwRop); } if(!res) OutTraceE("GDI.PatBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); @@ -2006,7 +1869,7 @@ BOOL WINAPI extGDIStretchBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, in // to do: what happend if StretchBlt is applied on screen DC ? - res=(*pStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop); + res=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWSrc, nHSrc, dwRop); if(!res) OutTraceE("GDI.StretchBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } @@ -2015,7 +1878,7 @@ BOOL WINAPI extGDIDeleteDC(HDC hdc) { BOOL res; OutTraceD("GDI.DeleteDC: hdc=%x\n", hdc); - res=(*pDeleteDC)(hdc); + res=(*pGDIDeleteDC)(hdc); if(!res) OutTraceE("GDI.DeleteDC: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } @@ -2062,20 +1925,19 @@ static HDC PrimHDC=NULL; HDC WINAPI extDDCreateCompatibleDC(HDC hdc) { HDC RetHdc, SrcHdc; - extern LPDIRECTDRAWSURFACE lpDDSPrimHDC; extern GetDC_Type pGetDC; OutTraceD("GDI.CreateCompatibleDC: hdc=%x\n", hdc); if(hdc==0 && pGetDC && dxw.IsFullScreen()){ - if(!lpDDSPrimHDC) lpDDSPrimHDC=GetPrimarySurface(); - (*pGetDC)(lpDDSPrimHDC,&SrcHdc); - OutTraceD("GDI.CreateCompatibleDC: duplicating screen HDC lpDDSPrimHDC=%x\n", lpDDSPrimHDC); - RetHdc=(*pCreateCompatibleDC)(SrcHdc); - (*pReleaseDC)(lpDDSPrimHDC,SrcHdc); + dxw.SetPrimarySurface(); + (*pGetDC)(dxw.lpDDSPrimHDC,&SrcHdc); + OutTraceD("GDI.CreateCompatibleDC: duplicating screen HDC lpDDSPrimHDC=%x\n", dxw.lpDDSPrimHDC); + RetHdc=(*pGDICreateCompatibleDC)(SrcHdc); + (*pReleaseDC)(dxw.lpDDSPrimHDC,SrcHdc); } else - RetHdc=(*pCreateCompatibleDC)(hdc); + RetHdc=(*pGDICreateCompatibleDC)(hdc); if(RetHdc) OutTraceD("GDI.CreateCompatibleDC: returning HDC=%x\n", RetHdc); @@ -2091,7 +1953,7 @@ BOOL WINAPI extDDDeleteDC(HDC hdc) OutTraceD("GDI.DeleteDC: hdc=%x\n", hdc); - res=(*pDeleteDC)(hdc); + res=(*pGDIDeleteDC)(hdc); if(!res) OutTraceE("GDI.DeleteDC: ERROR err=%d at %d\n", GetLastError(), __LINE__); return res; } @@ -2104,26 +1966,24 @@ static HDC WINAPI winDDGetDC(HWND hwnd, char *api) OutTraceD("%s: hwnd=%x\n", api, hwnd); - lpDDSPrimHDC=GetPrimarySurface(); + dxw.ResetPrimarySurface(); + dxw.SetPrimarySurface(); - if(lpDDSPrimHDC){ + if(dxw.lpDDSPrimHDC){ if (PrimHDC){ OutTraceD("%s: reusing primary hdc\n", api); - (*pUnlockMethod(lpDDSPrimHDC))(lpDDSPrimHDC, NULL); + (*pUnlockMethod(dxw.lpDDSPrimHDC))(dxw.lpDDSPrimHDC, NULL); hdc=PrimHDC; } else{ - OutTraceD("%s: get hdc from PRIMARY surface lpdds=%x\n", api, lpDDSPrimHDC); - //res=(*pGetDC)(lpDDSPrimHDC,&hdc); - //res=lpDDSPrimHDC->GetDC(&hdc); - res=extGetDC(lpDDSPrimHDC,&hdc); + OutTraceD("%s: get hdc from PRIMARY surface lpdds=%x\n", api, dxw.lpDDSPrimHDC); + res=extGetDC(dxw.lpDDSPrimHDC,&hdc); if(res) { - OutTraceE("%s: GetDC(%x) ERROR %x(%s) at %d\n", api, lpDDSPrimHDC, res, ExplainDDError(res), __LINE__); + OutTraceE("%s: GetDC(%x) ERROR %x(%s) at %d\n", api, dxw.lpDDSPrimHDC, res, ExplainDDError(res), __LINE__); if(res==DDERR_DCALREADYCREATED){ // try recovery.... - (*pReleaseDC)(lpDDSPrimHDC,NULL); - //res=(*pGetDC)(lpDDSPrimHDC,&hdc); - res=extGetDC(lpDDSPrimHDC,&hdc); + (*pReleaseDC)(dxw.lpDDSPrimHDC,NULL); + res=extGetDC(dxw.lpDDSPrimHDC,&hdc); } if(res)return 0; } @@ -2153,13 +2013,13 @@ HDC WINAPI extDDCreateDC(LPSTR Driver, LPSTR Device, LPSTR Output, CONST DEVMODE //HDC PrimHDC; LPDIRECTDRAWSURFACE lpdds; OutTraceD("GDI.CreateDC: returning primary surface DC\n"); - lpdds=GetPrimarySurface(); + lpdds=dxw.GetPrimarySurface(); (*pGetDC)(lpdds, &PrimHDC); - RetHDC=(*pCreateCompatibleDC)(PrimHDC); + RetHDC=(*pGDICreateCompatibleDC)(PrimHDC); (*pReleaseDC)(lpdds, PrimHDC); } else{ - RetHDC=(*pCreateDC)(Driver, Device, Output, InitData); + RetHDC=(*pGDICreateDC)(Driver, Device, Output, InitData); } if(RetHDC) OutTraceD("GDI.CreateDC: returning HDC=%x\n", RetHDC); @@ -2189,22 +2049,11 @@ int WINAPI extDDReleaseDC(HWND hwnd, HDC hDC) OutTraceD("GDI.ReleaseDC: hwnd=%x hdc=%x\n", hwnd, hDC); res=0; -// if (hDC == PrimHDC /* && IsAScreenHDC(hDC) */){ if ((hDC == PrimHDC) || (hwnd==0)){ - if(!lpDDSPrimHDC) lpDDSPrimHDC=GetPrimarySurface(); - OutTraceD("GDI.ReleaseDC: refreshing primary surface lpdds=%x\n",lpDDSPrimHDC); - if(!lpDDSPrimHDC) return 0; -#if 0 - //extBlt(lpDDSPrimHDC, NULL, lpDDSPrimHDC, NULL, 0, NULL); - sBlt("GDI.ReleaseDC", lpDDSPrimHDC, NULL, lpDDSPrimHDC, NULL, 0, NULL, 0); - res=(*pUnlockMethod(lpDDSPrimHDC))(lpDDSPrimHDC, NULL); - //if(res) OutTraceE("Unlock ERROR: res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - res=(*pReleaseDC)(lpDDSPrimHDC,hDC); - if(res) OutTraceE("GDI.ReleaseDC: ReleaseDC ERROR=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); -#else - //lpDDSPrimHDC->ReleaseDC(hDC); - extReleaseDC(lpDDSPrimHDC, hDC); -#endif + dxw.SetPrimarySurface(); + OutTraceD("GDI.ReleaseDC: refreshing primary surface lpdds=%x\n",dxw.lpDDSPrimHDC); + if(!dxw.lpDDSPrimHDC) return 0; + extReleaseDC(dxw.lpDDSPrimHDC, hDC); PrimHDC=NULL; res=1; // 1 = OK } @@ -2222,31 +2071,6 @@ BOOL WINAPI extDDBitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHe HRESULT res; extern HRESULT WINAPI extGetDC(LPDIRECTDRAWSURFACE, HDC FAR *); -#if 0 - OutTraceD("GDI.BitBlt: HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d hdcSrc=%x nXSrc=%d nYSrc=%d dwRop=%x\n", - hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); - - ret=1; // OK - - if(hdcDest==0) extGetDC(lpDDSPrimHDC, &hdcDest); - if(hdcDest != hdcSrc){ - ret=(*pBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); - if(!ret) { - OutTraceE("GDI.BitBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); - return ret; - } - } - -// if(hdcDest==PrimHDC){ - { - if(!lpDDSPrimHDC) lpDDSPrimHDC=GetPrimarySurface(); - OutTraceD("GDI.BitBlt: refreshing primary surface lpdds=%x\n",lpDDSPrimHDC); - //extBlt(lpDDSPrimHDC, NULL, lpDDSPrimHDC, NULL, 0, NULL); - sBlt("GDI.BitBlt", lpDDSPrimHDC, NULL, lpDDSPrimHDC, NULL, 0, NULL, 0); - res=(*pUnlockMethod(lpDDSPrimHDC))(lpDDSPrimHDC, NULL); - //if(res) OutTraceE("Unlock: ERROR err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - } -#else OutTraceD("GDI.BitBlt: HDC=%x nXDest=%d nYDest=%d nWidth=%d nHeight=%d hdcSrc=%x nXSrc=%d nYSrc=%d dwRop=%x(%s)\n", hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop, ExplainROP(dwRop)); @@ -2254,26 +2078,18 @@ BOOL WINAPI extDDBitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHe if(hdcDest==0) hdcDest=PrimHDC; if(hdcDest==0) { - lpDDSPrimHDC=GetPrimarySurface(); - res=extGetDC(lpDDSPrimHDC, &PrimHDC); + dxw.ResetPrimarySurface(); + dxw.SetPrimarySurface(); + res=extGetDC(dxw.lpDDSPrimHDC, &PrimHDC); hdcDest=PrimHDC; } - res=(*pBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); + res=(*pGDIBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); if(!res) OutTraceE("GDI.BitBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); - res=(*pBitBlt)(NULL, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); + res=(*pGDIBitBlt)(NULL, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop); - //if(hdcDest==PrimHDC){ - // OutTraceD("GDI.BitBlt: refreshing primary surface lpdds=%x\n",lpDDSPrimHDC); - // //extBlt(lpDDSPrimHDC, NULL, lpDDSPrimHDC, NULL, 0, NULL); - // res=sBlt("GDI.BitBlt", lpDDSPrimHDC, NULL, lpDDSPrimHDC, NULL, 0, NULL, 0); - // if(res) OutTraceE("GDI.BitBlt: ERROR err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - // res=(*pUnlockMethod(lpDDSPrimHDC))(lpDDSPrimHDC, NULL); - // if(res) OutTraceE("Unlock: ERROR err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - //} if(!res) ret=0; -#endif return ret; } @@ -2290,21 +2106,16 @@ BOOL WINAPI extDDStretchBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int if(hdcDest != hdcSrc){ (*pGetClientRect)(dxw.GethWnd(),&ClientRect); - ret=(*pStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, dwRop); + ret=(*pGDIStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, dwRop); if(!ret) { OutTraceE("GDI.StretchBlt: ERROR err=%d at %d\n", GetLastError(), __LINE__); return ret; } } -// if(hdcDest==PrimHDC){ - { - if(!lpDDSPrimHDC) lpDDSPrimHDC=GetPrimarySurface(); - OutTraceD("GDI.StretchBlt: refreshing primary surface lpdds=%x\n",lpDDSPrimHDC); - //extBlt(lpDDSPrimHDC, NULL, lpDDSPrimHDC, NULL, 0, NULL); - sBlt("GDI.StretchBlt", lpDDSPrimHDC, NULL, lpDDSPrimHDC, NULL, 0, NULL, 0); - res=(*pUnlockMethod(lpDDSPrimHDC))(lpDDSPrimHDC, NULL); - //if(res) OutTraceE("Unlock: ERROR err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - } + dxw.SetPrimarySurface(); + OutTraceD("GDI.StretchBlt: refreshing primary surface lpdds=%x\n",dxw.lpDDSPrimHDC); + sBlt("GDI.StretchBlt", dxw.lpDDSPrimHDC, NULL, dxw.lpDDSPrimHDC, NULL, 0, NULL, 0); + res=(*pUnlockMethod(dxw.lpDDSPrimHDC))(dxw.lpDDSPrimHDC, NULL); return ret; } @@ -2322,9 +2133,8 @@ HDC WINAPI extBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) // on MAPGDITOPRIMARY, return the PrimHDC handle instead of the window DC if(dxw.dwFlags1 & MAPGDITOPRIMARY) { - if(pGetDC && lpDDSPrimHDC){ - //(*pGetDC)(lpDDSPrimHDC,&PrimHDC); - extGetDC(lpDDSPrimHDC,&PrimHDC); + if(pGetDC && dxw.lpDDSPrimHDC){ + extGetDC(dxw.lpDDSPrimHDC,&PrimHDC); OutTraceD("GDI.BeginPaint: redirect hdc=%x -> PrimHDC=%x\n", hdc, PrimHDC); hdc=PrimHDC; } @@ -2392,8 +2202,6 @@ HWND WINAPI extCreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpT if(!(*pSetWindowLong)(RetHWND, DWL_DLGPROC, (LONG)extDialogWindowProc)) OutTraceE("SetWindowLong: ERROR err=%d at %d\n", GetLastError(), __LINE__); - //if(!(*pMoveWindow)(RetHWND, iPosX, iPosY, iSizX, iSizY, FALSE)) - // OutTraceE("MoveWindow: ERROR err=%d at %d\n", GetLastError(), __LINE__); OutTraceD("CreateDialogIndirectParam: hwnd=%x\n", RetHWND); isWithinDialog=FALSE; //if (IsDebug) EnumChildWindows(RetHWND, (WNDENUMPROC)TraceChildWin, (LPARAM)RetHWND); @@ -2413,26 +2221,12 @@ HWND WINAPI extCreateDialogParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HW if(!(*pSetWindowLong)(RetHWND, DWL_DLGPROC, (LONG)extDialogWindowProc)) OutTraceE("SetWindowLong: ERROR err=%d at %d\n", GetLastError(), __LINE__); - //if(!(*pMoveWindow)(RetHWND, iPosX, iPosY, iSizX, iSizY, FALSE)) - // OutTraceE("MoveWindow: ERROR err=%d at %d\n", GetLastError(), __LINE__); OutTraceD("CreateDialogParam: hwnd=%x\n", RetHWND); isWithinDialog=FALSE; //if (IsDebug) EnumChildWindows(RetHWND, (WNDENUMPROC)TraceChildWin, (LPARAM)RetHWND); return RetHWND; } -HWND WINAPI extSetCapture(HWND hwnd) -{ - OutTraceD("SetCapture: hwnd=%x\n", hwnd); - return NULL; -} - -BOOL WINAPI extReleaseCapture(void) -{ - OutTraceD("ReleaseCapture\n"); - return 1; -} - BOOL WINAPI extDDInvalidateRect(HWND hwnd, RECT *lpRect, BOOL bErase) { if(lpRect) @@ -2457,13 +2251,6 @@ BOOL WINAPI extInvalidateRect(HWND hwnd, RECT *lpRect, BOOL bErase) return (*pInvalidateRect)(hwnd, NULL, bErase); } -BOOL WINAPI extInvalidateRgn(HWND hwnd, HRGN hRgn, BOOL bErase) -{ - OutTraceD("InvalidateRgn: hwnd=%x hrgn=%x erase=%x\n", - hwnd, hRgn, bErase); - return (*pInvalidateRgn)(hwnd, hRgn, bErase); -} - /* --------------------------------------------------------------------------- */ // v2.1.75: Hooking for GDI32 CreatePalette, SelectPalette, RealizePalette: @@ -2485,6 +2272,7 @@ HPALETTE WINAPI extGDICreatePalette(CONST LOGPALETTE *plpal) HPALETTE ret; int idx; + dxw.IsGDIPalette=TRUE; OutTraceD("GDI.CreatePalette: plpal=%x version=%x NumEntries=%x\n", plpal, plpal->palVersion, plpal->palNumEntries); ret=(*pGDICreatePalette)(plpal); if(IsDebug){ @@ -2504,8 +2292,7 @@ HPALETTE WINAPI extSelectPalette(HDC hdc, HPALETTE hpal, BOOL bForceBackground) { HPALETTE ret; - ret=(*pSelectPalette)(hdc, hpal, bForceBackground); - //G_bForceBackground=bForceBackground; + ret=(*pGDISelectPalette)(hdc, hpal, bForceBackground); OutTraceD("GDI.SelectPalette: hdc=%x hpal=%x ForceBackground=%x ret=%x\n", hdc, hpal, bForceBackground, ret); return ret; } @@ -2515,13 +2302,16 @@ UINT WINAPI extRealizePalette(HDC hdc) UINT ret; extern void mySetPalette(int, int, LPPALETTEENTRY); - ret=(*pRealizePalette)(hdc); + ret=(*pGDIRealizePalette)(hdc); OutTraceD("GDI.RealizePalette: hdc=%x ret=%x\n", hdc, ret); + + if(!dxw.IsGDIPalette) return ret; + // quick & dirty implementation through a nasty global: // if the SelectPalette didn't force to the background (arg bForceBackground==FALSE) // then don't override the current palette set by the DirectDrawPalette class. // should be cleaned up a little.... - // maybe not: now both Diable & Dementia colors are working... + // maybe not: now both Diablo & Dementia colors are working... if(dxw.dwFlags1 & EMULATESURFACE) mySetPalette(0, MyPal.palNumEntries, MyPal.palPalEntry); // DEBUGGING @@ -2531,7 +2321,6 @@ UINT WINAPI extRealizePalette(HDC hdc) for(idx=0; idxwHour, lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds); +} + + +void WINAPI extGetLocalTime(LPSYSTEMTIME lpLocalTime) +{ + SYSTEMTIME SystemTime; + dxw.GetSystemTime(&SystemTime); + SystemTimeToTzSpecificLocalTime(NULL, &SystemTime, lpLocalTime); + OutTrace("GetLocalTime: %02d:%02d:%02d.%03d\n", + lpLocalTime->wHour, lpLocalTime->wMinute, lpLocalTime->wSecond, lpLocalTime->wMilliseconds); +} + +UINT_PTR WINAPI extSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc) +{ + UINT uShiftedElapse; + // beware: the quicker the time flows, the more the time clicks are incremented, + // and the lesser the pauses must be lasting! Shift operations are reverted in + // GetSystemTime vs. Sleep or SetTimer + uShiftedElapse = dxw.StretchTime(uElapse); + OutTrace("SetTimer: elapse=%d->%d timeshift=%d\n", uElapse, uShiftedElapse, dxw.TimeShift); + return (*pSetTimer)(hWnd, nIDEvent, uShiftedElapse, lpTimerFunc); +} + +VOID WINAPI extSleep(DWORD dwMilliseconds) +{ + DWORD dwNewDelay; + dwNewDelay=dwMilliseconds; + if (dwMilliseconds!=INFINITE && dwMilliseconds!=0){ + dwNewDelay = dxw.StretchTime(dwMilliseconds); + if (dwNewDelay==0){ // oh oh! troubles... + if (dxw.TimeShift > 0) dwNewDelay=1; // minimum allowed... + else dwNewDelay = INFINITE-1; // maximum allowed !!! + } + } + OutTrace("Sleep: msec=%d->%d timeshift=%d\n", dwMilliseconds, dwNewDelay, dxw.TimeShift); + (*pSleep)(dwNewDelay); +} + +DWORD WINAPI extSleepEx(DWORD dwMilliseconds, BOOL bAlertable) +{ + DWORD dwNewDelay; + dwNewDelay=dwMilliseconds; + if (dwMilliseconds!=INFINITE && dwMilliseconds!=0){ + dwNewDelay = dxw.StretchTime(dwMilliseconds); + if (dwNewDelay==0){ // oh oh! troubles... + if (dxw.TimeShift > 0) dwNewDelay=1; // minimum allowed... + else dwNewDelay = INFINITE-1; // maximum allowed !!! + } + } + OutTrace("SleepEx: msec=%d->%d alertable=%x, timeshift=%d\n", dwMilliseconds, dwNewDelay, bAlertable, dxw.TimeShift); + return (*pSleepEx)(dwNewDelay, bAlertable); +} + +int WINAPI extShowCursor(BOOL bShow) +{ + static int iFakeCounter; + int ret; + + OutTraceD("ShowCursor: bShow=%x\n", bShow); + if (bShow){ + if (dxw.dwFlags1 & HIDEHWCURSOR){ + iFakeCounter++; + OutTraceD("ShowCursor: HIDEHWCURSOR ret=%x\n", iFakeCounter); + return iFakeCounter; + } + } + else { + if (dxw.dwFlags2 & SHOWHWCURSOR){ + iFakeCounter--; + OutTraceD("ShowCursor: SHOWHWCURSOR ret=%x\n", iFakeCounter); + return iFakeCounter; + } + } + ret=(*pShowCursor)(bShow); + OutTraceD("ShowCursor: ret=%x\n", ret); + return ret; } \ No newline at end of file diff --git a/dll/syslibs.h b/dll/syslibs.h index 696cb8c..c178e0b 100644 --- a/dll/syslibs.h +++ b/dll/syslibs.h @@ -1,166 +1,285 @@ /* =================================================================== -u32lib.h: contains typedef definition and extern pointer declarations -for all GDI32.dll and user32.dll functions hooked by DxWnd +syslibs.h: contains typedef definition and extern pointer declarations +for all system calls hooked by DxWnd: +GDI32.dll +Kernel32.dll +ole32.dll +user32.dll.dll ====================================================================*/ -typedef BOOL (WINAPI *GetCursorPos_Type)(LPPOINT); -typedef BOOL (WINAPI *SetCursorPos_Type)(int, int); -typedef HCURSOR (WINAPI *SetCursor_Type)(HCURSOR); -typedef BOOL (WINAPI *ClipCursor_Type)(const RECT *); -typedef BOOL (WINAPI *TextOut_Type)(HDC, int, int, LPCTSTR, int); -typedef BOOL (WINAPI *Rectangle_Type)(HDC, int, int, int, int); -typedef COLORREF (WINAPI *SetBkColor_Type)(HDC, COLORREF); -typedef COLORREF (WINAPI *SetTextColor_Type)(HDC, COLORREF); -typedef HFONT (WINAPI *CreateFont_Type)(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCTSTR); -typedef HFONT (WINAPI *CreateFontIndirect_Type)(const LOGFONT*); -typedef HDC (WINAPI *GDIGetDC_Type)(HWND); -typedef int (WINAPI *GDIReleaseDC_Type)(HWND, HDC); -typedef BOOL (WINAPI *ColorCorrectPalette_Type)(HDC, HPALETTE, DWORD, DWORD); -typedef HWND (WINAPI *CreateWindowExA_Type)(DWORD, LPCTSTR, LPCTSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID); -typedef HWND (WINAPI *GetDesktopWindow_Type)(void); -typedef BOOL (WINAPI *ShowWindow_Type)(HWND, int); -typedef int (WINAPI *FillRect_Type)(HDC, const RECT *, HBRUSH); -typedef int (WINAPI *DrawFocusRect_Type)(HDC, const RECT *); -typedef int (WINAPI *GetSystemMetrics_Type)(int); -typedef int (WINAPI *GetDeviceCaps_Type)(HDC, int); -typedef int (WINAPI *GDIGetDisplayMode_Type)(HDC, int); -typedef BOOL (WINAPI *ShowWindow_Type)(HWND, int); -typedef LONG (WINAPI *SetWindowLong_Type)(HWND, int, LONG); -typedef LONG (WINAPI *GetWindowLong_Type)(HWND, int); -typedef BOOL (WINAPI *SetWindowPos_Type)(HWND, HWND, int, int, int, int, UINT); -typedef HDWP (WINAPI *DeferWindowPos_Type)(HDWP, HWND, HWND, int, int, int, int, UINT); -typedef LRESULT (WINAPI *CallWindowProc_Type)(WNDPROC, HWND, UINT, WPARAM, LPARAM); -typedef BOOL (WINAPI *ScaleWindowExtEx_Type)(HDC, int, int, int, int, LPSIZE); -typedef int (WINAPI *GDIChoosePixelFormat_Type)(HDC, const PIXELFORMATDESCRIPTOR *); -typedef int (WINAPI *GDIGetPixelFormat_Type)(HDC hdc); -typedef BOOL (WINAPI *GDISetPixelFormat_Type)(HDC, int, const PIXELFORMATDESCRIPTOR *); -//typedef HRGN (WINAPI *CreateRectRgn_Type)(int, int, int, int); -typedef LRESULT (WINAPI *DefWindowProc_Type)(HWND, UINT, WPARAM, LPARAM); -typedef LONG (WINAPI *ChangeDisplaySettings_Type)(DEVMODE *, DWORD); -typedef LONG (WINAPI *ChangeDisplaySettingsEx_Type)(LPCTSTR, DEVMODE *, HWND, DWORD, LPVOID); -typedef LONG (WINAPI *EnumDisplaySettings_Type)(LPCTSTR, DWORD, LPDEVMODEA); -typedef BOOL (WINAPI *SetWindowPlacement_Type)(const WINDOWPLACEMENT*); -typedef DWORD (WINAPI *SetLayeredWindowAttributes_Type)(HWND, DWORD, BYTE, DWORD); -typedef HDC (WINAPI *CreateCompatibleDC_Type)(HDC); -typedef BOOL (WINAPI *DeleteDC_Type)(HDC); -typedef BOOL (WINAPI *BitBlt_Type)(HDC, int, int, int, int, HDC, int, int, DWORD); -typedef BOOL (WINAPI *PatBlt_Type)(HDC, int, int, int, int, DWORD); -typedef BOOL (WINAPI *StretchBlt_Type)(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); -typedef HDC (WINAPI *CreateDC_Type)(LPCSTR, LPCSTR, LPCSTR, const DEVMODE *); -typedef int (WINAPI *SaveDC_Type)(HDC); -typedef BOOL (WINAPI *RestoreDC_Type)(HDC, int); -typedef HDC (WINAPI *BeginPaint_Type)(HWND, LPPAINTSTRUCT); -typedef BOOL (WINAPI *EndPaint_Type)(HWND, const PAINTSTRUCT *); +/* =================================================================== +type definitions +====================================================================*/ +// GDI32.dll: +typedef BOOL (WINAPI *BitBlt_Type)(HDC, int, int, int, int, HDC, int, int, DWORD); +typedef HDC (WINAPI *CreateCompatibleDC_Type)(HDC); +typedef HDC (WINAPI *CreateDC_Type)(LPCSTR, LPCSTR, LPCSTR, const DEVMODE *); +typedef HFONT (WINAPI *CreateFont_Type)(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCTSTR); +typedef HFONT (WINAPI *CreateFontIndirect_Type)(const LOGFONT*); +typedef HPALETTE(WINAPI *GDICreatePalette_Type)(CONST LOGPALETTE *); +typedef HDWP (WINAPI *DeferWindowPos_Type)(HDWP, HWND, HWND, int, int, int, int, UINT); +typedef BOOL (WINAPI *DeleteDC_Type)(HDC); +typedef int (WINAPI *GetDeviceCaps_Type)(HDC, int); +typedef BOOL (WINAPI *GetDeviceGammaRamp_Type)(HDC, LPVOID); +typedef BOOL (WINAPI *GetSystemPaletteEntries_Type)(HDC, UINT, UINT, LPPALETTEENTRY); +typedef BOOL (WINAPI *PatBlt_Type)(HDC, int, int, int, int, DWORD); +typedef UINT (WINAPI *RealizePalette_Type)(HDC); +typedef BOOL (WINAPI *Rectangle_Type)(HDC, int, int, int, int); +typedef BOOL (WINAPI *RestoreDC_Type)(HDC, int); +typedef int (WINAPI *SaveDC_Type)(HDC); +typedef BOOL (WINAPI *ScaleWindowExtEx_Type)(HDC, int, int, int, int, LPSIZE); +typedef HPALETTE(WINAPI *SelectPalette_Type)(HDC, HPALETTE, BOOL); +typedef COLORREF (WINAPI *SetBkColor_Type)(HDC, COLORREF); +typedef BOOL (WINAPI *SetDeviceGammaRamp_Type)(HDC, LPVOID); +typedef COLORREF(WINAPI *SetTextColor_Type)(HDC, COLORREF); +typedef BOOL (WINAPI *StretchBlt_Type)(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); +typedef BOOL (WINAPI *TextOut_Type)(HDC, int, int, LPCTSTR, int); + +// Kernel32.dll: +typedef BOOL (WINAPI *GetDiskFreeSpaceA_Type)(LPCSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); +typedef void (WINAPI *GetLocalTime_Type)(LPSYSTEMTIME); +typedef FARPROC (WINAPI *GetProcAddress_Type)(HMODULE, LPCSTR); +typedef void (WINAPI *GetSystemTime_Type)(LPSYSTEMTIME); +typedef DWORD (WINAPI *GetTickCount_Type)(void); typedef HMODULE (WINAPI *LoadLibraryA_Type)(LPCTSTR); typedef HMODULE (WINAPI *LoadLibraryExA_Type)(LPCTSTR, HANDLE, DWORD); -typedef BOOL (WINAPI *GetClipCursor_Type)(LPRECT); -typedef ATOM (WINAPI *RegisterClassExA_Type)(WNDCLASSEX *); -typedef BOOL (WINAPI *ScreenToClient_Type)(HWND, LPPOINT); -typedef BOOL (WINAPI *ClientToScreen_Type)(HWND, LPPOINT); -typedef BOOL (WINAPI *GetClientRect_Type)(HWND, LPRECT); -typedef BOOL (WINAPI *GetWindowRect_Type)(HWND, LPRECT); -typedef int (WINAPI *MapWindowPoints_Type)(HWND, HWND, LPPOINT, UINT); +typedef LPTOP_LEVEL_EXCEPTION_FILTER + (WINAPI *SetUnhandledExceptionFilter_Type)(LPTOP_LEVEL_EXCEPTION_FILTER); +typedef void (WINAPI *Sleep_Type)(DWORD); +typedef DWORD (WINAPI *SleepEx_Type)(DWORD, BOOL); -typedef BOOL (WINAPI *PeekMessage_Type)(LPMSG, HWND, UINT, UINT, UINT); -typedef BOOL (WINAPI *GetMessage_Type)(LPMSG, HWND, UINT, UINT); -typedef LRESULT (WINAPI *DispatchMessage_Type)(LPMSG); -typedef FARPROC (WINAPI *GetProcAddress_Type)(HMODULE, LPCSTR); -//typedef BOOL (WINAPI *GetUpdateRect_Type)(HWND, LPRECT, BOOL); -typedef HWND (WINAPI *CreateDialogIndirectParam_Type)(HINSTANCE, LPCDLGTEMPLATE, HWND, DLGPROC, LPARAM); -typedef HWND (WINAPI *CreateDialogParam_Type)(HINSTANCE, LPCTSTR, HWND, DLGPROC, LPARAM); -typedef BOOL (WINAPI *InvalidateRect_Type)(HWND, CONST RECT *, BOOL); -typedef BOOL (WINAPI *InvalidateRgn_Type)(HWND, HRGN, BOOL); +// ole32.dll: typedef HRESULT (STDAPICALLTYPE *CoCreateInstance_Type)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID FAR* ppv); -typedef HPALETTE (WINAPI *SelectPalette_Type)(HDC, HPALETTE, BOOL); -typedef UINT (WINAPI *RealizePalette_Type)(HDC); -typedef HDC (WINAPI *BeginPaint_Type)(HWND, LPPAINTSTRUCT); -typedef HPALETTE (WINAPI *GDICreatePalette_Type)(CONST LOGPALETTE *); -typedef BOOL (WINAPI *GetSystemPaletteEntries_Type)(HDC, UINT, UINT, LPPALETTEENTRY); -typedef BOOL (WINAPI *MoveWindow_Type)(HWND, int, int, int, int, BOOL); - -typedef LPTOP_LEVEL_EXCEPTION_FILTER (WINAPI *SetUnhandledExceptionFilter_Type)(LPTOP_LEVEL_EXCEPTION_FILTER); - -typedef BOOL (WINAPI *GetDiskFreeSpaceA_Type)(LPCSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); -typedef BOOL (WINAPI *SetDeviceGammaRamp_Type)(HDC, LPVOID); -typedef BOOL (WINAPI *GetDeviceGammaRamp_Type)(HDC, LPVOID); +// user32.dll: +typedef HDC (WINAPI *BeginPaint_Type)(HWND, LPPAINTSTRUCT); +typedef LRESULT (WINAPI *CallWindowProc_Type)(WNDPROC, HWND, UINT, WPARAM, LPARAM); +typedef LONG (WINAPI *ChangeDisplaySettings_Type)(DEVMODE *, DWORD); +typedef LONG (WINAPI *ChangeDisplaySettingsEx_Type)(LPCTSTR, DEVMODE *, HWND, DWORD, LPVOID); +typedef BOOL (WINAPI *ClientToScreen_Type)(HWND, LPPOINT); +typedef BOOL (WINAPI *ClipCursor_Type)(const RECT *); +typedef HWND (WINAPI *CreateDialogIndirectParam_Type)(HINSTANCE, LPCDLGTEMPLATE, HWND, DLGPROC, LPARAM); +typedef HWND (WINAPI *CreateDialogParam_Type)(HINSTANCE, LPCTSTR, HWND, DLGPROC, LPARAM); +typedef HWND (WINAPI *CreateWindowExA_Type)(DWORD, LPCTSTR, LPCTSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID); +typedef LRESULT (WINAPI *DefWindowProc_Type)(HWND, UINT, WPARAM, LPARAM); +typedef BOOL (WINAPI *EndPaint_Type)(HWND, const PAINTSTRUCT *); +typedef LONG (WINAPI *EnumDisplaySettings_Type)(LPCTSTR, DWORD, LPDEVMODEA); +typedef int (WINAPI *FillRect_Type)(HDC, const RECT *, HBRUSH); +typedef BOOL (WINAPI *GetClientRect_Type)(HWND, LPRECT); +typedef BOOL (WINAPI *GetClipCursor_Type)(LPRECT); +typedef BOOL (WINAPI *GetCursorPos_Type)(LPPOINT); +typedef HDC (WINAPI *GDIGetDC_Type)(HWND); +typedef HWND (WINAPI *GetDesktopWindow_Type)(void); +typedef BOOL (WINAPI *GetMessage_Type)(LPMSG, HWND, UINT, UINT); +typedef int (WINAPI *GetSystemMetrics_Type)(int); +typedef LONG (WINAPI *GetWindowLong_Type)(HWND, int); +typedef BOOL (WINAPI *GetWindowRect_Type)(HWND, LPRECT); +typedef BOOL (WINAPI *InvalidateRect_Type)(HWND, CONST RECT *, BOOL); +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 int (WINAPI *GDIReleaseDC_Type)(HWND, HDC); +typedef BOOL (WINAPI *ScreenToClient_Type)(HWND, LPPOINT); typedef LRESULT (WINAPI *SendMessage_Type)(HWND, UINT, WPARAM, LPARAM); -typedef DWORD (WINAPI *GetTickCount_Type)(void); +typedef HCURSOR (WINAPI *SetCursor_Type)(HCURSOR); +typedef BOOL (WINAPI *SetCursorPos_Type)(int, int); +typedef UINT_PTR(WINAPI *SetTimer_Type)(HWND, UINT_PTR, UINT, TIMERPROC); +typedef LONG (WINAPI *SetWindowLong_Type)(HWND, int, LONG); +typedef BOOL (WINAPI *SetWindowPos_Type)(HWND, HWND, int, int, int, int, UINT); +typedef int (WINAPI *ShowCursor_Type)(BOOL); +typedef BOOL (WINAPI *ShowWindow_Type)(HWND, int); -extern GetCursorPos_Type pGetCursorPos; -extern SetCursorPos_Type pSetCursorPos; -extern ClipCursor_Type pClipCursor; -extern TextOut_Type pTextOutA; -extern FillRect_Type pFillRect; -extern DrawFocusRect_Type pDrawFocusRect; -extern Rectangle_Type pRectangle; -extern SetTextColor_Type pSetTextColor; -extern GetSystemMetrics_Type pGetSystemMetrics; -extern CreateFont_Type pCreateFont; -extern CreateFontIndirect_Type pCreateFontIndirect; -extern SetBkColor_Type pSetBkColor; -extern GetDeviceCaps_Type pGetDeviceCaps; -extern GDIGetDisplayMode_Type pGDIGetDisplayMode; -extern ColorCorrectPalette_Type pColorCorrectPalette; -extern CreateWindowExA_Type pCreateWindowExA; -extern GetDesktopWindow_Type pGetDesktopWindow; -extern ShowWindow_Type pShowWindow; -extern SetWindowLong_Type pSetWindowLong; -extern GetWindowLong_Type pGetWindowLong; -extern SetWindowPos_Type pSetWindowPos; -extern DeferWindowPos_Type pDeferWindowPos; -extern CallWindowProc_Type pCallWindowProc; -extern ScaleWindowExtEx_Type pScaleWindowExtEx; -extern GDIChoosePixelFormat_Type pGDIChoosePixelFormat; -extern GDIGetPixelFormat_Type pGDIGetPixelFormat; -extern GDISetPixelFormat_Type pGDISetPixelFormat; -//extern CreateRectRgn_Type pCreateRectRgn; -extern DefWindowProc_Type pDefWindowProc; -extern ChangeDisplaySettings_Type pChangeDisplaySettings; -extern ChangeDisplaySettingsEx_Type pChangeDisplaySettingsEx; -extern EnumDisplaySettings_Type pEnumDisplaySettings; -extern SetWindowPlacement_Type pSetWindowPlacement; -extern CreateCompatibleDC_Type pCreateCompatibleDC; -extern DeleteDC_Type pDeleteDC; -extern BitBlt_Type pBitBlt; -extern PatBlt_Type pPatBlt; -extern StretchBlt_Type pStretchBlt; -extern CreateDC_Type pCreateDC; -extern SaveDC_Type pGDISaveDC; -extern RestoreDC_Type pGDIRestoreDC; -extern MapWindowPoints_Type pMapWindowPoints; +/* =================================================================== +hooked APIs real pointers +====================================================================*/ -extern LoadLibraryA_Type pLoadLibraryA; -extern LoadLibraryExA_Type pLoadLibraryExA; -extern GetClipCursor_Type pGetClipCursor; -extern RegisterClassExA_Type pRegisterClassExA; -extern ScreenToClient_Type pScreenToClient; -extern ClientToScreen_Type pClientToScreen; -extern GetClientRect_Type pGetClientRect; -extern GetWindowRect_Type pGetWindowRect; -extern PeekMessage_Type pPeekMessage; -extern GetMessage_Type pGetMessage; -extern DispatchMessage_Type pDispatchMessage; -extern GetProcAddress_Type pGetProcAddress; -//extern GetUpdateRect_Type pGetUpdateRect; -extern CreateDialogParam_Type pCreateDialogParam; -extern CreateDialogIndirectParam_Type pCreateDialogIndirectParam; -extern BeginPaint_Type pBeginPaint; -extern EndPaint_Type pEndPaint; -extern InvalidateRect_Type pInvalidateRect; -extern CoCreateInstance_Type pCoCreateInstance; -extern GDICreatePalette_Type pGDICreatePalette; -extern SelectPalette_Type pSelectPalette; -extern RealizePalette_Type pRealizePalette; -extern GetSystemPaletteEntries_Type pGetSystemPaletteEntries; -extern MoveWindow_Type pMoveWindow; -extern SetUnhandledExceptionFilter_Type pSetUnhandledExceptionFilter; -extern GetDiskFreeSpaceA_Type pGetDiskFreeSpaceA; -extern SetDeviceGammaRamp_Type pSetDeviceGammaRamp; -extern GetDeviceGammaRamp_Type pGetDeviceGammaRamp; -extern SendMessage_Type pSendMessage; -extern GetTickCount_Type pGetTickCount; +#ifdef DXWDECLARATIONS +#undef DXWEXTERN +#undef DXWINITIALIZED +#define DXWEXTERN +#define DXWINITIALIZED = NULL +#else +#undef DXWEXTERN +#undef DXWINITIALIZED +#define DXWEXTERN extern +#define DXWINITIALIZED +#endif +// GDI32.dll: +DXWEXTERN BitBlt_Type pGDIBitBlt DXWINITIALIZED; +DXWEXTERN CreateCompatibleDC_Type pGDICreateCompatibleDC DXWINITIALIZED; +DXWEXTERN CreateDC_Type pGDICreateDC DXWINITIALIZED; +DXWEXTERN CreateFont_Type pGDICreateFont DXWINITIALIZED; +DXWEXTERN CreateFontIndirect_Type pGDICreateFontIndirect DXWINITIALIZED; +DXWEXTERN GDICreatePalette_Type pGDICreatePalette DXWINITIALIZED; +DXWEXTERN DeferWindowPos_Type pGDIDeferWindowPos DXWINITIALIZED; +DXWEXTERN DeleteDC_Type pGDIDeleteDC DXWINITIALIZED; +DXWEXTERN GetDeviceCaps_Type pGDIGetDeviceCaps DXWINITIALIZED; +DXWEXTERN GetDeviceGammaRamp_Type pGDIGetDeviceGammaRamp DXWINITIALIZED; +DXWEXTERN GetSystemPaletteEntries_Type pGDIGetSystemPaletteEntries DXWINITIALIZED; +DXWEXTERN PatBlt_Type pGDIPatBlt DXWINITIALIZED; +DXWEXTERN RealizePalette_Type pGDIRealizePalette DXWINITIALIZED; +DXWEXTERN Rectangle_Type pGDIRectangle DXWINITIALIZED; +DXWEXTERN RestoreDC_Type pGDIRestoreDC DXWINITIALIZED; +DXWEXTERN SaveDC_Type pGDISaveDC DXWINITIALIZED; +DXWEXTERN ScaleWindowExtEx_Type pGDIScaleWindowExtEx DXWINITIALIZED; +DXWEXTERN SelectPalette_Type pGDISelectPalette DXWINITIALIZED; +DXWEXTERN SetBkColor_Type pGDISetBkColor DXWINITIALIZED; +DXWEXTERN SetDeviceGammaRamp_Type pGDISetDeviceGammaRamp DXWINITIALIZED; +DXWEXTERN SetTextColor_Type pGDISetTextColor DXWINITIALIZED; +DXWEXTERN StretchBlt_Type pGDIStretchBlt DXWINITIALIZED; +DXWEXTERN TextOut_Type pGDITextOutA DXWINITIALIZED; + +// Kernel32.dll: +DXWEXTERN GetDiskFreeSpaceA_Type pGetDiskFreeSpaceA DXWINITIALIZED; +DXWEXTERN GetLocalTime_Type pGetLocalTime DXWINITIALIZED; +DXWEXTERN GetProcAddress_Type pGetProcAddress DXWINITIALIZED; +DXWEXTERN GetSystemTime_Type pGetSystemTime DXWINITIALIZED; +DXWEXTERN GetTickCount_Type pGetTickCount DXWINITIALIZED; +DXWEXTERN LoadLibraryA_Type pLoadLibraryA DXWINITIALIZED; +DXWEXTERN LoadLibraryExA_Type pLoadLibraryExA DXWINITIALIZED; +DXWEXTERN SetUnhandledExceptionFilter_Type pSetUnhandledExceptionFilter DXWINITIALIZED; +DXWEXTERN Sleep_Type pSleep DXWINITIALIZED; +DXWEXTERN SleepEx_Type pSleepEx DXWINITIALIZED; + +// ole32.dll: +DXWEXTERN CoCreateInstance_Type pCoCreateInstance DXWINITIALIZED; + +// user32.dll: +DXWEXTERN BeginPaint_Type pBeginPaint DXWINITIALIZED; +DXWEXTERN CallWindowProc_Type pCallWindowProc DXWINITIALIZED; +DXWEXTERN ChangeDisplaySettings_Type pChangeDisplaySettings DXWINITIALIZED; +DXWEXTERN ChangeDisplaySettingsEx_Type pChangeDisplaySettingsEx DXWINITIALIZED; +DXWEXTERN ClientToScreen_Type pClientToScreen DXWINITIALIZED; +DXWEXTERN ClipCursor_Type pClipCursor DXWINITIALIZED; +DXWEXTERN CreateDialogIndirectParam_Type pCreateDialogIndirectParam DXWINITIALIZED; +DXWEXTERN CreateDialogParam_Type pCreateDialogParam DXWINITIALIZED; +DXWEXTERN CreateWindowExA_Type pCreateWindowExA DXWINITIALIZED; +DXWEXTERN DefWindowProc_Type pDefWindowProc DXWINITIALIZED; +DXWEXTERN EndPaint_Type pEndPaint DXWINITIALIZED; +DXWEXTERN EnumDisplaySettings_Type pEnumDisplaySettings DXWINITIALIZED; +DXWEXTERN FillRect_Type pFillRect DXWINITIALIZED; +DXWEXTERN GetClientRect_Type pGetClientRect DXWINITIALIZED; +DXWEXTERN GetClipCursor_Type pGetClipCursor DXWINITIALIZED; +DXWEXTERN GetCursorPos_Type pGetCursorPos DXWINITIALIZED; +DXWEXTERN GDIGetDC_Type pGDIGetDC DXWINITIALIZED; +DXWEXTERN GetDesktopWindow_Type pGetDesktopWindow DXWINITIALIZED; +DXWEXTERN GetMessage_Type pGetMessage DXWINITIALIZED; +DXWEXTERN GetSystemMetrics_Type pGetSystemMetrics DXWINITIALIZED; +DXWEXTERN GDIGetDC_Type pGDIGetWindowDC DXWINITIALIZED; +DXWEXTERN GetWindowLong_Type pGetWindowLong DXWINITIALIZED; +DXWEXTERN GetWindowRect_Type pGetWindowRect DXWINITIALIZED; +DXWEXTERN InvalidateRect_Type pInvalidateRect DXWINITIALIZED; +DXWEXTERN MapWindowPoints_Type pMapWindowPoints DXWINITIALIZED; +DXWEXTERN MoveWindow_Type pMoveWindow DXWINITIALIZED; +DXWEXTERN PeekMessage_Type pPeekMessage DXWINITIALIZED; +DXWEXTERN RegisterClassExA_Type pRegisterClassExA DXWINITIALIZED; +DXWEXTERN GDIReleaseDC_Type pGDIReleaseDC DXWINITIALIZED; +DXWEXTERN ScreenToClient_Type pScreenToClient DXWINITIALIZED; +DXWEXTERN SendMessage_Type pSendMessage DXWINITIALIZED; +DXWEXTERN SetCursor_Type pSetCursor DXWINITIALIZED; +DXWEXTERN SetCursorPos_Type pSetCursorPos DXWINITIALIZED; +DXWEXTERN SetTimer_Type pSetTimer DXWINITIALIZED; +DXWEXTERN SetWindowLong_Type pSetWindowLong DXWINITIALIZED; +DXWEXTERN SetWindowPos_Type pSetWindowPos DXWINITIALIZED; +DXWEXTERN ShowCursor_Type pShowCursor DXWINITIALIZED; +DXWEXTERN ShowWindow_Type pShowWindow DXWINITIALIZED; + +/* =================================================================== +hook procedures (possibly more tnan one per each API...) +====================================================================*/ + +// GDI32.dll: +extern BOOL WINAPI extGDIBitBlt(HDC, int, int, int, int, HDC, int, int, DWORD); +extern HDC WINAPI extGDICreateCompatibleDC(HDC); +extern HDC WINAPI extDDCreateCompatibleDC(HDC); +extern HDC WINAPI extGDICreateDC(LPSTR, LPSTR, LPSTR, CONST DEVMODE *); +extern HDC WINAPI extDDCreateDC(LPSTR, LPSTR, LPSTR, CONST DEVMODE *); +extern HFONT WINAPI extCreateFont(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCTSTR); +extern HFONT WINAPI extCreateFontIndirect(const LOGFONT*); +extern HPALETTE WINAPI extGDICreatePalette(CONST LOGPALETTE *); +extern HDWP WINAPI extDeferWindowPos(HDWP, HWND, HWND, int, int, int, int, UINT); +extern BOOL WINAPI extGDIDeleteDC(HDC); +extern BOOL WINAPI extDDDeleteDC(HDC); +extern int WINAPI extGetDeviceCaps(HDC, int); +extern BOOL WINAPI extGetDeviceGammaRamp(HDC, LPVOID); +extern UINT WINAPI extGetSystemPaletteEntries(HDC, UINT, UINT, LPPALETTEENTRY); +extern BOOL WINAPI extGDIPatBlt(HDC, int, int, int, int, DWORD); +extern BOOL WINAPI extDDBitBlt(HDC, int, int, int, int, HDC, int, int, DWORD); +extern UINT WINAPI extRealizePalette(HDC); +extern BOOL WINAPI extRectangle(HDC, int, int, int, int); +extern BOOL WINAPI extGDIRestoreDC(HDC, int); +extern int WINAPI extGDISaveDC(HDC); +extern BOOL WINAPI extScaleWindowExtEx(HDC, int, int, int, int, LPSIZE); +extern HPALETTE WINAPI extSelectPalette(HDC, HPALETTE, BOOL); +extern COLORREF WINAPI extSetBkColor(HDC, COLORREF); +extern BOOL WINAPI extSetDeviceGammaRamp(HDC, LPVOID); +extern COLORREF WINAPI extSetTextColor(HDC, COLORREF); +extern BOOL WINAPI extGDIStretchBlt(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); +extern BOOL WINAPI extDDStretchBlt(HDC, int, int, int, int, HDC, int, int, int, int, DWORD); +extern BOOL WINAPI extTextOutA(HDC, int, int, LPCTSTR, int); + +// Kernel32.dll: +extern BOOL WINAPI extGetDiskFreeSpaceA(LPCSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); +extern void WINAPI extGetLocalTime(LPSYSTEMTIME); +extern FARPROC WINAPI extGetProcAddress(HMODULE, LPCSTR); +extern void WINAPI extGetSystemTime(LPSYSTEMTIME); +extern DWORD WINAPI extGetTickCount(void); +extern HMODULE WINAPI extLoadLibraryA(LPCTSTR); +extern HMODULE WINAPI extLoadLibraryExA(LPCTSTR, HANDLE, DWORD); +extern LPTOP_LEVEL_EXCEPTION_FILTER WINAPI extSetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER); +extern void WINAPI extSleep(DWORD); +extern DWORD WINAPI extSleepEx(DWORD, BOOL); + +// ole32.dll: +extern HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID FAR*); + +// user32.dll: +extern HDC WINAPI extBeginPaint(HWND, LPPAINTSTRUCT); +extern LRESULT WINAPI extCallWindowProc(WNDPROC, HWND, UINT, WPARAM, LPARAM); +extern LONG WINAPI extChangeDisplaySettings(DEVMODE *, DWORD); +extern LONG WINAPI extChangeDisplaySettingsEx(LPCTSTR, DEVMODE *, HWND, DWORD, LPVOID); +extern BOOL WINAPI extClientToScreen(HWND, LPPOINT); +extern BOOL WINAPI extClipCursor(LPRECT); +extern HWND WINAPI extCreateDialogIndirectParam(HINSTANCE, LPCDLGTEMPLATE, HWND, DLGPROC, LPARAM); +extern HWND WINAPI extCreateDialogParam(HINSTANCE, LPCSTR, HWND, DLGPROC, LPARAM); +extern HWND WINAPI extCreateWindowExA(DWORD, LPCTSTR, LPCTSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID); +extern LRESULT WINAPI extDefWindowProc(HWND, UINT, WPARAM, LPARAM); +extern BOOL WINAPI extEndPaint(HWND, const PAINTSTRUCT *); +extern LONG WINAPI extEnumDisplaySettings(LPCTSTR, DWORD, DEVMODE *); +extern int WINAPI extFillRect(HDC, const RECT *, HBRUSH); +extern BOOL WINAPI extGetClientRect(HWND, LPRECT); +extern BOOL WINAPI extGetClipCursor(LPRECT); +extern BOOL WINAPI extGetCursorPos(LPPOINT); +extern HDC WINAPI extGDIGetDC(HWND); +extern HDC WINAPI extDDGetDC(HWND); +extern HWND WINAPI extGetDesktopWindow(void); +extern BOOL WINAPI extGetMessage(LPMSG, HWND, UINT, UINT); +extern int WINAPI extGetSystemMetrics(int); +extern HDC WINAPI extGDIGetWindowDC(HWND); +extern HDC WINAPI extDDGetWindowDC(HWND); +extern LONG WINAPI extGetWindowLong(HWND, int); +extern BOOL WINAPI extGetWindowRect(HWND, LPRECT); +extern BOOL WINAPI extInvalidateRect(HWND, RECT *, BOOL); +extern BOOL WINAPI extDDInvalidateRect(HWND, RECT *, BOOL); +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 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 HCURSOR WINAPI extSetCursor(HCURSOR); +extern BOOL WINAPI extSetCursorPos(int, int); +extern UINT_PTR WINAPI extSetTimer(HWND, UINT_PTR, UINT, TIMERPROC); +extern LONG WINAPI extSetWindowLong(HWND, int, LONG); +extern BOOL WINAPI extSetWindowPos(HWND, HWND, int, int, int, int, UINT); +extern int WINAPI extShowCursor(BOOL); +extern BOOL WINAPI extShowWindow(HWND, int); + +/* eof */ \ No newline at end of file diff --git a/host/Resource.h b/host/Resource.h index af7cfd1..b371b00 100644 --- a/host/Resource.h +++ b/host/Resource.h @@ -24,6 +24,7 @@ #define IDI_ICON3 148 #define IDI_RUN6 148 #define IDD_STATUS 149 +#define IDD_TIMESLIDER 150 #define IDC_AUTO 300 #define IDC_DIRECTX1 301 #define IDC_DIRECTX7 302 @@ -52,12 +53,14 @@ #define IDC_MODULE 1023 #define IDC_SNOOZE 1023 #define IDC_KILL 1024 +#define IDC_OPENGLLIB 1024 #define IDC_AUTOREFRESH 1025 #define IDC_FIXWINFRAME 1026 #define IDC_HIDEHWCURSOR 1027 #define IDC_ENABLECLIPPING 1028 #define IDC_COUNTDOWN 1028 #define IDC_EDIT1 1029 +#define IDC_SHOWHWCURSOR 1029 #define IDC_VIDEOTOSYSTEMMEM 1030 #define IDC_FIXTEXTOUT 1031 #define IDC_STATUSINFO 1031 @@ -72,6 +75,7 @@ #define IDC_TITLE 1039 #define IDC_SLOW 1040 #define IDC_CLIPCURSOR 1041 +#define IDC_INITTS 1042 #define IDC_CLIENTREMAPPING 1043 #define IDC_HANDLEALTF4 1044 #define IDC_LOCKWINPOS 1045 @@ -109,7 +113,12 @@ #define IDC_SKIPFPS 1076 #define IDC_SHOWFPS 1077 #define IDC_HIDEMULTIMONITOR 1078 +#define IDC_TIMESLIDER 1078 #define IDC_TIMESTRETCH 1079 +#define IDC_TIMESPEED 1079 +#define IDC_HOOKOPENGL 1080 +#define IDC_WALLPAPERMODE 1081 +#define IDC_HOOKGDI 1082 #define ID_MODIFY 32771 #define ID_DELETE 32772 #define ID_ADD 32773 @@ -138,15 +147,16 @@ #define ID_VIEW_STATUS 32809 #define ID_DXAPP_EXIT 32810 #define ID_SAVEFILE 32810 +#define ID_VIEW_TIMESLIDER 32811 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 150 -#define _APS_NEXT_COMMAND_VALUE 32811 -#define _APS_NEXT_CONTROL_VALUE 1078 +#define _APS_NEXT_RESOURCE_VALUE 151 +#define _APS_NEXT_COMMAND_VALUE 32812 +#define _APS_NEXT_CONTROL_VALUE 1080 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/host/StatusDialog.cpp b/host/StatusDialog.cpp index eb0c810..8ed0167 100644 --- a/host/StatusDialog.cpp +++ b/host/StatusDialog.cpp @@ -38,9 +38,12 @@ void CStatusDialog::OnTimer(UINT_PTR nIDEvent) int IconId; LPCSTR Status; char sMsg[1024]; + char sMsgBuf[80+1]; char DllVersion[21]; DXWNDSTATUS DxWndStatus; extern PRIVATEMAP *pTitles; + extern TARGETMAP *pTargets; + TARGETMAP *Target; CDialog::OnTimer(nIDEvent); DxStatus=GetHookStatus(NULL); @@ -53,19 +56,32 @@ void CStatusDialog::OnTimer(UINT_PTR nIDEvent) GetDllVersion(DllVersion); DxWndStatus.Status=DxStatus; if(DxStatus==DXW_RUNNING){ + int idx; + char *sTSCaption[9]={"x16","x8","x4","x2","x1",":2",":4",":8",":16"}; GetHookStatus(&DxWndStatus); + Target=&pTargets[DxWndStatus.TaskIdx]; + sprintf_s(sMsg, 1024, "DxWnd %s\nHook status: %s\n" "Running \"%s\"\nScreen = (%dx%d) %dBPP\n" "FullScreen = %s\nDX version = %d\n" - "Logging = %s\n" - "FPS = %d", - DllVersion, Status, - pTitles[DxWndStatus.TaskIdx].title, - DxWndStatus.Width, DxWndStatus.Height, DxWndStatus.ColorDepth, - DxWndStatus.IsFullScreen ? "Yes":"No", DxWndStatus.DXVersion, - DxWndStatus.isLogging?"ON":"OFF", - DxWndStatus.FPSCount); + "Logging = %s", + DllVersion, Status, + pTitles[DxWndStatus.TaskIdx].title, + DxWndStatus.Width, DxWndStatus.Height, DxWndStatus.ColorDepth, + DxWndStatus.IsFullScreen ? "Yes":"No", DxWndStatus.DXVersion, + DxWndStatus.isLogging?"ON":"OFF"); + if(Target->flags2 & SHOWFPS){ + sprintf(sMsgBuf, "\nFPS = %d", DxWndStatus.FPSCount); + strcat(sMsg, sMsgBuf); + } + if(Target->flags2 & TIMESTRETCH){ + idx=DxWndStatus.iTimeShift+4; + if(idx>=0 && idx<=8){ + sprintf(sMsgBuf, "\nTime speed: %s", sTSCaption[DxWndStatus.iTimeShift+4]); + strcat(sMsg, sMsgBuf); + } + } } else sprintf_s(sMsg, 1024, "DxWnd %s\nHook status: %s", DllVersion, Status); diff --git a/host/StatusDialog.h b/host/StatusDialog.h index 8928d54..eddabc2 100644 --- a/host/StatusDialog.h +++ b/host/StatusDialog.h @@ -13,6 +13,7 @@ public: // Dialog Data enum { IDD = IDD_STATUS }; + int iTimeSlider; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 0491664..95b46f1 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -46,6 +46,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_AutoRefresh = FALSE; m_FixWinFrame = FALSE; m_HideHwCursor = FALSE; + m_ShowHwCursor = FALSE; m_EnableClipping = FALSE; m_CursorClipping = FALSE; m_VideoToSystemMem = FALSE; @@ -63,7 +64,9 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_ModalStyle = FALSE; m_KeepAspectRatio = FALSE; m_ForceWinResize = FALSE; + m_HookGDI = FALSE; m_HideMultiMonitor = FALSE; + m_WallpaperMode = FALSE; m_HookChildWin = FALSE; m_MessageProc = FALSE; m_FixNCHITTEST = FALSE; @@ -77,6 +80,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_SkipFPS = FALSE; m_ShowFPS = FALSE; m_TimeStretch = FALSE; + m_HookOpenGL = FALSE; m_InitX = 0; m_InitY = 0; m_MaxX = 0; @@ -88,6 +92,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_SizX = 800; m_SizY = 600; m_MaxFPS = 0; + m_InitTS = 0; //}}AFX_DATA_INIT } @@ -126,6 +131,7 @@ void CTargetDlg::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_AUTOREFRESH, m_AutoRefresh); DDX_Check(pDX, IDC_FIXWINFRAME, m_FixWinFrame); DDX_Check(pDX, IDC_HIDEHWCURSOR, m_HideHwCursor); + DDX_Check(pDX, IDC_SHOWHWCURSOR, m_ShowHwCursor); DDX_Check(pDX, IDC_ENABLECLIPPING, m_EnableClipping); DDX_Check(pDX, IDC_CLIPCURSOR, m_CursorClipping); DDX_Check(pDX, IDC_VIDEOTOSYSTEMMEM, m_VideoToSystemMem); @@ -143,7 +149,9 @@ void CTargetDlg::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_MODALSTYLE, m_ModalStyle); DDX_Check(pDX, IDC_KEEPASPECTRATIO, m_KeepAspectRatio); DDX_Check(pDX, IDC_FORCEWINRESIZE, m_ForceWinResize); + DDX_Check(pDX, IDC_HOOKGDI, m_HookGDI); DDX_Check(pDX, IDC_HIDEMULTIMONITOR, m_HideMultiMonitor); + DDX_Check(pDX, IDC_WALLPAPERMODE, m_WallpaperMode); DDX_Check(pDX, IDC_HOOKCHILDWIN, m_HookChildWin); DDX_Check(pDX, IDC_MESSAGEPROC, m_MessageProc); DDX_Check(pDX, IDC_FIXNCHITTEST, m_FixNCHITTEST); @@ -157,6 +165,7 @@ void CTargetDlg::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_SKIPFPS, m_SkipFPS); DDX_Check(pDX, IDC_SHOWFPS, m_ShowFPS); DDX_Check(pDX, IDC_TIMESTRETCH, m_TimeStretch); + DDX_Check(pDX, IDC_HOOKOPENGL, m_HookOpenGL); DDX_Text(pDX, IDC_INITX, m_InitX); DDX_Text(pDX, IDC_INITY, m_InitY); DDX_Text(pDX, IDC_MAXX, m_MaxX); @@ -168,6 +177,7 @@ void CTargetDlg::DoDataExchange(CDataExchange* pDX) DDX_Text(pDX, IDC_SIZX, m_SizX); DDX_Text(pDX, IDC_SIZY, m_SizY); DDX_Text(pDX, IDC_MAXFPS, m_MaxFPS); + DDX_Text(pDX, IDC_INITTS, m_InitTS); //}}AFX_DATA_MAP } @@ -189,7 +199,7 @@ BEGIN_MESSAGE_MAP(CTargetDlg, CDialog) //ON_BN_CLICKED(IDC_ABSOLUTECOORD, &CTargetDlg::OnBnClickedAbsolutecoord) ON_BN_CLICKED(IDC_AUTOREFRESH, &CTargetDlg::OnBnClickedAutorefresh) ON_BN_CLICKED(IDC_FIXWINFRAME, &CTargetDlg::OnBnClickedFixWinFrame) - ON_BN_CLICKED(IDC_HIDEHWCURSOR, &CTargetDlg::OnBnClickedHideHwCursor) + //ON_BN_CLICKED(IDC_HIDEHWCURSOR, &CTargetDlg::OnBnClickedHideHwCursor) ON_BN_CLICKED(IDC_ENABLECLIPPING, &CTargetDlg::OnBnClickedEnableClipping) ON_BN_CLICKED(IDC_VIDEOTOSYSTEMMEM, &CTargetDlg::OnBnClickedHandleCursorPos) ON_BN_CLICKED(IDC_FIXTEXTOUT, &CTargetDlg::OnBnClickedFixTextOut) @@ -298,10 +308,10 @@ void CTargetDlg::OnBnClickedFixWinFrame() // TODO: Add your control notification handler code here } -void CTargetDlg::OnBnClickedHideHwCursor() -{ - // TODO: Add your control notification handler code here -} +//void CTargetDlg::OnBnClickedHideHwCursor() +//{ +// // TODO: Add your control notification handler code here +//} void CTargetDlg::OnBnClickedEnableClipping() { diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 08c57cb..3f07ecd 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -41,6 +41,7 @@ public: CString m_FilePath; CString m_Module; CString m_Title; + CString m_OpenGLLib; BOOL m_SaveLoad; BOOL m_SlowDown; BOOL m_BlitFromBackBuffer; @@ -49,6 +50,7 @@ public: BOOL m_AutoRefresh; BOOL m_FixWinFrame; BOOL m_HideHwCursor; + BOOL m_ShowHwCursor; BOOL m_EnableClipping; BOOL m_CursorClipping; BOOL m_VideoToSystemMem; @@ -66,7 +68,9 @@ public: BOOL m_ModalStyle; BOOL m_KeepAspectRatio; BOOL m_ForceWinResize; + BOOL m_HookGDI; BOOL m_HideMultiMonitor; + BOOL m_WallpaperMode; BOOL m_HookChildWin; BOOL m_MessageProc; BOOL m_FixNCHITTEST; @@ -81,6 +85,7 @@ public: BOOL m_LimitFPS; BOOL m_ShowFPS; BOOL m_TimeStretch; + BOOL m_HookOpenGL; int m_InitX; int m_InitY; int m_MaxX; @@ -92,6 +97,7 @@ public: int m_SizX; int m_SizY; int m_MaxFPS; + int m_InitTS; //}}AFX_DATA @@ -121,7 +127,7 @@ public: afx_msg void OnEnChangeFile2(); afx_msg void OnBnClickedAutorefresh(); afx_msg void OnBnClickedFixWinFrame(); - afx_msg void OnBnClickedHideHwCursor(); + //afx_msg void OnBnClickedHideHwCursor(); afx_msg void OnBnClickedEnableClipping(); afx_msg void OnBnClickedHandleCursorPos(); afx_msg void OnBnClickedFixTextOut(); diff --git a/host/TimeSliderDialog.h b/host/TimeSliderDialog.h new file mode 100644 index 0000000..b9012a1 --- /dev/null +++ b/host/TimeSliderDialog.h @@ -0,0 +1,29 @@ +#pragma once + + +// CTimeSlider dialog + +class CTimeSliderDialog : public CDialog +{ + DECLARE_DYNAMIC(CTimeSliderDialog) + +public: + CTimeSliderDialog(CWnd* pParent = NULL); // standard constructor + virtual ~CTimeSliderDialog(); + +// Dialog Data + enum { IDD = IDD_TIMESLIDER }; + //CSliderCtrl m_TimeSlider; + int i_TimeSlider; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnTimer(UINT_PTR nIDEvent); +public: + virtual BOOL OnInitDialog(); +protected: + virtual void OnOK(); +}; diff --git a/host/TimeSliderDlg.cpp b/host/TimeSliderDlg.cpp new file mode 100644 index 0000000..d489502 --- /dev/null +++ b/host/TimeSliderDlg.cpp @@ -0,0 +1,106 @@ +// TimeSliderDialog.cpp : implementation file +// + +#include "stdafx.h" +#include "dxwndhost.h" +#include "TimeSliderDialog.h" + +// CTimeSliderDialog dialog + +IMPLEMENT_DYNAMIC(CTimeSliderDialog, CDialog) + +CTimeSliderDialog::CTimeSliderDialog(CWnd* pParent /*=NULL*/) + : CDialog(CTimeSliderDialog::IDD, pParent) +{ + //m_TimeSlider.SetRange(-4, +4, TRUE); +} + +CTimeSliderDialog::~CTimeSliderDialog() +{ +} + +void CTimeSliderDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CTargetDlg) + DDX_Slider(pDX, IDC_TIMESLIDER, i_TimeSlider); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CTimeSliderDialog, CDialog) + ON_WM_TIMER() +END_MESSAGE_MAP() + +#define IDTIMER 1 + +// CTimeSliderDialog message handlers + +void CTimeSliderDialog::OnTimer(UINT_PTR nIDEvent) +{ + DXWNDSTATUS Status; + CSliderCtrl *Slider; + CStatic *Text; + char *sTSCaption[9]={"x16","x8","x4","x2","x1",":2",":4",":8",":16"}; + char sMsg[81]; + static int iLastPos=-1; + + Slider=(CSliderCtrl *)this->GetDlgItem(IDC_TIMESLIDER); + Text=(CStatic *)this->GetDlgItem(IDC_TIMESPEED); + + CDialog::OnTimer(nIDEvent); + i_TimeSlider=Slider->GetPos(); + if(GetHookStatus(&Status)!=DXW_RUNNING) { + Slider->SetPos(0); + Text->SetWindowTextA("idle"); + return; + } + if(i_TimeSlider==iLastPos){ + // no change, check for keyboard input changes + i_TimeSlider=Status.iTimeShift; + if(i_TimeSlider != iLastPos) Slider->SetPos(i_TimeSlider); + } + else { + // slider position changed, set the new value + if (i_TimeSlider < -4) i_TimeSlider=-4; + if (i_TimeSlider > 4) i_TimeSlider=4; + Status.iTimeShift=i_TimeSlider; + SetHookStatus(&Status); + } + iLastPos = i_TimeSlider; + sprintf(sMsg, "Time speed: %s", sTSCaption[i_TimeSlider+4]); + Text->SetWindowTextA(sMsg); +} + +BOOL CTimeSliderDialog::OnInitDialog() +{ + CSliderCtrl *Slider; + CDialog::OnInitDialog(); + DXWNDSTATUS Status; + + GetHookStatus(&Status); + Slider=(CSliderCtrl *)this->GetDlgItem(IDC_TIMESLIDER); + Slider->SetRange(-4, +4, 0); + Slider->SetTicFreq(1); + Slider->SetPos(Status.iTimeShift); + SetTimer(IDTIMER, 1000, NULL); + + // TODO: Add extra initialization here + + return TRUE; // return TRUE unless you set the focus to a control +} + +void CTimeSliderDialog::OnOK() +{ + // TODO: Add your specialized code here and/or call the base class + + KillTimer(IDTIMER); + // stop timer + + DXWNDSTATUS Status; + GetHookStatus(&Status); + Status.iTimeShift=i_TimeSlider; + SetHookStatus(&Status); + + CDialog::OnOK(); +} diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 0ab8db46843c23250be84db71b51f8b546fe11bf..5cbe54c828d832a15a28f8d832a0bf7042d84516 100644 GIT binary patch delta 5368 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 WS74TQndA3a+5pEVvo%{T%lto#fgRHT delta 4387 zcmZuz3vg3a8vf5|o2F2pwYF(OY(oJ7w_wtiCgq(bH*IK0F3Bw|gdkuy1U~(Q1?IgCZSNyu= z=1h+Zyne+Y@CulLW74c_CeBLB%b%sQ5yh?4M*Klvh$N*Bn2l@Ftfo0SSsRhURh3iA zrwXnV+_*o@$}0hnZ?JF=;2$=axfh;l$z>7_Gg#*PbSrPY91hh>USZ^dDjih(NF!Y^9utaaOy7-hku|D84d5mq9?s10hdM zoj)jtA_ATY^K_Wn^#Uk|U=mm;04IcWAmVS(6fTgHfTpN``8rS?3e|W*d+p*V>(=#xiOvgo{l0}z zTH++v8#Kr(1tdk%pb}`&Ah*}6wM${6)|Tq!0Bt4>D}zlM7Oo9yZ6~y9Z8-tB;9eaV zgKg%Lxx?nBtDqL~HzkfQDAU zg8*0o|nH>;{+UyC?Q$n%ApFcceN10Vi!9o$7SKZk)Kv%ASrbA2EA&Y+v9!V;Q(M_yp6A$k@nGIn%4S zSl$z_WzLV&`0M#!#IZx+g>jQHkx$dm)?h;8!bfpV!z3N%E{1<^D8gShjL`x1FZ`q- zZo~3%{-OzS+>E=Dbqn?{x-*WC#;nET<8>*SnnGzuu<(WsXanlZ8<&n!lu}+!!;>x?J><0!%JpTk!4Qzse;qwjQ0!He&Zt zXEwRNL6VQ@-OX9bjo@RrwYxU$Kdc8P;|UJNQ^4={YV$Ht0qf6rJhhq1S33MyrOA?;+{LjJjZ`W{$qO~_jchKtIAMk*L zdwQ*Sx_2BdemBElV{#YF!S8$PXgAfJsBx^Iv#~y&)^_?XSOM$k*$AtEZYC<8WEylA z#rWO{PqvcGgFw5W94DOgWG_ra13EevA3W*dvKx<`+{mRUmc8@J%qV?VBnp?)X**O7 zn${q#!?ompnkEU;XNq2Q-8!3>ur@b%2sNHsdkUJXsBGDH{IJ_{L?8Z{biOy8G1H$_q!&>>aptdSRM-F zn$tx*?8Z)dIqcX)FV67t=_lD-T-o=y*dAZ?`FJ>lt}_j6DdL&?xV;TC&rV|sR-LWk zZ9d$6wt3k^<1u$^FQm8x6-<2Io4o1&tGxnWdZF1kR?Yd~T znkWOs*m2T~O&4zG@Fi}!P|kxAc3r5HQuaj$)uckkSQPaODSchmk^O z6?~?DCc%60O8;n+Pv2+pb;{X3I!iL)JDh(c2bcAwlI}&EaB+OfCD@Oli&N7M!jo`6 zK5=n6F^BM-i<47cho9p&7hBT0;CE1lYu_7d6~WM*McEfyIgOsDsRm%r$}r;2OZj;1 zgSOcFmwP$i1Gx7}$6pMTK5}i~&1(ZJ%gv6dBMNvGUt6OtDByRpiRwf2;cv*u1^DMY z^@Rdn#K+x(vlM$fsxra9fu+fD3rw4fSv0ZGBT6X`}bCH`OWPU42*$+PK9qU;^0vTXh{_MVBrhFH--mi|RRHvxnNY5AeAwvkcW#y(X$<_UkG5jI@oHL|-ZNh=c%SQRcM@ z{k@b4@cf53>#C*dC7Sl;za*q7n&M_@>o*BLbtq5vGg6s)Wf(J05S>-$vbbNvEyY=P zGWFGBW=1!XWX%dZyMyNt{nT_pVBahu>0sZ9P+;*-YZ* zGyr2qLOkM@;?BpIdiPJ`F+Hm?b^3F0%RMh8EGYmgH^*dqg{j?LWGP}Q?q+J=iTG$5 zPb4gJZfUvU5>rQg6c@WbO^9g?-og$1o2mQ1V`jtcM6US|hh4Q8il}P;2G4zK*($23 zTHZ%e?&)h#P=n@M@R!Sl3&HOk!rKXH)eb66!v3jS^2L;}z5!-lDWW}PD1*O!S;P#FCCzC>xRBZyUmkeXG!! zqDPiDgl`}|Gn=cwGI4X&$DEGP?1VUHhSYSTEM surf. on fail",IDC_VIDEOTOSYSTEMMEM, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,180,64,108,8 - CONTROL "Fix TextOutA placement",IDC_FIXTEXTOUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,24,107,9 - GROUPBOX "Generic",IDC_STATIC,299,101,120,88 - CONTROL "Keep cursor within window",IDC_KEEPCURSORWITHIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,44,105,9 - CONTROL "Set 16BPP RGB565 encoding",IDC_USERGB565,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,54,108,8 - CONTROL "Suppress DX common errors",IDC_SUPPRESSDXERRORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,74,109,9 + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,180,54,108,8 + CONTROL "Fix TextOutA placement",IDC_FIXTEXTOUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,164,107,9 + GROUPBOX "Generic",IDC_STATIC,299,111,120,89 + CONTROL "Keep cursor within window",IDC_KEEPCURSORWITHIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,54,105,9 + CONTROL "Set 16BPP RGB565 encoding",IDC_USERGB565,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,44,108,8 + CONTROL "Suppress DX common errors",IDC_SUPPRESSDXERRORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,64,109,9 CONTROL "Prevent Win Maximize",IDC_PREVENTMAXIMIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,24,98,9 GROUPBOX "Trace",IDC_STATIC,90,75,74,115 CONTROL "Win Events",IDC_OUTWINMESSAGES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,124,62,10 CONTROL "DirectX ",IDC_OUTDXTRACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,134,62,10 EDITTEXT IDC_TITLE,7,12,139,12,ES_AUTOHSCROLL LTEXT "Path:",IDC_STATIC,7,27,66,8 - LTEXT "Name:",IDC_STATIC,7,1,66,8 - CONTROL "Slow down",IDC_SLOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,144,88,10 - CONTROL "Force cursor clipping",IDC_CLIPCURSOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,34,107,9 - CONTROL "Remap GDI Client Rect",IDC_CLIENTREMAPPING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,84,102,9 - CONTROL "Intercept Alt-F4 key",IDC_HANDLEALTF4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,154,93,10 - GROUPBOX "Windows handling",IDC_STATIC,425,3,120,156 + LTEXT "Name:",IDC_STATIC,7,3,66,8 + CONTROL "Slow down",IDC_SLOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,154,88,10 + CONTROL "Force cursor clipping",IDC_CLIPCURSOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,44,107,9 + CONTROL "Remap Client Rect",IDC_CLIENTREMAPPING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,74,102,9 + CONTROL "Intercept Alt-F4 key",IDC_HANDLEALTF4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,164,93,10 + GROUPBOX "Windows handling",IDC_STATIC,424,3,120,167 CONTROL "Lock win coordinates",IDC_LOCKWINPOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,34,98,9 CONTROL "Hook CHILD windows",IDC_HOOKCHILDWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,54,98,9 LTEXT "Window initial position && size",IDC_STATIC,12,195,98,8 @@ -267,41 +268,77 @@ BEGIN EDITTEXT IDC_POSY,40,206,16,12,ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT EDITTEXT IDC_SIZX,65,206,16,12,ES_AUTOHSCROLL,WS_EX_RIGHT EDITTEXT IDC_SIZY,90,206,16,12,ES_AUTOHSCROLL,WS_EX_RIGHT - CONTROL "Message processing",IDC_MESSAGEPROC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,74,98,9 + CONTROL "Message processing",IDC_MESSAGEPROC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,84,98,9 CONTROL "Map GDI HDC to Primary DC",IDC_MAPGDITOPRIMARY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,14,102,9 CONTROL "Recover screen mode",IDC_RECOVERSCREENMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,64,98,9 CONTROL "Refresh on win resize",IDC_REFRESHONRESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,74,98,9 - CONTROL "Make Backbuf attachable",IDC_BACKBUFATTACH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,94,102,9 + CONTROL "Make Backbuf attachable",IDC_BACKBUFATTACH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,84,102,9 CONTROL "ddraw Proxy",IDC_DXPROXED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,94,62,10 CONTROL "Assert Dialog",IDC_ASSERT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,104,62,10 CONTROL "Simulate 8BPP desktop",IDC_INIT8BPP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,84,98,9 CONTROL "Simulate 16BPP desktop",IDC_INIT16BPP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,94,98,9 - CONTROL "Keep cursor fixed",IDC_KEEPCURSORFIXED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,54,105,9 + CONTROL "Keep cursor fixed",IDC_KEEPCURSORFIXED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,64,105,9 CONTROL "Lock win style",IDC_LOCKWINSTYLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,44,98,9 CONTROL "Enable Trace",IDC_LOGENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,84,62,10 CONTROL "Cursor/Mouse",IDC_CURSORTRACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,144,62,10 CONTROL "Import Table",IDC_IMPORTTABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,154,62,10 - CONTROL "Handle Exceptions",IDC_HANDLEEXCEPTIONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,164,93,10 + CONTROL "Handle Exceptions",IDC_HANDLEEXCEPTIONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,174,93,10 CONTROL "Fix Parent Window",IDC_FIXPARENTWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,104,98,9 CONTROL "Debug",IDC_OUTDEBUG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,164,62,10 - CONTROL "Blit from BackBuffer",IDC_BLITFROMBACKBUFFER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,104,102,9 + CONTROL "Blit from BackBuffer",IDC_BLITFROMBACKBUFFER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,94,102,9 GROUPBOX "Emulation",IDC_STATIC,7,149,78,42,WS_GROUP - CONTROL "Suppress clipping",IDC_SUPPRESSCLIPPING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,114,102,9 + CONTROL "Suppress clipping",IDC_SUPPRESSCLIPPING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,104,102,9 CONTROL "Modal Style",IDC_MODALSTYLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,114,98,9 CONTROL "Keep aspect ratio",IDC_KEEPASPECTRATIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,124,98,9 - CONTROL "Limit available resources",IDC_LIMITRESOURCES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,174,93,10 + CONTROL "Limit available resources",IDC_LIMITRESOURCES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,184,93,10 CONTROL "Force win resize",IDC_FORCEWINRESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,134,98,9 - CONTROL "Disable setting gamma ramp",IDC_DISABLEGAMMARAMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,124,102,9 - CONTROL "fix WM_NCHITTEST",IDC_FIXNCHITTEST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,84,98,9 - CONTROL "Limit",IDC_LIMITFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,154,28,9 - EDITTEXT IDC_MAXFPS,258,157,26,12,ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT - CONTROL "Skip",IDC_SKIPFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,164,27,9 - LTEXT "delay (msec)",IDC_STATIC,214,159,43,8 - GROUPBOX "Frame per Second",IDC_STATIC,172,142,121,58 - CONTROL "Show FPS",IDC_SHOWFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,176,52,9 - GROUPBOX "",IDC_STATIC,178,150,110,24 + CONTROL "fix WM_NCHITTEST",IDC_FIXNCHITTEST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,94,98,9 + CONTROL "Limit",IDC_LIMITFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,557,123,28,9 + EDITTEXT IDC_MAXFPS,635,126,26,12,ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT + CONTROL "Skip",IDC_SKIPFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,557,133,27,9 + LTEXT "delay (msec)",IDC_STATIC,591,128,43,8 + GROUPBOX "Frame per Second",IDC_STATIC,549,111,120,58 + CONTROL "Show FPS",IDC_SHOWFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,557,145,52,9 + GROUPBOX "",IDC_STATIC,555,119,110,24 CONTROL "Hide multi-monitor config.",IDC_HIDEMULTIMONITOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,144,98,9 - CONTROL "Time Stretch",IDC_TIMESTRETCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,186,52,9 + CONTROL "Time Stretch - init val:",IDC_TIMESTRETCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,557,155,75,9 + GROUPBOX "OpenGL",IDC_STATIC,549,3,120,50 + CONTROL "Hook OpenGL",IDC_HOOKOPENGL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,557,14,98,9 + EDITTEXT IDC_OPENGLLIB,554,36,108,12,ES_AUTOHSCROLL + LTEXT "Custom OpenGL library",IDC_STATIC,566,26,94,8 + CONTROL "Show Cursor",IDC_SHOWHWCURSOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,306,24,100,9 + CONTROL "Wallpaper mode",IDC_WALLPAPERMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,433,154,98,9 + GROUPBOX "GDI Handling",IDC_STATIC,172,144,120,62 + CONTROL "Hook GDI",IDC_HOOKGDI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,154,102,9 + CONTROL "Disable setting gamma ramp",IDC_DISABLEGAMMARAMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,174,102,9 + EDITTEXT IDC_INITTS,635,152,14,12,ES_AUTOHSCROLL,WS_EX_RIGHT +END + +IDD_STATUS DIALOGEX 0, 0, 186, 95 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "DxWnd Status" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Wait ...",IDC_STATUSINFO,2,2,182,91,SS_SUNKEN +END + +IDD_TIMESLIDER DIALOGEX 0, 0, 168, 65 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Time Slider" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,111,44,50,14 + CONTROL "",IDC_TIMESLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TRANSPARENTBKGND | WS_TABSTOP,7,7,154,18,WS_EX_TRANSPARENT + LTEXT "Time shift:",IDC_TIMESPEED,7,43,64,15 + LTEXT "x16",IDC_STATIC,7,31,15,9 + LTEXT "x8",IDC_STATIC,30,30,15,9 + LTEXT "x4",IDC_STATIC,47,30,15,9 + LTEXT "x2",IDC_STATIC,63,30,15,9 + LTEXT "x1",IDC_STATIC,81,30,15,9 + LTEXT ":2",IDC_STATIC,99,30,15,9 + LTEXT ":4",IDC_STATIC,115,30,15,9 + LTEXT ":8",IDC_STATIC,132,30,15,9 + LTEXT ":16",IDC_STATIC,149,30,15,9 END @@ -362,11 +399,27 @@ BEGIN IDD_TARGET, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 545 - TOPMARGIN, 7 + RIGHTMARGIN, 669 + TOPMARGIN, 3 BOTTOMMARGIN, 218 HORZGUIDE, 91 END + + IDD_STATUS, DIALOG + BEGIN + LEFTMARGIN, 2 + RIGHTMARGIN, 184 + TOPMARGIN, 2 + BOTTOMMARGIN, 93 + END + + IDD_TIMESLIDER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 161 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END END #endif // APSTUDIO_INVOKED @@ -494,39 +547,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK #pragma code_page(1252) #endif //_WIN32 -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_STATUS DIALOGEX 0, 0, 186, 95 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "DxWnd Status" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - LTEXT "Wait ...",IDC_STATUSINFO,2,2,182,91,SS_SUNKEN -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_STATUS, DIALOG - BEGIN - LEFTMARGIN, 2 - RIGHTMARGIN, 184 - TOPMARGIN, 2 - BOTTOMMARGIN, 93 - END -END -#endif // APSTUDIO_INVOKED - - ///////////////////////////////////////////////////////////////////////////// // // Icon diff --git a/host/dxwndhost.sln b/host/dxwndhost.sln deleted file mode 100644 index 3ab2975..0000000 --- a/host/dxwndhost.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dxwndhost", "dxwndhost.vcproj", "{FD0B0234-8EC5-43C0-A384-1B881DD3D925}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FD0B0234-8EC5-43C0-A384-1B881DD3D925}.Debug|Win32.ActiveCfg = Debug|Win32 - {FD0B0234-8EC5-43C0-A384-1B881DD3D925}.Debug|Win32.Build.0 = Debug|Win32 - {FD0B0234-8EC5-43C0-A384-1B881DD3D925}.Release|Win32.ActiveCfg = Release|Win32 - {FD0B0234-8EC5-43C0-A384-1B881DD3D925}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/host/dxwndhost.suo b/host/dxwndhost.suo deleted file mode 100644 index 8ee64fde7363d7a554a8de79848704a6b868a488..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 413696 zcmeF42Y?mT-M5!2B3A5;1;h$SFIK9e0xDofafPKWEV7G=V(-{{@4ducqp@H&_Cymk ziKb{`PhyJE7{BM4IcM)>_wL-gyZXN0_r335AO7e5=FFTkXHJ_lbML

Zi{I=&KSz`-yRX2EQj19M>_R6{K+fXT2BYTyt! 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 z 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 jP!!9CnvpE|*pXJ9;cy7Fv#J<``YZZ|{h6 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͔=4Z!})qEp^|5?v;HHhcpY$`R! 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 CH4}jV delta 1887 zcmZvdT}+!*7{||P-}j|J*Os=FcC_Vle3sHuWE-FqMm9jOgP;-}apP;K3~=kp$1rr! zJLg>b7_%5Z@YZD}q+V_d1}`=f5=>0I*#+L1IitJb!eK)FpSOj)%(eOTobx}=`FNgl z&eQn!y7-6uMwshX+skyW-Bc=7$QbhgFDL>++g&28rh7UKs;Z<^w%pi$wp(Zb{5ZP9-2$VDLEgDV4{CB$g`% zqF##fJgCmJg;t4r74U%?Pz&Cn+e!;>p+A%v>2R6NU;@OzBzPN$ z3ExFI1ulR&Fau`6d*C9t1ft+F5cY!kOnos^E@jF%%H?!DnaZl>Wbrv@z|cXz4EyM; z!AyzETQ$jBUJ|Lp5)rZl(ki2Wr^Mo}j+t7MQ3)UW5cLilTTGRAYw4@+KZ4reF4{TcJ za?@_W629cwJ@hcIoZcGsli&U$P3Ai(?5m)1$wKk`-x1I%y6$M;2I8K!L_r)u%%WRk z3kl~5h2>#}eC^b72^5JIoG;5F9(rvbZ9B0W7i7-?IqHgt%_?Q+iRoy^^+0$++lL2v z&NGHp^hMzqt@T!lbJh>Ca}@T(Xt2IiJ@;0Rl|HF2pey4;*&^!m^5^=TMAWTE;HgBi zb1#KQzg9g8)GBW-u_bne9b+9Vgx`h?b*u^X0H|X@d^D4tICQlrl(-uiVcBT8y*^sNrw z>;M1& diff --git a/host/dxwndhost.vs2008.vcproj b/host/dxwndhost.vs2008.vcproj index f9c70e6..0838f91 100644 --- a/host/dxwndhost.vs2008.vcproj +++ b/host/dxwndhost.vs2008.vcproj @@ -372,6 +372,10 @@ /> + + + + isUpdated=FALSE; @@ -260,6 +271,8 @@ void CDxwndhostView::OnInitialUpdate() GetPrivateProfileString("target", key, "", TitleMaps[i].title, sizeof(TitleMaps[i].title)-1, InitPath); sprintf_s(key, sizeof(key), "module%i", i); GetPrivateProfileString("target", key, "", TargetMaps[i].module, sizeof(TargetMaps[i].module)-1, InitPath); + sprintf_s(key, sizeof(key), "opengllib%i", i); + GetPrivateProfileString("target", key, "", TargetMaps[i].OpenGLLib, sizeof(TargetMaps[i].OpenGLLib)-1, InitPath); sprintf_s(key, sizeof(key), "ver%i", i); TargetMaps[i].dxversion = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "flag%i", i); @@ -290,6 +303,8 @@ void CDxwndhostView::OnInitialUpdate() TargetMaps[i].sizy = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "maxfps%i", i); TargetMaps[i].MaxFPS = GetPrivateProfileInt("target", key, 0, InitPath); + sprintf_s(key, sizeof(key), "initts%i", i); + TargetMaps[i].InitTS = GetPrivateProfileInt("target", key, 0, InitPath); listitem.mask = LVIF_TEXT; listitem.iItem = i; listitem.iSubItem = 0; @@ -306,6 +321,7 @@ void CDxwndhostView::OnInitialUpdate() if(m_StartToTray) this->OnGoToTrayIcon(); this->isUpdated=FALSE; pTitles = &TitleMaps[0]; + pTargets= &TargetMaps[0]; } ///////////////////////////////////////////////////////////////////////////// @@ -353,6 +369,7 @@ void CDxwndhostView::OnModify() if(dlg.m_DXVersion > 6) dlg.m_DXVersion -= 5; dlg.m_FilePath = TargetMaps[i].path; dlg.m_Module = TargetMaps[i].module; + dlg.m_OpenGLLib = TargetMaps[i].OpenGLLib; dlg.m_Title = TitleMaps[i].title; dlg.m_UnNotify = TargetMaps[i].flags & UNNOTIFY ? 1 : 0; dlg.m_EmulateSurface = TargetMaps[i].flags & EMULATESURFACE ? 1 : 0; @@ -379,6 +396,7 @@ void CDxwndhostView::OnModify() dlg.m_AutoRefresh = TargetMaps[i].flags & AUTOREFRESH ? 1 : 0; dlg.m_FixWinFrame = TargetMaps[i].flags & FIXWINFRAME ? 1 : 0; dlg.m_HideHwCursor = TargetMaps[i].flags & HIDEHWCURSOR ? 1 : 0; + dlg.m_ShowHwCursor = TargetMaps[i].flags2 & SHOWHWCURSOR ? 1 : 0; dlg.m_EnableClipping = TargetMaps[i].flags & ENABLECLIPPING ? 1 : 0; dlg.m_CursorClipping = TargetMaps[i].flags & CLIPCURSOR ? 1 : 0; dlg.m_VideoToSystemMem = TargetMaps[i].flags & SWITCHVIDEOMEMORY ? 1 : 0; @@ -396,7 +414,9 @@ void CDxwndhostView::OnModify() dlg.m_ModalStyle = TargetMaps[i].flags2 & MODALSTYLE ? 1 : 0; dlg.m_KeepAspectRatio = TargetMaps[i].flags2 & KEEPASPECTRATIO ? 1 : 0; dlg.m_ForceWinResize = TargetMaps[i].flags2 & FORCEWINRESIZE ? 1 : 0; + dlg.m_HookGDI = TargetMaps[i].flags2 & HOOKGDI ? 1 : 0; dlg.m_HideMultiMonitor = TargetMaps[i].flags2 & HIDEMULTIMONITOR ? 1 : 0; + dlg.m_WallpaperMode = TargetMaps[i].flags2 & WALLPAPERMODE ? 1 : 0; dlg.m_HookChildWin = TargetMaps[i].flags & HOOKCHILDWIN ? 1 : 0; dlg.m_MessageProc = TargetMaps[i].flags & MESSAGEPROC ? 1 : 0; dlg.m_FixNCHITTEST = TargetMaps[i].flags2 & FIXNCHITTEST ? 1 : 0; @@ -410,6 +430,7 @@ void CDxwndhostView::OnModify() dlg.m_SkipFPS = TargetMaps[i].flags2 & SKIPFPS ? 1 : 0; dlg.m_ShowFPS = TargetMaps[i].flags2 & SHOWFPS ? 1 : 0; dlg.m_TimeStretch = TargetMaps[i].flags2 & TIMESTRETCH ? 1 : 0; + dlg.m_HookOpenGL = TargetMaps[i].flags2 & HOOKOPENGL ? 1 : 0; dlg.m_InitX = TargetMaps[i].initx; dlg.m_InitY = TargetMaps[i].inity; dlg.m_MinX = TargetMaps[i].minx; @@ -421,9 +442,11 @@ void CDxwndhostView::OnModify() dlg.m_SizX = TargetMaps[i].sizx; dlg.m_SizY = TargetMaps[i].sizy; dlg.m_MaxFPS = TargetMaps[i].MaxFPS; + dlg.m_InitTS = TargetMaps[i].InitTS; if(dlg.DoModal() == IDOK && dlg.m_FilePath.GetLength()){ strcpy_s(TargetMaps[i].path, sizeof(TargetMaps[i].path), dlg.m_FilePath); strcpy_s(TargetMaps[i].module, sizeof(TargetMaps[i].module), dlg.m_Module); + strcpy_s(TargetMaps[i].OpenGLLib, sizeof(TargetMaps[i].OpenGLLib), dlg.m_OpenGLLib); strcpy_s(TitleMaps[i].title, sizeof(TitleMaps[i].title), dlg.m_Title); if(dlg.m_DXVersion > 1) dlg.m_DXVersion += 5; TargetMaps[i].dxversion = dlg.m_DXVersion; @@ -469,6 +492,7 @@ void CDxwndhostView::OnModify() if(dlg.m_AutoRefresh) TargetMaps[i].flags |= AUTOREFRESH; if(dlg.m_FixWinFrame) TargetMaps[i].flags |= FIXWINFRAME; if(dlg.m_HideHwCursor) TargetMaps[i].flags |= HIDEHWCURSOR; + if(dlg.m_ShowHwCursor) TargetMaps[i].flags2 |= SHOWHWCURSOR; if(dlg.m_EnableClipping) TargetMaps[i].flags |= ENABLECLIPPING; if(dlg.m_CursorClipping) TargetMaps[i].flags |= CLIPCURSOR; if(dlg.m_VideoToSystemMem) TargetMaps[i].flags |= SWITCHVIDEOMEMORY; @@ -486,7 +510,9 @@ void CDxwndhostView::OnModify() if(dlg.m_ModalStyle) TargetMaps[i].flags2 |= MODALSTYLE; if(dlg.m_KeepAspectRatio) TargetMaps[i].flags2 |= KEEPASPECTRATIO; if(dlg.m_ForceWinResize) TargetMaps[i].flags2 |= FORCEWINRESIZE; + if(dlg.m_HookGDI) TargetMaps[i].flags2 |= HOOKGDI; if(dlg.m_HideMultiMonitor) TargetMaps[i].flags2 |= HIDEMULTIMONITOR; + if(dlg.m_WallpaperMode) TargetMaps[i].flags2 |= WALLPAPERMODE; if(dlg.m_HookChildWin) TargetMaps[i].flags |= HOOKCHILDWIN; if(dlg.m_MessageProc) TargetMaps[i].flags |= MESSAGEPROC; if(dlg.m_FixNCHITTEST) TargetMaps[i].flags2 |= FIXNCHITTEST; @@ -500,6 +526,7 @@ void CDxwndhostView::OnModify() if(dlg.m_SkipFPS) TargetMaps[i].flags2 |= SKIPFPS; if(dlg.m_ShowFPS) TargetMaps[i].flags2 |= SHOWFPS; if(dlg.m_TimeStretch) TargetMaps[i].flags2 |= TIMESTRETCH; + if(dlg.m_HookOpenGL) TargetMaps[i].flags2 |= HOOKOPENGL; TargetMaps[i].initx = dlg.m_InitX; TargetMaps[i].inity = dlg.m_InitY; TargetMaps[i].minx = dlg.m_MinX; @@ -511,7 +538,9 @@ void CDxwndhostView::OnModify() TargetMaps[i].sizx = dlg.m_SizX; TargetMaps[i].sizy = dlg.m_SizY; TargetMaps[i].MaxFPS = dlg.m_MaxFPS; + TargetMaps[i].InitTS = dlg.m_InitTS; strcpy_s(TargetMaps[i].module, sizeof(TargetMaps[i].module), dlg.m_Module); + strcpy_s(TargetMaps[i].OpenGLLib, sizeof(TargetMaps[i].OpenGLLib), dlg.m_OpenGLLib); strcpy_s(TitleMaps[i].title, sizeof(TitleMaps[i].title), dlg.m_Title); CListCtrl& listctrl = GetListCtrl(); listitem.mask = LVIF_TEXT; @@ -706,6 +735,7 @@ void CDxwndhostView::OnAdd() if(dlg.DoModal() == IDOK && dlg.m_FilePath.GetLength()){ strcpy_s(TargetMaps[i].path,sizeof(TargetMaps[i].path),dlg.m_FilePath); strcpy_s(TargetMaps[i].module,sizeof(TargetMaps[i].module),dlg.m_Module); + strcpy_s(TargetMaps[i].OpenGLLib,sizeof(TargetMaps[i].OpenGLLib),dlg.m_OpenGLLib); strcpy_s(TitleMaps[i].title, sizeof(TitleMaps[i].title), dlg.m_Title); if(dlg.m_DXVersion > 1) dlg.m_DXVersion += 5; TargetMaps[i].dxversion = dlg.m_DXVersion; @@ -751,6 +781,7 @@ void CDxwndhostView::OnAdd() if(dlg.m_AutoRefresh) TargetMaps[i].flags |= AUTOREFRESH; if(dlg.m_FixWinFrame) TargetMaps[i].flags |= FIXWINFRAME; if(dlg.m_HideHwCursor) TargetMaps[i].flags |= HIDEHWCURSOR; + if(dlg.m_ShowHwCursor) TargetMaps[i].flags2 |= SHOWHWCURSOR; if(dlg.m_EnableClipping) TargetMaps[i].flags |= ENABLECLIPPING; if(dlg.m_CursorClipping) TargetMaps[i].flags |= CLIPCURSOR; if(dlg.m_VideoToSystemMem) TargetMaps[i].flags |= SWITCHVIDEOMEMORY; @@ -768,7 +799,9 @@ void CDxwndhostView::OnAdd() if(dlg.m_ModalStyle) TargetMaps[i].flags2 |= MODALSTYLE; if(dlg.m_KeepAspectRatio) TargetMaps[i].flags2 |= KEEPASPECTRATIO; if(dlg.m_ForceWinResize) TargetMaps[i].flags2 |= FORCEWINRESIZE; + if(dlg.m_HookGDI) TargetMaps[i].flags2 |= HOOKGDI; if(dlg.m_HideMultiMonitor) TargetMaps[i].flags2 |= HIDEMULTIMONITOR; + if(dlg.m_WallpaperMode) TargetMaps[i].flags2 |= WALLPAPERMODE; if(dlg.m_HookChildWin) TargetMaps[i].flags |= HOOKCHILDWIN; if(dlg.m_MessageProc) TargetMaps[i].flags |= MESSAGEPROC; if(dlg.m_FixNCHITTEST) TargetMaps[i].flags2 |= FIXNCHITTEST; @@ -782,6 +815,7 @@ void CDxwndhostView::OnAdd() if(dlg.m_SkipFPS) TargetMaps[i].flags2 |= SKIPFPS; if(dlg.m_ShowFPS) TargetMaps[i].flags2 |= SHOWFPS; if(dlg.m_TimeStretch) TargetMaps[i].flags2 |= TIMESTRETCH; + if(dlg.m_HookOpenGL) TargetMaps[i].flags2 |= HOOKOPENGL; TargetMaps[i].initx = dlg.m_InitX; TargetMaps[i].inity = dlg.m_InitY; TargetMaps[i].minx = dlg.m_MinX; @@ -793,6 +827,7 @@ void CDxwndhostView::OnAdd() TargetMaps[i].sizx = dlg.m_SizX; TargetMaps[i].sizy = dlg.m_SizY; TargetMaps[i].MaxFPS = dlg.m_MaxFPS; + TargetMaps[i].InitTS = dlg.m_InitTS; CListCtrl& listctrl = GetListCtrl(); listitem.mask = LVIF_TEXT; listitem.iItem = i; @@ -1018,6 +1053,13 @@ void CDxwndhostView::OnViewStatus() pDlg->ShowWindow(SW_SHOW); } +void CDxwndhostView::OnViewTimeSlider() +{ + CTimeSliderDialog *pDlg = new CTimeSliderDialog(); + BOOL ret = pDlg->Create(CTimeSliderDialog::IDD, this); + pDlg->ShowWindow(SW_SHOW); +} + void CDxwndhostView::Resize() { CListCtrl& listctrl = GetListCtrl(); diff --git a/host/dxwndhostView.h b/host/dxwndhostView.h index f1075f2..281e7d8 100644 --- a/host/dxwndhostView.h +++ b/host/dxwndhostView.h @@ -76,6 +76,7 @@ protected: afx_msg void OnHookStop(); afx_msg void OnTrayRestore(); afx_msg void OnViewStatus(); + afx_msg void OnViewTimeSlider(); afx_msg void OnExit(); //}}AFX_MSG DECLARE_MESSAGE_MAP()