1
0
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:
gho tik 2015-01-31 11:40:19 -05:00 committed by Refael ACkermann
parent 84e20e2ffb
commit bb0b5128e0
33 changed files with 837 additions and 583 deletions

View File

@ -122,7 +122,7 @@
#define DISABLEFOGGING 0x00000080 // Disable D3D fogging
#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 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 LIMITSCREENRES 0x00001000 // Limit available screen resolution up to defined maximum
#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 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 TEXTUREFORMAT 0x08000000 // Apply virtual pixel format to texture surfaces without DDSD_PIXELFORMAT attribute
// logging Tflags DWORD:
#define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4c798c0cff917a4dfb846882ff9d9ffc9cc2fcd747228487da1f88b8e58c5b74
size 563712
oid sha256:09c3405b326eb5eff358f5713b62cd1107c84ce64625529de44283cab2b64c9a
size 564224

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3a88f64a7bf93e63942698c78c94a1b57ab660eea0e6b2eaf8fdd2774c0ca0e3
size 536576
oid sha256:be381f4fba85d8c7dcb13682c470713728dd133b38e6d4d1ed65fc6ceb74e771
size 536064

View File

@ -1,11 +1,11 @@
[window]
posx=1227
posy=471
posx=50
posy=50
sizx=320
sizy=200
lang=default
;lang=automatic
;debug=1
debug=1
;multiprocesshook=0
;checkadmin=0
[texture]

View File

@ -5,11 +5,11 @@ module0=
opengllib0=
ver0=0
coord0=0
flag0=679477280
flag0=679477282
flagg0=1207959568
flagh0=20
flagi0=4
tflag0=259
flagi0=4194308
tflag0=0
initx0=0
inity0=0
minx0=0
@ -24,3 +24,6 @@ maxfps0=0
initts0=0
winver0=0
maxres0=0
launchpath0=
notes0=
flagj0=128

View File

@ -10,7 +10,7 @@ flag0=134217760
flagg0=1207959552
flagh0=65557
flagi0=69206020
tflag0=6211
tflag0=64
initx0=0
inity0=0
minx0=0
@ -25,3 +25,5 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
notes0=
flagj0=0

View 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

View 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 &amp; 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">&copy;&nbsp;2008 Wikisend - File Sharing. All rights reserved.</div>
</div></div></div>
<!-- ################# END FOOTER ################## -->
</body>
</html>

View File

@ -7,9 +7,9 @@ ver0=0
coord0=0
flag0=134217762
flagg0=1241513984
flagh0=25165844
flagi0=0
tflag0=323
flagh0=20
flagi0=4194304
tflag0=0
initx0=0
inity0=0
minx0=0
@ -22,5 +22,10 @@ sizx0=800
sizy0=600
maxfps0=0
initts0=0
launchpath0=
notes0=
flagj0=0
winver0=0
maxres0=0
; remember to set SW emulated mode in game setup panel

View File

@ -719,3 +719,9 @@ add: made check for admin rights configurable in dxwnd.ini
add: "portable" capability to configure relative pathnames
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

View File

@ -15,62 +15,41 @@
BOOL Inject(DWORD pID, const char * DLL_NAME)
{
HANDLE Proc;
HANDLE hProc, hThread;
HMODULE hLib;
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)
//hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP
hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID);
if(!hProc)
{
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
if(!CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL)){
hLib=GetModuleHandle("kernel32.dll");
LoadLibAddy = (LPVOID)GetProcAddress(hLib, "LoadLibraryA");
// Allocate space in the process for the DLL
RemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
// Write the string name of the DLL in the memory allocated
WriteProcessMemory(hProc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), 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());
MessageBox(NULL, buf, "Loader", MB_OK);
printf(buf);
CloseHandle(hProc);
return false;
}
CloseHandle(Proc);
CloseHandle(hThread);
CloseHandle(hProc);
CloseHandle(hLib);
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 ThreadQuerySetWin32StartAddress 9

366
dll/ddblit.cpp Normal file
View 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;
}

View File

