Revise hardware scaler option to scale the window properly. Fix hardware scale calculation to scale the window properly in both dimensions for all hardware scaler options. Fix bug in hardware scale calculations that only vertically stretched the display beyond hardware2x. Disable normal scalers entirely if hardware scaling. Add comments to code explaning that if hardware scaling makes your DOS screen fuzzy you should either use a shader or go back to the none or normal2x, etc. scaler options

This commit is contained in:
Jonathan Campbell 2025-01-09 12:17:12 -08:00
parent ff83448dd7
commit a4d24f8fc7
3 changed files with 68 additions and 30 deletions

View File

@ -48,6 +48,7 @@ struct GFX_PalEntry {
#define GFX_LOVE_32 0x0080u
#define GFX_RGBONLY 0x0100u
#define GFX_NORMALSCALE 0x0200u // one of the Normal scalers and therefore should be ignored for hardware scaling
#define GFX_SCALING 0x1000u
#define GFX_HARDWARE 0x2000u

View File

@ -641,14 +641,44 @@ forcenormal:
#else
goto forcenormal;
#endif
gfx_flags = complexBlock->gfxFlags;
gfx_flags = complexBlock->gfxFlags & ~(GFX_NORMALSCALE);
xscale = complexBlock->xscale;
yscale = complexBlock->yscale;
// LOG_MSG("Scaler:%s",complexBlock->name);
} else {
gfx_flags = simpleBlock->gfxFlags;
gfx_flags = simpleBlock->gfxFlags & ~(GFX_NORMALSCALE);
xscale = simpleBlock->xscale;
yscale = simpleBlock->yscale;
if ((simpleBlock->gfxFlags & GFX_NORMALSCALE) && render.scale.hardware) {
/* Normal (pixel duplication) scalers should not be used for hardware scaling,
* because the hardware scaling will do all the scaling, AND so that users who
* use CRT scanline emulation shaders can work with the raw pixels and scanlines
* of the source video memory.
*
* This is not related to the "doublescan" option (on by default) that VGA emulation
* uses to emulate the hardware scan line duplication used to ensure that the raster
* to the monitor is 400-line or 480-line nor is it related to the double scan used
* in PC-98 200-line 8/16-color graphics modes to render as a 400-line raster.
*
* A side effect is that all your low res modes will look blurry when scaled up
* by your GPU. If you want a crisper look from the pixel duplication you're used
* too, use the none, normal2x, etc. scalers that are default anyway, OR use a
* shader that processes the video the way you prefer to see it.
*
* For this reason, the only difference in hardware_none, hardware2x, etc. is
* how much to multiply the GFX window scale without duplicating the pixels
* in software using any of the normal scalers INCLUDING the normal scalers
* used to double pixels horizontally and/or vertically for 200-line modes
* or 320-pixel wide modes.
*
* Because of integer scaling, the scale factor is restricted to a multiple of 2
* if the video mode would normally double pixels in one direction only but not
* both, such as CGA 80x25 text or CGA/EGA 640x200 graphics where normal scaler would
* normally only double pixels in the Y direction (height). */
simpleBlock = &ScaleNormal1x;
xscale = 1;
yscale = 1;
}
// LOG_MSG("Scaler:%s",simpleBlock->name);
}
switch (render.src.bpp) {
@ -700,34 +730,41 @@ forcenormal:
Bitu skip = complexBlock ? 1 : 0;
if (gfx_flags & GFX_SCALING) {
if(render.scale.size == 1 && render.scale.hardware) { //hardware_none
if(dblh)
gfx_scaleh *= 1;
if(dblw)
gfx_scalew *= 1;
} else if(render.scale.size == 4 && render.scale.hardware) {
/* don't scale */
} else if(render.scale.size == 2 && render.scale.hardware) {
if(dblh)
gfx_scaleh *= 2;
if(dblw)
gfx_scalew *= 2;
} else if(render.scale.size == 6 && render.scale.hardware) {
} else if(render.scale.size == 3 && render.scale.hardware) {
if(dblh && dblw) {
gfx_scaleh *= 3; gfx_scalew *= 3;
} else if(dblh) {
gfx_scaleh *= 2;
} else if(dblw)
gfx_scalew *= 2;
} else if(render.scale.size == 8 && render.scale.hardware) { //hardware4x
}
else {
if(dblh)
gfx_scaleh *= 2;
if(dblw)
gfx_scalew *= 2;
}
} else if(render.scale.size == 4 && render.scale.hardware) { //hardware4x
gfx_scaleh *= 2;
gfx_scalew *= 2;
if(dblh)
gfx_scaleh *= 4;
gfx_scaleh *= 2;
if(dblw)
gfx_scalew *= 4;
} else if(render.scale.size == 10 && render.scale.hardware) { //hardware5x
gfx_scalew *= 2;
} else if(render.scale.size == 5 && render.scale.hardware) { //hardware5x
if(dblh && dblw) {
gfx_scaleh *= 5; gfx_scalew *= 5;
} else if(dblh) {
gfx_scaleh *= 4;
} else if(dblw)
gfx_scalew *= 4;
}
else{
gfx_scaleh *= 2;
gfx_scalew *= 2;
if(dblh)
gfx_scaleh *= 2;
if(dblw)
gfx_scalew *= 2;
}
}
height = MakeAspectTable(skip, render.src.height, (double)yscale, yscale );
} else {

View File

@ -188,7 +188,7 @@ ScalerLineBlock_t ScalerCache = {
ScalerSimpleBlock_t ScaleNormal1x = {
"Normal",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
1,1,{
{ Normal1x_8_8_L, Normal1x_8_15_L , Normal1x_8_16_L , Normal1x_8_32_L },
{ nullptr, Normal1x_15_15_L, Normal1x_15_16_L, Normal1x_15_32_L},
@ -205,7 +205,7 @@ ScalerSimpleBlock_t ScaleNormal1x = {
ScalerSimpleBlock_t ScaleNormalDw = {
"Normal",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
2,1,{
{ NormalDw_8_8_L, NormalDw_8_15_L , NormalDw_8_16_L , NormalDw_8_32_L },
{ nullptr, NormalDw_15_15_L, NormalDw_15_16_L, NormalDw_15_32_L},
@ -222,7 +222,7 @@ ScalerSimpleBlock_t ScaleNormalDw = {
ScalerSimpleBlock_t ScaleNormalDh = {
"Normal",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
1,2,{
{ NormalDh_8_8_L, NormalDh_8_15_L , NormalDh_8_16_L , NormalDh_8_32_L },
{ nullptr, NormalDh_15_15_L, NormalDh_15_16_L, NormalDh_15_32_L},
@ -239,7 +239,7 @@ ScalerSimpleBlock_t ScaleNormalDh = {
ScalerSimpleBlock_t ScaleNormal2xDw = {
"Normal2x",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
4,2,{
{ Normal2xDw_8_8_L, Normal2xDw_8_15_L , Normal2xDw_8_16_L , Normal2xDw_8_32_L },
{ nullptr, Normal2xDw_15_15_L, Normal2xDw_15_16_L, Normal2xDw_15_32_L},
@ -256,7 +256,7 @@ ScalerSimpleBlock_t ScaleNormal2xDw = {
ScalerSimpleBlock_t ScaleNormal2xDh = {
"Normal2x",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
2,4,{
{ Normal2xDh_8_8_L, Normal2xDh_8_15_L , Normal2xDh_8_16_L , Normal2xDh_8_32_L },
{ nullptr, Normal2xDh_15_15_L, Normal2xDh_15_16_L, Normal2xDh_15_32_L},
@ -273,7 +273,7 @@ ScalerSimpleBlock_t ScaleNormal2xDh = {
ScalerSimpleBlock_t ScaleNormal2x = {
"Normal2x",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
2,2,{
{ Normal2x_8_8_L, Normal2x_8_15_L, Normal2x_8_16_L, Normal2x_8_32_L },
{ nullptr, Normal2x_15_15_L, Normal2x_15_16_L, Normal2x_15_32_L},
@ -290,7 +290,7 @@ ScalerSimpleBlock_t ScaleNormal2x = {
ScalerSimpleBlock_t ScaleNormal3x = {
"Normal3x",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
3,3,{
{ Normal3x_8_8_L, Normal3x_8_15_L , Normal3x_8_16_L , Normal3x_8_32_L },
{ nullptr, Normal3x_15_15_L, Normal3x_15_16_L, Normal3x_15_32_L},
@ -307,7 +307,7 @@ ScalerSimpleBlock_t ScaleNormal3x = {
ScalerSimpleBlock_t ScaleNormal4x = {
"Normal4x",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
4,4,{
{ Normal4x_8_8_L, Normal4x_8_15_L , Normal4x_8_16_L , Normal4x_8_32_L },
{ nullptr, Normal4x_15_15_L, Normal4x_15_16_L, Normal4x_15_32_L},
@ -324,7 +324,7 @@ ScalerSimpleBlock_t ScaleNormal4x = {
ScalerSimpleBlock_t ScaleNormal5x = {
"Normal5x",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
5,5,{
{ Normal5x_8_8_L, Normal5x_8_15_L , Normal5x_8_16_L , Normal5x_8_32_L },
{ nullptr, Normal5x_15_15_L, Normal5x_15_16_L, Normal5x_15_32_L},
@ -341,7 +341,7 @@ ScalerSimpleBlock_t ScaleNormal5x = {
/*ScalerSimpleBlock_t ScaleNormal6x = {
"Normal6x",
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_NORMALSCALE,
6,6,{
{ Normal6x_8_8_L, Normal6x_8_15_L , Normal6x_8_16_L , Normal6x_8_32_L },
{ nullptr, Normal6x_15_15_L, Normal6x_15_16_L, Normal6x_15_32_L},