Skip to content

Commit

Permalink
Copy surface to memory before FixByteAlignment
Browse files Browse the repository at this point in the history
  • Loading branch information
elishacloud committed Mar 8, 2024
1 parent 594bb91 commit bf692c6
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Dllmain/BuildNo.rc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define BUILD_NUMBER 6950
#define BUILD_NUMBER 6951
57 changes: 42 additions & 15 deletions ddraw/IDirectDrawSurfaceX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1756,6 +1756,11 @@ HRESULT m_IDirectDrawSurfaceX::GetDC(HDC FAR* lphDC)
return DDERR_GENERIC;
}

if (EmuLock.Locked && EmuLock.Addr)
{
LOG_LIMIT(100, __FUNCTION__ << " Warning: does not support device context with bit alignment!");
}

SetLockCriticalSection();

// Present before write if needed
Expand Down Expand Up @@ -2742,22 +2747,10 @@ HRESULT m_IDirectDrawSurfaceX::Unlock(LPRECT lpRect)
{
SetSurfaceCriticalSection();

// Fix issue with some games that ignore the pitch size
if (EmuLock.Locked && EmuLock.Addr)
// Fix misaligned bytes
if (Config.DdrawFixByteAlignment)
{
BYTE* InAddr = EmuLock.Mem.data();
DWORD InPitch = (EmuLock.BBP / 8) * EmuLock.Width;
BYTE* OutAddr = (BYTE*)EmuLock.Addr;
DWORD OutPitch = EmuLock.Pitch;
for (DWORD x = 0; x < EmuLock.Height; x++)
{
memcpy(OutAddr, InAddr, InPitch);
InAddr += InPitch;
OutAddr += OutPitch;
}

EmuLock.Locked = false;
EmuLock.Addr = nullptr;
UnlockBitAlign();
}

HRESULT hr = DD_OK;
Expand Down Expand Up @@ -4512,6 +4505,40 @@ void m_IDirectDrawSurfaceX::LockBitAlign(LPRECT lpDestRect, LPDDSURFACEDESC2 lpD
}
lpDDSurfaceDesc->lpSurface = EmuLock.Mem.data();
lpDDSurfaceDesc->lPitch = NewPitch;

// Copy surface data to memory
BYTE* InAddr = (BYTE*)EmuLock.Addr;
DWORD InPitch = EmuLock.Pitch;
BYTE* OutAddr = EmuLock.Mem.data();
DWORD OutPitch = NewPitch;
for (DWORD x = 0; x < EmuLock.Height; x++)
{
memcpy(OutAddr, InAddr, OutPitch);
InAddr += InPitch;
OutAddr += OutPitch;
}
}
}

// Fix issue with some games that ignore the pitch size
void m_IDirectDrawSurfaceX::UnlockBitAlign()
{
if (EmuLock.Locked && EmuLock.Addr)
{
// Copy memory back to surface
BYTE* InAddr = EmuLock.Mem.data();
DWORD InPitch = (EmuLock.BBP / 8) * EmuLock.Width;
BYTE* OutAddr = (BYTE*)EmuLock.Addr;
DWORD OutPitch = EmuLock.Pitch;
for (DWORD x = 0; x < EmuLock.Height; x++)
{
memcpy(OutAddr, InAddr, InPitch);
InAddr += InPitch;
OutAddr += OutPitch;
}

EmuLock.Locked = false;
EmuLock.Addr = nullptr;
}
}

Expand Down
1 change: 1 addition & 0 deletions ddraw/IDirectDrawSurfaceX.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ class m_IDirectDrawSurfaceX : public IUnknown, public AddressLookupTableDdrawObj

// Fix byte alignment issue
void LockBitAlign(LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurfaceDesc);
void UnlockBitAlign();

// For removing scanlines
void RestoreScanlines(LASTLOCK &LLock);
Expand Down

0 comments on commit bf692c6

Please sign in to comment.