@ -286,6 +286,8 @@ FARPROC Remap_ddraw_ProcAddress(LPCSTR proc, HMODULE hModule)
return NULL;
}
extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL);
/* ------------------------------------------------------------------------------ */
// auxiliary (static) functions
/* ------------------------------------------------------------------------------ */
@ -456,7 +458,7 @@ static void DumpSurfaceAttributes(LPDDSURFACEDESC lpddsd, char *label, int 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;
HRESULT res;
@ -1515,7 +1517,7 @@ static void HandleCapsD(char *sLabel, LPDDCAPS c)
HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2)
{
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);
if(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);
if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=dwVidMemTotal;
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);
@ -2127,6 +2133,7 @@ static void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion)
{
// rules of thumb:
// 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.
// 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
@ -2144,6 +2151,11 @@ static void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion)
lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
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;
}
@ -2375,7 +2387,7 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS
// create BackBuffer surface
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.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
@ -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....
if(dxw.dwFlags5 & NOSYSTEMMEMORY) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY;
DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]" , __LINE__);
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__);
ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
@ -2486,6 +2497,8 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf
OutTraceE("CreateSurface: ERROR on Emu_Generic res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;
}
DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]" , __LINE__);
OutTraceDW("CreateSurface: created Emu_Generic dds=%x\n", *lplpdds);
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(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) {
lpDDZBuffer=*lplpdds;
DDZBufferCaps = lpddsd->ddsCaps.dwCaps;
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);
if(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) {
lpDDZBuffer=*lplpdds;
DDZBufferCaps = lpddsd->ddsCaps.dwCaps;
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;
}
@ -2814,7 +2829,7 @@ HRESULT WINAPI extGetAttachedSurface7(LPDIRECTDRAWSURFACE lpdds, LPDDSCAPS lpdds
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);
if (res==DDERR_INVALIDRECT){
@ -2831,7 +2846,7 @@ static void BlitError(HRESULT res, LPRECT lps, LPRECT lpd, int line)
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;
WaitForSingleObject(hTraceMutex, INFINITE);
@ -3144,347 +3159,6 @@ HRESULT WINAPI ColorConversionDDRAW(LPDIRECTDRAWSURFACE lpdds, RECT emurect, LPD
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)
{
BOOL IsPrim;
@ -4582,7 +4256,7 @@ HRESULT WINAPI extEnumAttachedSurfaces(LPDIRECTDRAWSURFACE lpdds, LPVOID lpConte
HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddsadd)
{
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
// 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!
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...
res=(*pAddAttachedSurface)(lpdds, lpddsadd);
if (res) {
@ -4613,7 +4289,7 @@ HRESULT WINAPI extAddAttachedSurface(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURF
if (pAddRefS) (*pAddRefS)(lpdds);
res=DD_OK;
}
else if (lpdds == lpDDSBack) {
else if (IsBack) {
// v2.02.13: emulate ZBUFFER attach to backbuffer: do nothing and return OK
// this trick makes at least "Nocturne" work also in emulated mode when hardware acceleration
// is set in the game "Options" menu.

View File

@ -1413,6 +1413,7 @@ void dxwCore::ShowBanner(HWND hwnd)
RECT client;
RECT win;
POINT PrevViewPort;
int StretchMode;
hClientDC=(*pGDIGetDC)(hwnd);
(*pGetClientRect)(hwnd, &client);
@ -1432,6 +1433,8 @@ void dxwCore::ShowBanner(HWND hwnd)
//if(!pSetViewportOrgEx) pSetViewportOrgEx=SetViewportOrgEx;
(*pSetViewportOrgEx)(hClientDC, 0, 0, &PrevViewPort);
StretchMode=GetStretchBltMode(hClientDC);
SetStretchBltMode(hClientDC, HALFTONE);
for (int i=1; i<=16; i++){
int w, h;
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);
Sleep(40);
}
SetStretchBltMode(hClientDC, StretchMode);
(*pSetViewportOrgEx)(hClientDC, PrevViewPort.x, PrevViewPort.y, NULL);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);

Binary file not shown.

View File

@ -27,7 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "TlHelp32.h"
#define VERSION "2.03.08"
#define VERSION "2.03.09"
#define DDTHREADLOCK 1
//#define LOCKTHREADS
@ -176,7 +176,11 @@ int SetTarget(TARGETMAP *targets){
for(i = 0; targets[i].path[0]; i ++){
char *c;
pMapping[i] = targets[i];
GetFullPathName(targets[i].path, MAX_PATH, path, NULL);
c = targets[i].path;
if(*c == '*')
strcpy(path, targets[i].path);
else
GetFullPathName(targets[i].path, MAX_PATH, path, NULL);
for(c = path; *c; c++) *c = tolower(*c);
strcpy(pMapping[i].path, path);
}

View File

@ -1,8 +1,10 @@
LIBRARY dxwnd
EXPORTS
SetTarget @1
StartHook @2
EndHook @3
GetDllVersion @4
GetHookStatus @5
GetHookInfo @6
SetTarget @1
StartHook @2
EndHook @3
GetDllVersion @4
GetHookStatus @5
GetHookInfo @6
Inject @7
GetThreadStartAddress @8

Binary file not shown.

View File

@ -233,6 +233,10 @@
RelativePath=".\d3dtexture.cpp"
>
</File>
<File
RelativePath=".\ddblit.cpp"
>
</File>
<File
RelativePath=".\ddproxy.cpp"
>

View File

@ -40,6 +40,10 @@ void BlitToWindow(HWND w, LPDIRECTDRAWSURFACE s)
if(!ret) OutTrace("BitBlt error=%d\n", GetLastError());
}
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);
if(!ret) OutTrace("GDI StretchBlt error=%d\n", GetLastError());
}

View File

@ -1,5 +1,8 @@
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <d3d.h>
#include <stdio.h>
#include "dxwnd.h"
#include "dxwcore.hpp"
#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 *CreateDevice3_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE4, LPDIRECT3DDEVICE3 *, LPUNKNOWN);
typedef HRESULT (WINAPI *CreateDevice7_Type)(void *, REFCLSID, LPDIRECTDRAWSURFACE7, LPDIRECT3DDEVICE7 *);
typedef HRESULT (WINAPI *EnumZBufferFormats_Type)(void *, REFCLSID, LPD3DENUMPIXELFORMATSCALLBACK, LPVOID);
QueryInterfaceD3_Type pQueryInterfaceD3 = NULL;
Initialize_Type pInitialize = NULL;
@ -46,6 +50,9 @@ FindDevice_Type pFindDevice = NULL;
CreateDevice2_Type pCreateDevice2 = NULL;
CreateDevice3_Type pCreateDevice3 = NULL;
CreateDevice7_Type pCreateDevice7 = NULL;
EnumZBufferFormats_Type pEnumZBufferFormats = NULL;
HRESULT WINAPI extEnumZBufferFormats(void *, REFCLSID, LPD3DENUMPIXELFORMATSCALLBACK, LPVOID);
// Direct3DDevice-n interfaces
@ -216,6 +223,89 @@ HRESULT WINAPI extTexUnload(void *);
extern char *ExplainDDError(DWORD);
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){
void *tmp;
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 + 28), extFindDevice, (void **)&pFindDevice, "FindDevice");
SetHook((void *)(**(DWORD **)lplpdd + 32), extCreateDevice3, (void **)&pCreateDevice3, "CreateDevice(D3D3)");
SetHook((void *)(**(DWORD **)lplpdd + 40), extEnumZBufferFormats, (void **)&pEnumZBufferFormats, "EnumZBufferFormats(D3D3)");
break;
case 7:
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));
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;
}

