1
0
mirror of https://github.com/DxWnd/DxWnd.reloaded synced 2024-12-30 09:25:35 +01:00

v2_02_87_src

Former-commit-id: 0ace3cadaa26eea269335760a9e5f36cae8d24ee
This commit is contained in:
gho tik 2014-07-28 12:39:37 -04:00 committed by Refael ACkermann
parent daa49a0521
commit 754d4ebe62
37 changed files with 867 additions and 113 deletions

View File

@ -146,6 +146,9 @@
#define OVERRIDEREGISTRY 0x40000000 // same as EMULATEREGISTRY, but fake keys takeprecedence
#define HIDECDROMEMPTY 0x80000000 // hide empty CDROM drivers
// fifth flags DWORD dxw.dwFlags5:
#define DIABLOTWEAK 0x00000001 // ... ??? ...
// logging Tflags DWORD:
#define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general
#define OUTDDRAWTRACE 0x00000002 // traces DxWnd directdraw screen handling
@ -176,6 +179,7 @@ typedef struct TARGETMAP
int flags2;
int flags3;
int flags4;
int flags5;
int tflags;
short initx;
short inity;
@ -285,3 +289,5 @@ typedef enum {
TIMER_TYPE_USER32,
TIMER_TYPE_WINMM
} Timer_Types;
#define CREATEDESKTOP FALSE

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c6ce831ba912fd0a77ada82ff268cc3c5cc5b143ceba47afa5e0788624735db6
oid sha256:782d53dad4046b681b15ecfbc8dd370c7a8097b7903daf63e4089c9b96916158
size 125952

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e39bc9f35955a42e51eccb033dbb72b802e4e0a91c62191beef0052f7f1d3d22
oid sha256:9ad4422aea023277c8d4310eb68782709f10d7567c8b12af62a30a32b3016c57
size 131072

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e4a8fde842a309899161df48662be08b6bf37c06b73f603cd9d199224e09ff82
oid sha256:ab41e49d035c39a3a88ce07e5900ea8b8e8768ad56749e8f06969b9df343374f
size 132096

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:560b196fd41dbbde675f2e6704d3c54299dd975d272960a9cee2b7ce33ea7dc8
size 495616
oid sha256:4f143e88ec5785fc2144af1a779b09b9e0791bf0e1e7d7050c1921d36284787e
size 501248

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c4f935425138f4ca43dedf590f0e046ccea571fc42e7620b6673226b6f2179f9
oid sha256:ad3ceed714b0d4f97f1187893964ff234e6c48de19bac84b66a1f25c9105088c
size 549376

View File

@ -2,6 +2,120 @@
sizx=320
sizy=200
lang=automatic
posx=50
posy=50
posx=1429
posy=317
[target]
title0=Age of Empires
path0=D:\Games\Age of Empires\Empires.exe
launchpath0=
module0=
opengllib0=
ver0=0
coord0=2
flag0=134217762
flagg0=1207959568
flagh0=20
flagi0=4195332
tflag0=6147
initx0=0
inity0=0
minx0=0
miny0=0
maxx0=0
maxy0=0
posx0=50
posy0=50
sizx0=800
sizy0=600
maxfps0=0
initts0=0
winver0=0
maxres0=-1
title1=Diablo
path1=D:\Games\Diablo\Diablo.exe
launchpath1=
module1=
opengllib1=
ver1=1
coord1=3
flag1=138428450
flagg1=1242562576
flagh1=20
flagi1=4195328
tflag1=0
initx1=0
inity1=0
minx1=0
miny1=0
maxx1=0
maxy1=0
posx1=50
posy1=50
sizx1=640
sizy1=480
maxfps1=0
initts1=0
winver1=0
maxres1=0
title2=Dune 2000
path2=D:\Games\Dune 2000\DUNE2000.DAT
launchpath2=D:\Games\Dune 2000\DUNE2000.EXE
module2=
opengllib2=
ver2=0
coord2=2
flag2=671105058
flagg2=1207959568
flagh2=20
flagi2=4195332
tflag2=64
initx2=0
inity2=0
minx2=0
miny2=0
maxx2=0
maxy2=0
posx2=50
posy2=50
sizx2=800
sizy2=600
maxfps2=0
initts2=0
winver2=0
maxres2=-1
title3=Genocide (REMIXED VERSION)
path3=D:\Games\genocide\remixed version (1999)\genocide\genocide.exe
launchpath3=
module3=
opengllib3=
ver3=0
coord3=3
flag3=134217762
flagg3=1207959568
flagh3=20
flagi3=4195332
tflag3=6402
initx3=0
inity3=0
minx3=0
miny3=0
maxx3=0
maxy3=0
posx3=50
posy3=50
sizx3=800
sizy3=600
maxfps3=0
initts3=0
winver3=0
maxres3=-1
title4=Dune 2000
module4=
opengllib4=
title5=Genocide (REMIXED VERSION)
module5=
opengllib5=
flagj0=0
flagj1=1
flagj2=0
flagj3=0

View File

@ -1,5 +1,5 @@
[window]
posx=1547
posy=779
posx=1392
posy=385
sizx=320
sizy=200

View File

@ -556,4 +556,16 @@ fix: added recovery for rounded child win coordinates: fixes blitting problems i
v2.02.86
fix: thank to aqrit's research, hooked and hanlded user32.dll GetUpdateRgn API. This fixes refresh and crash problems in Diablo & Hellfire.
added bilinear filtering to directdraw palettized 8BPP emulated mode (where it is mostly needed!). A must try is "Genocide" !
added bilinear filtering to directdraw palettized 8BPP emulated mode (where it is mostly needed!). A must try is "Genocide" !
v2.02.87
attempt to fix Win8 missing support for earlier ddraw releases (Croc legend of the Gobbos, Project I.G.I., ...)
fix: optimized bilinear filtering with no horizontal / vertical sawtooth artifacts
added support for 16BPP and 32BPP desktop bilinear filtering
suppressed compatibility checking
fix: doubled default window size when bilinear filtering is active
added repositioning of control parent window when main win is moved
added debug messages about hooked window class and name
fix: ignore IME window when hooking main win, destroy it when requested
fix: ignore HWND_MESSAGE type windows
added "Diablo tweak" compatibility flag for Diablo proper screen update handling. It is a temporary tweak waiting to understand better how to properly manage it.

View File

