gdi, display: fix 320x240 letterboxed modes

This commit is contained in:
Rairii
2025-03-16 22:05:11 +00:00
parent 4c138cc582
commit af4f08fbdf
3 changed files with 61 additions and 22 deletions

View File

@@ -59,13 +59,21 @@ POINTL *pptlSrc)
ULONG destWidth = psoDest->sizlBitmap.cx;
if (psoDest->lDelta < 0) pDestFbStart += (destHeight * psoDest->lDelta);
ULONG heightOffset = 0, widthOffset = 0;
if (destHeight == 240) {
heightOffset = (480 / 2) - (240 / 2);
widthOffset = (640 / 2) - (320 / 2);
}
if ((heightOffset & 1) != 0) heightOffset--;
if ((widthOffset & 1) != 0) widthOffset--;
ULONG cyIdx = 0;
while (1) {
PULONG pulSrcTemp = pulSrc;
PULONG pulDstTemp = pulDst;
// Bounds check the pointers, we could be in here when drawing off the screen
if (pulSrc >= pstartSrc && pulDst >= pstartDst) {
ULONG TexOffsetY = CalculateTexYOffset32(yDstStart + cyIdx, destWidth);
ULONG TexOffsetY = CalculateTexYOffset32(yDstStart + cyIdx + heightOffset, 640);
ULONG TexOffset = 0;
ULONG cxTemp = cx;
@@ -82,7 +90,7 @@ POINTL *pptlSrc)
pulSrcTemp++;
//EfbWrite32(pulDstTemp, sourceVal);
//pulDstTemp++;
TexOffset = CalculateTexOffsetWithYOffset32(xDst + cxIdx, TexOffsetY);
TexOffset = CalculateTexOffsetWithYOffset32(xDst + cxIdx + widthOffset, TexOffsetY);
if (((TexOffset & 3) == 0) && ((xDst + cxIdx) & 3) < 3 && (cxTemp > 1)) {
// Will be writing the next pixel too, we can optimise this to two writes from four reads and four writes.
ULONG sourceVal2 = LoadToRegister32(*pulSrcTemp);
@@ -172,13 +180,21 @@ POINTL *pptlSrc)
ULONG destWidth = psoDest->sizlBitmap.cx;
if (psoDest->lDelta < 0) pDestFbStart += (destHeight * psoDest->lDelta);
ULONG heightOffset = 0, widthOffset = 0;
if (destHeight == 240) {
heightOffset = (480 / 2) - (240 / 2);
widthOffset = (640 / 2) - (320 / 2);
}
if ((heightOffset & 1) != 0) heightOffset--;
if ((widthOffset & 1) != 0) widthOffset--;
ULONG cyIdx = 0;
while (1) {
PUSHORT pusSrcTemp = pusSrc;
PUSHORT pusDstTemp = pusDst;
// Bounds check the pointers, we could be in here when drawing off the screen
if (pusSrc >= pstartSrc && pusDst >= pstartDst) {
ULONG TexOffsetY = CalculateTexYOffset16(yDstStart + cyIdx, destWidth);
ULONG TexOffsetY = CalculateTexYOffset16(yDstStart + cyIdx + heightOffset, 640);
ULONG TexOffset = 0;
ULONG cxTemp = cx;
@@ -193,7 +209,7 @@ POINTL *pptlSrc)
if (validAccess) {
//EfbWrite32(pulDstTemp, sourceVal);
//pulDstTemp++;
TexOffset = CalculateTexOffsetWithYOffset16(xDst + cxIdx, TexOffsetY);
TexOffset = CalculateTexOffsetWithYOffset16(xDst + cxIdx + widthOffset, TexOffsetY);
if (((TexOffset & 3) == 0) && ((xDst + cxIdx) & 3) < 3 && (cxTemp > 1)) {
// Will be writing the next pixel too, optimise to a single write from one read and one write
ULONG sourceVal2 = LoadToRegister32(*(PULONG)pusSrcTemp);
@@ -280,13 +296,21 @@ POINTL *pptlSrc)
ULONG destWidth = psoDest->sizlBitmap.cx;
if (lDeltaDst < 0) pDestFbStart += (destHeight * lDeltaDst);
ULONG heightOffset = 0, widthOffset = 0;
if (destHeight == 240) {
heightOffset = (480 / 2) - (240 / 2);
widthOffset = (640 / 2) - (320 / 2);
}
if ((heightOffset & 3) != 0) heightOffset -= (4 - (heightOffset & 3));
if ((widthOffset & 3) != 0) widthOffset -= (4 - (widthOffset & 3));
ULONG cyIdx = 0;
while (1) {
PUCHAR pucSrcTemp = pucSrc;
PUCHAR pucDstTemp = pucDst;
// Bounds check the pointers, we could be in here when drawing off the screen
if (pucSrc >= pstartSrc && pucDst >= pstartDst) {
ULONG TexOffsetY = CalculateTexYOffset8(yDstStart + cyIdx, destWidth);
ULONG TexOffsetY = CalculateTexYOffset8(yDstStart + cyIdx + heightOffset, 640);
ULONG TexOffset = 0;
ULONG cxTemp = cx;
@@ -301,7 +325,7 @@ POINTL *pptlSrc)
if (validAccess) {
//EfbWrite32(pulDstTemp, sourceVal);
//pulDstTemp++;
TexOffset = CalculateTexOffsetWithYOffset8(xDst + cxIdx, TexOffsetY);
TexOffset = CalculateTexOffsetWithYOffset8(xDst + cxIdx + widthOffset, TexOffsetY);
if (((TexOffset & 3) == 0) && ((xDst + cxIdx) & 7) < 5 && (cxTemp > 3)) {
// Writing aligned at least four pixels.
// Optimise to a single write

View File

@@ -59,13 +59,21 @@ POINTL *pptlSrc)
ULONG destWidth = psoDest->sizlBitmap.cx;
if (psoDest->lDelta < 0) pDestFbStart += (destHeight * psoDest->lDelta);
ULONG heightOffset = 0, widthOffset = 0;
if (destHeight == 240) {
heightOffset = (480 / 2) - (240 / 2);
widthOffset = (640 / 2) - (320 / 2);
}
if ((heightOffset & 1) != 0) heightOffset--;
if ((widthOffset & 1) != 0) widthOffset--;
ULONG cyIdx = 0;
while (1) {
PULONG pulSrcTemp = pulSrc;
PULONG pulDstTemp = pulDst;
// Bounds check the pointers, we could be in here when drawing off the screen
if (pulSrc >= pstartSrc && pulDst >= pstartDst) {
ULONG TexOffsetY = CalculateTexYOffset32(yDstStart + cyIdx, destWidth);
ULONG TexOffsetY = CalculateTexYOffset32(yDstStart + cyIdx + heightOffset, 640);
ULONG TexOffset = 0;
ULONG cxTemp = cx;
@@ -82,7 +90,7 @@ POINTL *pptlSrc)
pulSrcTemp++;
//EfbWrite32(pulDstTemp, sourceVal);
//pulDstTemp++;
TexOffset = CalculateTexOffsetWithYOffset32(xDst + cxIdx, TexOffsetY);
TexOffset = CalculateTexOffsetWithYOffset32(xDst + cxIdx + widthOffset, TexOffsetY);
if (((TexOffset & 3) == 0) && ((xDst + cxIdx) & 3) < 3 && (cxTemp > 1)) {
// Will be writing the next pixel too, we can optimise this to two writes from four reads and four writes.
ULONG sourceVal2 = LoadToRegister32(*pulSrcTemp);
@@ -172,13 +180,21 @@ POINTL *pptlSrc)
ULONG destWidth = psoDest->sizlBitmap.cx;
if (psoDest->lDelta < 0) pDestFbStart += (destHeight * psoDest->lDelta);
ULONG heightOffset = 0, widthOffset = 0;
if (destHeight == 240) {
heightOffset = (480 / 2) - (240 / 2);
widthOffset = (640 / 2) - (320 / 2);
}
if ((heightOffset & 1) != 0) heightOffset--;
if ((widthOffset & 1) != 0) widthOffset--;
ULONG cyIdx = 0;
while (1) {
PUSHORT pusSrcTemp = pusSrc;
PUSHORT pusDstTemp = pusDst;
// Bounds check the pointers, we could be in here when drawing off the screen
if (pusSrc >= pstartSrc && pusDst >= pstartDst) {
ULONG TexOffsetY = CalculateTexYOffset16(yDstStart + cyIdx, destWidth);
ULONG TexOffsetY = CalculateTexYOffset16(yDstStart + cyIdx + heightOffset, 640);
ULONG TexOffset = 0;
ULONG cxTemp = cx;
@@ -193,7 +209,7 @@ POINTL *pptlSrc)
if (validAccess) {
//EfbWrite32(pulDstTemp, sourceVal);
//pulDstTemp++;
TexOffset = CalculateTexOffsetWithYOffset16(xDst + cxIdx, TexOffsetY);
TexOffset = CalculateTexOffsetWithYOffset16(xDst + cxIdx + widthOffset, TexOffsetY);
if (((TexOffset & 3) == 0) && ((xDst + cxIdx) & 3) < 3 && (cxTemp > 1)) {
// Will be writing the next pixel too, optimise to a single write from one read and one write
ULONG sourceVal2 = LoadToRegister32(*(PULONG)pusSrcTemp);
@@ -280,13 +296,21 @@ POINTL *pptlSrc)
ULONG destWidth = psoDest->sizlBitmap.cx;
if (lDeltaDst < 0) pDestFbStart += (destHeight * lDeltaDst);
ULONG heightOffset = 0, widthOffset = 0;
if (destHeight == 240) {
heightOffset = (480 / 2) - (240 / 2);
widthOffset = (640 / 2) - (320 / 2);
}
if ((heightOffset & 3) != 0) heightOffset -= (4 - (heightOffset & 3));
if ((widthOffset & 3) != 0) widthOffset -= (4 - (widthOffset & 3));
ULONG cyIdx = 0;
while (1) {
PUCHAR pucSrcTemp = pucSrc;
PUCHAR pucDstTemp = pucDst;
// Bounds check the pointers, we could be in here when drawing off the screen
if (pucSrc >= pstartSrc && pucDst >= pstartDst) {
ULONG TexOffsetY = CalculateTexYOffset8(yDstStart + cyIdx, destWidth);
ULONG TexOffsetY = CalculateTexYOffset8(yDstStart + cyIdx + heightOffset, 640);
ULONG TexOffset = 0;
ULONG cxTemp = cx;
@@ -301,7 +325,7 @@ POINTL *pptlSrc)
if (validAccess) {
//EfbWrite32(pulDstTemp, sourceVal);
//pulDstTemp++;
TexOffset = CalculateTexOffsetWithYOffset8(xDst + cxIdx, TexOffsetY);
TexOffset = CalculateTexOffsetWithYOffset8(xDst + cxIdx + widthOffset, TexOffsetY);
if (((TexOffset & 3) == 0) && ((xDst + cxIdx) & 7) < 5 && (cxTemp > 3)) {
// Writing aligned at least four pixels.
// Optimise to a single write

View File

@@ -57,7 +57,6 @@ typedef struct _DEVICE_EXTENSION {
PUSHORT ArrayVerticies;
ULONG ArrayVerticiesPhys;
ULONG VideoModeIndex;
ULONG CurrentDoubleOffset;
KDPC TimerDpc;
KTIMER Timer;
//BOOLEAN InIoSpace;
@@ -888,7 +887,6 @@ VP_STATUS ViFindAdapter(PVOID HwDeviceExtension, PVOID HwContext, PWSTR Argument
Extension->BitmapBuffer = NULL;
Extension->DoubleFrameBufferPhys = 0;
Extension->FrameBufferOffset = 0;
Extension->CurrentDoubleOffset = 0;
Extension->VideoModeIndex = 0;
if (SetupddLoaded || !HasWin32k)
{
@@ -1013,6 +1011,7 @@ VP_STATUS ViFindAdapter(PVOID HwDeviceExtension, PVOID HwContext, PWSTR Argument
if (Res == RESOLUTION_240P) {
s_VideoModes[i].VisScreenWidth = 320;
s_VideoModes[i].VisScreenHeight = 240;
s_VideoModes[i].ScreenStride = 320 * sizeof(ULONG);
}
if (Depth == COLOUR_DEPTH_16) {
@@ -1372,14 +1371,6 @@ VP_STATUS ViStartIoImpl(PDEVICE_EXTENSION Extension, PVIDEO_REQUEST_PACKET Reque
VI_INTERRUPT_DISABLE(0);
VI_INTERRUPT_DISABLE(1);
Extension->VideoModeIndex = Mode->RequestedMode;
ULONG Offset = 0;
if ((Extension->VideoModeIndex / RESOLUTION_COUNT) == RESOLUTION_240P) {
Offset = DOUBLE_FRAMEBUFFER_STRIDE;
ULONG CentreHeight = (480 / 2) - (240 / 2);
Offset *= CentreHeight;
Offset += (640 / 2) - (320 / 2);
}
Extension->CurrentDoubleOffset = Offset;
ViInitialise(Extension);
return NO_ERROR;
}