View File

@ -853,6 +853,9 @@ BOOL WINAPI extCreateProcessA(
}
#endif
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;
case EXIT_THREAD_DEBUG_EVENT:
#ifdef LOCKINJECTIONTHREADS
@ -881,8 +884,16 @@ BOOL WINAPI extCreateProcessA(
debug_event.u.Exception.dwFirstChance);
// exception twice in same address, then do not continue.
if(LastExceptionPtr == ei->ExceptionRecord.ExceptionAddress) bContinueDebugging = FALSE;
//if(ei->dwFirstChance == 0) bContinueDebugging = FALSE;
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:
break;
}

View File

@ -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;
}

Binary file not shown.

View File

@ -32,6 +32,7 @@ void CTabDirectX::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_SUPPRESSCLIPPING, cTarget->m_SuppressClipping);
DDX_Check(pDX, IDC_BLITFROMBACKBUFFER, cTarget->m_BlitFromBackBuffer);
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_SUPPRESSDXERRORS, cTarget->m_SuppressDXErrors);
DDX_Check(pDX, IDC_BACKBUFATTACH, cTarget->m_BackBufAttach);

View File

@ -96,6 +96,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_SuppressClipping = FALSE;
m_DisableGammaRamp = FALSE;
m_AutoRefresh = FALSE;
m_TextureFormat = FALSE;
m_FixWinFrame = FALSE;
m_EnableClipping = FALSE;
m_CursorClipping = FALSE;

View File

@ -76,6 +76,7 @@ public:
BOOL m_SuppressClipping;
BOOL m_DisableGammaRamp;
BOOL m_AutoRefresh;
BOOL m_TextureFormat;
BOOL m_FixWinFrame;
BOOL m_EnableClipping;
BOOL m_CursorClipping;

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -323,10 +323,6 @@
RelativePath=".\host.rc"
>
</File>
<File
RelativePath=".\Inject.cpp"
>
</File>
<File
RelativePath=".\KillProc.cpp"
>

View File