@ -293,11 +293,18 @@ int iRefreshDelayCount=2;
void SetVSyncDelays(LPDIRECTDRAW lpdd)
{
DDSURFACEDESC ddsdRefreshRate;
DDSURFACEDESC2 ddsdRefreshRate;
int Reminder;
HRESULT res;
memset(&ddsdRefreshRate, 0, sizeof(ddsdRefreshRate));
ddsdRefreshRate.dwSize = sizeof(ddsdRefreshRate);
(*pGetDisplayMode)(lpdd, &ddsdRefreshRate);
ddsdRefreshRate.dwSize = sizeof(DDSURFACEDESC);
res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsdRefreshRate);
if(res==DDERR_GENERIC){ // handling Win8 missing support for old ddraw interface
ddsdRefreshRate.dwSize = sizeof(DDSURFACEDESC2);
res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsdRefreshRate);
}
if(res) return;
gdwRefreshRate = ddsdRefreshRate.dwRefreshRate;
if(!gdwRefreshRate) return;
iRefreshDelayCount=0;
@ -533,9 +540,14 @@ void mySetPalette(int dwstart, int dwcount, LPPALETTEENTRY lpentries)
void InitDDScreenParameters(LPDIRECTDRAW lpdd)
{
HRESULT res;
DDSURFACEDESC ddsd;
DDSURFACEDESC2 ddsd;
ddsd.dwSize=sizeof(DDSURFACEDESC);
if(res=(*pGetDisplayMode)(lpdd, &ddsd)){
res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd);
if(res==DDERR_GENERIC){ // Win8 missing support for old ddraw interfaces
ddsd.dwSize=sizeof(DDSURFACEDESC2);
res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd);
}
if(res){
OutTraceE("GetDisplayMode: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return;
}
@ -1905,7 +1917,11 @@ HRESULT WINAPI extSetDisplayMode(int version, LPDIRECTDRAW lpdd,
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_REFRESHRATE;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd);
res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd);
if(res==DDERR_GENERIC){ // handling Win8 missing support for old ddraw interface
ddsd.dwSize = sizeof(DDSURFACEDESC2);
res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&ddsd);
}
if(dxw.Windowize){
if(!IsChangeDisplaySettingsHotPatched){
@ -4176,6 +4192,10 @@ HRESULT WINAPI extEnumDisplayModes(EnumDisplayModes1_Type pEnumDisplayModes, LPD
memset(&EmuDesc, 0, sizeof(EmuDesc));
EmuDesc.dwSize = sizeof(DDSURFACEDESC); // using release 1 type ....
res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&EmuDesc);
if(res==DDERR_GENERIC){ // Win8 missing support for old ddraw interface
EmuDesc.dwSize = sizeof(DDSURFACEDESC2); // using release 2 type ....
res=(*pGetDisplayMode)(lpdd, (LPDDSURFACEDESC)&EmuDesc);
}
if(res){
OutTraceE("GetDisplayMode(D): ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;

View File

@ -63,6 +63,74 @@ static void MarkRect16(SHORT *dest, int w, int h, int destpitch)
return;
}
static DWORD Melt32(DWORD c1, DWORD c2)
{
DWORD ret;
ret =
((((c1 & 0x0000FF) + (c2 & 0x0000FF)) >> 1) & 0x0000FF) |
((((c1 & 0x00FF00) + (c2 & 0x00FF00)) >> 1) & 0x00FF00) |
((((c1 & 0xFF0000) + (c2 & 0xFF0000)) >> 1) & 0xFF0000);
return ret;
}
static DWORD Melt16_555(DWORD c1, DWORD c2)
{
DWORD ret;
ret =
((((c1 & 0x00001F) + (c2 & 0x00001F)) >> 1) & 0x00001F) |
((((c1 & 0x0003E0) + (c2 & 0x0003E0)) >> 1) & 0x0003E0) |
((((c1 & 0x007C00) + (c2 & 0x007C00)) >> 1) & 0x007C00);
return ret;
}
static DWORD Melt16_565(DWORD c1, DWORD c2)
{
DWORD ret;
ret =
((((c1 & 0x00001F) + (c2 & 0x00001F)) >> 1) & 0x00001F) |
((((c1 & 0x0007E0) + (c2 & 0x0007E0)) >> 1) & 0x0007E0) |
((((c1 & 0x00F800) + (c2 & 0x00F800)) >> 1) & 0x00F800);
return ret;
}
static void SetPalette16BPP()
{
// OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src16,dest,srcpitch,destpitch);
unsigned int pi;
Palette16BPP = (DWORD *)malloc(0x10000 * sizeof(DWORD));
if (dxw.dwFlags3 & BLACKWHITE){
// actually, it should be like this: R/G/B = (red * 0.30) + (green * 0.59) + (blue * 0.11)
// (http://www.codeproject.com/Articles/66253/Converting-Colors-to-Gray-Shades)
DWORD grey;
if (dxw.dwFlags1 & USERGB565){
for (pi=0; pi<0x10000; pi++) {
//grey = ((((pi & 0x1F)<<3) + ((pi & 0x7E0)>>3) + ((pi & 0xF800)>>8)) / 3) & 0xFF;
grey = (((((pi & 0x1F)<<3) * 30) + (((pi & 0x7E0)>>3) * 59) + (((pi & 0xF800)>>8) * 11)) / 100) & 0xFF;
Palette16BPP[pi] = (grey) + (grey<<8) + (grey<<16);
}
}
else {
for (pi=0; pi<0x10000; pi++) {
//grey = ((((pi & 0x1F)<<3) + ((pi & 0x3E0)>>2) + ((pi & 0x7C00)>>7)) / 3) & 0xFF;
grey = (((((pi & 0x1F)<<3) * 30) + (((pi & 0x3E0)>>2) * 59) + (((pi & 0x7C00)>>7) * 11)) / 100) & 0xFF;
Palette16BPP[pi] = grey + (grey<<8) + (grey<<16);
}
}
}
else {
if (dxw.dwFlags1 & USERGB565){
for (pi=0; pi<0x10000; pi++) {
Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x7E0)<<5 | (pi & 0xF800)<<8; // RGB565
}
}
else {
for (pi=0; pi<0x10000; pi++) {
Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x3E0)<<6 | (pi & 0x7C00)<<9; // RGB555
}
}
}
}
static HRESULT WINAPI EmuBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
@ -134,19 +202,6 @@ static HRESULT WINAPI EmuBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdest
return res;
}
static DWORD Melt(DWORD c1, DWORD c2)
{
DWORD ret;
register BYTE *b1 = (BYTE *)&c1;
register BYTE *b2 = (BYTE *)&c2;
register BYTE *br = (BYTE *)&ret;
//for(int i=0; i<4; i++)
*br++ = (*(b1++)>>1) + (*(b2++)>>1);
*br++ = (*(b1++)>>1) + (*(b2++)>>1);
*br++ = (*(b1++)>>1) + (*(b2++)>>1);
return ret;
}
static HRESULT WINAPI BilinearBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
@ -206,30 +261,38 @@ static HRESULT WINAPI BilinearBlt_8_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT l
srcpitch = ddsd_src.lPitch - w;
// OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src8,dest,srcpitch,destpitch);
for(y = 0; y < h; y ++){
BYTE *begin = src8;
for(x = 0; x < w; x ++){
*(dest ++) = PaletteEntries[*(src8)];
*(dest ++) = Melt(PaletteEntries[*(src8)], PaletteEntries[*(src8+1)]);
for(y = 0; y < h-1; y ++){ // first h-1 lines ....
register DWORD Q1, Q2, Q3, Q4, Q5;
Q5 = Melt32(PaletteEntries[*(src8)], PaletteEntries[*(src8+ddsd_src.lPitch)]);
for(x = 0; x < w; x ++){
Q1 = PaletteEntries[*(src8)];
Q2 = Melt32(Q1, PaletteEntries[*(src8+1)]);
Q3 = Q5;
Q5 = Melt32(PaletteEntries[*(src8+1)], PaletteEntries[*(src8+ddsd_src.lPitch+1)]); // to be used in next for cycle
Q4 = Melt32(Q3, Q5);
*(dest) = Q1;
*(dest+1) = Q2;
*(dest+ddsd_dst.lPitch) = Q3;
*(dest+ddsd_dst.lPitch+1) = Q4;
src8++;
}
src8 = begin;
dest += destpitch;
if(y+1 == h)
for(x = 0; x < w; x ++){ // last line, duplicate the line above
*(dest ++) = PaletteEntries[*(src8)];
*(dest ++) = Melt(PaletteEntries[*(src8)], PaletteEntries[*(src8+1)]);
src8++;
}
else
for(x = 0; x < w; x ++){
*(dest ++) = Melt(PaletteEntries[*(src8)], PaletteEntries[*(src8+w)]);
*(dest ++) = Melt(PaletteEntries[*(src8+1)], PaletteEntries[*(src8+w)]);
src8++;
}
src8 += srcpitch;
dest += destpitch;
dest+=2;
}
src8 += srcpitch;
dest += (ddsd_dst.lPitch + destpitch);
}
for(x = 0; x < w; x ++){ // last line (there's no next line to melt...)
register DWORD Q1, Q2;
Q1 = PaletteEntries[*(src8)];
Q2 = Melt32(Q1, PaletteEntries[*(src8+1)]);
*(dest) = Q1;
*(dest+1) = Q2;
*(dest+ddsd_dst.lPitch) = Q1;
*(dest+ddsd_dst.lPitch+1) = Q2;
src8++;
dest+=2;
}
if(dxw.dwFlags3 & MARKBLIT) MarkRect32(dest0, w, h, destpitch);
@ -294,42 +357,8 @@ static HRESULT WINAPI EmuBlt_16_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes
src16 += lpsrcrect->left;
srcpitch = ddsd_src.lPitch - w;
// OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src16,dest,srcpitch,destpitch);
if (!Palette16BPP) { // first time through .....
unsigned int pi;
Palette16BPP = (DWORD *)malloc(0x10000 * sizeof(DWORD));
if (dxw.dwFlags3 & BLACKWHITE){
// actually, it should be like this: R/G/B = (red * 0.30) + (green * 0.59) + (blue * 0.11)
// (http://www.codeproject.com/Articles/66253/Converting-Colors-to-Gray-Shades)
DWORD grey;
if (dxw.dwFlags1 & USERGB565){
for (pi=0; pi<0x10000; pi++) {
//grey = ((((pi & 0x1F)<<3) + ((pi & 0x7E0)>>3) + ((pi & 0xF800)>>8)) / 3) & 0xFF;
grey = (((((pi & 0x1F)<<3) * 30) + (((pi & 0x7E0)>>3) * 59) + (((pi & 0xF800)>>8) * 11)) / 100) & 0xFF;
Palette16BPP[pi] = (grey) + (grey<<8) + (grey<<16);
}
}
else {
for (pi=0; pi<0x10000; pi++) {
//grey = ((((pi & 0x1F)<<3) + ((pi & 0x3E0)>>2) + ((pi & 0x7C00)>>7)) / 3) & 0xFF;
grey = (((((pi & 0x1F)<<3) * 30) + (((pi & 0x3E0)>>2) * 59) + (((pi & 0x7C00)>>7) * 11)) / 100) & 0xFF;
Palette16BPP[pi] = grey + (grey<<8) + (grey<<16);
}
}
}
else {
if (dxw.dwFlags1 & USERGB565){
for (pi=0; pi<0x10000; pi++) {
Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x7E0)<<5 | (pi & 0xF800)<<8; // RGB565
}
}
else {
for (pi=0; pi<0x10000; pi++) {
Palette16BPP[pi]=(pi & 0x1F)<<3 | (pi & 0x3E0)<<6 | (pi & 0x7C00)<<9; // RGB555
}
}
}
}
if (!Palette16BPP) SetPalette16BPP();
for(y = 0; y < h; y ++){
for(x = 0; x < w; x ++){
//if (!(*src16 & 0x8000)) // try implement alpha bit
@ -348,6 +377,110 @@ static HRESULT WINAPI EmuBlt_16_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes
return res;
}
static HRESULT WINAPI BilinearBlt_16_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
HRESULT res;
WORD *src16;
DWORD *dest, *dest0;
DDSURFACEDESC2 ddsd_src, ddsd_dst;
long srcpitch, destpitch;
DWORD x, y, w, h;
w = lpdestrect->right - lpdestrect->left;
h = lpdestrect->bottom - lpdestrect->top;
lpdestrect->left <<= 1;
lpdestrect->top <<= 1;
lpdestrect->right <<= 1;
lpdestrect->bottom <<= 1;
memset(&ddsd_dst,0,sizeof(DDSURFACEDESC2));
ddsd_dst.dwSize = Set_dwSize_From_Surface(lpddsdst);
ddsd_dst.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
if(res=(*pLock)(lpddsdst, 0, (LPDDSURFACEDESC)&ddsd_dst, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){
OutTraceE("BilBlt16_32: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;
}
memset(&ddsd_src,0,sizeof(DDSURFACEDESC2));
ddsd_src.dwSize = Set_dwSize_From_Surface(lpddssrc);
ddsd_src.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
if (lpsurface) { // already locked, just get info ....
if(res=lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd_src)) {
OutTraceE("BilBlt16_32: GetSurfaceDesc ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect);
(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect);
return 0;
}
}
else {
if(res=(*pLock)(lpddssrc, 0, (LPDDSURFACEDESC)&ddsd_src, DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY|DDLOCK_WAIT, 0)) {
(*pUnlockMethod(lpddsdst))(lpddsdst,0);
OutTraceE("BilBlt16_32: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;
}
lpsurface=ddsd_src.lpSurface;
}
ddsd_dst.lPitch >>= 2;
dest = (DWORD *)ddsd_dst.lpSurface;
dest += lpdestrect->top*ddsd_dst.lPitch;
dest += lpdestrect->left;
destpitch = ddsd_dst.lPitch - (2 * w);
dest0 = dest;
ddsd_src.lPitch >>= 1;
src16 = (WORD *)(lpsurface ? lpsurface:ddsd_src.lpSurface);
src16 += lpsrcrect->top*ddsd_src.lPitch;
src16 += lpsrcrect->left;
srcpitch = ddsd_src.lPitch - w;
if (!Palette16BPP) SetPalette16BPP();
// OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src8,dest,srcpitch,destpitch);
for(y = 0; y < h-1; y ++){ // first h-1 lines ....
register DWORD Q1, Q2, Q3, Q4, Q5;
Q5 = Melt32(Palette16BPP[*(src16)], Palette16BPP[*(src16+ddsd_src.lPitch)]);
for(x = 0; x < w; x ++){
Q1 = Palette16BPP[*(src16)];
Q2 = Melt32(Q1, Palette16BPP[*(src16+1)]);
Q3 = Q5;
Q5 = Melt32(Palette16BPP[*(src16+1)], Palette16BPP[*(src16+ddsd_src.lPitch+1)]); // to be used in next for cycle
Q4 = Melt32(Q3, Q5);
*(dest) = Q1;
*(dest+1) = Q2;
*(dest+ddsd_dst.lPitch) = Q3;
*(dest+ddsd_dst.lPitch+1) = Q4;
src16++;
dest+=2;
}
src16 += srcpitch;
dest += (ddsd_dst.lPitch + destpitch);
}
for(x = 0; x < w; x ++){ // last line (there's no next line to melt...)
register DWORD Q1, Q2;
Q1 = Palette16BPP[*(src16)];
Q2 = Melt32(Q1, Palette16BPP[*(src16+1)]);
*(dest) = Q1;
*(dest+1) = Q2;
*(dest+ddsd_dst.lPitch) = Q1;
*(dest+ddsd_dst.lPitch+1) = Q2;
src16++;
dest+=2;
}
if(dxw.dwFlags3 & MARKBLIT) MarkRect32(dest0, w, h, destpitch);
res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect);
if (res) OutTraceE("BilBlt16_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__);
res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect);
if (res) OutTraceE("BilBlt16_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__);
return res;
}
static HRESULT WINAPI EmuBlt_24_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
@ -569,6 +702,110 @@ static HRESULT WINAPI EmuBlt_8_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdest
return res;
}
static HRESULT WINAPI BilinearBlt_8_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
HRESULT res;
BYTE *src8;
SHORT *dest, *dest0;
DDSURFACEDESC2 ddsd_src, ddsd_dst;
long srcpitch, destpitch;
DWORD x, y, w, h;
typedef DWORD (*Melt16_Type)(DWORD, DWORD);
Melt16_Type Melt16;
w = lpdestrect->right - lpdestrect->left;
h = lpdestrect->bottom - lpdestrect->top;
lpdestrect->left <<= 1;
lpdestrect->top <<= 1;
lpdestrect->right <<= 1;
lpdestrect->bottom <<= 1;
memset(&ddsd_dst,0,sizeof(DDSURFACEDESC2));
ddsd_dst.dwSize = Set_dwSize_From_Surface(lpddsdst);
ddsd_dst.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
if(res=(*pLock)(lpddsdst, 0, (LPDDSURFACEDESC)&ddsd_dst, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){
OutTraceE("BilBlt8_16: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;
}
Melt16 = (ddsd_dst.ddpfPixelFormat.dwGBitMask == 0x3E0) ? Melt16_555 : Melt16_565;
memset(&ddsd_src,0,sizeof(DDSURFACEDESC2));
ddsd_src.dwSize = Set_dwSize_From_Surface(lpddssrc);
ddsd_src.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
if (lpsurface) { // already locked, just get info ....
if(res=lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd_src)) {
OutTraceE("BilBlt8_16: GetSurfaceDesc ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect);
(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect);
return 0;
}
}
else {
if(res=(*pLock)(lpddssrc, 0, (LPDDSURFACEDESC)&ddsd_src, DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY, 0)) {
(*pUnlockMethod(lpddsdst))(lpddsdst,0);
OutTraceE("BilBlt8_16: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return 0;
}
lpsurface=ddsd_src.lpSurface;
}
ddsd_dst.lPitch >>= 1;
dest = (SHORT *)ddsd_dst.lpSurface;
dest += lpdestrect->top*ddsd_dst.lPitch;
dest += lpdestrect->left;
destpitch = ddsd_dst.lPitch - (2 * w);
dest0 = dest;
src8 = (BYTE *)lpsurface;
src8 += lpsrcrect->top*ddsd_src.lPitch;
src8 += lpsrcrect->left;
srcpitch = ddsd_src.lPitch - w;
// OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src8,dest,srcpitch,destpitch);
for(y = 0; y < h-1; y ++){ // first h-1 lines ....
register DWORD Q1, Q2, Q3, Q4, Q5;
Q5 = Melt16(PaletteEntries[*(src8)], PaletteEntries[*(src8+ddsd_src.lPitch)]);
for(x = 0; x < w; x ++){
Q1 = PaletteEntries[*(src8)];
Q2 = Melt16(Q1, PaletteEntries[*(src8+1)]);
Q3 = Q5;
Q5 = Melt16(PaletteEntries[*(src8+1)], PaletteEntries[*(src8+ddsd_src.lPitch+1)]); // to be used in next for cycle
Q4 = Melt16(Q3, Q5);
*(dest) = (SHORT)Q1;
*(dest+1) = (SHORT)Q2;
*(dest+ddsd_dst.lPitch) = (SHORT)Q3;
*(dest+ddsd_dst.lPitch+1) = (SHORT)Q4;
src8++;
dest+=2;
}
src8 += srcpitch;
dest += (ddsd_dst.lPitch + destpitch);
}
for(x = 0; x < w; x ++){ // last line (there's no next line to melt...)
register DWORD Q1, Q2;
Q1 = PaletteEntries[*(src8)];
Q2 = Melt16(Q1, PaletteEntries[*(src8+1)]);
*(dest) = (SHORT)Q1;
*(dest+1) = (SHORT)Q2;
*(dest+ddsd_dst.lPitch) = (SHORT)Q1;
*(dest+ddsd_dst.lPitch+1) = (SHORT)Q2;
src8++;
dest+=2;
}
if(dxw.dwFlags3 & MARKBLIT) MarkRect16(dest0, w, h, destpitch);
res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect);
if (res) OutTraceE("BilBlt8_16: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__);
res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect);
if (res) OutTraceE("BilBlt8_16: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__);
return res;
}
static HRESULT WINAPI EmuBlt_16_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
@ -581,6 +818,113 @@ static HRESULT WINAPI EmuBlt_16_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes
#endif
}
static HRESULT WINAPI BilinearBlt_16_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
HRESULT res;
WORD *src16;
WORD *dest, *dest0;
DDSURFACEDESC2 ddsd_src, ddsd_dst;
long srcpitch, destpitch;
DWORD x, y, w, h;
typedef DWORD (*Melt16_Type)(DWORD, DWORD);
Melt16_Type Melt16;
w = lpdestrect->right - lpdestrect->left;
h = lpdestrect->bottom - lpdestrect->top;
lpdestrect->left <<= 1;
lpdestrect->top <<= 1;
lpdestrect->right <<= 1;
lpdestrect->bottom <<= 1;
memset(&ddsd_dst,0,sizeof(DDSURFACEDESC2));
ddsd_dst.dwSize = Set_dwSize_From_Surface(lpddsdst);
ddsd_dst.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
if(res=(*pLock)(lpddsdst, 0, (LPDDSURFACEDESC)&ddsd_dst, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){
OutTraceE("BilBlt16_16: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;
}
Melt16 = (ddsd_dst.ddpfPixelFormat.dwGBitMask == 0x3E0) ? Melt16_555 : Melt16_565;
memset(&ddsd_src,0,sizeof(DDSURFACEDESC2));
ddsd_src.dwSize = Set_dwSize_From_Surface(lpddssrc);
ddsd_src.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
if (lpsurface) { // already locked, just get info ....
if(res=lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd_src)) {
OutTraceE("BilBlt16_16: GetSurfaceDesc ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect);
(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect);
return 0;
}
}
else {
if(res=(*pLock)(lpddssrc, 0, (LPDDSURFACEDESC)&ddsd_src, DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY|DDLOCK_WAIT, 0)) {
(*pUnlockMethod(lpddsdst))(lpddsdst,0);
OutTraceE("BilBlt16_16: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;
}
lpsurface=ddsd_src.lpSurface;
}
ddsd_dst.lPitch >>= 1;
dest = (WORD *)ddsd_dst.lpSurface;
dest += lpdestrect->top*ddsd_dst.lPitch;
dest += lpdestrect->left;
destpitch = ddsd_dst.lPitch - (2 * w);
dest0 = dest;
ddsd_src.lPitch >>= 1;
src16 = (WORD *)(lpsurface ? lpsurface:ddsd_src.lpSurface);
src16 += lpsrcrect->top*ddsd_src.lPitch;
src16 += lpsrcrect->left;
srcpitch = ddsd_src.lPitch - w;
// OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src8,dest,srcpitch,destpitch);
for(y = 0; y < h-1; y ++){ // first h-1 lines ....
register DWORD Q1, Q2, Q3, Q4, Q5;
Q5 = Melt16(*(src16), *(src16+ddsd_src.lPitch));
for(x = 0; x < w; x ++){
Q1 = *(src16);
Q2 = Melt16(Q1, *(src16+1));
Q3 = Q5;
Q5 = Melt16(*(src16+1), *(src16+ddsd_src.lPitch+1)); // to be used in next for cycle
Q4 = Melt16(Q3, Q5);
*(dest) = (WORD)Q1;
*(dest+1) = (WORD)Q2;
*(dest+ddsd_dst.lPitch) = (WORD)Q3;
*(dest+ddsd_dst.lPitch+1) = (WORD)Q4;
src16++;
dest+=2;
}
src16 += srcpitch;
dest += (ddsd_dst.lPitch + destpitch);
}
for(x = 0; x < w; x ++){ // last line (there's no next line to melt...)
register DWORD Q1, Q2;
Q1 = *(src16);
Q2 = Melt16(Q1, *(src16+1));
*(dest) = (WORD)Q1;
*(dest+1) = (WORD)Q2;
*(dest+ddsd_dst.lPitch) = (WORD)Q1;
*(dest+ddsd_dst.lPitch+1) = (WORD)Q2;
src16++;
dest+=2;
}
if(dxw.dwFlags3 & MARKBLIT) MarkRect16((SHORT *)dest0, w, h, destpitch);
res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect);
if (res) OutTraceE("BilBlt16_16: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__);
res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect);
if (res) OutTraceE("BilBlt16_16: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__);
return res;
}
static HRESULT WINAPI EmuBlt_24_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
@ -723,6 +1067,108 @@ static HRESULT WINAPI EmuBlt_32_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes
return res;
}
static HRESULT WINAPI BilinearBlt_32_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
HRESULT res;
DWORD *src32;
DWORD *dest, *dest0;
DDSURFACEDESC2 ddsd_src, ddsd_dst;
long srcpitch, destpitch;
DWORD x, y, w, h;
w = lpdestrect->right - lpdestrect->left;
h = lpdestrect->bottom - lpdestrect->top;
lpdestrect->left <<= 1;
lpdestrect->top <<= 1;
lpdestrect->right <<= 1;
lpdestrect->bottom <<= 1;
memset(&ddsd_dst,0,sizeof(DDSURFACEDESC2));
ddsd_dst.dwSize = Set_dwSize_From_Surface(lpddsdst);
ddsd_dst.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
if(res=(*pLock)(lpddsdst, 0, (LPDDSURFACEDESC)&ddsd_dst, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){
OutTraceE("BilBlt32_32: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;
}
memset(&ddsd_src,0,sizeof(DDSURFACEDESC2));
ddsd_src.dwSize = Set_dwSize_From_Surface(lpddssrc);
ddsd_src.dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
if (lpsurface) { // already locked, just get info ....
if(res=lpddssrc->GetSurfaceDesc((LPDDSURFACEDESC)&ddsd_src)) {
OutTraceE("BilBlt32_32: GetSurfaceDesc ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect);
(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect);
return 0;
}
}
else {
if(res=(*pLock)(lpddssrc, 0, (LPDDSURFACEDESC)&ddsd_src, DDLOCK_SURFACEMEMORYPTR|DDLOCK_READONLY|DDLOCK_WAIT, 0)) {
(*pUnlockMethod(lpddsdst))(lpddsdst,0);
OutTraceE("BilBlt32_32: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
return res;
}
lpsurface=ddsd_src.lpSurface;
}
ddsd_dst.lPitch >>= 2;
dest = (DWORD *)ddsd_dst.lpSurface;
dest += lpdestrect->top*ddsd_dst.lPitch;
dest += lpdestrect->left;
destpitch = ddsd_dst.lPitch - (2 * w);
dest0 = dest;
ddsd_src.lPitch >>= 2;
src32 = (DWORD *)(lpsurface ? lpsurface:ddsd_src.lpSurface);
src32 += lpsrcrect->top*ddsd_src.lPitch;
src32 += lpsrcrect->left;
srcpitch = ddsd_src.lPitch - w;
// OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src8,dest,srcpitch,destpitch);
for(y = 0; y < h-1; y ++){ // first h-1 lines ....
register DWORD Q1, Q2, Q3, Q4, Q5;
Q5 = Melt32(*(src32), *(src32+ddsd_src.lPitch));
for(x = 0; x < w; x ++){
Q1 = *(src32);
Q2 = Melt32(Q1, *(src32+1));
Q3 = Q5;
Q5 = Melt32(*(src32+1), *(src32+ddsd_src.lPitch+1)); // to be used in next for cycle
Q4 = Melt32(Q3, Q5);
*(dest) = (WORD)Q1;
*(dest+1) = (WORD)Q2;
*(dest+ddsd_dst.lPitch) = (WORD)Q3;
*(dest+ddsd_dst.lPitch+1) = (WORD)Q4;
src32++;
dest+=2;
}
src32 += srcpitch;
dest += (ddsd_dst.lPitch + destpitch);
}
for(x = 0; x < w; x ++){ // last line (there's no next line to melt...)
register DWORD Q1, Q2;
Q1 = *(src32);
Q2 = Melt32(Q1, *(src32+1));
*(dest) = (WORD)Q1;
*(dest+1) = (WORD)Q2;
*(dest+ddsd_dst.lPitch) = (WORD)Q1;
*(dest+ddsd_dst.lPitch+1) = (WORD)Q2;
src32++;
dest+=2;
}
if(dxw.dwFlags3 & MARKBLIT) MarkRect16((SHORT *)dest0, w, h, destpitch);
res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect);
if (res) OutTraceE("BilBlt32_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__);
res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect);
if (res) OutTraceE("BilBlt32_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__);
return res;
}
static HRESULT WINAPI EmuBlt_Null(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface)
{
@ -1086,6 +1532,7 @@ void SetBltTransformations()
case 16:
pRevBlt=RevBlt_32_to_16;
pEmuBlt=EmuBlt_16_to_32;
if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_16_to_32;
OutTraceDW("set color transformation 16<->32\n");
break;
case 24:
@ -1095,6 +1542,7 @@ void SetBltTransformations()
break;
case 32:
pEmuBlt=EmuBlt_32_to_32;
if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_32_to_32;
OutTraceDW("set color transformation 32->32\n");
break;
default:
@ -1107,11 +1555,13 @@ void SetBltTransformations()
case 8:
pRevBlt=RevBlt_16_to_8;
pEmuBlt=EmuBlt_8_to_16;
if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_8_to_16;
OutTraceDW("set color transformation 8<->16\n");
break;
case 16:
pRevBlt=RevBlt_16_to_16;
pEmuBlt=EmuBlt_16_to_16;
if(dxw.dwFlags4 & BILINEARFILTER) pEmuBlt=BilinearBlt_16_to_16;
OutTraceDW("set color transformation 16<->16\n");
break;
case 24:

View File

@ -21,6 +21,8 @@
#include "Mmsystem.h"
#include "disasm.h"
#define SKIPIMEWINDOW TRUE
dxwCore dxw;
typedef char *(*Geterrwarnmessage_Type)(unsigned long, unsigned long);
@ -90,6 +92,17 @@ static char *Flag4Names[32]={
"HOTPATCHALWAYS", "NOD3DRESET", "OVERRIDEREGISTRY", "HIDECDROMEMPTY",
};
static char *Flag5Names[32]={
"DIABLOCHEAT", "", "", "",
"", "", "", "",
"", "", "", "",
"", "", "", "",
"", "", "", "",
"", "", "", "",
"", "", "", "",
"", "", "", "",
};
static char *TFlagNames[32]={
"OUTTRACE", "OUTDDRAWTRACE", "OUTWINMESSAGES", "OUTCURSORTRACE",
"OUTPROXYTRACE", "DXPROXED", "ASSERTDIALOG", "OUTIMPORTTABLE",
@ -116,6 +129,7 @@ static void OutTraceHeader(FILE *fp)
for(i=0, dword=dxw.dwFlags2; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag2Names[i]);
for(i=0, dword=dxw.dwFlags3; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag3Names[i]);
for(i=0, dword=dxw.dwFlags4; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag4Names[i]);
for(i=0, dword=dxw.dwFlags5; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag5Names[i]);
for(i=0, dword=dxw.dwTFlags; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", TFlagNames[i]);
fprintf(fp, "***\n");
}
@ -154,6 +168,7 @@ void OutTrace(const char *format, ...)
fflush(fp);
}
#ifdef CHECKFORCOMPATIBILITYFLAGS
static BOOL CheckCompatibilityFlags()
{
typedef DWORD (WINAPI *GetFileVersionInfoSizeA_Type)(LPCSTR, LPDWORD);
@ -194,6 +209,7 @@ static BOOL CheckCompatibilityFlags()
}
return FALSE;
}
#endif
static void dx_ToggleLogging()
{
@ -430,8 +446,14 @@ void CalculateWindowPos(HWND hwnd, DWORD width, DWORD height, LPWINDOWPOS wp)
case DXW_DESKTOP_CENTER:
MaxX = dxw.iSizX;
MaxY = dxw.iSizY;
if (!MaxX) MaxX = width;
if (!MaxY) MaxY = height;
if (!MaxX) {
MaxX = width;
if(dxw.dwFlags4 & BILINEARFILTER) MaxX <<= 1; // double
}
if (!MaxY) {
MaxY = height;
if(dxw.dwFlags4 & BILINEARFILTER) MaxY <<= 1; // double
}
//GetClientRect(0, &desktop);
(*pGetClientRect)(GetDesktopWindow(), &desktop);
rect.left = (desktop.right - MaxX) / 2;
@ -842,10 +864,18 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED:
if(dxw.Windowize && dxw.IsFullScreen()){
extern HWND hControlParentWnd;
LPWINDOWPOS wp;
wp = (LPWINDOWPOS)lparam;
dxwFixWindowPos("WindowProc", hwnd, lparam);
OutTraceDW("WindowProc: WM_WINDOWPOSCHANGING fixed size=(%d,%d)\n", wp->cx, wp->cy);
// try to lock main wind & control parent together
if((message==WM_WINDOWPOSCHANGED) && hControlParentWnd){
if(dxw.IsDesktop(hwnd)) {
POINT fo = dxw.GetFrameOffset();
(*pMoveWindow)(hControlParentWnd, wp->x+fo.x, wp->y+fo.y, wp->cx, wp->cy, TRUE);
}
}
}
break;
case WM_ENTERSIZEMOVE:
@ -1451,6 +1481,10 @@ static void ReplaceRDTSC()
FreeLibrary(disasmlib);
}
#ifdef CREATEDESKTOP
HWND hDesktopWindow = NULL;
#endif
void HookInit(TARGETMAP *target, HWND hwnd)
{
HMODULE base;
@ -1468,7 +1502,7 @@ void HookInit(TARGETMAP *target, HWND hwnd)
if(dxw.dwFlags1 & AUTOMATIC) dxw.dwFlags1 |= EMULATESURFACE; // if AUTOMATIC, try this first!
if(hwnd){ // v2/02.32: skip this when in code injection mode.
if(hwnd){ // v2.02.32: skip this when in code injection mode.
// v2.1.75: is it correct to set hWnd here?
//dxw.SethWnd(hwnd);
dxw.hParentWnd=GetParent(hwnd);
@ -1478,6 +1512,22 @@ void HookInit(TARGETMAP *target, HWND hwnd)
if(dxw.dwFlags4 & ENABLEHOTKEYS) dxw.MapKeysInit();
}
#ifdef CREATEDESKTOP
if(CREATEDESKTOP){
if (!hDesktopWindow){
//hDesktopWindow=CreateWindowEx(0, "STATIC", "DxWnd Desktop", 0,
hDesktopWindow=CreateWindowEx(WS_EX_CONTROLPARENT, "STATIC", "DxWnd Desktop", 0,
target->posx, target->posy, target->sizx, target->sizy, NULL, NULL, NULL, NULL);
if(hDesktopWindow){
OutTraceDW("created desktop emulation: hwnd=%x\n", hDesktopWindow);
}
else{
OutTraceE("CreateWindowEx ERROR: err=%d at %d\n", GetLastError(), __LINE__);
}
}
}
#endif
if(IsTraceDW){
OutTrace("HookInit: path=\"%s\" module=\"%s\" dxversion=%s pos=(%d,%d) size=(%d,%d)",
target->path, target->module, dxversions[dxw.dwTargetDDVersion],
@ -1490,16 +1540,51 @@ void HookInit(TARGETMAP *target, HWND hwnd)
if (hwnd && IsDebug){
DWORD dwStyle, dwExStyle;
char ClassName[81];
char WinText[81];
dwStyle=GetWindowLong(dxw.GethWnd(), GWL_STYLE);
dwExStyle=GetWindowLong(dxw.GethWnd(), GWL_EXSTYLE);
OutTrace("HookInit: hWnd style=%x(%s) exstyle=%x(%s)\n", dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle));
GetClassName(dxw.GethWnd(), ClassName, sizeof(ClassName));
GetWindowText(dxw.GethWnd(), WinText, sizeof(WinText));
OutTrace("HookInit: dxw.hChildWnd=%x class=\"%s\" text=\"%s\" style=%x(%s) exstyle=%x(%s)\n",
dxw.hChildWnd, ClassName, WinText, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle));
dwStyle=GetWindowLong(dxw.hParentWnd, GWL_STYLE);
dwExStyle=GetWindowLong(dxw.hParentWnd, GWL_EXSTYLE);
OutTrace("HookInit: dxw.hParentWnd style=%x(%s) exstyle=%x(%s)\n", dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle));
GetClassName(dxw.hParentWnd, ClassName, sizeof(ClassName));
GetWindowText(dxw.hParentWnd, WinText, sizeof(WinText));
OutTrace("HookInit: dxw.hParentWnd=%x class=\"%s\" text=\"%s\" style=%x(%s) exstyle=%x(%s)\n",
dxw.hParentWnd, ClassName, WinText, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle));
OutTrace("HookInit: target window pos=(%d,%d) size=(%d,%d)\n", dxw.iPosX, dxw.iPosY, dxw.iSizX, dxw.iSizY);
}
if (SKIPIMEWINDOW) {
char ClassName[8+1];
GetClassName(hwnd, ClassName, sizeof(ClassName));
if(!strcmp(ClassName, "IME")){
dxw.hChildWnd=GetParent(hwnd);
dxw.hParentWnd=GetParent(dxw.hChildWnd);
if (dxw.dwFlags2 & SUPPRESSIME) DestroyWindow(hwnd);
// v2.02.31: set main win either this one or the parent!
dxw.SethWnd((dxw.dwFlags1 & FIXPARENTWIN) ? dxw.hParentWnd : dxw.hChildWnd);
hwnd = dxw.GethWnd();
if(hwnd) OutTraceDW("HookInit: skipped IME window. current hWnd=%x(hdc=%x) dxw.hParentWnd=%x(hdc=%x)\n",
hwnd, GetDC(hwnd), dxw.hParentWnd, GetDC(dxw.hParentWnd));
}
}
#ifdef CREATEDESKTOP
if(CREATEDESKTOP){
if (hDesktopWindow){
OutTraceDW("HookInit: set new parent=%x\n", hDesktopWindow);
SetParent(dxw.hChildWnd, hDesktopWindow);
dxw.hParentWnd = hDesktopWindow;
}
}
#endif
#ifdef CHECKFORCOMPATIBILITYFLAGS
CheckCompatibilityFlags(); // v2.02.83 Check for change of OS release
#endif
HookSysLibsInit(); // this just once...
@ -1558,7 +1643,7 @@ void HookInit(TARGETMAP *target, HWND hwnd)
InitScreenParameters();
if(hwnd) HookWindowProc(hwnd);
// in fullscreen mode, messages seem to reach and get processed by the parent window
if(!dxw.Windowize && hwnd) HookWindowProc(GetParent(hwnd));
if((!dxw.Windowize) && hwnd) HookWindowProc(GetParent(hwnd));
// initialize window: if
// 1) not in injection mode (hwnd != 0) and

View File

@ -76,6 +76,7 @@ void dxwCore::InitTarget(TARGETMAP *target)
dwFlags2 = target->flags2;
dwFlags3 = target->flags3;
dwFlags4 = target->flags4;
dwFlags5 = target->flags5;
dwTFlags = target->tflags;
Windowize = (dwFlags2 & WINDOWIZE) ? TRUE : FALSE;
if(dwFlags3 & FULLSCREENONLY) FullScreen=TRUE;
@ -302,6 +303,17 @@ RECT dxwCore::GetUnmappedScreenRect()
return Screen;
}
POINT dxwCore::GetFrameOffset()
{
RECT wrect;
POINT FrameOffset={0, 0};
(*pGetWindowRect)(hWnd, &wrect);
(*pClientToScreen)(hWnd, &FrameOffset);
FrameOffset.x -= wrect.left;
FrameOffset.y -= wrect.top;
OutTraceB("GetFrameOffset: offset=(%d,%d)\n", FrameOffset.x, FrameOffset.y);
return FrameOffset;
}
BOOL dxwCore::IsDesktop(HWND hwnd)
{

View File

@ -68,6 +68,7 @@ public: // methods
RECT GetUnmappedScreenRect();
RECT GetWindowRect(RECT);
RECT GetClientRect(RECT);
POINT GetFrameOffset();
POINT AddCoordinates(POINT, POINT);
RECT AddCoordinates(RECT, POINT);
POINT SubCoordinates(POINT, POINT);
@ -130,6 +131,7 @@ public: // simple data variables
DWORD dwFlags2;
DWORD dwFlags3;
DWORD dwFlags4;
DWORD dwFlags5;
DWORD dwTFlags;
HWND hParentWnd;
HWND hChildWnd;

View File

@ -24,7 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "dxwnd.h"
#include "dxwcore.hpp"
#define VERSION "2.02.86"
#define VERSION "2.02.87"
#define DDTHREADLOCK 1
@ -184,6 +184,8 @@ LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam)
// This callback is invoked per each process' thread.
DoOnce = TRUE;
extern HHOOK hHook;
UnhookWindowsHookEx(hHook);
// V.68: concurrency check. One game at a time, or exiting.
// no good trying to insert fancy dialog boxes: the window

Binary file not shown.

View File

@ -871,6 +871,12 @@ HDC WINAPI extGDICreateCompatibleDC(HDC hdc)
OutTraceDW("GDI.CreateCompatibleDC: hdc=%x\n", hdc);
if(hdc==0){
hdc=(*pGDIGetDC)(dxw.GethWnd());
#ifdef CREATEDESKTOP
if(CREATEDESKTOP){
extern HWND hDesktopWindow;
hdc=(*pGDIGetDC)(hDesktopWindow);
}
#endif
OutTraceDW("GDI.CreateCompatibleDC: duplicating win HDC hWnd=%x\n", dxw.GethWnd());
}

View File

@ -816,14 +816,11 @@ BOOL WINAPI extGetCursorPos(LPPOINT lppoint)
if(dxw.dwFlags4 & FRAMECOMPENSATION){
static int dx, dy, todo=TRUE;
if (todo){
RECT wrect;
POINT upleft={0, 0};
todo=FALSE;
(*pGetWindowRect)(dxw.GethWnd(), &wrect);
(*pClientToScreen)(dxw.GethWnd(), &upleft);
dx=upleft.x - wrect.left;
dy=upleft.y - wrect.top;
POINT FrameOffset = dxw.GetFrameOffset();
dx=FrameOffset.x;
dy=FrameOffset.y;
OutTraceC("GetCursorPos: frame compensation=(%d,%d)\n", dx, dy);
todo=FALSE;
}
lppoint->x += dx;
lppoint->y += dy;
@ -1062,11 +1059,19 @@ int WINAPI extMapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT
HWND WINAPI extGetDesktopWindow(void)
{
// V2.1.73: correct ???
HWND res;
if((!dxw.Windowize) || (dxw.dwFlags5 & DIABLOTWEAK)) return (*pGetDesktopWindow)();
OutTraceDW("GetDesktopWindow: FullScreen=%x\n", dxw.IsFullScreen());
if (dxw.IsFullScreen()){
#ifdef CREATEDESKTOP
if(CREATEDESKTOP){
extern HWND hDesktopWindow;
OutTraceDW("GetDesktopWindow: returning desktop emulated hwnd=%x\n", hDesktopWindow);
return hDesktopWindow;
}
#endif
OutTraceDW("GetDesktopWindow: returning main window hwnd=%x\n", dxw.GethWnd());
return dxw.GethWnd();
}
@ -1174,6 +1179,8 @@ static void HookChildWndProc(HWND hwnd, DWORD dwStyle, LPCTSTR ApiName)
if(!res) OutTraceE("%s: SetWindowLong ERROR %x\n", ApiName, GetLastError());
}
HWND hControlParentWnd = NULL;
static HWND WINAPI extCreateWindowCommon(
LPCTSTR ApiName,
BOOL WideChar,
@ -1196,7 +1203,7 @@ static HWND WINAPI extCreateWindowCommon(
iOrigW=nWidth;
iOrigH=nHeight;
if(!dxw.Windowize){
if(!dxw.Windowize || (hWndParent == HWND_MESSAGE)){ // v2.02.87: don't process message windows (hWndParent == HWND_MESSAGE)
if(WideChar)
hwnd= (*pCreateWindowExW)(dwExStyle, (LPCWSTR)lpClassName, (LPCWSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
else
@ -1215,6 +1222,16 @@ static HWND WINAPI extCreateWindowCommon(
dwStyle &= ~WS_MAXIMIZE;
}
#ifdef CREATEDESKTOP
if(CREATEDESKTOP){
extern HWND hDesktopWindow;
if (dxw.IsRealDesktop(hWndParent)){
OutTraceE("%s: new parent win %x->%x\n", ApiName, hWndParent, hDesktopWindow);
hWndParent=hDesktopWindow;
}
}
#endif
// v2.1.92: fixes size & position for auxiliary big window, often used
// for intro movies etc. : needed for ......
// evidently, this was supposed to be a fullscreen window....
@ -1240,7 +1257,7 @@ static HWND WINAPI extCreateWindowCommon(
&&
!(dwStyle & WS_CHILD) // Diablo fix
)
{
{
RECT screen;
POINT upleft = {0,0};
@ -1340,6 +1357,8 @@ static HWND WINAPI extCreateWindowCommon(
return hwnd;
}
if (dwExStyle & WS_EX_CONTROLPARENT) hControlParentWnd=hwnd;
if ((!isValidHandle) && dxw.IsFullScreen()){
dxw.SethWnd(hwnd);
extern void AdjustWindowPos(HWND, DWORD, DWORD);
@ -1409,9 +1428,10 @@ HWND WINAPI extCreateWindowExW(
else sprintf(wString,"%d", nWidth);
if (nHeight==CW_USEDEFAULT) strcpy(hString,"CW_USEDEFAULT");
else sprintf(hString,"%d", nHeight);
OutTrace("CreateWindowExW: class=\"%ls\" wname=\"%ls\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s)\n",
OutTrace("CreateWindowExW: class=\"%ls\" wname=\"%ls\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s) hWndParent=%x%s hMenu=%x\n",
ClassToWStr(lpClassName), lpWindowName, xString, yString, wString, hString,
dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle));
dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle),
hWndParent, hWndParent==HWND_MESSAGE?"(HWND_MESSAGE)":"", hMenu);
}
if(IsDebug) OutTrace("CreateWindowExW: DEBUG screen=(%d,%d)\n", dxw.GetScreenWidth(), dxw.GetScreenHeight());
@ -1443,9 +1463,10 @@ HWND WINAPI extCreateWindowExA(
else sprintf(wString,"%d", nWidth);
if (nHeight==CW_USEDEFAULT) strcpy(hString,"CW_USEDEFAULT");
else sprintf(hString,"%d", nHeight);
OutTrace("CreateWindowExA: class=\"%s\" wname=\"%s\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s)\n",
OutTrace("CreateWindowExA: class=\"%s\" wname=\"%s\" pos=(%s,%s) size=(%s,%s) Style=%x(%s) ExStyle=%x(%s) hWndParent=%x%s hMenu=%x\n",
ClassToStr(lpClassName), lpWindowName, xString, yString, wString, hString,
dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle));
dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle),
hWndParent, hWndParent==HWND_MESSAGE?"(HWND_MESSAGE)":"", hMenu);
}
if(IsDebug) OutTrace("CreateWindowExA: DEBUG screen=(%d,%d)\n", dxw.GetScreenWidth(), dxw.GetScreenHeight());
@ -2317,6 +2338,10 @@ BOOL WINAPI extDestroyWindow(HWND hWnd)
OutTraceDW("DestroyWindow: destroy main hwnd=%x\n", hWnd);
dxw.SethWnd(NULL);
}
if (hControlParentWnd && (hWnd == hControlParentWnd)) {
OutTraceDW("DestroyWindow: destroy control parent hwnd=%x\n", hWnd);
hControlParentWnd = NULL;
}
res=(*pDestroyWindow)(hWnd);
if(!res)OutTraceE("DestroyWindow: ERROR err=%d\n", GetLastError());
return res;
@ -2716,7 +2741,9 @@ int WINAPI extGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
if( regionType == SIMPLEREGION ){
dxw.UnmapClient(&rc);
if( SetRectRgn( hRgn, rc.left, rc.top, rc.right, rc.bottom ) ){
; // success
// success
OutTraceDW("GetUpdateRgn: hwnd=%x hrgn=%x update rgn=(%d,%d)-(%d,%d) erase=%x\n",
hWnd, hRgn, rc.left, rc.top, rc.right, rc.bottom, bErase);
}
}
}

View File

@ -116,6 +116,7 @@ BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
cs.cx = GetPrivateProfileInt("window", "sizx", 320, InitPath);
cs.cy = GetPrivateProfileInt("window", "sizy", 200, InitPath);
// keep window inside desktop boundaries
::GetWindowRect(::GetDesktopWindow(), &DesktopRect);
if(cs.cx < 320) cs.cx = 320;

Binary file not shown.

View File

@ -42,6 +42,7 @@ void CTabCompat::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_NOPOWER2FIX, cTarget->m_NoPower2Fix);
DDX_Check(pDX, IDC_NOPERFCOUNTER, cTarget->m_NoPerfCounter);
DDX_Check(pDX, IDC_HIDECDROMEMPTY, cTarget->m_HideCDROMEmpty);
DDX_Check(pDX, IDC_DIABLOTWEAK, cTarget->m_DiabloTweak);
// 3D management
DDX_Check(pDX, IDC_NOTEXTURES, cTarget->m_NoTextures);

View File

@ -40,6 +40,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_SuppressIME = FALSE;
m_SuppressD3DExt = FALSE;
m_SetCompatibility = TRUE;
m_DiabloTweak = TRUE;
m_DisableHAL = FALSE;
m_ForcesHEL = FALSE;
m_ColorFix = FALSE;

View File

@ -142,6 +142,7 @@ public:
BOOL m_DisableFogging;
BOOL m_SuppressIME;
BOOL m_SetCompatibility;
BOOL m_DiabloTweak;
BOOL m_DisableHAL;
BOOL m_ForcesHEL;
BOOL m_ColorFix;

Binary file not shown.

View File

@ -104,6 +104,8 @@ CDxwndhostApp theApp;
BOOL CDxwndhostApp::InitInstance()
{
char InitPath[MAX_PATH];
int CompatibilityMinLevel;
AfxEnableControlContainer();
// standard initialization
@ -130,13 +132,15 @@ BOOL CDxwndhostApp::InitInstance()
// and user-defined flags. The CCommandLine class has been replaced
CNewCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
GetCurrentDirectory(MAX_PATH, InitPath);
strcat_s(InitPath, sizeof(InitPath), "\\dxwnd.ini");
//CompatibilityMinLevel = GetPrivateProfileInt("window", "compatminlevel", 0, InitPath);
if(!LangSelected){
LANGID LangId;
char LangString[20+1];
char InitPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, InitPath);
strcat_s(InitPath, sizeof(InitPath), "\\dxwnd.ini");
GetPrivateProfileString("window", "lang", "", LangString, 20+1, InitPath);
if(!strcmp(LangString, "default") || !strlen(LangString)){ // if no specification, or lang=default
// do nothing

Binary file not shown.

Binary file not shown.

View File

@ -107,6 +107,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
t->flags2 = 0;
t->flags3 = 0;
t->flags4 = 0;
t->flags5 = 0;
t->tflags = 0;
if(dlg->m_UnNotify) t->flags |= UNNOTIFY;
if(dlg->m_Windowize) t->flags2 |= WINDOWIZE;
@ -179,6 +180,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
if(dlg->m_SuppressIME) t->flags2 |= SUPPRESSIME;
if(dlg->m_SuppressD3DExt) t->flags3 |= SUPPRESSD3DEXT;
if(dlg->m_SetCompatibility) t->flags2 |= SETCOMPATIBILITY;
if(dlg->m_DiabloTweak) t->flags5 |= DIABLOTWEAK;
if(dlg->m_DisableHAL) t->flags3 |= DISABLEHAL;
if(dlg->m_ForcesHEL) t->flags3 |= FORCESHEL;
if(dlg->m_ColorFix) t->flags3 |= COLORFIX;
@ -344,6 +346,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
dlg->m_SuppressIME = t->flags2 & SUPPRESSIME ? 1 : 0;
dlg->m_SuppressD3DExt = t->flags3 & SUPPRESSD3DEXT ? 1 : 0;
dlg->m_SetCompatibility = t->flags2 & SETCOMPATIBILITY ? 1 : 0;
dlg->m_DiabloTweak = t->flags5 & DIABLOTWEAK ? 1 : 0;
dlg->m_DisableHAL = t->flags3 & DISABLEHAL ? 1 : 0;
dlg->m_ForcesHEL = t->flags3 & FORCESHEL ? 1 : 0;
dlg->m_ColorFix = t->flags3 & COLORFIX ? 1 : 0;
@ -488,6 +491,9 @@ static void SaveConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i,
sprintf_s(key, sizeof(key), "flagi%i", i);
sprintf_s(val, sizeof(val), "%i", TargetMap->flags4);
WritePrivateProfileString("target", key, val, InitPath);
sprintf_s(key, sizeof(key), "flagj%i", i);
sprintf_s(val, sizeof(val), "%i", TargetMap->flags5);
WritePrivateProfileString("target", key, val, InitPath);
sprintf_s(key, sizeof(key), "tflag%i", i);
sprintf_s(val, sizeof(val), "%i", TargetMap->tflags);
WritePrivateProfileString("target", key, val, InitPath);
@ -555,6 +561,8 @@ static void ClearTarget(int i, char *InitPath)
WritePrivateProfileString("target", key, 0, InitPath);
sprintf_s(key, sizeof(key), "flagi%i", i);
WritePrivateProfileString("target", key, 0, InitPath);
sprintf_s(key, sizeof(key), "flagj%i", i);
WritePrivateProfileString("target", key, 0, InitPath);
sprintf_s(key, sizeof(key), "tflag%i", i);
WritePrivateProfileString("target", key, 0, InitPath);
sprintf_s(key, sizeof(key), "initx%i", i);
@ -626,6 +634,8 @@ static int LoadConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, c
TargetMap->flags3 = GetPrivateProfileInt("target", key, 0, InitPath);
sprintf_s(key, sizeof(key), "flagi%i", i);
TargetMap->flags4 = GetPrivateProfileInt("target", key, 0, InitPath);
sprintf_s(key, sizeof(key), "flagj%i", i);
TargetMap->flags5 = GetPrivateProfileInt("target", key, 0, InitPath);
sprintf_s(key, sizeof(key), "tflag%i", i);
TargetMap->tflags = GetPrivateProfileInt("target", key, 0, InitPath);
sprintf_s(key, sizeof(key), "initx%i", i);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.