Basic Blitter (directdraw): fix flipping
This commit is contained in:
parent
ae3330bd57
commit
ebd01a7c1e
|
@ -225,6 +225,7 @@ extern INT32 nVidScrnAspectX, nVidScrnAspectY;
|
|||
extern INT32 nVidVerScrnAspectX, nVidVerScrnAspectY;
|
||||
|
||||
extern UINT8* pVidImage;
|
||||
extern INT32 pVidImageSize;
|
||||
extern INT32 nVidImageWidth, nVidImageHeight;
|
||||
extern INT32 nVidImageLeft, nVidImageTop;
|
||||
extern INT32 nVidImagePitch, nVidImageBPP;
|
||||
|
|
|
@ -134,7 +134,8 @@ INT32 nVidScrnDepth = 0; // Actual screen depth
|
|||
INT32 nVidScrnAspectX = 4, nVidScrnAspectY = 3; // Aspect ratio of the horizontally orientated display screen
|
||||
INT32 nVidVerScrnAspectX = 4, nVidVerScrnAspectY = 3; // Aspect ratio of the vertically orientated display screen
|
||||
|
||||
UINT8* pVidImage = NULL; // Memory buffer
|
||||
UINT8* pVidImage = NULL; // Video Memory buffer
|
||||
INT32 pVidImageSize = 0; // Size in bytes
|
||||
INT32 nVidImageWidth = DEFAULT_IMAGE_WIDTH; // Memory buffer size
|
||||
INT32 nVidImageHeight = DEFAULT_IMAGE_HEIGHT; //
|
||||
INT32 nVidImageLeft = 0, nVidImageTop = 0; // Memory buffer visible area offsets
|
||||
|
|
|
@ -30,9 +30,11 @@ INT32 VidSAllocVidImage()
|
|||
if (pVidSFullImage) {
|
||||
memset(pVidSFullImage, 0, nMemLen);
|
||||
pVidImage = pVidSFullImage + nVidImagePitch;
|
||||
pVidImageSize = nMemLen;
|
||||
return 0;
|
||||
} else {
|
||||
pVidImage = NULL;
|
||||
pVidImageSize = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ static DDBLTFX* DtoBltFx = NULL; // We use mirrored blits for flipped games
|
|||
static IDirectDrawSurface7* pddsDtos = NULL; // The screen surface
|
||||
static int nGameWidth = 0, nGameHeight = 0; // screen size
|
||||
|
||||
static bool bNoHWFlip = 0; // no HW Flipping available, and we need to flip
|
||||
static UINT8* pVidImage2 = NULL; // Video Memory buffer for soft-flipping -dink
|
||||
|
||||
static bool bDtosScan;
|
||||
|
||||
static RECT Src = { 0, 0, 0, 0 };
|
||||
|
@ -164,6 +167,13 @@ static int DtosExit()
|
|||
|
||||
VidSFreeVidImage();
|
||||
|
||||
if (bNoHWFlip && nRotateGame & 2) { // dink
|
||||
free(pVidImage2);
|
||||
bNoHWFlip = 0;
|
||||
}
|
||||
|
||||
pVidImage2 = NULL;
|
||||
|
||||
VidSExitOSD();
|
||||
|
||||
return 0;
|
||||
|
@ -209,6 +219,13 @@ static int DtosInit()
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (bNoHWFlip && nRotateGame & 2) { // dink
|
||||
// Make second memory buffer, for soft-flipping
|
||||
pVidImage2 = (UINT8*)malloc(pVidImageSize);
|
||||
} else {
|
||||
pVidImage2 = pVidImage;
|
||||
}
|
||||
|
||||
// Make the DirectDraw secondary surface
|
||||
if (DtosMakeSurf()) {
|
||||
DtosExit();
|
||||
|
@ -300,6 +317,7 @@ static int vidInit()
|
|||
nGameWidth = nVidImageWidth; nGameHeight = nVidImageHeight;
|
||||
|
||||
nRotateGame = 0;
|
||||
|
||||
if (bDrvOkay) {
|
||||
DtoBltFx = NULL;
|
||||
|
||||
|
@ -321,6 +339,13 @@ static int vidInit()
|
|||
}
|
||||
|
||||
if (nRotateGame & 2) {
|
||||
// GetCaps() can't be trusted for DDFXCAPS_BLTMIRROR*!!!
|
||||
// Some drivers report having them, but they don't flip.
|
||||
// Some drivers report NOT having them, but they will flip.
|
||||
// The last time it worked reliably was in WinXP. -dink April 25, 2021
|
||||
// Solution: software flipping.
|
||||
bNoHWFlip = 1;
|
||||
#if 0
|
||||
DDCAPS ddcaps;
|
||||
|
||||
// Disable flipping until we've checked the hardware supports it
|
||||
|
@ -330,8 +355,7 @@ static int vidInit()
|
|||
ddcaps.dwSize = sizeof(ddcaps);
|
||||
|
||||
DtoDD->GetCaps(&ddcaps, NULL);
|
||||
if (((ddcaps.dwFXCaps & DDFXCAPS_BLTMIRRORLEFTRIGHT) && (ddcaps.dwFXCaps & DDFXCAPS_BLTMIRRORUPDOWN)) || bVidForceFlip) {
|
||||
|
||||
if (((ddcaps.dwFXCaps & DDFXCAPS_BLTMIRRORLEFTRIGHT) && (ddcaps.dwFXCaps & DDFXCAPS_BLTMIRRORUPDOWN)) /*|| bVidForceFlip */) {
|
||||
DtoBltFx = (DDBLTFX*)malloc(sizeof(DDBLTFX));
|
||||
if (DtoBltFx == NULL) {
|
||||
vidExit();
|
||||
|
@ -346,6 +370,7 @@ static int vidInit()
|
|||
// Enable flipping now
|
||||
nRotateGame |= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,7 +406,7 @@ static int vidInit()
|
|||
if (bDrvOkay) {
|
||||
if (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) {
|
||||
if (nRotateGame & 2) {
|
||||
dprintf(_T(" * Using graphics hardware to rotate the image 180 degrees.\n"));
|
||||
dprintf(_T(" * Using software to rotate the image 180 degrees.\n"));
|
||||
} else {
|
||||
dprintf(_T(" * Warning: Graphics hardware does not support mirroring blits.\n Image orientation will be incorrect.\n"));
|
||||
}
|
||||
|
@ -480,7 +505,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
case 4: {
|
||||
int t;
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 4;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 4;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
t = *(int*)ps;
|
||||
|
@ -495,7 +520,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
}
|
||||
case 3: {
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 3;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 3;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
pdd[0] = ps[0];
|
||||
|
@ -513,7 +538,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
case 2: {
|
||||
short t;
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 2;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 2;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
t = *(short*)ps;
|
||||
|
@ -536,7 +561,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
case 4: {
|
||||
int t;
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch * 2) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 4;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 4;
|
||||
pdd = pd;
|
||||
pd2 = pBuffer;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
|
@ -557,7 +582,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
}
|
||||
case 3: {
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch * 2) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 3;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 3;
|
||||
pdd = pd;
|
||||
pd2 = pBuffer;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
|
@ -584,7 +609,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
case 2: {
|
||||
short t;
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch * 2) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 2;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 2;
|
||||
pdd = pd;
|
||||
pd2 = pBuffer;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
|
@ -620,7 +645,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
switch (nVidImageBPP) {
|
||||
case 4: {
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 4;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 4;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
*(int*)pdd = *(int*)ps;
|
||||
|
@ -632,7 +657,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
}
|
||||
case 3: {
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 3;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 3;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
pdd[0] = ps[0];
|
||||
|
@ -646,7 +671,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
}
|
||||
case 2: {
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 2;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 2;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
*(short*)pdd = *(short*)ps;
|
||||
|
@ -662,7 +687,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
switch (nVidImageBPP) {
|
||||
case 4: {
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 4;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 4;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
*(int*)pdd = *(int*)ps;
|
||||
|
@ -674,7 +699,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
}
|
||||
case 3: {
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 3;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 3;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
pdd[0] = ps[0];
|
||||
|
@ -688,7 +713,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
}
|
||||
case 2: {
|
||||
for (int y = 0; y < nGameHeight; y++, pd += nPitch) {
|
||||
ps = pVidImage + (nGameHeight - 1 - y) * 2;
|
||||
ps = pVidImage2 + (nGameHeight - 1 - y) * 2;
|
||||
pdd = pd;
|
||||
for (int x = 0; x < nGameWidth; x++) {
|
||||
*(short*)pdd = *(short*)ps;
|
||||
|
@ -704,7 +729,7 @@ static int vidRenderRotate(DDSURFACEDESC2* ddsd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Copy pVidImage to pddsDtos, don't rotate, add scanlines in odd lines if needed
|
||||
// Copy pVidImage2 to pddsDtos, don't rotate, add scanlines in odd lines if needed
|
||||
static int vidRenderNoRotateHorScanlines(DDSURFACEDESC2* ddsd, int nField, int nHalf)
|
||||
{
|
||||
unsigned char *pd, *ps;
|
||||
|
@ -718,7 +743,7 @@ static int vidRenderNoRotateHorScanlines(DDSURFACEDESC2* ddsd, int nField, int n
|
|||
nPitch <<= 1;
|
||||
}
|
||||
|
||||
pd = Surf; ps = pVidImage;
|
||||
pd = Surf; ps = pVidImage2;
|
||||
for (int y = 0; y < nVidImageHeight; y++, pd += nPitch, ps += nVidImagePitch) {
|
||||
if (nHalf == 0) {
|
||||
memcpy(pd, ps, nVidImagePitch);
|
||||
|
@ -742,7 +767,7 @@ static int vidRenderNoRotateHorScanlines(DDSURFACEDESC2* ddsd, int nField, int n
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Copy pVidImage to pddsDtos, don't rotate, add rotated scanlines
|
||||
// Copy pVidImage2 to pddsDtos, don't rotate, add rotated scanlines
|
||||
static int vidRenderNoRotateVertScanlines(DDSURFACEDESC2* ddsd)
|
||||
{
|
||||
unsigned char *pd, *ps;
|
||||
|
@ -750,7 +775,7 @@ static int vidRenderNoRotateVertScanlines(DDSURFACEDESC2* ddsd)
|
|||
int nPitch = ddsd->lPitch;
|
||||
|
||||
if (bVidScanHalf) {
|
||||
pd = Surf; ps = pVidImage;
|
||||
pd = Surf; ps = pVidImage2;
|
||||
switch (nVidImageBPP) {
|
||||
case 4: {
|
||||
unsigned char* pdp;
|
||||
|
@ -815,7 +840,7 @@ static int vidRenderNoRotateVertScanlines(DDSURFACEDESC2* ddsd)
|
|||
}
|
||||
|
||||
} else {
|
||||
pd = Surf; ps = pVidImage;
|
||||
pd = Surf; ps = pVidImage2;
|
||||
switch (nVidImageBPP) {
|
||||
case 4: {
|
||||
unsigned char* pdp;
|
||||
|
@ -876,6 +901,55 @@ static int vidRenderNoRotateVertScanlines(DDSURFACEDESC2* ddsd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void vidSoftFlip()
|
||||
{
|
||||
// DirectDraw HW flipping is not supported in most newer video drivers
|
||||
// (Windows 7+). Sometimes GetCaps() even says the driver can flip when
|
||||
// it can't. Let's do it manually. -dink
|
||||
|
||||
unsigned char* ps;
|
||||
unsigned char* pd = pVidImage2;
|
||||
pd += nVidImageHeight * nVidImagePitch - nVidImageBPP;
|
||||
|
||||
switch (nVidImageBPP) {
|
||||
case 4: {
|
||||
for (int y = 0; y < nVidImageHeight; y++) {
|
||||
ps = pVidImage + y * nVidImagePitch + nVidImageLeft * 2;
|
||||
for (int x = 0; x < nVidImageWidth; x++) {
|
||||
*(int*)pd = *(int*)ps;
|
||||
ps += 4;
|
||||
pd -= 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
for (int y = 0; y < nVidImageHeight; y++) {
|
||||
ps = pVidImage + y * nVidImagePitch + nVidImageLeft * 3;
|
||||
for (int x = 0; x < nVidImageWidth; x++) {
|
||||
pd[0] = ps[0];
|
||||
pd[1] = ps[2];
|
||||
pd[2] = ps[2];
|
||||
ps += 3;
|
||||
pd -= 3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
for (int y = 0; y < nVidImageHeight; y++) {
|
||||
ps = pVidImage + y * nVidImagePitch + nVidImageLeft * 2;
|
||||
for (int x = 0; x < nVidImageWidth; x++) {
|
||||
*(short*)pd = *(short*)ps;
|
||||
ps += 2;
|
||||
pd -= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int vidBurnToSurf()
|
||||
{
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
@ -940,6 +1014,10 @@ static int vidBurnToSurf()
|
|||
|
||||
bDtosScan = bScan;
|
||||
|
||||
if (nRotateGame & 2 && bNoHWFlip) {
|
||||
vidSoftFlip();
|
||||
}
|
||||
|
||||
if (nRotateGame & 1) {
|
||||
vidRenderRotate(&ddsd);
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue