|
|
|
|
#include "diablo.h"
|
|
|
|
|
#include "../3rdParty/Storm/Source/storm.h"
|
|
|
|
|
#include "miniwin/ddraw.h"
|
|
|
|
|
|
|
|
|
|
namespace dvl {
|
|
|
|
|
|
|
|
|
|
BYTE *sgpBackBuf;
|
|
|
|
|
LPDIRECTDRAW lpDDInterface;
|
|
|
|
|
IDirectDrawPalette *lpDDPalette; // idb
|
|
|
|
|
int sgdwLockCount;
|
|
|
|
|
BYTE *gpBuffer;
|
|
|
|
|
IDirectDrawSurface *lpDDSBackBuf;
|
|
|
|
|
IDirectDrawSurface *lpDDSPrimary;
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
int locktbl[256];
|
|
|
|
|
#endif
|
|
|
|
|
static CCritSect sgMemCrit;
|
|
|
|
|
char gbBackBuf;
|
|
|
|
|
char gbEmulate;
|
|
|
|
|
HMODULE ghDiabMod;
|
|
|
|
|
|
|
|
|
|
void dx_init(HWND hWnd)
|
|
|
|
|
{
|
|
|
|
|
SetFocus(hWnd);
|
|
|
|
|
SDL_ShowWindow(window);
|
|
|
|
|
|
|
|
|
|
lpDDInterface = new StubDraw();
|
|
|
|
|
|
|
|
|
|
dx_create_primary_surface();
|
|
|
|
|
palette_init();
|
|
|
|
|
dx_create_back_buffer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dx_create_back_buffer()
|
|
|
|
|
{
|
|
|
|
|
DDSCAPS caps;
|
|
|
|
|
HRESULT error_code;
|
|
|
|
|
DDSURFACEDESC ddsd;
|
|
|
|
|
|
|
|
|
|
error_code = lpDDSPrimary->GetCaps(&caps);
|
|
|
|
|
if (error_code != DVL_S_OK)
|
|
|
|
|
DD_ERR_MSG(error_code);
|
|
|
|
|
|
|
|
|
|
gbBackBuf = 1;
|
|
|
|
|
if (!gbBackBuf) {
|
|
|
|
|
ddsd.dwSize = sizeof(ddsd);
|
|
|
|
|
error_code = lpDDSPrimary->Lock(NULL, &ddsd, 0 | 0, NULL);
|
|
|
|
|
if (error_code == DVL_S_OK) {
|
|
|
|
|
lpDDSPrimary->Unlock(NULL);
|
|
|
|
|
sgpBackBuf = (BYTE *)DiabloAllocPtr(BUFFER_HEIGHT * BUFFER_WIDTH);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (error_code != 2)
|
|
|
|
|
ERR_DLG(IDD_DIALOG1, error_code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(&ddsd, 0, sizeof(ddsd));
|
|
|
|
|
ddsd.dwWidth = BUFFER_WIDTH;
|
|
|
|
|
ddsd.lPitch = BUFFER_WIDTH;
|
|
|
|
|
ddsd.dwSize = sizeof(ddsd);
|
|
|
|
|
ddsd.dwFlags = 0 | 0 | 0 | 0 | 0;
|
|
|
|
|
ddsd.ddsCaps.dwCaps = 0 | 0;
|
|
|
|
|
ddsd.dwHeight = BUFFER_HEIGHT;
|
|
|
|
|
ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
|
|
|
|
|
error_code = lpDDSPrimary->GetPixelFormat(&ddsd.ddpfPixelFormat);
|
|
|
|
|
if (error_code != DVL_S_OK)
|
|
|
|
|
ERR_DLG(IDD_DIALOG1, error_code);
|
|
|
|
|
error_code = lpDDInterface->CreateSurface(&ddsd, &lpDDSBackBuf, NULL);
|
|
|
|
|
if (error_code != DVL_S_OK)
|
|
|
|
|
ERR_DLG(IDD_DIALOG1, error_code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dx_create_primary_surface()
|
|
|
|
|
{
|
|
|
|
|
DDSURFACEDESC ddsd;
|
|
|
|
|
HRESULT error_code;
|
|
|
|
|
|
|
|
|
|
memset(&ddsd, 0, sizeof(ddsd));
|
|
|
|
|
ddsd.dwSize = sizeof(ddsd);
|
|
|
|
|
ddsd.dwFlags = 0;
|
|
|
|
|
ddsd.ddsCaps.dwCaps = 0;
|
|
|
|
|
error_code = lpDDInterface->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
|
|
|
|
|
if (error_code != DVL_S_OK)
|
|
|
|
|
ERR_DLG(IDD_DIALOG1, error_code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void lock_buf(BYTE idx)
|
|
|
|
|
{
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
++locktbl[idx];
|
|
|
|
|
#endif
|
|
|
|
|
lock_buf_priv();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void lock_buf_priv()
|
|
|
|
|
{
|
|
|
|
|
DDSURFACEDESC ddsd;
|
|
|
|
|
HRESULT error_code;
|
|
|
|
|
|
|
|
|
|
sgMemCrit.Enter();
|
|
|
|
|
if (sgpBackBuf != NULL) {
|
|
|
|
|
gpBuffer = sgpBackBuf;
|
|
|
|
|
sgdwLockCount++;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sgdwLockCount != 0) {
|
|
|
|
|
sgdwLockCount++;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ddsd.dwSize = sizeof(ddsd);
|
|
|
|
|
error_code = lpDDSBackBuf->Lock(NULL, &ddsd, 0, NULL);
|
|
|
|
|
if (error_code != DVL_S_OK)
|
|
|
|
|
DD_ERR_MSG(error_code);
|
|
|
|
|
|
|
|
|
|
gpBufEnd += (uintptr_t)ddsd.lpSurface;
|
|
|
|
|
gpBuffer = (BYTE *)ddsd.lpSurface;
|
|
|
|
|
sgdwLockCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void unlock_buf(BYTE idx)
|
|
|
|
|
{
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
if (!locktbl[idx])
|
|
|
|
|
app_fatal("Draw lock underflow: 0x%x", idx);
|
|
|
|
|
--locktbl[idx];
|
|
|
|
|
#endif
|
|
|
|
|
unlock_buf_priv();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void unlock_buf_priv()
|
|
|
|
|
{
|
|
|
|
|
HRESULT error_code;
|
|
|
|
|
|
|
|
|
|
if (sgdwLockCount == 0)
|
|
|
|
|
app_fatal("draw main unlock error");
|
|
|
|
|
if (!gpBuffer)
|
|
|
|
|
app_fatal("draw consistency error");
|
|
|
|
|
|
|
|
|
|
sgdwLockCount--;
|
|
|
|
|
if (sgdwLockCount == 0) {
|
|
|
|
|
gpBufEnd -= (uintptr_t)gpBuffer;
|
|
|
|
|
//gpBuffer = NULL; unable to return to menu
|
|
|
|
|
if (sgpBackBuf == NULL) {
|
|
|
|
|
error_code = lpDDSBackBuf->Unlock(NULL);
|
|
|
|
|
if (error_code != DVL_S_OK)
|
|
|
|
|
DD_ERR_MSG(error_code);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sgMemCrit.Leave();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dx_cleanup()
|
|
|
|
|
{
|
|
|
|
|
BYTE *v0; // ecx
|
|
|
|
|
|
|
|
|
|
if (ghMainWnd)
|
|
|
|
|
ShowWindow(ghMainWnd, 0);
|
|
|
|
|
sgMemCrit.Enter();
|
|
|
|
|
if (sgpBackBuf != NULL) {
|
|
|
|
|
v0 = sgpBackBuf;
|
|
|
|
|
sgpBackBuf = 0;
|
|
|
|
|
mem_free_dbg(v0);
|
|
|
|
|
} else if (lpDDSBackBuf != NULL) {
|
|
|
|
|
lpDDSBackBuf->Release();
|
|
|
|
|
delete lpDDSBackBuf;
|
|
|
|
|
lpDDSBackBuf = NULL;
|
|
|
|
|
}
|
|
|
|
|
sgdwLockCount = 0;
|
|
|
|
|
gpBuffer = 0;
|
|
|
|
|
sgMemCrit.Leave();
|
|
|
|
|
if (lpDDSPrimary) {
|
|
|
|
|
lpDDSPrimary->Release();
|
|
|
|
|
delete lpDDSPrimary;
|
|
|
|
|
lpDDSPrimary = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (lpDDPalette) {
|
|
|
|
|
lpDDPalette->Release();
|
|
|
|
|
lpDDPalette = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (lpDDInterface) {
|
|
|
|
|
lpDDInterface->Release();
|
|
|
|
|
lpDDInterface = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dx_reinit()
|
|
|
|
|
{
|
|
|
|
|
int lockCount;
|
|
|
|
|
|
|
|
|
|
sgMemCrit.Enter();
|
|
|
|
|
ClearCursor();
|
|
|
|
|
lockCount = sgdwLockCount;
|
|
|
|
|
|
|
|
|
|
while (sgdwLockCount != 0)
|
|
|
|
|
unlock_buf_priv();
|
|
|
|
|
|
|
|
|
|
dx_cleanup();
|
|
|
|
|
|
|
|
|
|
drawpanflag = 255;
|
|
|
|
|
|
|
|
|
|
dx_init(ghMainWnd);
|
|
|
|
|
|
|
|
|
|
while (lockCount != 0) {
|
|
|
|
|
lock_buf_priv();
|
|
|
|
|
lockCount--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sgMemCrit.Leave();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace dvl
|