@ -35,7 +35,6 @@ TARGETMAP *pTargets; // idem.
#define LOCKINJECTIONTHREADS
static char *Escape(char *s)
{
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_DisableGammaRamp) t->flags2 |= DISABLEGAMMARAMP;
if(dlg->m_AutoRefresh) t->flags |= AUTOREFRESH;
if(dlg->m_TextureFormat) t->flags5 |= TEXTUREFORMAT;
if(dlg->m_FixWinFrame) t->flags |= FIXWINFRAME;
if(dlg->m_EnableClipping) t->flags |= ENABLECLIPPING;
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_DisableGammaRamp = t->flags2 & DISABLEGAMMARAMP ? 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_EnableClipping = t->flags & ENABLECLIPPING ? 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);
}
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
#define DEBUG_EVENT_MESSAGE WM_APP + 0x100
@ -1699,13 +1732,13 @@ DWORD WINAPI StartDebug(void *p)
int res;
BOOL step=TRUE; // initialize to TRUE to enable
BOOL stepdll=FALSE; // initialize to TRUE to enable
extern char *GetFileNameFromHandle(HANDLE);
#endif
#ifdef LOCKINJECTIONTHREADS
DWORD StartingCode;
LPVOID StartAddress = 0;
DWORD TargetHandle = NULL;
HANDLE TargetHandle = NULL;
#endif
extern char *GetFileNameFromHandle(HANDLE);
bool bContinueDebugging;
char DebugMessage[256+1];
@ -1728,30 +1761,12 @@ DWORD WINAPI StartDebug(void *p)
while(bContinueDebugging)
{
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){
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;
break;
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);
if(!Inject(pinfo.dwProcessId, path)){
// DXW_STRING_INJECTION
@ -1763,20 +1778,14 @@ DWORD WINAPI StartDebug(void *p)
DWORD EndlessLoop;
EndlessLoop=0x9090FEEB; // careful: it's BIG ENDIAN: EB FE 90 90
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){
//sprintf(DebugMessage,"OpenProcess returns=%x", TargetHandle);
//MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
StartAddress = GetThreadStartAddress(pinfo.hThread);
//sprintf(DebugMessage,"GetThreadStartAddress returns=%x", StartAddress);
//MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
if(StartAddress){
if(!ReadProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){
sprintf(DebugMessage,"ReadProcessMemory error=%d", GetLastError());
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)){
sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError());
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
@ -1784,95 +1793,55 @@ DWORD WINAPI StartDebug(void *p)
}
}
#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;
case CREATE_THREAD_DEBUG_EVENT:
#ifdef DXWDEBUGSTEPPING
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
CloseHandle(((CREATE_THREAD_DEBUG_INFO *)&debug_event.u)->hThread);
break;
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
if(TargetHandle && StartAddress){
//sprintf(DebugMessage,"OpenProcess returns=%x", TargetHandle);
//MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){
sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError());
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
bContinueDebugging=false;
break;
case LOAD_DLL_DEBUG_EVENT:
#ifdef DXWDEBUGSTEPPING
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
CloseHandle(((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->hFile);
break;
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;
case OUTPUT_DEBUG_STRING_EVENT:
break;
case EXCEPTION_DEBUG_EVENT:
#ifdef DXWDEBUGSTEPPING
if(step){
ei=(EXCEPTION_DEBUG_INFO *)&debug_event.u;
sprintf(DebugMessage, "EXCEPTION code=%x flags=%x addr=%x firstchance=%x",
ei->ExceptionRecord.ExceptionCode,
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
//sprintf(DebugMessage, "Exception %x(%s) caught at addr=%x",
// debug_event.u.Exception.ExceptionRecord.ExceptionCode,
// ExceptionCaption(debug_event.u.Exception.ExceptionRecord.ExceptionCode),
// debug_event.u.Exception.ExceptionRecord.ExceptionAddress);
//MessageBoxEx(0, DebugMessage, "EXCEPTION", MB_ICONEXCLAMATION, NULL);
break;
default:
sprintf(DebugMessage,"Unknown eventcode=%x", debug_event.dwDebugEventCode);
MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL);
break;
}
if(bContinueDebugging){
ContinueDebugEvent(debug_event.dwProcessId,
debug_event.dwThreadId,
dwContinueStatus);
ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, dwContinueStatus);
}
else{
DebugSetProcessKillOnExit(FALSE);
ContinueDebugEvent(debug_event.dwProcessId,debug_event.dwThreadId, DBG_CONTINUE);
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;
}
@ -1896,12 +1865,14 @@ void CDxwndhostView::OnRun()
if(TargetMaps[i].flags2 & STARTDEBUG){
ThreadInfo.TM=&TargetMaps[i];
ThreadInfo.PM=&TitleMaps[i];
CreateThread( NULL, 0, StartDebug, &ThreadInfo, 0, NULL);
CloseHandle(CreateThread( NULL, 0, StartDebug, &ThreadInfo, 0, NULL));
}
else{
CreateProcess(NULL,
(strlen(TitleMaps[i].launchpath)>0) ? TitleMaps[i].launchpath: TargetMaps[i].path,
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
}
}

Binary file not shown.