mirror of
https://github.com/DxWnd/DxWnd.reloaded
synced 2024-12-30 09:25:35 +01:00
v2_03_09_src
Former-commit-id: 412cc9877e7e53a916b5a059e5b1b5479c220e6c
This commit is contained in:
parent
84e20e2ffb
commit
bb0b5128e0
@ -122,7 +122,7 @@
|
|||||||
#define DISABLEFOGGING 0x00000080 // Disable D3D fogging
|
#define DISABLEFOGGING 0x00000080 // Disable D3D fogging
|
||||||
#define NOPOWER2FIX 0x00000100 // Handle textures whose size is not a power of 2 (32, 64, 128 ...)
|
#define NOPOWER2FIX 0x00000100 // Handle textures whose size is not a power of 2 (32, 64, 128 ...)
|
||||||
#define NOPERFCOUNTER 0x00000200 // Disables the GetPerfCounter performance metrics API,as if it was not supported....
|
#define NOPERFCOUNTER 0x00000200 // Disables the GetPerfCounter performance metrics API,as if it was not supported....
|
||||||
#define BILINEAR2XFILTER 0x00000400 // attempt to smooth low-res graphic by applying biulinear filtering in emulation mode
|
#define BILINEAR2XFILTER 0x00000400 // attempt to smooth low-res graphic by applying simplified bilinear filtering in emulation mode
|
||||||
#define INTERCEPTRDTSC 0x00000800 // Intercapts RDTSC opcodes to hook at assembly level
|
#define INTERCEPTRDTSC 0x00000800 // Intercapts RDTSC opcodes to hook at assembly level
|
||||||
#define LIMITSCREENRES 0x00001000 // Limit available screen resolution up to defined maximum
|
#define LIMITSCREENRES 0x00001000 // Limit available screen resolution up to defined maximum
|
||||||
#define NOFILLRECT 0x00002000 // Suppress FillRect calls
|
#define NOFILLRECT 0x00002000 // Suppress FillRect calls
|
||||||
@ -173,6 +173,7 @@
|
|||||||
#define CENTERTOWIN 0x01000000 // do NOT stretch the image to the whole window client area, but center to it.
|
#define CENTERTOWIN 0x01000000 // do NOT stretch the image to the whole window client area, but center to it.
|
||||||
#define STRESSRESOURCES 0x02000000 // simulates a lack of resources condition, for testing (debug opt.)
|
#define STRESSRESOURCES 0x02000000 // simulates a lack of resources condition, for testing (debug opt.)
|
||||||
#define MESSAGEPUMP 0x04000000 // inserts a "message pump" loop between repeated operation that may stop the task on Win7 and greater
|
#define MESSAGEPUMP 0x04000000 // inserts a "message pump" loop between repeated operation that may stop the task on Win7 and greater
|
||||||
|
#define TEXTUREFORMAT 0x08000000 // Apply virtual pixel format to texture surfaces without DDSD_PIXELFORMAT attribute
|
||||||
|
|
||||||
// logging Tflags DWORD:
|
// logging Tflags DWORD:
|
||||||
#define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general
|
#define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4c798c0cff917a4dfb846882ff9d9ffc9cc2fcd747228487da1f88b8e58c5b74
|
oid sha256:09c3405b326eb5eff358f5713b62cd1107c84ce64625529de44283cab2b64c9a
|
||||||
size 563712
|
size 564224
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:3a88f64a7bf93e63942698c78c94a1b57ab660eea0e6b2eaf8fdd2774c0ca0e3
|
oid sha256:be381f4fba85d8c7dcb13682c470713728dd133b38e6d4d1ed65fc6ceb74e771
|
||||||
size 536576
|
size 536064
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
[window]
|
[window]
|
||||||
posx=1227
|
posx=50
|
||||||
posy=471
|
posy=50
|
||||||
sizx=320
|
sizx=320
|
||||||
sizy=200
|
sizy=200
|
||||||
lang=default
|
lang=default
|
||||||
;lang=automatic
|
;lang=automatic
|
||||||
;debug=1
|
debug=1
|
||||||
;multiprocesshook=0
|
;multiprocesshook=0
|
||||||
;checkadmin=0
|
;checkadmin=0
|
||||||
[texture]
|
[texture]
|
||||||
|
@ -5,11 +5,11 @@ module0=
|
|||||||
opengllib0=
|
opengllib0=
|
||||||
ver0=0
|
ver0=0
|
||||||
coord0=0
|
coord0=0
|
||||||
flag0=679477280
|
flag0=679477282
|
||||||
flagg0=1207959568
|
flagg0=1207959568
|
||||||
flagh0=20
|
flagh0=20
|
||||||
flagi0=4
|
flagi0=4194308
|
||||||
tflag0=259
|
tflag0=0
|
||||||
initx0=0
|
initx0=0
|
||||||
inity0=0
|
inity0=0
|
||||||
minx0=0
|
minx0=0
|
||||||
@ -24,3 +24,6 @@ maxfps0=0
|
|||||||
initts0=0
|
initts0=0
|
||||||
winver0=0
|
winver0=0
|
||||||
maxres0=0
|
maxres0=0
|
||||||
|
launchpath0=
|
||||||
|
notes0=
|
||||||
|
flagj0=128
|
||||||
|
@ -10,7 +10,7 @@ flag0=134217760
|
|||||||
flagg0=1207959552
|
flagg0=1207959552
|
||||||
flagh0=65557
|
flagh0=65557
|
||||||
flagi0=69206020
|
flagi0=69206020
|
||||||
tflag0=6211
|
tflag0=64
|
||||||
initx0=0
|
initx0=0
|
||||||
inity0=0
|
inity0=0
|
||||||
minx0=0
|
minx0=0
|
||||||
@ -25,3 +25,5 @@ maxfps0=0
|
|||||||
initts0=0
|
initts0=0
|
||||||
winver0=0
|
winver0=0
|
||||||
maxres0=-1
|
maxres0=-1
|
||||||
|
notes0=
|
||||||
|
flagj0=0
|
||||||
|
29
build/exports/Hitchcock the Final Cut.dxw
Normal file
29
build/exports/Hitchcock the Final Cut.dxw
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
[target]
|
||||||
|
title0=Hitchcock the Final Cut
|
||||||
|
path0=D:\Games\Hitchcock\Hitchcock_Kyro.exe
|
||||||
|
launchpath0=
|
||||||
|
module0=
|
||||||
|
opengllib0=
|
||||||
|
notes0=
|
||||||
|
ver0=1
|
||||||
|
coord0=0
|
||||||
|
flag0=134217762
|
||||||
|
flagg0=1207959552
|
||||||
|
flagh0=20
|
||||||
|
flagi0=138412036
|
||||||
|
flagj0=67113088
|
||||||
|
tflag0=0
|
||||||
|
initx0=0
|
||||||
|
inity0=0
|
||||||
|
minx0=0
|
||||||
|
miny0=0
|
||||||
|
maxx0=0
|
||||||
|
maxy0=0
|
||||||
|
posx0=50
|
||||||
|
posy0=50
|
||||||
|
sizx0=800
|
||||||
|
sizy0=600
|
||||||
|
maxfps0=0
|
||||||
|
initts0=0
|
||||||
|
winver0=0
|
||||||
|
maxres0=-1
|
142
build/exports/Moon Tycoon.dxw
Normal file
142
build/exports/Moon Tycoon.dxw
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta http-equiv="content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>Wikisend: free file sharing service</title>
|
||||||
|
<link href="http://wikisend.com/css/styles.css" type="text/css" rel="stylesheet" />
|
||||||
|
<script src="http://wikisend.com/js/jquery-1.2.1.min.js" type="text/javascript"></script>
|
||||||
|
<script src="http://wikisend.com/js/download.js" type="text/javascript"></script><script src="http://wikisend.com/js/common.js" type="text/javascript"></script></head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="pagebgr">
|
||||||
|
<div id="topbgr">
|
||||||
|
<div id="page">
|
||||||
|
|
||||||
|
<!-- Login -->
|
||||||
|
<div id="login">
|
||||||
|
<form action="/sign-in/" method="post" id="signInForm">
|
||||||
|
|
||||||
|
<div id="close"><input name="" type="image" id="close_login" src="http://wikisend.com/images/close_win.gif" /></div>
|
||||||
|
|
||||||
|
<div id="left">
|
||||||
|
|
||||||
|
<div class="formelement">
|
||||||
|
<div class="formtitle"><label for="username">Username:</label></div><input id="username" name="username" type="text" class="inputfield" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="formelement">
|
||||||
|
<div class="formtitle"><label for="password">Password:</label></div><input id="password" name="password" type="password" class="inputfield" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="right">
|
||||||
|
|
||||||
|
<input type="image" src="http://wikisend.com/images/button_login.gif" alt="Sign in" /><br />
|
||||||
|
<a id="forgot" href="/forgot-password/">Forgot your password?</a>
|
||||||
|
<input type="hidden" name="sent" value="1" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!-- End Login -->
|
||||||
|
|
||||||
|
<!-- ################# HEADER ################## -->
|
||||||
|
<div id="header">
|
||||||
|
<div id="logo"><a href="/"><img src="http://wikisend.com/images/logo.gif" width="351" height="58" alt="Wikisend: file sharing service" class="imgblock" /></a></div>
|
||||||
|
|
||||||
|
<div id="toplinks">
|
||||||
|
Have an account: <a href="/sign-in/" id="open_login">Sign in here</a><br />New user: <a href="/sign-up/">Sign up now</a></div></div>
|
||||||
|
|
||||||
|
<!-- ################# END HEADER ################## -->
|
||||||
|
|
||||||
|
<!-- ################# EARTH BLOCK ################## -->
|
||||||
|
|
||||||
|
<div id="earthtabs">
|
||||||
|
<div id="upload"><a href="/"><img src="/images/upload_inactive.gif" width="260" height="46" alt="Upload" class="imgblock" /></a></div>
|
||||||
|
<div id="download"><img src="/images/earth_download.gif" width="278" height="59" alt="Download" class="imgblock" /></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="earth"><div id="themebgr"><div id="cloud"><div id="grass"><div id="insidetheme">
|
||||||
|
|
||||||
|
|
||||||
|
<div id="titleblock">
|
||||||
|
<span id="filetitle">Moon Tycoon.dxw</span> </div>
|
||||||
|
|
||||||
|
<form action="" method="post" id="downloadform">
|
||||||
|
<div class="textindent">
|
||||||
|
|
||||||
|
<ul id="details">
|
||||||
|
<li><span class="detailtitle">File ID:</span> <span id="fileidvalue">271650</span></li>
|
||||||
|
<li><span class="detailtitle">File size:</span> 512 B</li>
|
||||||
|
<li><span class="detailtitle">Time to live:</span> 28 days</li> </ul>
|
||||||
|
<div class="linkblock">
|
||||||
|
<div class="linktitle"><label for="dlink">Download link:</label></div><input id="dlink" type="text" value="http://wikisend.com/download/271650/Moon Tycoon.dxw" class="linkfield" readonly="readonly"/></div><div class="linkblock">
|
||||||
|
<div class="linktitle"><label for="flink">Forum link:</label></div><input id="flink" type="text" value="[URL=http://wikisend.com/download/271650/Moon Tycoon.dxw]Moon Tycoon.dxw[/URL]" class="linkfield" readonly="readonly"/></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- end properties -->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="button">
|
||||||
|
<input type="hidden" name="act" value="download" id="act" />
|
||||||
|
<input type="image" src="/images/button_download.gif" alt="Download file" id="d_but"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
</div></div></div></div></div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ################# END EARTH BLOCK ################## -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ################# WHY BLOCK ################## -->
|
||||||
|
|
||||||
|
<div id="why"><div id="bgr"><div id="gradient"><div id="earthpics">
|
||||||
|
<h1>Why our site?</h1>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
<h2>Simple & Free</h2>
|
||||||
|
Upload and download lots of files, big files, small files, data files,
|
||||||
|
media files, archives or backups - any files. With Wikisend it`s simple and
|
||||||
|
free.
|
||||||
|
|
||||||
|
<h2>Share with Friends</h2>
|
||||||
|
Share files with your friends using E-mail, MySpace page, your blog, forums
|
||||||
|
and so on. With Wikisend sharing files, photos, videos or documents is easy,
|
||||||
|
fast, and reliable.
|
||||||
|
|
||||||
|
<h2>Start now</h2>
|
||||||
|
No need to register, activate, install or read manuals - use our uploading
|
||||||
|
form, you`re ready to go.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div></div></div></div>
|
||||||
|
|
||||||
|
<!-- ################# END WHY BLOCK ################## -->
|
||||||
|
|
||||||
|
|
||||||
|
</div></div></div>
|
||||||
|
|
||||||
|
<!-- ################# FOOTER ################## -->
|
||||||
|
<div id="footer"><div id="bottom"><div id="top">
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li id="first"><a class="footlink" href="/">Home page</a></li>
|
||||||
|
<li><a class="footlink" href="/feedback/">Feedback</a></li>
|
||||||
|
<li><a class="footlink" href="/terms/">Terms and conditions</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div id="copy">© 2008 Wikisend - File Sharing. All rights reserved.</div>
|
||||||
|
|
||||||
|
</div></div></div>
|
||||||
|
<!-- ################# END FOOTER ################## -->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -7,9 +7,9 @@ ver0=0
|
|||||||
coord0=0
|
coord0=0
|
||||||
flag0=134217762
|
flag0=134217762
|
||||||
flagg0=1241513984
|
flagg0=1241513984
|
||||||
flagh0=25165844
|
flagh0=20
|
||||||
flagi0=0
|
flagi0=4194304
|
||||||
tflag0=323
|
tflag0=0
|
||||||
initx0=0
|
initx0=0
|
||||||
inity0=0
|
inity0=0
|
||||||
minx0=0
|
minx0=0
|
||||||
@ -22,5 +22,10 @@ sizx0=800
|
|||||||
sizy0=600
|
sizy0=600
|
||||||
maxfps0=0
|
maxfps0=0
|
||||||
initts0=0
|
initts0=0
|
||||||
|
launchpath0=
|
||||||
|
notes0=
|
||||||
|
flagj0=0
|
||||||
|
winver0=0
|
||||||
|
maxres0=0
|
||||||
|
|
||||||
; remember to set SW emulated mode in game setup panel
|
; remember to set SW emulated mode in game setup panel
|
||||||
|
@ -719,3 +719,9 @@ add: made check for admin rights configurable in dxwnd.ini
|
|||||||
add: "portable" capability to configure relative pathnames
|
add: "portable" capability to configure relative pathnames
|
||||||
fix: small bug in game menu string width - now game titles should not be trunked any longer.
|
fix: small bug in game menu string width - now game titles should not be trunked any longer.
|
||||||
|
|
||||||
|
v2.03.09
|
||||||
|
code reorganization & reuse
|
||||||
|
add: "Set texture pixel format" flag, makes "Jeff Gordon XS Racing" working on emulated mode and 32BPP desktop
|
||||||
|
add: "GDI mode" emulation uses HALFTONE to activate GDI bilinear stretching when "Full Bilinear" filter is activated: slower, but better quality
|
||||||
|
add: preliminary hooking for EnumZBufferFormats ddraw7 method
|
||||||
|
fix: eliminated some handle leakage when injecting launched processes
|
||||||
|
@ -15,62 +15,41 @@
|
|||||||
|
|
||||||
BOOL Inject(DWORD pID, const char * DLL_NAME)
|
BOOL Inject(DWORD pID, const char * DLL_NAME)
|
||||||
{
|
{
|
||||||
HANDLE Proc;
|
HANDLE hProc, hThread;
|
||||||
|
HMODULE hLib;
|
||||||
char buf[50] = {0};
|
char buf[50] = {0};
|
||||||
LPVOID RemoteString, LoadLibAddy;
|
LPVOID RemoteString, LoadLibAddy;
|
||||||
if(!pID) return false;
|
if(!pID) return false;
|
||||||
//Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP
|
//hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP
|
||||||
Proc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID);
|
hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID);
|
||||||
if(!Proc)
|
if(!hProc)
|
||||||
{
|
{
|
||||||
sprintf(buf, "OpenProcess() failed: pid=%x err=%d", pID, GetLastError());
|
sprintf(buf, "OpenProcess() failed: pid=%x err=%d", pID, GetLastError());
|
||||||
MessageBox(NULL, buf, "Loader", MB_OK);
|
MessageBox(NULL, buf, "Loader", MB_OK);
|
||||||
printf(buf);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
|
hLib=GetModuleHandle("kernel32.dll");
|
||||||
// Allocate space in the process for our DLL
|
LoadLibAddy = (LPVOID)GetProcAddress(hLib, "LoadLibraryA");
|
||||||
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
// Allocate space in the process for the DLL
|
||||||
// Write the string name of our DLL in the memory allocated
|
RemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||||
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL);
|
// Write the string name of the DLL in the memory allocated
|
||||||
// Load our DLL
|
WriteProcessMemory(hProc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL);
|
||||||
if(!CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL)){
|
// Load the DLL
|
||||||
|
hThread=CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL);
|
||||||
|
// Free/Release/Close everything
|
||||||
|
VirtualFreeEx(hProc, RemoteString, strlen(DLL_NAME), MEM_RELEASE);
|
||||||
|
if(!hThread){
|
||||||
sprintf(buf, "CreateRemoteThread() failed: pid=%x err=%d", pID, GetLastError());
|
sprintf(buf, "CreateRemoteThread() failed: pid=%x err=%d", pID, GetLastError());
|
||||||
MessageBox(NULL, buf, "Loader", MB_OK);
|
MessageBox(NULL, buf, "Loader", MB_OK);
|
||||||
printf(buf);
|
CloseHandle(hProc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CloseHandle(Proc);
|
CloseHandle(hThread);
|
||||||
|
CloseHandle(hProc);
|
||||||
|
CloseHandle(hLib);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
DWORD GetTargetThreadIDFromProcName(const char * ProcName)
|
|
||||||
{
|
|
||||||
PROCESSENTRY32 pe;
|
|
||||||
HANDLE thSnapShot;
|
|
||||||
BOOL retval, ProcFound = false;
|
|
||||||
thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
||||||
if(thSnapShot == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
MessageBox(NULL, "Error: Unable to create toolhelp snapshot!", "2MLoader", MB_OK);
|
|
||||||
//printf("Error: Unable to create toolhelp snapshot!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
pe.dwSize = sizeof(PROCESSENTRY32);
|
|
||||||
retval = Process32First(thSnapShot, &pe);
|
|
||||||
while(retval)
|
|
||||||
{
|
|
||||||
if(StrStrI(pe.szExeFile, ProcName))
|
|
||||||
{
|
|
||||||
return pe.th32ProcessID;
|
|
||||||
}
|
|
||||||
retval = Process32Next(thSnapShot, &pe);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define STATUS_SUCCESS ((NTSTATUS)0x000 00000L)
|
#define STATUS_SUCCESS ((NTSTATUS)0x000 00000L)
|
||||||
#define ThreadQuerySetWin32StartAddress 9
|
#define ThreadQuerySetWin32StartAddress 9
|
||||||
|
|
||||||
|
366
dll/ddblit.cpp
Normal file
366
dll/ddblit.cpp
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <ddraw.h>
|
||||||
|
#include "dxwnd.h"
|
||||||
|
#include "dxwcore.hpp"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "hddraw.h"
|
||||||
|
#include "dxhelper.h"
|
||||||
|
|
||||||
|
extern LPDIRECTDRAWSURFACE lpDDSBack;
|
||||||
|
extern LPDIRECTDRAWSURFACE lpDDSEmu_Prim;
|
||||||
|
extern LPDIRECTDRAWSURFACE lpDDSEmu_Back;
|
||||||
|
extern LPDIRECTDRAW lpPrimaryDD;
|
||||||
|
extern Blt_Type pBlt;
|
||||||
|
extern ReleaseS_Type pReleaseS;
|
||||||
|
extern CreateSurface1_Type pCreateSurface1;
|
||||||
|
extern CreateSurface1_Type pCreateSurface2;
|
||||||
|
extern CreateSurface1_Type pCreateSurface3;
|
||||||
|
extern CreateSurface2_Type pCreateSurface4;
|
||||||
|
extern CreateSurface2_Type pCreateSurface7;
|
||||||
|
extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE);
|
||||||
|
|
||||||
|
extern void BlitError(HRESULT, LPRECT, LPRECT, int);
|
||||||
|
extern void BlitTrace(char *, LPRECT, LPRECT, int);
|
||||||
|
extern void DescribeSurface(LPDIRECTDRAWSURFACE, int, char *, int);
|
||||||
|
extern void TextureHandling(LPDIRECTDRAWSURFACE);
|
||||||
|
|
||||||
|
static HRESULT sBltNoPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
|
||||||
|
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
|
||||||
|
{
|
||||||
|
RECT srcrect;
|
||||||
|
HRESULT res;
|
||||||
|
BOOL FromScreen;
|
||||||
|
//extern PrimaryBlt_Type pPrimaryBlt;
|
||||||
|
//CkArg arg;
|
||||||
|
|
||||||
|
FromScreen=dxw.IsAPrimarySurface(lpddssrc) && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77
|
||||||
|
|
||||||
|
// make a working copy of srcrect if not NULL
|
||||||
|
if (lpsrcrect){
|
||||||
|
srcrect=*lpsrcrect;
|
||||||
|
}
|
||||||
|
// when blitting from a primary surface on screen (that is in non emulated mode), correct offsets
|
||||||
|
// You should take account also for scaled primary surfaces, but that would be a hard task:
|
||||||
|
// a reduced primary surface (in not-emulated mode) would bring quality loss!!!
|
||||||
|
// v2.1.83: BLITFROMBACKBUFFER mode, let you chose to blit from backbuffer, where the surface size
|
||||||
|
// is fixed no matter how the window/primary surface is scaled.
|
||||||
|
// In "The Sims" there is no quality loss, but some scrolling artifact.
|
||||||
|
if(lpsrcrect && FromScreen){
|
||||||
|
if(lpDDSBack && (dxw.dwFlags1 & BLITFROMBACKBUFFER)){
|
||||||
|
lpddssrc=lpDDSBack;
|
||||||
|
srcrect=dxw.GetScreenRect();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
srcrect=dxw.MapWindowRect(lpsrcrect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsDebug) BlitTrace("NOPRIM", lpsrcrect, lpdestrect, __LINE__);
|
||||||
|
res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx);
|
||||||
|
// Blitting compressed data may work to screen surfaces only. In this case, it may be worth
|
||||||
|
// trying blitting directly to lpDDSEmu_Prim: it makes DK2 intro movies working.
|
||||||
|
// Wrong guess!!! The cause was not compression, but simply a pixelformat mismatch. Better
|
||||||
|
// configure things properly and avoid this branch.
|
||||||
|
switch(res){
|
||||||
|
case DDERR_UNSUPPORTED:
|
||||||
|
if (dxw.dwFlags1 & EMULATESURFACE){
|
||||||
|
RECT targetrect;
|
||||||
|
if (IsDebug) BlitTrace("UNSUPP", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__);
|
||||||
|
targetrect=*lpdestrect;
|
||||||
|
dxw.MapWindowRect(&targetrect);
|
||||||
|
res=(*pBlt)(lpDDSEmu_Prim, &targetrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DDERR_SURFACEBUSY:
|
||||||
|
(*pUnlockMethod(lpdds))(lpdds, NULL);
|
||||||
|
if (lpddssrc) (*pUnlockMethod(lpddssrc))(lpddssrc, NULL);
|
||||||
|
if (IsDebug) BlitTrace("BUSY", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__);
|
||||||
|
res=(*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_WAIT, lpddbltfx);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (res) BlitError(res, &srcrect, lpdestrect, __LINE__);
|
||||||
|
if(IsDebug) {
|
||||||
|
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
|
||||||
|
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
|
||||||
|
}
|
||||||
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0;
|
||||||
|
if(dxw.dwFlags5 & TEXTUREMASK) {
|
||||||
|
// Texture Handling on Blt
|
||||||
|
TextureHandling(lpdds);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
|
||||||
|
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping)
|
||||||
|
{
|
||||||
|
HRESULT res;
|
||||||
|
RECT destrect, emurect;
|
||||||
|
extern PrimaryBlt_Type pPrimaryBlt;
|
||||||
|
|
||||||
|
// debug suppressions
|
||||||
|
if(isFlipping){
|
||||||
|
if(dxw.dwFlags3 & NODDRAWFLIP) return DD_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(dxw.dwFlags3 & NODDRAWBLT) return DD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ONEPIXELFIX
|
||||||
|
if (lpdestrect){
|
||||||
|
if ((lpdestrect->top == 0) && (lpdestrect->bottom == dxw.GetScreenHeight() -1)) lpdestrect->bottom = dxw.GetScreenHeight();
|
||||||
|
if ((lpdestrect->left == 0) && (lpdestrect->right == dxw.GetScreenWidth() -1)) lpdestrect->right = dxw.GetScreenWidth();
|
||||||
|
}
|
||||||
|
if (lpsrcrect){
|
||||||
|
if ((lpsrcrect->top == 0) && (lpsrcrect->bottom == dxw.GetScreenHeight() -1)) lpsrcrect->bottom = dxw.GetScreenHeight();
|
||||||
|
if ((lpsrcrect->left == 0) && (lpsrcrect->right == dxw.GetScreenWidth() -1)) lpsrcrect->right = dxw.GetScreenWidth();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FIXBIGGERRECT 1
|
||||||
|
#if FIXBIGGERRECT
|
||||||
|
if(lpdestrect){
|
||||||
|
if((DWORD)lpdestrect->top < 0) lpdestrect->top = 0;
|
||||||
|
if((DWORD)lpdestrect->left < 0) lpdestrect->left = 0;
|
||||||
|
if((DWORD)lpdestrect->bottom > dxw.GetScreenHeight()) lpdestrect->bottom = dxw.GetScreenHeight();
|
||||||
|
if((DWORD)lpdestrect->right > dxw.GetScreenWidth()) lpdestrect->right = dxw.GetScreenWidth();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(dxw.dwFlags5 & QUARTERBLT){
|
||||||
|
BOOL QuarterUpdate;
|
||||||
|
QuarterUpdate = lpdestrect ?
|
||||||
|
(((lpdestrect->bottom - lpdestrect->top) * (lpdestrect->right - lpdestrect->left)) > ((LONG)(dxw.GetScreenHeight() * dxw.GetScreenWidth()) >> 2))
|
||||||
|
:
|
||||||
|
TRUE;
|
||||||
|
if(QuarterUpdate) if(dxw.HandleFPS()) return DD_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(dxw.HandleFPS()) return DD_OK;
|
||||||
|
if(dxw.dwFlags5 & NOBLT) return DD_OK;
|
||||||
|
|
||||||
|
destrect=dxw.MapWindowRect(lpdestrect);
|
||||||
|
OutTraceB("DESTRECT=(%d,%d)-(%d,%d) Screen=(%dx%d)\n",
|
||||||
|
destrect.left, destrect.top, destrect.right, destrect.bottom,
|
||||||
|
dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
||||||
|
|
||||||
|
if(!lpddssrc) {
|
||||||
|
if (isFlipping){
|
||||||
|
// handle the flipping chain ...
|
||||||
|
lpddssrc=lpDDSBack;
|
||||||
|
OutTraceDW("Flip: setting flip chain to lpdds=%x\n", lpddssrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
// Blit to primary direct surface
|
||||||
|
// =========================
|
||||||
|
|
||||||
|
if(!(dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER))){
|
||||||
|
res=DD_OK;
|
||||||
|
|
||||||
|
// blit only when source and dest surface are different. Should make ScreenRefresh faster.
|
||||||
|
if (lpdds != lpddssrc) {
|
||||||
|
dxw.ShowOverlay(lpddssrc);
|
||||||
|
if (IsDebug) BlitTrace("PRIM-NOEMU", lpsrcrect, &destrect, __LINE__);
|
||||||
|
res=(*pPrimaryBlt)(lpdds, &destrect, lpddssrc, lpsrcrect);
|
||||||
|
}
|
||||||
|
if(res){
|
||||||
|
BlitError(res, lpsrcrect, &destrect, __LINE__);
|
||||||
|
if(IsDebug) {
|
||||||
|
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
|
||||||
|
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
|
||||||
|
}
|
||||||
|
// Try to handle HDC lock concurrency....
|
||||||
|
if(res==DDERR_SURFACEBUSY){
|
||||||
|
(*pUnlockMethod(lpdds))(lpdds, NULL);
|
||||||
|
if (IsDebug) BlitTrace("BUSY", lpsrcrect, &destrect, __LINE__);
|
||||||
|
res= (*pBlt)(lpdds, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
||||||
|
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
|
||||||
|
}
|
||||||
|
// Try to handle DDBLT_KEYSRC on primary surface
|
||||||
|
if((res==DDERR_INVALIDPARAMS) && (dwflags & DDBLT_KEYSRC)){
|
||||||
|
// to do: handle possible situations with surface 2 / 4 / 7 types
|
||||||
|
DDSURFACEDESC ddsd;
|
||||||
|
LPDIRECTDRAWSURFACE lpddsTmp;
|
||||||
|
if (IsDebug) BlitTrace("KEYSRC", lpsrcrect, &destrect, __LINE__);
|
||||||
|
memset(&ddsd, 0, sizeof(ddsd));
|
||||||
|
ddsd.dwSize = sizeof(ddsd);
|
||||||
|
lpddssrc->GetSurfaceDesc(&ddsd);
|
||||||
|
res=(*pCreateSurface1)(lpPrimaryDD, &ddsd, &lpddsTmp, NULL);
|
||||||
|
if(res) OutTraceE("CreateSurface: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
|
||||||
|
// copy background
|
||||||
|
res= (*pBlt)(lpddsTmp, lpsrcrect, lpdds, &destrect, DDBLT_WAIT, NULL);
|
||||||
|
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
|
||||||
|
// overlay texture
|
||||||
|
res= (*pBlt)(lpddsTmp, lpsrcrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
||||||
|
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
|
||||||
|
// copy back to destination
|
||||||
|
res= (*pBlt)(lpdds, &destrect, lpddsTmp, lpsrcrect, DDBLT_WAIT, lpddbltfx);
|
||||||
|
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
|
||||||
|
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
|
||||||
|
(*pReleaseS)(lpddsTmp);
|
||||||
|
}
|
||||||
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... else blitting on emulated surface
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
// Blit/Flip to emulated primary surface
|
||||||
|
// =========================
|
||||||
|
|
||||||
|
if(dxw.dwFlags5 & GDIMODE){
|
||||||
|
extern void BlitToWindow(HWND, LPDIRECTDRAWSURFACE);
|
||||||
|
//if (lpdds != lpddssrc)
|
||||||
|
BlitToWindow(dxw.GethWnd(), lpddssrc);
|
||||||
|
return DD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpdestrect){
|
||||||
|
emurect=*lpdestrect;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// emurect: emulated rect is full surface (dwWidth x dwHeight)
|
||||||
|
emurect.left = 0;
|
||||||
|
emurect.top = 0;
|
||||||
|
emurect.right = dxw.GetScreenWidth();
|
||||||
|
emurect.bottom = dxw.GetScreenHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
res=0;
|
||||||
|
// blit only when source and dest surface are different. Should make ScreenRefresh faster.
|
||||||
|
if (lpdds != lpddssrc){
|
||||||
|
if (IsDebug) BlitTrace("SRC2EMU", &emurect, &destrect, __LINE__);
|
||||||
|
if(destrect.top == -32000) return DD_OK; // happens when window is minimized & do not notify on task switch ...
|
||||||
|
res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
BlitError(res, lpsrcrect, &emurect, __LINE__);
|
||||||
|
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
|
||||||
|
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
|
||||||
|
/*
|
||||||
|
Dungeon Keeper II intro movies bug ....
|
||||||
|
it seems that you can't blit from compressed or different surfaces in memory,
|
||||||
|
while the operation COULD be supported to video. As a mater of fact, it DOES
|
||||||
|
work on my PC. The error code is DDERR_UNSUPPORTED.
|
||||||
|
v2.02.98 update....
|
||||||
|
The same thing happens with New York Racer, but with DDERR_EXCEPTION error code.
|
||||||
|
*/
|
||||||
|
if((res==DDERR_UNSUPPORTED) || (res==DDERR_EXCEPTION)){
|
||||||
|
dxw.ShowOverlay(lpddssrc);
|
||||||
|
if (IsDebug) BlitTrace("UNSUPP", &emurect, &destrect, __LINE__);
|
||||||
|
res=(*pBlt)(lpDDSEmu_Prim, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
||||||
|
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to handle HDC lock concurrency....
|
||||||
|
if(res==DDERR_SURFACEBUSY){
|
||||||
|
res=(*pUnlockMethod(lpddssrc))(lpddssrc, NULL);
|
||||||
|
if(res) OutTraceE("Unlock ERROR: err=%x(%s)\n", res, ExplainDDError(res));
|
||||||
|
if (IsDebug) BlitTrace("BUSY", &emurect, &destrect, __LINE__);
|
||||||
|
res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
||||||
|
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPDIRECTDRAWSURFACE lpDDSSource;
|
||||||
|
if (res=(*pColorConversion)(lpdds, emurect, &lpDDSSource)) {
|
||||||
|
OutTraceE("sBlt ERROR: Color conversion failed res=%d(%s)\n", res, ExplainDDError(res));
|
||||||
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
dxw.ShowOverlay(lpDDSSource);
|
||||||
|
if (IsDebug) BlitTrace("BACK2PRIM", &emurect, &destrect, __LINE__);
|
||||||
|
res=(*pPrimaryBlt)(lpDDSEmu_Prim, &destrect, lpDDSSource, &emurect);
|
||||||
|
|
||||||
|
if (res) BlitError(res, &emurect, &destrect, __LINE__);
|
||||||
|
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
||||||
|
if (IsDebug) OutTrace("%s: done ret=%x at %d\n", api, res, __LINE__);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
|
||||||
|
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping)
|
||||||
|
{
|
||||||
|
POINT p = {0, 0};
|
||||||
|
HRESULT res;
|
||||||
|
BOOL ToPrim, FromPrim, ToScreen, FromScreen;
|
||||||
|
|
||||||
|
if(dxw.dwFlags5 & MESSAGEPUMP){
|
||||||
|
MSG msg;
|
||||||
|
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){
|
||||||
|
OutTraceW("MESSAGEPUMP: msg=%x l-wParam=(%x,%x)\n", msg.message, msg.lParam, msg.wParam);
|
||||||
|
if((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) break; // do not consume keyboard inputs
|
||||||
|
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ToPrim=dxw.IsAPrimarySurface(lpdds);
|
||||||
|
FromPrim=dxw.IsAPrimarySurface(lpddssrc);
|
||||||
|
ToScreen=ToPrim && !(dxw.dwFlags1 & EMULATESURFACE);
|
||||||
|
FromScreen=FromPrim && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77
|
||||||
|
|
||||||
|
// log
|
||||||
|
if(IsTraceDW){
|
||||||
|
char sLog[256];
|
||||||
|
char sInfo[128];
|
||||||
|
sprintf(sLog, "%s: dest=%x%s src=%x%s dwFlags=%x(%s)",
|
||||||
|
api, lpdds, (ToPrim ? "(PRIM)":""), lpddssrc, (FromPrim ? "(PRIM)":""), dwflags, ExplainBltFlags(dwflags));
|
||||||
|
if (lpdestrect)
|
||||||
|
sprintf(sInfo, " destrect=(%d,%d)-(%d,%d)", lpdestrect->left, lpdestrect->top, lpdestrect->right, lpdestrect->bottom);
|
||||||
|
else
|
||||||
|
sprintf(sInfo, " destrect=(NULL)");
|
||||||
|
strcat(sLog, sInfo);
|
||||||
|
if (lpsrcrect)
|
||||||
|
sprintf(sInfo, " srcrect=(%d,%d)-(%d,%d)", lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom);
|
||||||
|
else
|
||||||
|
sprintf(sInfo, " srcrect=(NULL)");
|
||||||
|
strcat(sLog, sInfo);
|
||||||
|
if(lpddbltfx){
|
||||||
|
if (dwflags & DDBLT_COLORFILL){
|
||||||
|
sprintf(sInfo, " ddbltfx.FillColor=%x", lpddbltfx->dwFillColor);
|
||||||
|
strcat(sLog, sInfo);
|
||||||
|
}
|
||||||
|
if (dwflags & DDBLT_KEYDESTOVERRIDE){
|
||||||
|
sprintf(sInfo, " ddbltfx.DestColorkey=%x", lpddbltfx->ddckDestColorkey);
|
||||||
|
strcat(sLog, sInfo);
|
||||||
|
}
|
||||||
|
if (dwflags & DDBLT_KEYSRCOVERRIDE){
|
||||||
|
sprintf(sInfo, " ddbltfx.SrcColorkey=%x", lpddbltfx->ddckSrcColorkey);
|
||||||
|
strcat(sLog, sInfo);
|
||||||
|
}
|
||||||
|
if (dwflags & DDBLT_ROP){
|
||||||
|
sprintf(sInfo, " ddbltfx.ROP=%x", lpddbltfx->dwROP);
|
||||||
|
strcat(sLog, sInfo);
|
||||||
|
}
|
||||||
|
if (dwflags & DDBLT_DEPTHFILL){
|
||||||
|
sprintf(sInfo, " ddbltfx.FillDepth=%x", lpddbltfx->dwFillDepth);
|
||||||
|
strcat(sLog, sInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(sLog,"\n");
|
||||||
|
OutTrace(sLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ToPrim)
|
||||||
|
res = sBltToPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx, isFlipping);
|
||||||
|
else
|
||||||
|
res = sBltNoPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
382
dll/ddraw.cpp
382
dll/ddraw.cpp
@ -286,6 +286,8 @@ FARPROC Remap_ddraw_ProcAddress(LPCSTR proc, HMODULE hModule)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------ */
|
||||||
// auxiliary (static) functions
|
// auxiliary (static) functions
|
||||||
/* ------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------ */
|
||||||
@ -456,7 +458,7 @@ static void DumpSurfaceAttributes(LPDDSURFACEDESC lpddsd, char *label, int line)
|
|||||||
LogSurfaceAttributes(lpddsd, label, line);
|
LogSurfaceAttributes(lpddsd, label, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DescribeSurface(LPDIRECTDRAWSURFACE lpdds, int dxversion, char *label, int line)
|
void DescribeSurface(LPDIRECTDRAWSURFACE lpdds, int dxversion, char *label, int line)
|
||||||
{
|
{
|
||||||
DDSURFACEDESC2 ddsd;
|
DDSURFACEDESC2 ddsd;
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
@ -1515,7 +1517,7 @@ static void HandleCapsD(char *sLabel, LPDDCAPS c)
|
|||||||
HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
|
HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
|
||||||
{
|
{
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
OutTraceDDRAW("GetCaps(D): lpdd=%x\n", lpdd);
|
OutTraceDDRAW("GetCaps(D): lpdd=%x %s %s\n", lpdd, c1?"c1":"NULL", c2?"c2":"NULL");
|
||||||
res=(*pGetCapsD)(lpdd, c1, c2);
|
res=(*pGetCapsD)(lpdd, c1, c2);
|
||||||
if(res)
|
if(res)
|
||||||
OutTraceE("GetCaps(D): ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
OutTraceE("GetCaps(D): ERROR res=%x(%s)\n", res, ExplainDDError(res));
|
||||||
@ -1539,6 +1541,10 @@ HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
|
|||||||
memcpy((void *)c1, (void *)c2, size);
|
memcpy((void *)c1, (void *)c2, size);
|
||||||
if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=dwVidMemTotal;
|
if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=dwVidMemTotal;
|
||||||
if(c1->dwVidMemFree == 0) c1->dwVidMemFree =dwVidMemFree;
|
if(c1->dwVidMemFree == 0) c1->dwVidMemFree =dwVidMemFree;
|
||||||
|
if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=0x20000000; // 500 MB
|
||||||
|
if(c1->dwVidMemFree == 0) c1->dwVidMemFree =0x20000000; // 500 MB
|
||||||
|
if (c1) HandleCapsD("D-HW(fixed)", c1);
|
||||||
|
if (c2) HandleCapsD("D-SW(fixed)", c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dxw.dwFlags3 & CAPMASK) MaskCapsD(c1, c2);
|
if(dxw.dwFlags3 & CAPMASK) MaskCapsD(c1, c2);
|
||||||
@ -2127,6 +2133,7 @@ static void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion)
|
|||||||
{
|
{
|
||||||
// rules of thumb:
|
// rules of thumb:
|
||||||
// 1) textures should be left untouched (switching to SYSTEMMEMORY when forcing HEL may even fail!)
|
// 1) textures should be left untouched (switching to SYSTEMMEMORY when forcing HEL may even fail!)
|
||||||
|
// 1.1) textures with no DDSD_PIXELFORMAT specification should have one when virtual color depth is not equal to real color depth?
|
||||||
// 2) if a pixel format is specified, if DDSCAPS_SYSTEMMEMORY add DDSCAPS_OFFSCREENPLAY (if pixel formats are different?), otherwise do not touch anything.
|
// 2) if a pixel format is specified, if DDSCAPS_SYSTEMMEMORY add DDSCAPS_OFFSCREENPLAY (if pixel formats are different?), otherwise do not touch anything.
|
||||||
// 3) if the surface is used as a buffer (DDSD_WIDTH set, DDSD_HEIGHT unset) do not touch anything.
|
// 3) if the surface is used as a buffer (DDSD_WIDTH set, DDSD_HEIGHT unset) do not touch anything.
|
||||||
// 4) zbuffer surfaces (DDSCAPS_ZBUFFER set) must have DDSCAPS_SYSTEMMEMORY
|
// 4) zbuffer surfaces (DDSCAPS_ZBUFFER set) must have DDSCAPS_SYSTEMMEMORY
|
||||||
@ -2144,6 +2151,11 @@ static void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion)
|
|||||||
lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
|
lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
|
||||||
lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
||||||
}
|
}
|
||||||
|
if((dxw.dwFlags5 & TEXTUREFORMAT) && !(lpddsd->dwFlags & DDSD_PIXELFORMAT)){
|
||||||
|
// TEXTURE: enforce PIXELFORMAT on MEMORY
|
||||||
|
lpddsd->dwFlags |= DDSD_PIXELFORMAT;
|
||||||
|
GetPixFmt(lpddsd);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2375,7 +2387,7 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS
|
|||||||
|
|
||||||
// create BackBuffer surface
|
// create BackBuffer surface
|
||||||
memcpy(&ddsd, lpddsd, lpddsd->dwSize);
|
memcpy(&ddsd, lpddsd, lpddsd->dwSize);
|
||||||
ddsd.dwFlags &= ~(DDSD_WIDTH|DDSD_HEIGHT|DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE);
|
ddsd.dwFlags &= ~(DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE);
|
||||||
ddsd.dwFlags |= (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT);
|
ddsd.dwFlags |= (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT);
|
||||||
ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER|DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM);
|
ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER|DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM);
|
||||||
// DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces
|
// DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces
|
||||||
@ -2474,9 +2486,8 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf
|
|||||||
// on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it....
|
// on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it....
|
||||||
if(dxw.dwFlags5 & NOSYSTEMMEMORY) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
|
if(dxw.dwFlags5 & NOSYSTEMMEMORY) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
|
||||||
|
|
||||||
DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]" , __LINE__);
|
|
||||||
res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, pu);
|
res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, pu);
|
||||||
if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res==DDERR_OUTOFVIDEOMEMORY)){
|
if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res!=DD_OK)){
|
||||||
OutTraceDW("CreateSurface ERROR: res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__);
|
OutTraceDW("CreateSurface ERROR: res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__);
|
||||||
ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
|
ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
|
||||||
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
||||||
@ -2487,6 +2498,8 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]" , __LINE__);
|
||||||
|
|
||||||
OutTraceDW("CreateSurface: created Emu_Generic dds=%x\n", *lplpdds);
|
OutTraceDW("CreateSurface: created Emu_Generic dds=%x\n", *lplpdds);
|
||||||
if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSEmu_Generic", __LINE__);
|
if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSEmu_Generic", __LINE__);
|
||||||
|
|
||||||
@ -2691,14 +2704,16 @@ static HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreate
|
|||||||
|
|
||||||
// if nothing else, it's a generic/zbuffer surface
|
// if nothing else, it's a generic/zbuffer surface
|
||||||
|
|
||||||
|
res=BuildGeneric(lpdd, pCreateSurface, lpddsd, dxversion, lplpdds, pu);
|
||||||
|
if(!res) {
|
||||||
|
dxw.MarkRegularSurface(*lplpdds);
|
||||||
if(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) {
|
if(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) {
|
||||||
lpDDZBuffer=*lplpdds;
|
lpDDZBuffer=*lplpdds;
|
||||||
DDZBufferCaps = lpddsd->ddsCaps.dwCaps;
|
DDZBufferCaps = lpddsd->ddsCaps.dwCaps;
|
||||||
OutTraceDW("CreateSurface: lpDDZBuffer=%x save ZBUFFER caps=%x(%s)\n", lpDDZBuffer, DDZBufferCaps, ExplainDDSCaps(DDZBufferCaps));
|
OutTraceDW("CreateSurface: lpDDZBuffer=%x save ZBUFFER caps=%x(%s)\n", lpDDZBuffer, DDZBufferCaps, ExplainDDSCaps(DDZBufferCaps));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
res=BuildGeneric(lpdd, pCreateSurface, lpddsd, dxversion, lplpdds, pu);
|
|
||||||
if(!res) dxw.MarkRegularSurface(*lplpdds);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -2814,7 +2829,7 @@ HRESULT WINAPI extGetAttachedSurface7(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpdds
|
|||||||
return extGetAttachedSurface(7, pGetAttachedSurface7, lpdds, lpddsc, lplpddas);
|
return extGetAttachedSurface(7, pGetAttachedSurface7, lpdds, lpddsc, lplpddas);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line)
|
void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line)
|
||||||
{
|
{
|
||||||
OutTrace("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), line);
|
OutTrace("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), line);
|
||||||
if (res==DDERR_INVALIDRECT){
|
if (res==DDERR_INVALIDRECT){
|
||||||
@ -2831,7 +2846,7 @@ static void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BlitTrace(char *label, LPRECT lps, LPRECT lpd, int line)
|
void BlitTrace(char *label, LPRECT lps, LPRECT lpd, int line)
|
||||||
{
|
{
|
||||||
extern HANDLE hTraceMutex;
|
extern HANDLE hTraceMutex;
|
||||||
WaitForSingleObject(hTraceMutex, INFINITE);
|
WaitForSingleObject(hTraceMutex, INFINITE);
|
||||||
@ -3144,347 +3159,6 @@ HRESULT WINAPI ColorConversionDDRAW(LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPD
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT sBltNoPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
|
|
||||||
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
|
|
||||||
{
|
|
||||||
RECT srcrect;
|
|
||||||
HRESULT res;
|
|
||||||
BOOL FromScreen;
|
|
||||||
//extern PrimaryBlt_Type pPrimaryBlt;
|
|
||||||
//CkArg arg;
|
|
||||||
|
|
||||||
FromScreen=dxw.IsAPrimarySurface(lpddssrc) && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77
|
|
||||||
|
|
||||||
// make a working copy of srcrect if not NULL
|
|
||||||
if (lpsrcrect){
|
|
||||||
srcrect=*lpsrcrect;
|
|
||||||
}
|
|
||||||
// when blitting from a primary surface on screen (that is in non emulated mode), correct offsets
|
|
||||||
// You should take account also for scaled primary surfaces, but that would be a hard task:
|
|
||||||
// a reduced primary surface (in not-emulated mode) would bring quality loss!!!
|
|
||||||
// v2.1.83: BLITFROMBACKBUFFER mode, let you chose to blit from backbuffer, where the surface size
|
|
||||||
// is fixed no matter how the window/primary surface is scaled.
|
|
||||||
// In "The Sims" there is no quality loss, but some scrolling artifact.
|
|
||||||
if(lpsrcrect && FromScreen){
|
|
||||||
if(lpDDSBack && (dxw.dwFlags1 & BLITFROMBACKBUFFER)){
|
|
||||||
lpddssrc=lpDDSBack;
|
|
||||||
srcrect=dxw.GetScreenRect();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
srcrect=dxw.MapWindowRect(lpsrcrect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDebug) BlitTrace("NOPRIM", lpsrcrect, lpdestrect, __LINE__);
|
|
||||||
res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx);
|
|
||||||
// Blitting compressed data may work to screen surfaces only. In this case, it may be worth
|
|
||||||
// trying blitting directly to lpDDSEmu_Prim: it makes DK2 intro movies working.
|
|
||||||
// Wrong guess!!! The cause was not compression, but simply a pixelformat mismatch. Better
|
|
||||||
// configure things properly and avoid this branch.
|
|
||||||
switch(res){
|
|
||||||
case DDERR_UNSUPPORTED:
|
|
||||||
if (dxw.dwFlags1 & EMULATESURFACE){
|
|
||||||
RECT targetrect;
|
|
||||||
if (IsDebug) BlitTrace("UNSUPP", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__);
|
|
||||||
targetrect=*lpdestrect;
|
|
||||||
dxw.MapWindowRect(&targetrect);
|
|
||||||
res=(*pBlt)(lpDDSEmu_Prim, &targetrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DDERR_SURFACEBUSY:
|
|
||||||
(*pUnlockMethod(lpdds))(lpdds, NULL);
|
|
||||||
if (lpddssrc) (*pUnlockMethod(lpddssrc))(lpddssrc, NULL);
|
|
||||||
if (IsDebug) BlitTrace("BUSY", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__);
|
|
||||||
res=(*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_WAIT, lpddbltfx);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (res) BlitError(res, &srcrect, lpdestrect, __LINE__);
|
|
||||||
if(IsDebug) {
|
|
||||||
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
|
|
||||||
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
|
|
||||||
}
|
|
||||||
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0;
|
|
||||||
if(dxw.dwFlags5 & TEXTUREMASK) {
|
|
||||||
// Texture Handling on Blt
|
|
||||||
TextureHandling(lpdds);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
|
|
||||||
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping)
|
|
||||||
{
|
|
||||||
HRESULT res;
|
|
||||||
RECT destrect, emurect;
|
|
||||||
extern PrimaryBlt_Type pPrimaryBlt;
|
|
||||||
|
|
||||||
// debug suppressions
|
|
||||||
if(isFlipping){
|
|
||||||
if(dxw.dwFlags3 & NODDRAWFLIP) return DD_OK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(dxw.dwFlags3 & NODDRAWBLT) return DD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ONEPIXELFIX
|
|
||||||
if (lpdestrect){
|
|
||||||
if ((lpdestrect->top == 0) && (lpdestrect->bottom == dxw.GetScreenHeight() -1)) lpdestrect->bottom = dxw.GetScreenHeight();
|
|
||||||
if ((lpdestrect->left == 0) && (lpdestrect->right == dxw.GetScreenWidth() -1)) lpdestrect->right = dxw.GetScreenWidth();
|
|
||||||
}
|
|
||||||
if (lpsrcrect){
|
|
||||||
if ((lpsrcrect->top == 0) && (lpsrcrect->bottom == dxw.GetScreenHeight() -1)) lpsrcrect->bottom = dxw.GetScreenHeight();
|
|
||||||
if ((lpsrcrect->left == 0) && (lpsrcrect->right == dxw.GetScreenWidth() -1)) lpsrcrect->right = dxw.GetScreenWidth();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FIXBIGGERRECT 1
|
|
||||||
#if FIXBIGGERRECT
|
|
||||||
if(lpdestrect){
|
|
||||||
if((DWORD)lpdestrect->top < 0) lpdestrect->top = 0;
|
|
||||||
if((DWORD)lpdestrect->left < 0) lpdestrect->left = 0;
|
|
||||||
if((DWORD)lpdestrect->bottom > dxw.GetScreenHeight()) lpdestrect->bottom = dxw.GetScreenHeight();
|
|
||||||
if((DWORD)lpdestrect->right > dxw.GetScreenWidth()) lpdestrect->right = dxw.GetScreenWidth();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(dxw.dwFlags5 & QUARTERBLT){
|
|
||||||
BOOL QuarterUpdate;
|
|
||||||
QuarterUpdate = lpdestrect ?
|
|
||||||
(((lpdestrect->bottom - lpdestrect->top) * (lpdestrect->right - lpdestrect->left)) > ((LONG)(dxw.GetScreenHeight() * dxw.GetScreenWidth()) >> 2))
|
|
||||||
:
|
|
||||||
TRUE;
|
|
||||||
if(QuarterUpdate) if(dxw.HandleFPS()) return DD_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(dxw.HandleFPS()) return DD_OK;
|
|
||||||
if(dxw.dwFlags5 & NOBLT) return DD_OK;
|
|
||||||
|
|
||||||
destrect=dxw.MapWindowRect(lpdestrect);
|
|
||||||
OutTraceB("DESTRECT=(%d,%d)-(%d,%d) Screen=(%dx%d)\n",
|
|
||||||
destrect.left, destrect.top, destrect.right, destrect.bottom,
|
|
||||||
dxw.GetScreenWidth(), dxw.GetScreenHeight());
|
|
||||||
|
|
||||||
if(!lpddssrc) {
|
|
||||||
if (isFlipping){
|
|
||||||
// handle the flipping chain ...
|
|
||||||
lpddssrc=lpDDSBack;
|
|
||||||
OutTraceDW("Flip: setting flip chain to lpdds=%x\n", lpddssrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// Blit to primary direct surface
|
|
||||||
// =========================
|
|
||||||
|
|
||||||
if(!(dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER))){
|
|
||||||
res=DD_OK;
|
|
||||||
|
|
||||||
// blit only when source and dest surface are different. Should make ScreenRefresh faster.
|
|
||||||
if (lpdds != lpddssrc) {
|
|
||||||
dxw.ShowOverlay(lpddssrc);
|
|
||||||
if (IsDebug) BlitTrace("PRIM-NOEMU", lpsrcrect, &destrect, __LINE__);
|
|
||||||
res=(*pPrimaryBlt)(lpdds, &destrect, lpddssrc, lpsrcrect);
|
|
||||||
}
|
|
||||||
if(res){
|
|
||||||
BlitError(res, lpsrcrect, &destrect, __LINE__);
|
|
||||||
if(IsDebug) {
|
|
||||||
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
|
|
||||||
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
|
|
||||||
}
|
|
||||||
// Try to handle HDC lock concurrency....
|
|
||||||
if(res==DDERR_SURFACEBUSY){
|
|
||||||
(*pUnlockMethod(lpdds))(lpdds, NULL);
|
|
||||||
if (IsDebug) BlitTrace("BUSY", lpsrcrect, &destrect, __LINE__);
|
|
||||||
res= (*pBlt)(lpdds, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
|
||||||
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
|
|
||||||
}
|
|
||||||
// Try to handle DDBLT_KEYSRC on primary surface
|
|
||||||
if((res==DDERR_INVALIDPARAMS) && (dwflags & DDBLT_KEYSRC)){
|
|
||||||
// to do: handle possible situations with surface 2 / 4 / 7 types
|
|
||||||
DDSURFACEDESC ddsd;
|
|
||||||
LPDIRECTDRAWSURFACE lpddsTmp;
|
|
||||||
if (IsDebug) BlitTrace("KEYSRC", lpsrcrect, &destrect, __LINE__);
|
|
||||||
memset(&ddsd, 0, sizeof(ddsd));
|
|
||||||
ddsd.dwSize = sizeof(ddsd);
|
|
||||||
lpddssrc->GetSurfaceDesc(&ddsd);
|
|
||||||
res=(*pCreateSurface1)(lpPrimaryDD, &ddsd, &lpddsTmp, NULL);
|
|
||||||
if(res) OutTraceE("CreateSurface: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
|
|
||||||
// copy background
|
|
||||||
res= (*pBlt)(lpddsTmp, lpsrcrect, lpdds, &destrect, DDBLT_WAIT, NULL);
|
|
||||||
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
|
|
||||||
// overlay texture
|
|
||||||
res= (*pBlt)(lpddsTmp, lpsrcrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
|
||||||
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
|
|
||||||
// copy back to destination
|
|
||||||
res= (*pBlt)(lpdds, &destrect, lpddsTmp, lpsrcrect, DDBLT_WAIT, lpddbltfx);
|
|
||||||
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
|
|
||||||
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
|
|
||||||
(*pReleaseS)(lpddsTmp);
|
|
||||||
}
|
|
||||||
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... else blitting on emulated surface
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// Blit/Flip to emulated primary surface
|
|
||||||
// =========================
|
|
||||||
|
|
||||||
if(dxw.dwFlags5 & GDIMODE){
|
|
||||||
extern void BlitToWindow(HWND, LPDIRECTDRAWSURFACE);
|
|
||||||
if (lpdds != lpddssrc) BlitToWindow(dxw.GethWnd(), lpddssrc);
|
|
||||||
return DD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpdestrect){
|
|
||||||
emurect=*lpdestrect;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
// emurect: emulated rect is full surface (dwWidth x dwHeight)
|
|
||||||
emurect.left = 0;
|
|
||||||
emurect.top = 0;
|
|
||||||
emurect.right = dxw.GetScreenWidth();
|
|
||||||
emurect.bottom = dxw.GetScreenHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
res=0;
|
|
||||||
// blit only when source and dest surface are different. Should make ScreenRefresh faster.
|
|
||||||
if (lpdds != lpddssrc){
|
|
||||||
if (IsDebug) BlitTrace("SRC2EMU", &emurect, &destrect, __LINE__);
|
|
||||||
if(destrect.top == -32000) return DD_OK; // happens when window is minimized & do not notify on task switch ...
|
|
||||||
res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
BlitError(res, lpsrcrect, &emurect, __LINE__);
|
|
||||||
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
|
|
||||||
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
|
|
||||||
/*
|
|
||||||
Dungeon Keeper II intro movies bug ....
|
|
||||||
it seems that you can't blit from compressed or different surfaces in memory,
|
|
||||||
while the operation COULD be supported to video. As a mater of fact, it DOES
|
|
||||||
work on my PC. The error code is DDERR_UNSUPPORTED.
|
|
||||||
v2.02.98 update....
|
|
||||||
The same thing happens with New York Racer, but with DDERR_EXCEPTION error code.
|
|
||||||
*/
|
|
||||||
if((res==DDERR_UNSUPPORTED) || (res==DDERR_EXCEPTION)){
|
|
||||||
dxw.ShowOverlay(lpddssrc);
|
|
||||||
if (IsDebug) BlitTrace("UNSUPP", &emurect, &destrect, __LINE__);
|
|
||||||
res=(*pBlt)(lpDDSEmu_Prim, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
|
||||||
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to handle HDC lock concurrency....
|
|
||||||
if(res==DDERR_SURFACEBUSY){
|
|
||||||
res=(*pUnlockMethod(lpddssrc))(lpddssrc, NULL);
|
|
||||||
if(res) OutTraceE("Unlock ERROR: err=%x(%s)\n", res, ExplainDDError(res));
|
|
||||||
if (IsDebug) BlitTrace("BUSY", &emurect, &destrect, __LINE__);
|
|
||||||
res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
|
||||||
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPDIRECTDRAWSURFACE lpDDSSource;
|
|
||||||
if (res=(*pColorConversion)(lpdds, emurect, &lpDDSSource)) {
|
|
||||||
OutTraceE("sBlt ERROR: Color conversion failed res=%d(%s)\n", res, ExplainDDError(res));
|
|
||||||
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
dxw.ShowOverlay(lpDDSSource);
|
|
||||||
if (IsDebug) BlitTrace("BACK2PRIM", &emurect, &destrect, __LINE__);
|
|
||||||
res=(*pPrimaryBlt)(lpDDSEmu_Prim, &destrect, lpDDSSource, &emurect);
|
|
||||||
|
|
||||||
if (res) BlitError(res, &emurect, &destrect, __LINE__);
|
|
||||||
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
|
|
||||||
if (IsDebug) OutTrace("%s: done ret=%x at %d\n", api, res, __LINE__);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
|
|
||||||
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping)
|
|
||||||
{
|
|
||||||
POINT p = {0, 0};
|
|
||||||
HRESULT res;
|
|
||||||
BOOL ToPrim, FromPrim, ToScreen, FromScreen;
|
|
||||||
|
|
||||||
if(dxw.dwFlags5 & MESSAGEPUMP){
|
|
||||||
MSG msg;
|
|
||||||
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){
|
|
||||||
OutTraceW("MESSAGEPUMP: msg=%x l-wParam=(%x,%x)\n", msg.message, msg.lParam, msg.wParam);
|
|
||||||
if((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) break; // do not consume keyboard inputs
|
|
||||||
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ToPrim=dxw.IsAPrimarySurface(lpdds);
|
|
||||||
FromPrim=dxw.IsAPrimarySurface(lpddssrc);
|
|
||||||
ToScreen=ToPrim && !(dxw.dwFlags1 & EMULATESURFACE);
|
|
||||||
FromScreen=FromPrim && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77
|
|
||||||
|
|
||||||
CleanRect(&lpdestrect,__LINE__);
|
|
||||||
CleanRect(&lpsrcrect,__LINE__);
|
|
||||||
|
|
||||||
// log
|
|
||||||
if(IsTraceDW){
|
|
||||||
char sLog[256];
|
|
||||||
char sInfo[128];
|
|
||||||
sprintf(sLog, "%s: dest=%x%s src=%x%s dwFlags=%x(%s)",
|
|
||||||
api, lpdds, (ToPrim ? "(PRIM)":""), lpddssrc, (FromPrim ? "(PRIM)":""), dwflags, ExplainBltFlags(dwflags));
|
|
||||||
if (lpdestrect)
|
|
||||||
sprintf(sInfo, " destrect=(%d,%d)-(%d,%d)", lpdestrect->left, lpdestrect->top, lpdestrect->right, lpdestrect->bottom);
|
|
||||||
else
|
|
||||||
sprintf(sInfo, " destrect=(NULL)");
|
|
||||||
strcat(sLog, sInfo);
|
|
||||||
if (lpsrcrect)
|
|
||||||
sprintf(sInfo, " srcrect=(%d,%d)-(%d,%d)", lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom);
|
|
||||||
else
|
|
||||||
sprintf(sInfo, " srcrect=(NULL)");
|
|
||||||
strcat(sLog, sInfo);
|
|
||||||
if(lpddbltfx){
|
|
||||||
if (dwflags & DDBLT_COLORFILL){
|
|
||||||
sprintf(sInfo, " ddbltfx.FillColor=%x", lpddbltfx->dwFillColor);
|
|
||||||
strcat(sLog, sInfo);
|
|
||||||
}
|
|
||||||
if (dwflags & DDBLT_KEYDESTOVERRIDE){
|
|
||||||
sprintf(sInfo, " ddbltfx.DestColorkey=%x", lpddbltfx->ddckDestColorkey);
|
|
||||||
strcat(sLog, sInfo);
|
|
||||||
}
|
|
||||||
if (dwflags & DDBLT_KEYSRCOVERRIDE){
|
|
||||||
sprintf(sInfo, " ddbltfx.SrcColorkey=%x", lpddbltfx->ddckSrcColorkey);
|
|
||||||
strcat(sLog, sInfo);
|
|
||||||
}
|
|
||||||
if (dwflags & DDBLT_ROP){
|
|
||||||
sprintf(sInfo, " ddbltfx.ROP=%x", lpddbltfx->dwROP);
|
|
||||||
strcat(sLog, sInfo);
|
|
||||||
}
|
|
||||||
if (dwflags & DDBLT_DEPTHFILL){
|
|
||||||
sprintf(sInfo, " ddbltfx.FillDepth=%x", lpddbltfx->dwFillDepth);
|
|
||||||
strcat(sLog, sInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strcat(sLog,"\n");
|
|
||||||
OutTrace(sLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ToPrim)
|
|
||||||
res = sBltToPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx, isFlipping);
|
|
||||||
else
|
|
||||||
res = sBltNoPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT WINAPI extFlip(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags)
|
HRESULT WINAPI extFlip(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, DWORD dwflags)
|
||||||
{
|
{
|
||||||
BOOL IsPrim;
|
BOOL IsPrim;
|
||||||
@ -4582,7 +4256,7 @@ HRESULT WINAPI extEnumAttachedSurfaces(LPDIRECTDRAWSURFACE lpdds, LPVOID lpConte
|
|||||||
HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
|
HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
|
||||||
{
|
{
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
BOOL IsPrim;
|
BOOL IsPrim, IsBack;
|
||||||
|
|
||||||
// You can add backbuffers to primary surfaces to join the flipping chain, but you can't do that
|
// You can add backbuffers to primary surfaces to join the flipping chain, but you can't do that
|
||||||
// to an emulated primary surface, and you receive a DDERR_CANNOTATTACHSURFACE error code.
|
// to an emulated primary surface, and you receive a DDERR_CANNOTATTACHSURFACE error code.
|
||||||
@ -4591,7 +4265,9 @@ HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURF
|
|||||||
// But beware: this holds to BACKBUFFER surfaces only, and NOT for attached ZBUFFERS or similar!
|
// But beware: this holds to BACKBUFFER surfaces only, and NOT for attached ZBUFFERS or similar!
|
||||||
|
|
||||||
IsPrim=dxw.IsAPrimarySurface(lpdds);
|
IsPrim=dxw.IsAPrimarySurface(lpdds);
|
||||||
OutTraceDDRAW("AddAttachedSurface: lpdds=%x%s lpddsadd=%x\n", lpdds, IsPrim?"(PRIM)":"", lpddsadd);
|
IsBack=dxw.IsABackBufferSurface(lpdds);
|
||||||
|
OutTraceDDRAW("AddAttachedSurface: lpdds=%x%s lpddsadd=%x%s\n", lpdds, IsPrim?"(PRIM)":(IsBack?"(BACK)":""), lpddsadd, (lpddsadd==lpDDZBuffer)?"(ZBUF)":"");
|
||||||
|
|
||||||
//if(!lpddsadd) return DDERR_CANNOTATTACHSURFACE; // to avoid a crash...
|
//if(!lpddsadd) return DDERR_CANNOTATTACHSURFACE; // to avoid a crash...
|
||||||
res=(*pAddAttachedSurface)(lpdds, lpddsadd);
|
res=(*pAddAttachedSurface)(lpdds, lpddsadd);
|
||||||
if (res) {
|
if (res) {
|
||||||
@ -4613,7 +4289,7 @@ HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURF
|
|||||||
if (pAddRefS) (*pAddRefS)(lpdds);
|
if (pAddRefS) (*pAddRefS)(lpdds);
|
||||||
res=DD_OK;
|
res=DD_OK;
|
||||||
}
|
}
|
||||||
else if (lpdds == lpDDSBack) {
|
else if (IsBack) {
|
||||||
// v2.02.13: emulate ZBUFFER attach to backbuffer: do nothing and return OK
|
// v2.02.13: emulate ZBUFFER attach to backbuffer: do nothing and return OK
|
||||||
// this trick makes at least "Nocturne" work also in emulated mode when hardware acceleration
|
// this trick makes at least "Nocturne" work also in emulated mode when hardware acceleration
|
||||||
// is set in the game "Options" menu.
|
// is set in the game "Options" menu.
|
||||||
|
@ -1413,6 +1413,7 @@ void dxwCore::ShowBanner(HWND hwnd)
|
|||||||
RECT client;
|
RECT client;
|
||||||
RECT win;
|
RECT win;
|
||||||
POINT PrevViewPort;
|
POINT PrevViewPort;
|
||||||
|
int StretchMode;
|
||||||
|
|
||||||
hClientDC=(*pGDIGetDC)(hwnd);
|
hClientDC=(*pGDIGetDC)(hwnd);
|
||||||
(*pGetClientRect)(hwnd, &client);
|
(*pGetClientRect)(hwnd, &client);
|
||||||
@ -1432,6 +1433,8 @@ void dxwCore::ShowBanner(HWND hwnd)
|
|||||||
|
|
||||||
//if(!pSetViewportOrgEx) pSetViewportOrgEx=SetViewportOrgEx;
|
//if(!pSetViewportOrgEx) pSetViewportOrgEx=SetViewportOrgEx;
|
||||||
(*pSetViewportOrgEx)(hClientDC, 0, 0, &PrevViewPort);
|
(*pSetViewportOrgEx)(hClientDC, 0, 0, &PrevViewPort);
|
||||||
|
StretchMode=GetStretchBltMode(hClientDC);
|
||||||
|
SetStretchBltMode(hClientDC, HALFTONE);
|
||||||
for (int i=1; i<=16; i++){
|
for (int i=1; i<=16; i++){
|
||||||
int w, h;
|
int w, h;
|
||||||
w=(bm.bmWidth*i)/8;
|
w=(bm.bmWidth*i)/8;
|
||||||
@ -1447,6 +1450,7 @@ void dxwCore::ShowBanner(HWND hwnd)
|
|||||||
(*pGDIStretchBlt)(hClientDC, (client.right-w)/2, (client.bottom-h)/2, w, h, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
|
(*pGDIStretchBlt)(hClientDC, (client.right-w)/2, (client.bottom-h)/2, w, h, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
|
||||||
Sleep(40);
|
Sleep(40);
|
||||||
}
|
}
|
||||||
|
SetStretchBltMode(hClientDC, StretchMode);
|
||||||
(*pSetViewportOrgEx)(hClientDC, PrevViewPort.x, PrevViewPort.y, NULL);
|
(*pSetViewportOrgEx)(hClientDC, PrevViewPort.x, PrevViewPort.y, NULL);
|
||||||
SelectObject(hdcMem, hbmOld);
|
SelectObject(hdcMem, hbmOld);
|
||||||
DeleteDC(hdcMem);
|
DeleteDC(hdcMem);
|
||||||
|
BIN
dll/dxwnd.aps
BIN
dll/dxwnd.aps
Binary file not shown.
@ -27,7 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include "TlHelp32.h"
|
#include "TlHelp32.h"
|
||||||
|
|
||||||
#define VERSION "2.03.08"
|
#define VERSION "2.03.09"
|
||||||
|
|
||||||
#define DDTHREADLOCK 1
|
#define DDTHREADLOCK 1
|
||||||
//#define LOCKTHREADS
|
//#define LOCKTHREADS
|
||||||
@ -176,6 +176,10 @@ int SetTarget(TARGETMAP *targets){
|
|||||||
for(i = 0; targets[i].path[0]; i ++){
|
for(i = 0; targets[i].path[0]; i ++){
|
||||||
char *c;
|
char *c;
|
||||||
pMapping[i] = targets[i];
|
pMapping[i] = targets[i];
|
||||||
|
c = targets[i].path;
|
||||||
|
if(*c == '*')
|
||||||
|
strcpy(path, targets[i].path);
|
||||||
|
else
|
||||||
GetFullPathName(targets[i].path, MAX_PATH, path, NULL);
|
GetFullPathName(targets[i].path, MAX_PATH, path, NULL);
|
||||||
for(c = path; *c; c++) *c = tolower(*c);
|
for(c = path; *c; c++) *c = tolower(*c);
|
||||||
strcpy(pMapping[i].path, path);
|
strcpy(pMapping[i].path, path);
|
||||||
|
@ -6,3 +6,5 @@ EXPORTS
|
|||||||
GetDllVersion @4
|
GetDllVersion @4
|
||||||
GetHookStatus @5
|
GetHookStatus @5
|
||||||
GetHookInfo @6
|
GetHookInfo @6
|
||||||
|
Inject @7
|
||||||
|
GetThreadStartAddress @8
|
||||||
|
Binary file not shown.
@ -233,6 +233,10 @@
|
|||||||
RelativePath=".\d3dtexture.cpp"
|
RelativePath=".\d3dtexture.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ddblit.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\ddproxy.cpp"
|
RelativePath=".\ddproxy.cpp"
|
||||||
>
|
>
|
||||||
|
@ -40,6 +40,10 @@ void BlitToWindow(HWND w, LPDIRECTDRAWSURFACE s)
|
|||||||
if(!ret) OutTrace("BitBlt error=%d\n", GetLastError());
|
if(!ret) OutTrace("BitBlt error=%d\n", GetLastError());
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
if(dxw.dwFlags5 & BILINEARFILTER) {
|
||||||
|
ret=SetStretchBltMode(thdc, HALFTONE);
|
||||||
|
if((!ret) || (ret==ERROR_INVALID_PARAMETER)) OutTrace("GDI SetStretchBltMode error=%d\n", GetLastError());
|
||||||
|
}
|
||||||
ret=(*pGDIStretchBlt)(thdc, 0, 0, client.right, client.bottom, shdc, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), SRCCOPY);
|
ret=(*pGDIStretchBlt)(thdc, 0, 0, client.right, client.bottom, shdc, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), SRCCOPY);
|
||||||
if(!ret) OutTrace("GDI StretchBlt error=%d\n", GetLastError());
|
if(!ret) OutTrace("GDI StretchBlt error=%d\n", GetLastError());
|
||||||
}
|
}
|
||||||
|
118
dll/hd3d7.cpp
118
dll/hd3d7.cpp
@ -1,5 +1,8 @@
|
|||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <d3d.h>
|
#include <d3d.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "dxwnd.h"
|
#include "dxwnd.h"
|
||||||
#include "dxwcore.hpp"
|
#include "dxwcore.hpp"
|
||||||
#include "dxhook.h"
|
#include "dxhook.h"
|
||||||
@ -32,6 +35,7 @@ typedef HRESULT (WINAPI *FindDevice_Type)(void *, LPD3DFINDDEVICESEARCH, LPD3DFI
|
|||||||
typedef HRESULT (WINAPI *CreateDevice2_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE, LPDIRECT3DDEVICE2 *);
|
typedef HRESULT (WINAPI *CreateDevice2_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE, LPDIRECT3DDEVICE2 *);
|
||||||
typedef HRESULT (WINAPI *CreateDevice3_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE4, LPDIRECT3DDEVICE3 *, LPUNKNOWN);
|
typedef HRESULT (WINAPI *CreateDevice3_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE4, LPDIRECT3DDEVICE3 *, LPUNKNOWN);
|
||||||
typedef HRESULT (WINAPI *CreateDevice7_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE7, LPDIRECT3DDEVICE7 *);
|
typedef HRESULT (WINAPI *CreateDevice7_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE7, LPDIRECT3DDEVICE7 *);
|
||||||
|
typedef HRESULT (WINAPI *EnumZBufferFormats_Type)(void *, REFCLSID, LPD3DENUMPIXELFORMATSCALLBACK, LPVOID);
|
||||||
|
|
||||||
QueryInterfaceD3_Type pQueryInterfaceD3 = NULL;
|
QueryInterfaceD3_Type pQueryInterfaceD3 = NULL;
|
||||||
Initialize_Type pInitialize = NULL;
|
Initialize_Type pInitialize = NULL;
|
||||||
@ -46,6 +50,9 @@ FindDevice_Type pFindDevice = NULL;
|
|||||||
CreateDevice2_Type pCreateDevice2 = NULL;
|
CreateDevice2_Type pCreateDevice2 = NULL;
|
||||||
CreateDevice3_Type pCreateDevice3 = NULL;
|
CreateDevice3_Type pCreateDevice3 = NULL;
|
||||||
CreateDevice7_Type pCreateDevice7 = NULL;
|
CreateDevice7_Type pCreateDevice7 = NULL;
|
||||||
|
EnumZBufferFormats_Type pEnumZBufferFormats = NULL;
|
||||||
|
|
||||||
|
HRESULT WINAPI extEnumZBufferFormats(void *, REFCLSID, LPD3DENUMPIXELFORMATSCALLBACK, LPVOID);
|
||||||
|
|
||||||
// Direct3DDevice-n interfaces
|
// Direct3DDevice-n interfaces
|
||||||
|
|
||||||
@ -216,6 +223,89 @@ HRESULT WINAPI extTexUnload(void *);
|
|||||||
extern char *ExplainDDError(DWORD);
|
extern char *ExplainDDError(DWORD);
|
||||||
int GD3DDeviceVersion;
|
int GD3DDeviceVersion;
|
||||||
|
|
||||||
|
static char *sFourCC(DWORD fcc)
|
||||||
|
{
|
||||||
|
static char sRet[5];
|
||||||
|
char c;
|
||||||
|
int i;
|
||||||
|
char *t=&sRet[0];
|
||||||
|
for(i=0; i<4; i++){
|
||||||
|
c = fcc & (0xFF);
|
||||||
|
*t++ = isprint(c) ? c : '.';
|
||||||
|
c = c >> 8;
|
||||||
|
}
|
||||||
|
*t = 0;
|
||||||
|
return sRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *DumpPixelFormat(LPDDPIXELFORMAT ddpfPixelFormat)
|
||||||
|
{
|
||||||
|
static char sBuf[512];
|
||||||
|
char sItem[256];
|
||||||
|
DWORD flags=ddpfPixelFormat->dwFlags;
|
||||||
|
sprintf(sBuf, " PixelFormat flags=%x(%s) BPP=%d",
|
||||||
|
flags, ExplainPixelFormatFlags(flags), ddpfPixelFormat->dwRGBBitCount);
|
||||||
|
if (flags & DDPF_RGB) {
|
||||||
|
if (flags & DDPF_ALPHAPIXELS) {
|
||||||
|
sprintf(sItem, " RGBA=(%x,%x,%x,%x)",
|
||||||
|
ddpfPixelFormat->dwRBitMask,
|
||||||
|
ddpfPixelFormat->dwGBitMask,
|
||||||
|
ddpfPixelFormat->dwBBitMask,
|
||||||
|
ddpfPixelFormat->dwRGBAlphaBitMask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(sItem, " RGB=(%x,%x,%x)",
|
||||||
|
ddpfPixelFormat->dwRBitMask,
|
||||||
|
ddpfPixelFormat->dwGBitMask,
|
||||||
|
ddpfPixelFormat->dwBBitMask);
|
||||||
|
}
|
||||||
|
strcat(sBuf, sItem);
|
||||||
|
}
|
||||||
|
if (flags & DDPF_YUV) {
|
||||||
|
sprintf(sItem, " YUVA=(%x,%x,%x,%x)",
|
||||||
|
ddpfPixelFormat->dwYBitMask,
|
||||||
|
ddpfPixelFormat->dwUBitMask,
|
||||||
|
ddpfPixelFormat->dwVBitMask,
|
||||||
|
ddpfPixelFormat->dwYUVAlphaBitMask);
|
||||||
|
strcat(sBuf, sItem);
|
||||||
|
}
|
||||||
|
if (flags & DDPF_ZBUFFER) {
|
||||||
|
sprintf(sItem, " SdZSbL=(%x,%x,%x,%x)",
|
||||||
|
ddpfPixelFormat->dwStencilBitDepth,
|
||||||
|
ddpfPixelFormat->dwZBitMask,
|
||||||
|
ddpfPixelFormat->dwStencilBitMask,
|
||||||
|
ddpfPixelFormat->dwLuminanceAlphaBitMask);
|
||||||
|
strcat(sBuf, sItem);
|
||||||
|
}
|
||||||
|
if (flags & DDPF_ALPHA) {
|
||||||
|
sprintf(sItem, " LBdBlZ=(%x,%x,%x,%x)",
|
||||||
|
ddpfPixelFormat->dwLuminanceBitMask,
|
||||||
|
ddpfPixelFormat->dwBumpDvBitMask,
|
||||||
|
ddpfPixelFormat->dwBumpLuminanceBitMask,
|
||||||
|
ddpfPixelFormat->dwRGBZBitMask);
|
||||||
|
strcat(sBuf, sItem);
|
||||||
|
}
|
||||||
|
if (flags & DDPF_LUMINANCE) {
|
||||||
|
sprintf(sItem, " BMbMF=(%x,%x,%x,%x)",
|
||||||
|
ddpfPixelFormat->dwBumpDuBitMask,
|
||||||
|
ddpfPixelFormat->MultiSampleCaps.wBltMSTypes,
|
||||||
|
ddpfPixelFormat->MultiSampleCaps.wFlipMSTypes,
|
||||||
|
ddpfPixelFormat->dwYUVZBitMask);
|
||||||
|
strcat(sBuf, sItem);
|
||||||
|
}
|
||||||
|
if (flags & DDPF_BUMPDUDV) {
|
||||||
|
sprintf(sItem, " O=(%x)",
|
||||||
|
ddpfPixelFormat->dwOperations);
|
||||||
|
strcat(sBuf, sItem);
|
||||||
|
}
|
||||||
|
if (flags & DDPF_FOURCC) {
|
||||||
|
sprintf(sItem, " FourCC=%x(%s)",
|
||||||
|
ddpfPixelFormat->dwFourCC, sFourCC(ddpfPixelFormat->dwFourCC));
|
||||||
|
strcat(sBuf, sItem);
|
||||||
|
}
|
||||||
|
return sBuf;
|
||||||
|
}
|
||||||
|
|
||||||
int HookDirect3D7(HMODULE module, int version){
|
int HookDirect3D7(HMODULE module, int version){
|
||||||
void *tmp;
|
void *tmp;
|
||||||
HINSTANCE hinst;
|
HINSTANCE hinst;
|
||||||
@ -305,6 +395,7 @@ void HookDirect3DSession(LPDIRECTDRAW *lplpdd, int d3dversion)
|
|||||||
SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateViewport3, (void **)&pCreateViewport3, "CreateViewport(3)");
|
SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateViewport3, (void **)&pCreateViewport3, "CreateViewport(3)");
|
||||||
SetHook((void *)(**(DWORD **)lplpdd + 28), extFindDevice, (void **)&pFindDevice, "FindDevice");
|
SetHook((void *)(**(DWORD **)lplpdd + 28), extFindDevice, (void **)&pFindDevice, "FindDevice");
|
||||||
SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice3, (void **)&pCreateDevice3, "CreateDevice(D3D3)");
|
SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice3, (void **)&pCreateDevice3, "CreateDevice(D3D3)");
|
||||||
|
SetHook((void *)(**(DWORD **)lplpdd + 40), extEnumZBufferFormats, (void **)&pEnumZBufferFormats, "EnumZBufferFormats(D3D3)");
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)");
|
SetHook((void *)(**(DWORD **)lplpdd + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3S)");
|
||||||
@ -1420,3 +1511,30 @@ HRESULT WINAPI extTexUnload(void *t)
|
|||||||
if(ret) OutTraceE("Texture::Load ERROR res=%x(%s)\n", ret, ExplainDDError(ret));
|
if(ret) OutTraceE("Texture::Load ERROR res=%x(%s)\n", ret, ExplainDDError(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LPD3DENUMPIXELFORMATSCALLBACK *cb;
|
||||||
|
LPVOID arg;
|
||||||
|
} CallbackZBufArg;
|
||||||
|
|
||||||
|
HRESULT WINAPI extZBufferProxy(LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext)
|
||||||
|
{
|
||||||
|
HRESULT res;
|
||||||
|
OutTraceD3D("EnumZBufferFormats: CALLBACK PixelFormat=%x(%s) context=%x\n", lpDDPixFmt->dwFlags, lpContext);
|
||||||
|
res = (*(((CallbackZBufArg *)lpContext)->cb))(lpDDPixFmt, ((CallbackZBufArg *)lpContext)->arg);
|
||||||
|
OutTraceD3D("EnumDevices: CALLBACK ret=%x\n", res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI extEnumZBufferFormats(void *lpd3d, REFCLSID riidDevice, LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, LPVOID lpContext)
|
||||||
|
{
|
||||||
|
HRESULT ret;
|
||||||
|
CallbackZBufArg Arg;
|
||||||
|
OutTrace("Direct3D::EnumZBufferFormats d3d=%x clsid=%x context=%x\n", lpd3d, riidDevice.Data1, lpContext);
|
||||||
|
Arg.cb= &lpEnumCallback;
|
||||||
|
Arg.arg=lpContext;
|
||||||
|
ret = (*pEnumZBufferFormats)(lpd3d, riidDevice, (LPD3DENUMPIXELFORMATSCALLBACK)extZBufferProxy, (LPVOID)&Arg);
|
||||||
|
OutTraceE("Direct3D::EnumZBufferFormats res=%x(%s)\n", ret, ExplainDDError(ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -853,6 +853,9 @@ BOOL WINAPI extCreateProcessA(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
OutTrace("CreateProcess: injection started\n", res);
|
OutTrace("CreateProcess: injection started\n", res);
|
||||||
|
CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hProcess);
|
||||||
|
CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hThread);
|
||||||
|
CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hFile);
|
||||||
break;
|
break;
|
||||||
case EXIT_THREAD_DEBUG_EVENT:
|
case EXIT_THREAD_DEBUG_EVENT:
|
||||||
#ifdef LOCKINJECTIONTHREADS
|
#ifdef LOCKINJECTIONTHREADS
|
||||||
@ -881,8 +884,16 @@ BOOL WINAPI extCreateProcessA(
|
|||||||
debug_event.u.Exception.dwFirstChance);
|
debug_event.u.Exception.dwFirstChance);
|
||||||
// exception twice in same address, then do not continue.
|
// exception twice in same address, then do not continue.
|
||||||
if(LastExceptionPtr == ei->ExceptionRecord.ExceptionAddress) bContinueDebugging = FALSE;
|
if(LastExceptionPtr == ei->ExceptionRecord.ExceptionAddress) bContinueDebugging = FALSE;
|
||||||
|
//if(ei->dwFirstChance == 0) bContinueDebugging = FALSE;
|
||||||
LastExceptionPtr = ei->ExceptionRecord.ExceptionAddress;
|
LastExceptionPtr = ei->ExceptionRecord.ExceptionAddress;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case LOAD_DLL_DEBUG_EVENT:
|
||||||
|
CloseHandle(((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->hFile);
|
||||||
|
break;
|
||||||
|
case CREATE_THREAD_DEBUG_EVENT:
|
||||||
|
CloseHandle(((CREATE_THREAD_DEBUG_INFO *)&debug_event.u)->hThread);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include <windows.h>
|
|
||||||
#include <tlhelp32.h>
|
|
||||||
#include <shlwapi.h>
|
|
||||||
#include <conio.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <Winternl.h>
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
|
|
||||||
#define true 1
|
|
||||||
#define false 0
|
|
||||||
|
|
||||||
BOOL Inject(DWORD pID, const char * DLL_NAME)
|
|
||||||
{
|
|
||||||
HANDLE Proc;
|
|
||||||
char buf[50] = {0};
|
|
||||||
LPVOID RemoteString, LoadLibAddy;
|
|
||||||
if(!pID) return false;
|
|
||||||
//Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP
|
|
||||||
Proc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID);
|
|
||||||
if(!Proc)
|
|
||||||
{
|
|
||||||
sprintf(buf, "OpenProcess() failed: pid=%x err=%d", pID, GetLastError());
|
|
||||||
MessageBox(NULL, buf, "Loader", MB_OK);
|
|
||||||
printf(buf);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
|
|
||||||
// Allocate space in the process for our DLL
|
|
||||||
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
||||||
// Write the string name of our DLL in the memory allocated
|
|
||||||
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL);
|
|
||||||
// Load our DLL
|
|
||||||
CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL);
|
|
||||||
CloseHandle(Proc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STATUS_SUCCESS ((NTSTATUS)0x000 00000L)
|
|
||||||
#define ThreadQuerySetWin32StartAddress 9
|
|
||||||
|
|
||||||
LPVOID GetThreadStartAddress(HANDLE hThread)
|
|
||||||
{
|
|
||||||
NTSTATUS ntStatus;
|
|
||||||
HANDLE hDupHandle;
|
|
||||||
HMODULE hLibNTHandle;
|
|
||||||
LPVOID dwStartAddress;
|
|
||||||
|
|
||||||
typedef NTSTATUS (WINAPI *NtQueryInformationThread_Type)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG);
|
|
||||||
hLibNTHandle = GetModuleHandle("ntdll.dll");
|
|
||||||
if(!hLibNTHandle) return 0;
|
|
||||||
|
|
||||||
NtQueryInformationThread_Type NtQueryInformationThread =
|
|
||||||
(NtQueryInformationThread_Type)GetProcAddress(hLibNTHandle, "NtQueryInformationThread");
|
|
||||||
|
|
||||||
if(NtQueryInformationThread == NULL) return 0;
|
|
||||||
|
|
||||||
HANDLE hCurrentProcess = GetCurrentProcess();
|
|
||||||
if(!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){
|
|
||||||
SetLastError(ERROR_ACCESS_DENIED);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ntStatus = NtQueryInformationThread(hDupHandle, (THREADINFOCLASS)ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL);
|
|
||||||
CloseHandle(hDupHandle);
|
|
||||||
CloseHandle(hLibNTHandle);
|
|
||||||
//if(ntStatus != STATUS_SUCCESS) return 0;
|
|
||||||
|
|
||||||
return dwStartAddress;
|
|
||||||
}
|
|
BIN
host/Resource.h
BIN
host/Resource.h
Binary file not shown.
@ -32,6 +32,7 @@ void CTabDirectX::DoDataExchange(CDataExchange* pDX)
|
|||||||
DDX_Check(pDX, IDC_SUPPRESSCLIPPING, cTarget->m_SuppressClipping);
|
DDX_Check(pDX, IDC_SUPPRESSCLIPPING, cTarget->m_SuppressClipping);
|
||||||
DDX_Check(pDX, IDC_BLITFROMBACKBUFFER, cTarget->m_BlitFromBackBuffer);
|
DDX_Check(pDX, IDC_BLITFROMBACKBUFFER, cTarget->m_BlitFromBackBuffer);
|
||||||
DDX_Check(pDX, IDC_AUTOREFRESH, cTarget->m_AutoRefresh);
|
DDX_Check(pDX, IDC_AUTOREFRESH, cTarget->m_AutoRefresh);
|
||||||
|
DDX_Check(pDX, IDC_TEXTUREFORMAT, cTarget->m_TextureFormat);
|
||||||
DDX_Check(pDX, IDC_VIDEOTOSYSTEMMEM, cTarget->m_VideoToSystemMem);
|
DDX_Check(pDX, IDC_VIDEOTOSYSTEMMEM, cTarget->m_VideoToSystemMem);
|
||||||
DDX_Check(pDX, IDC_SUPPRESSDXERRORS, cTarget->m_SuppressDXErrors);
|
DDX_Check(pDX, IDC_SUPPRESSDXERRORS, cTarget->m_SuppressDXErrors);
|
||||||
DDX_Check(pDX, IDC_BACKBUFATTACH, cTarget->m_BackBufAttach);
|
DDX_Check(pDX, IDC_BACKBUFATTACH, cTarget->m_BackBufAttach);
|
||||||
|
@ -96,6 +96,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
|
|||||||
m_SuppressClipping = FALSE;
|
m_SuppressClipping = FALSE;
|
||||||
m_DisableGammaRamp = FALSE;
|
m_DisableGammaRamp = FALSE;
|
||||||
m_AutoRefresh = FALSE;
|
m_AutoRefresh = FALSE;
|
||||||
|
m_TextureFormat = FALSE;
|
||||||
m_FixWinFrame = FALSE;
|
m_FixWinFrame = FALSE;
|
||||||
m_EnableClipping = FALSE;
|
m_EnableClipping = FALSE;
|
||||||
m_CursorClipping = FALSE;
|
m_CursorClipping = FALSE;
|
||||||
|
@ -76,6 +76,7 @@ public:
|
|||||||
BOOL m_SuppressClipping;
|
BOOL m_SuppressClipping;
|
||||||
BOOL m_DisableGammaRamp;
|
BOOL m_DisableGammaRamp;
|
||||||
BOOL m_AutoRefresh;
|
BOOL m_AutoRefresh;
|
||||||
|
BOOL m_TextureFormat;
|
||||||
BOOL m_FixWinFrame;
|
BOOL m_FixWinFrame;
|
||||||
BOOL m_EnableClipping;
|
BOOL m_EnableClipping;
|
||||||
BOOL m_CursorClipping;
|
BOOL m_CursorClipping;
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -323,10 +323,6 @@
|
|||||||
RelativePath=".\host.rc"
|
RelativePath=".\host.rc"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\Inject.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\KillProc.cpp"
|
RelativePath=".\KillProc.cpp"
|
||||||
>
|
>
|
||||||
|
@ -35,7 +35,6 @@ TARGETMAP *pTargets; // idem.
|
|||||||
|
|
||||||
#define LOCKINJECTIONTHREADS
|
#define LOCKINJECTIONTHREADS
|
||||||
|
|
||||||
|
|
||||||
static char *Escape(char *s)
|
static char *Escape(char *s)
|
||||||
{
|
{
|
||||||
static char tmp[1024];
|
static char tmp[1024];
|
||||||
@ -276,6 +275,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
|
|||||||
if(dlg->m_SuppressClipping) t->flags |= SUPPRESSCLIPPING;
|
if(dlg->m_SuppressClipping) t->flags |= SUPPRESSCLIPPING;
|
||||||
if(dlg->m_DisableGammaRamp) t->flags2 |= DISABLEGAMMARAMP;
|
if(dlg->m_DisableGammaRamp) t->flags2 |= DISABLEGAMMARAMP;
|
||||||
if(dlg->m_AutoRefresh) t->flags |= AUTOREFRESH;
|
if(dlg->m_AutoRefresh) t->flags |= AUTOREFRESH;
|
||||||
|
if(dlg->m_TextureFormat) t->flags5 |= TEXTUREFORMAT;
|
||||||
if(dlg->m_FixWinFrame) t->flags |= FIXWINFRAME;
|
if(dlg->m_FixWinFrame) t->flags |= FIXWINFRAME;
|
||||||
if(dlg->m_EnableClipping) t->flags |= ENABLECLIPPING;
|
if(dlg->m_EnableClipping) t->flags |= ENABLECLIPPING;
|
||||||
if(dlg->m_CursorClipping) t->flags |= CLIPCURSOR;
|
if(dlg->m_CursorClipping) t->flags |= CLIPCURSOR;
|
||||||
@ -482,6 +482,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
|
|||||||
dlg->m_SuppressClipping = t->flags & SUPPRESSCLIPPING ? 1 : 0;
|
dlg->m_SuppressClipping = t->flags & SUPPRESSCLIPPING ? 1 : 0;
|
||||||
dlg->m_DisableGammaRamp = t->flags2 & DISABLEGAMMARAMP ? 1 : 0;
|
dlg->m_DisableGammaRamp = t->flags2 & DISABLEGAMMARAMP ? 1 : 0;
|
||||||
dlg->m_AutoRefresh = t->flags & AUTOREFRESH ? 1 : 0;
|
dlg->m_AutoRefresh = t->flags & AUTOREFRESH ? 1 : 0;
|
||||||
|
dlg->m_TextureFormat = t->flags5 & TEXTUREFORMAT ? 1 : 0;
|
||||||
dlg->m_FixWinFrame = t->flags & FIXWINFRAME ? 1 : 0;
|
dlg->m_FixWinFrame = t->flags & FIXWINFRAME ? 1 : 0;
|
||||||
dlg->m_EnableClipping = t->flags & ENABLECLIPPING ? 1 : 0;
|
dlg->m_EnableClipping = t->flags & ENABLECLIPPING ? 1 : 0;
|
||||||
dlg->m_CursorClipping = t->flags & CLIPCURSOR ? 1 : 0;
|
dlg->m_CursorClipping = t->flags & CLIPCURSOR ? 1 : 0;
|
||||||
@ -1673,6 +1674,38 @@ void CDxwndhostView::OnRButtonDown(UINT nFlags, CPoint point)
|
|||||||
CListView::OnRButtonDown(nFlags, point);
|
CListView::OnRButtonDown(nFlags, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *ExceptionCaption(DWORD ec)
|
||||||
|
{
|
||||||
|
char *c;
|
||||||
|
switch(ec){
|
||||||
|
case EXCEPTION_ACCESS_VIOLATION: c="Access Violation"; break;
|
||||||
|
case EXCEPTION_DATATYPE_MISALIGNMENT: c="Datatype Misalignment"; break;
|
||||||
|
case EXCEPTION_BREAKPOINT: c="Breakpoint"; break;
|
||||||
|
case EXCEPTION_SINGLE_STEP: c="Single Step"; break;
|
||||||
|
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: c="Array Bouds Exceeded"; break;
|
||||||
|
case EXCEPTION_FLT_DENORMAL_OPERAND: c="Float Denormal Operand"; break;
|
||||||
|
case EXCEPTION_FLT_DIVIDE_BY_ZERO: c="Divide by Zero"; break;
|
||||||
|
case EXCEPTION_FLT_INEXACT_RESULT: c="Inexact Result"; break;
|
||||||
|
case EXCEPTION_FLT_INVALID_OPERATION: c="Invalid Operation"; break;
|
||||||
|
case EXCEPTION_FLT_OVERFLOW: c="Float Overflow"; break;
|
||||||
|
case EXCEPTION_FLT_STACK_CHECK: c="Float Stack Check"; break;
|
||||||
|
case EXCEPTION_FLT_UNDERFLOW: c="Float Undeflow"; break;
|
||||||
|
case EXCEPTION_INT_DIVIDE_BY_ZERO: c="Integer Divide by Zero"; break;
|
||||||
|
case EXCEPTION_INT_OVERFLOW: c="Integer Overflow"; break;
|
||||||
|
case EXCEPTION_PRIV_INSTRUCTION: c="Priviliged Instruction"; break;
|
||||||
|
case EXCEPTION_IN_PAGE_ERROR: c="In Page Error"; break;
|
||||||
|
case EXCEPTION_ILLEGAL_INSTRUCTION: c="Illegal Instruction"; break;
|
||||||
|
case EXCEPTION_NONCONTINUABLE_EXCEPTION:c="Non-continuable exception"; break;
|
||||||
|
case EXCEPTION_STACK_OVERFLOW: c="Stack Overflow"; break;
|
||||||
|
case EXCEPTION_INVALID_DISPOSITION: c="Invalid Disposition"; break;
|
||||||
|
case EXCEPTION_GUARD_PAGE: c="Guard Page Violation"; break;
|
||||||
|
case EXCEPTION_INVALID_HANDLE: c="Invalid Handle"; break;
|
||||||
|
//case EXCEPTION_POSSIBLE_DEADLOCK: c="Possible Deadlock"; break;
|
||||||
|
default: c="unknown"; break;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
// For thread messaging
|
// For thread messaging
|
||||||
#define DEBUG_EVENT_MESSAGE WM_APP + 0x100
|
#define DEBUG_EVENT_MESSAGE WM_APP + 0x100
|
||||||
|
|
||||||
@ -1699,13 +1732,13 @@ DWORD WINAPI StartDebug(void *p)
|
|||||||
int res;
|
int res;
|
||||||
BOOL step=TRUE; // initialize to TRUE to enable
|
BOOL step=TRUE; // initialize to TRUE to enable
|
||||||
BOOL stepdll=FALSE; // initialize to TRUE to enable
|
BOOL stepdll=FALSE; // initialize to TRUE to enable
|
||||||
|
extern char *GetFileNameFromHandle(HANDLE);
|
||||||
#endif
|
#endif
|
||||||
#ifdef LOCKINJECTIONTHREADS
|
#ifdef LOCKINJECTIONTHREADS
|
||||||
DWORD StartingCode;
|
DWORD StartingCode;
|
||||||
LPVOID StartAddress = 0;
|
LPVOID StartAddress = 0;
|
||||||
DWORD TargetHandle = NULL;
|
HANDLE TargetHandle = NULL;
|
||||||
#endif
|
#endif
|
||||||
extern char *GetFileNameFromHandle(HANDLE);
|
|
||||||
bool bContinueDebugging;
|
bool bContinueDebugging;
|
||||||
char DebugMessage[256+1];
|
char DebugMessage[256+1];
|
||||||
|
|
||||||
@ -1728,30 +1761,12 @@ DWORD WINAPI StartDebug(void *p)
|
|||||||
while(bContinueDebugging)
|
while(bContinueDebugging)
|
||||||
{
|
{
|
||||||
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||||
if (!WaitForDebugEvent(&debug_event, INFINITE)) return TRUE;
|
if (!WaitForDebugEvent(&debug_event, INFINITE)) break; // must release pinfo handles
|
||||||
switch(debug_event.dwDebugEventCode){
|
switch(debug_event.dwDebugEventCode){
|
||||||
case EXIT_PROCESS_DEBUG_EVENT:
|
case EXIT_PROCESS_DEBUG_EVENT:
|
||||||
#ifdef DXWDEBUGSTEPPING
|
|
||||||
if(step){
|
|
||||||
// DXW_STRING_STEPPING
|
|
||||||
xpi=(EXIT_PROCESS_DEBUG_INFO *)&debug_event.u;
|
|
||||||
sprintf(DebugMessage, "EXIT PROCESS RetCode=%x", xpi->dwExitCode);
|
|
||||||
res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL);
|
|
||||||
if(res!=IDYES) step=FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bContinueDebugging=false;
|
bContinueDebugging=false;
|
||||||
break;
|
break;
|
||||||
case CREATE_PROCESS_DEBUG_EVENT:
|
case CREATE_PROCESS_DEBUG_EVENT:
|
||||||
#ifdef DXWDEBUGSTEPPING
|
|
||||||
if(step){
|
|
||||||
pi=(PROCESS_INFORMATION *)&debug_event.u;
|
|
||||||
sprintf(DebugMessage, "CREATE PROCESS hProcess=%x hThread=%x dwProcessId=%x dwThreadId=%x path=%s",
|
|
||||||
pi->hProcess, pi->hThread, pi->dwProcessId, pi->dwThreadId, GetFileNameFromHandle(pi->hProcess));
|
|
||||||
res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL);
|
|
||||||
if(res!=IDYES) step=FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
GetFullPathName("dxwnd.dll", MAX_PATH, path, NULL);
|
GetFullPathName("dxwnd.dll", MAX_PATH, path, NULL);
|
||||||
if(!Inject(pinfo.dwProcessId, path)){
|
if(!Inject(pinfo.dwProcessId, path)){
|
||||||
// DXW_STRING_INJECTION
|
// DXW_STRING_INJECTION
|
||||||
@ -1763,20 +1778,14 @@ DWORD WINAPI StartDebug(void *p)
|
|||||||
DWORD EndlessLoop;
|
DWORD EndlessLoop;
|
||||||
EndlessLoop=0x9090FEEB; // careful: it's BIG ENDIAN: EB FE 90 90
|
EndlessLoop=0x9090FEEB; // careful: it's BIG ENDIAN: EB FE 90 90
|
||||||
SIZE_T BytesCount;
|
SIZE_T BytesCount;
|
||||||
TargetHandle = (DWORD)OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pinfo.dwProcessId);
|
TargetHandle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pinfo.dwProcessId);
|
||||||
if(TargetHandle){
|
if(TargetHandle){
|
||||||
//sprintf(DebugMessage,"OpenProcess returns=%x", TargetHandle);
|
|
||||||
//MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
|
||||||
StartAddress = GetThreadStartAddress(pinfo.hThread);
|
StartAddress = GetThreadStartAddress(pinfo.hThread);
|
||||||
//sprintf(DebugMessage,"GetThreadStartAddress returns=%x", StartAddress);
|
|
||||||
//MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
|
||||||
if(StartAddress){
|
if(StartAddress){
|
||||||
if(!ReadProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){
|
if(!ReadProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){
|
||||||
sprintf(DebugMessage,"ReadProcessMemory error=%d", GetLastError());
|
sprintf(DebugMessage,"ReadProcessMemory error=%d", GetLastError());
|
||||||
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
||||||
}
|
}
|
||||||
//sprintf(DebugMessage,"ReadProcessMemory got=%x", StartingCode);
|
|
||||||
//MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
|
||||||
if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &EndlessLoop, 4, &BytesCount)){
|
if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &EndlessLoop, 4, &BytesCount)){
|
||||||
sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError());
|
sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError());
|
||||||
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
||||||
@ -1784,95 +1793,55 @@ DWORD WINAPI StartDebug(void *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hProcess);
|
||||||
|
CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hThread);
|
||||||
|
CloseHandle(((CREATE_PROCESS_DEBUG_INFO *)&debug_event.u)->hFile);
|
||||||
break;
|
break;
|
||||||
case CREATE_THREAD_DEBUG_EVENT:
|
case CREATE_THREAD_DEBUG_EVENT:
|
||||||
#ifdef DXWDEBUGSTEPPING
|
CloseHandle(((CREATE_THREAD_DEBUG_INFO *)&debug_event.u)->hThread);
|
||||||
if(step){
|
|
||||||
ti=(CREATE_THREAD_DEBUG_INFO *)&debug_event.u;
|
|
||||||
sprintf(DebugMessage, "CREATE THREAD hThread=%x lpThreadLocalBase=%x lpStartAddress=%x",
|
|
||||||
ti->hThread, ti->lpThreadLocalBase, ti->lpStartAddress);
|
|
||||||
res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL);
|
|
||||||
if(res!=IDYES) step=FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case EXIT_THREAD_DEBUG_EVENT:
|
case EXIT_THREAD_DEBUG_EVENT:
|
||||||
#ifdef DXWDEBUGSTEPPING
|
|
||||||
if(step){
|
|
||||||
xti=(EXIT_THREAD_DEBUG_INFO *)&debug_event.u;
|
|
||||||
sprintf(DebugMessage, "EXIT THREAD RetCode=%x", xti->dwExitCode);
|
|
||||||
res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL);
|
|
||||||
if(res!=IDYES) step=FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef LOCKINJECTIONTHREADS
|
#ifdef LOCKINJECTIONTHREADS
|
||||||
if(TargetHandle && StartAddress){
|
if(TargetHandle && StartAddress){
|
||||||
//sprintf(DebugMessage,"OpenProcess returns=%x", TargetHandle);
|
|
||||||
//MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
|
||||||
if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){
|
if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){
|
||||||
sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError());
|
sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError());
|
||||||
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
||||||
}
|
}
|
||||||
//sprintf(DebugMessage,"WriteProcessMemory recovered=%x", StartingCode);
|
|
||||||
//MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
|
||||||
CloseHandle((HANDLE)TargetHandle);
|
|
||||||
}
|
}
|
||||||
|
if(TargetHandle) CloseHandle((HANDLE)TargetHandle);
|
||||||
#endif
|
#endif
|
||||||
bContinueDebugging=false;
|
bContinueDebugging=false;
|
||||||
break;
|
break;
|
||||||
case LOAD_DLL_DEBUG_EVENT:
|
case LOAD_DLL_DEBUG_EVENT:
|
||||||
#ifdef DXWDEBUGSTEPPING
|
CloseHandle(((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->hFile);
|
||||||
if(stepdll){
|
|
||||||
li=(LOAD_DLL_DEBUG_INFO *)&debug_event.u;
|
|
||||||
sprintf(DebugMessage, "LOAD DLL hFile=%x path=%s",
|
|
||||||
li->hFile, GetFileNameFromHandle(li->hFile));
|
|
||||||
res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL);
|
|
||||||
if(res!=IDYES) stepdll=FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case UNLOAD_DLL_DEBUG_EVENT:
|
case UNLOAD_DLL_DEBUG_EVENT:
|
||||||
#ifdef DXWDEBUGSTEPPING
|
|
||||||
if(stepdll){
|
|
||||||
ui=(UNLOAD_DLL_DEBUG_INFO *)&debug_event.u;
|
|
||||||
sprintf(DebugMessage, "UNLOAD DLL Base=%x", ui->lpBaseOfDll);
|
|
||||||
res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL);
|
|
||||||
if(res!=IDYES) stepdll=FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case OUTPUT_DEBUG_STRING_EVENT:
|
case OUTPUT_DEBUG_STRING_EVENT:
|
||||||
break;
|
break;
|
||||||
case EXCEPTION_DEBUG_EVENT:
|
case EXCEPTION_DEBUG_EVENT:
|
||||||
#ifdef DXWDEBUGSTEPPING
|
//sprintf(DebugMessage, "Exception %x(%s) caught at addr=%x",
|
||||||
if(step){
|
// debug_event.u.Exception.ExceptionRecord.ExceptionCode,
|
||||||
ei=(EXCEPTION_DEBUG_INFO *)&debug_event.u;
|
// ExceptionCaption(debug_event.u.Exception.ExceptionRecord.ExceptionCode),
|
||||||
sprintf(DebugMessage, "EXCEPTION code=%x flags=%x addr=%x firstchance=%x",
|
// debug_event.u.Exception.ExceptionRecord.ExceptionAddress);
|
||||||
ei->ExceptionRecord.ExceptionCode,
|
//MessageBoxEx(0, DebugMessage, "EXCEPTION", MB_ICONEXCLAMATION, NULL);
|
||||||
ei->ExceptionRecord.ExceptionFlags,
|
|
||||||
ei->ExceptionRecord.ExceptionAddress,
|
|
||||||
debug_event.u.Exception.dwFirstChance);
|
|
||||||
res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL);
|
|
||||||
if(res!=IDYES) step=FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
sprintf(DebugMessage,"Unknown eventcode=%x", debug_event.dwDebugEventCode);
|
||||||
|
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(bContinueDebugging){
|
if(bContinueDebugging){
|
||||||
ContinueDebugEvent(debug_event.dwProcessId,
|
ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, dwContinueStatus);
|
||||||
debug_event.dwThreadId,
|
|
||||||
dwContinueStatus);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
DebugSetProcessKillOnExit(FALSE);
|
DebugSetProcessKillOnExit(FALSE);
|
||||||
ContinueDebugEvent(debug_event.dwProcessId,debug_event.dwThreadId, DBG_CONTINUE);
|
ContinueDebugEvent(debug_event.dwProcessId,debug_event.dwThreadId, DBG_CONTINUE);
|
||||||
DebugActiveProcessStop(debug_event.dwProcessId);
|
DebugActiveProcessStop(debug_event.dwProcessId);
|
||||||
if (pinfo.hProcess) CloseHandle(pinfo.hProcess);
|
|
||||||
if (pinfo.hThread) CloseHandle(pinfo.hThread);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CloseHandle(pinfo.hThread); // no longer needed, avoid handle leakage
|
||||||
|
CloseHandle(pinfo.hProcess); // no longer needed, avoid handle leakage
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1896,12 +1865,14 @@ void CDxwndhostView::OnRun()
|
|||||||
if(TargetMaps[i].flags2 & STARTDEBUG){
|
if(TargetMaps[i].flags2 & STARTDEBUG){
|
||||||
ThreadInfo.TM=&TargetMaps[i];
|
ThreadInfo.TM=&TargetMaps[i];
|
||||||
ThreadInfo.PM=&TitleMaps[i];
|
ThreadInfo.PM=&TitleMaps[i];
|
||||||
CreateThread( NULL, 0, StartDebug, &ThreadInfo, 0, NULL);
|
CloseHandle(CreateThread( NULL, 0, StartDebug, &ThreadInfo, 0, NULL));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
CreateProcess(NULL,
|
CreateProcess(NULL,
|
||||||
(strlen(TitleMaps[i].launchpath)>0) ? TitleMaps[i].launchpath: TargetMaps[i].path,
|
(strlen(TitleMaps[i].launchpath)>0) ? TitleMaps[i].launchpath: TargetMaps[i].path,
|
||||||
0, 0, false, CREATE_DEFAULT_ERROR_MODE, NULL, path, &sinfo, &pinfo);
|
0, 0, false, CREATE_DEFAULT_ERROR_MODE, NULL, path, &sinfo, &pinfo);
|
||||||
|
CloseHandle(pinfo.hProcess); // no longer needed, avoid handle leakage
|
||||||
|
CloseHandle(pinfo.hThread); // no longer needed, avoid handle leakage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
host/resource
BIN
host/resource
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user