Fixed and improved the code in Graphics module

This commit is contained in:
NovaRain
2020-10-15 09:30:04 +08:00
parent d36031613d
commit 5c9d512d12
3 changed files with 77 additions and 42 deletions
+74 -41
View File
@@ -56,7 +56,19 @@ static DDSURFACEDESC surfaceDesc;
static DDSURFACEDESC mveDesc;
static D3DSURFACE_DESC movieDesc;
static DWORD palette[256];
#pragma pack(push, 1)
static struct PALCOLOR {
union {
DWORD xRGB;
struct {
BYTE B;
BYTE G;
BYTE R;
};
};
} palette[256];
#pragma pack(pop)
//static bool paletteInit = false;
static DWORD gWidth;
@@ -603,6 +615,7 @@ private:
ULONG Refs;
bool isPrimary;
BYTE* lockTarget = nullptr;
RECT* lockRect;
public:
static bool IsPlayMovie;
@@ -653,22 +666,24 @@ public:
mainTex->LockRect(0, &dRect, dsc, 0);
DWORD width = mveDesc.lPitch; // the current size of the width of the mve movie
int pitch = dRect.Pitch;
if (Graphics::GPUBlt) {
fo::func::buf_to_buf(lockTarget, width, mveDesc.dwHeight, width, (BYTE*)dRect.pBits, pitch);
fo::func::buf_to_buf(lockTarget, width, mveDesc.dwHeight, width, (BYTE*)dRect.pBits, dRect.Pitch);
//char* pBits = (char*)dRect.pBits;
//for (DWORD y = 0; y < mveDesc.dwHeight; y++) {
// CopyMemory(&pBits[y * pitch], &lockTarget[y * width], width);
//}
} else {
pitch /= 4;
for (DWORD y = 0; y < mveDesc.dwHeight; y++) {
int yp = y * pitch;
int yw = y * width;
for (DWORD x = 0; x < width; x++) {
((DWORD*)dRect.pBits)[yp + x] = palette[lockTarget[yw + x]];
}
int pitch = dRect.Pitch / 4;
DWORD* pBits = (DWORD*)dRect.pBits;
BYTE* target = lockTarget;
int height = mveDesc.dwHeight;
while (height--) {
int x = width;
while (x--) pBits[x] = palette[target[x]].xRGB;
target += width;
pBits += pitch;
}
}
mainTex->UnlockRect(0);
@@ -740,16 +755,15 @@ public:
HRESULT __stdcall Lock(LPRECT a, LPDDSURFACEDESC b, DWORD c, HANDLE d) {
if (DeviceLost) return DDERR_SURFACELOST;
if (isPrimary) {
lockRect = a;
if (Graphics::GPUBlt) {
D3DLOCKED_RECT buf;
if (mainTex->LockRect(0, &buf, a, 0)) goto surface; // fail to lock, use old method
mainTexLock = true;
b->lpSurface = buf.pBits;
b->lPitch = buf.Pitch;
if (SUCCEEDED(mainTex->LockRect(0, &buf, lockRect, 0))) {
mainTexLock = true;
b->lpSurface = buf.pBits;
b->lPitch = buf.Pitch;
}
} else {
surface:
*b = surfaceDesc;
b->lpSurface = lockTarget;
}
@@ -788,15 +802,18 @@ public:
mainTex->LockRect(0, &dRect, 0, 0);
DWORD* pBits = (DWORD*)dRect.pBits;
int pitch = dRect.Pitch / 4;
DWORD width = ResWidth;
int pitch = (dRect.Pitch / 4) - ResWidth;
for (DWORD y = 0; y < ResHeight; y++) {
int yp = y * pitch;
int yw = y * width;
for (DWORD x = 0; x < width; x++) {
pBits[yp + x] = palette[lockTarget[yw + x]]; // takes the color index in the palette and copies the color value to the texture surface
BYTE* target = lockTarget;
int height = ResHeight;
while (height--) {
int width = ResWidth;
while (width--) {
pBits[0] = palette[target[0]].xRGB; // takes the color index in the palette and copies the color value to the texture surface
target++;
pBits++;
}
pBits += pitch;
}
mainTex->UnlockRect(0);
mainTexLock = false;
@@ -810,27 +827,43 @@ public:
0x4F5ECC sub_4F5E60 (from MVE_rmStepMovie_)
0x4868BA movie_MVE_ShowFrame_ (capture never call)
*/
HRESULT __stdcall Unlock(LPVOID) {
HRESULT __stdcall Unlock(LPVOID lockSurface) {
//dlog("\nUnlock", DL_INIT);
if ((DeviceLost && Restore() == DD_FALSE) || !isPrimary) return DD_OK;
//dlog("\nUnlock -> primary", DL_INIT);
if (Graphics::GPUBlt == 0) {
mainTexLock = true;
D3DLOCKED_RECT dRect;
mainTex->LockRect(0, &dRect, 0, 0);
mainTex->LockRect(0, &dRect, lockRect, 0);
int pitch = dRect.Pitch / 4;
DWORD* pBits = (DWORD*)dRect.pBits;
DWORD width = ResWidth;
// slow copy method
for (DWORD y = 0; y < ResHeight; y++) {
int yp = y * pitch;
int yw = y * width;
for (DWORD x = 0; x < width; x++) {
pBits[yp + x] = palette[lockTarget[yw + x]];
int pitch = dRect.Pitch / 4;
if (lockRect) {
BYTE* target = (BYTE*)lockSurface;
int width = (lockRect->right - lockRect->left);
int height = (lockRect->bottom - lockRect->top);
while (height--) {
int w = width;
while (w--) pBits[w] = palette[target[w]].xRGB;
pBits += pitch;
target += ResWidth;
}
} else {
pitch -= ResWidth;
BYTE* target = lockTarget;
int height = ResHeight;
// slow copy method
while (height--) {
int width = ResWidth;
while (width--) {
pBits[0] = palette[target[0]].xRGB;
target++;
pBits++;
}
pBits += pitch;
}
}
}
@@ -886,20 +919,20 @@ public:
HRESULT __stdcall SetEntries(DWORD a, DWORD b, DWORD c, LPPALETTEENTRY destPal) { // used to set palette for splash screen, fades, subtitles
if (!windowInit || c == 0 || b + c > 256) return DDERR_INVALIDPARAMS;
__movsd(&palette[b], (unsigned long*)destPal, c);
__movsd((DWORD*)&palette[b], (DWORD*)destPal, c);
if (Graphics::GPUBlt && gpuPalette) {
if (Graphics::GPUBlt) {
D3DLOCKED_RECT rect;
if (!FAILED(gpuPalette->LockRect(0, &rect, 0, D3DLOCK_DISCARD))) {
if (gpuPalette && !FAILED(gpuPalette->LockRect(0, &rect, 0, D3DLOCK_DISCARD))) {
CopyMemory(rect.pBits, palette, 256 * 4);
gpuPalette->UnlockRect(0);
}
} else {
// X8B8G8R8 format
for (size_t i = b; i < b + c; i++) { // swap color B <> R
BYTE clr = *(BYTE*)((long)&palette[i]); // B
*(BYTE*)((long)&palette[i]) = *(BYTE*)((long)&palette[i] + 2); // R
*(BYTE*)((long)&palette[i] + 2) = clr;
BYTE clr = palette[i].B;
palette[i].B = palette[i].R;
palette[i].R = clr;
}
primaryDDSurface->SetPalette(0); // update
if (FakeDirectDrawSurface::IsPlayMovie) return DD_OK; // prevents flickering at the beginning of playback (w/o HRP & GPUBlt=2)
+2 -1
View File
@@ -72,7 +72,8 @@ public:
primaryDDSurface->Lock(&lockRect, &desc, 0, 0);
fo::func::buf_to_buf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch); //+ (desc.lPitch * rect->top) + rect->left
if (Graphics::GPUBlt == 0) desc.lpSurface = (BYTE*)desc.lpSurface + (desc.lPitch * rect->top) + rect->left;
fo::func::buf_to_buf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch);
primaryDDSurface->Unlock(desc.lpSurface);
}
+1
View File
@@ -202,6 +202,7 @@ void GameRender::init() {
// custom implementation of the GNW_win_refresh function
MakeJump(0x4D6FD9, GNW_win_refresh_hack, 1);
SafeWrite16(0x4D75E6, 0x9090); // win_clip_ (remove _buffering checking)
SafeWrite32(0x4C8FD1, FO_VAR_screen_buffer); // replace screendump_buf
} else { // for default or HRP graphics mode
SafeWrite8(0x4D5DAB, 0x1D); // ecx > ebx (enable _buffering)
BlockCall(0x431076); // dialogMessage_