- Improve letterboxing in fullscreen by taking into account animorphic ratio settings.

- Added more resolutions to the hard coded table (up to 5K).
- Since we're using scaling for fullscreen, we should probably just use the hard coded table for fullscreen resolutions as well.
- Fixed: Resolution menu used fake aspect ratio to determine which aspect to file a resolution under.
- Added a way to use SDL surface blitting instead of accelerated textures.
This commit is contained in:
Braden Obrzut 2014-12-11 01:35:27 -05:00
parent a7b33a8ce3
commit 965d602d26
4 changed files with 156 additions and 65 deletions

View file

@ -247,8 +247,12 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits)
if (Video != NULL)
{
while ((haveMode = Video->NextMode (&width, &height, &letterbox)) &&
(ratiomatch >= 0 && CheckRatio (width, height) != ratiomatch))
ratiomatch >= 0)
{
int ratio;
CheckRatio (width, height, &ratio);
if (ratio == ratiomatch)
break;
}
}

View file

@ -18,6 +18,8 @@
#include "templates.h"
#include "s_sound.h"
void ScaleWithAspect (int &w, int &h, int Width, int Height);
static void I_CheckGUICapture ();
static void I_CheckNativeMouse ();
@ -318,6 +320,33 @@ void MessagePump (const SDL_Event &sev)
int x, y;
SDL_GetMouseState (&x, &y);
// Detect if we're doing scaling in the Window and adjust the mouse
// coordinates accordingly. This could be more efficent, but I
// don't think performance is an issue in the menus.
SDL_Window *focus;
if (screen->IsFullscreen() && (focus = SDL_GetMouseFocus ()))
{
int w, h;
SDL_GetWindowSize (focus, &w, &h);
int realw = w, realh = h;
ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT);
if (realw != SCREENWIDTH || realh != SCREENHEIGHT)
{
double xratio = (double)SCREENWIDTH/realw;
double yratio = (double)SCREENHEIGHT/realh;
if (realw < w)
{
x = (x - (w - realw)/2)*xratio;
y *= yratio;
}
else
{
y = (y - (h - realh)/2)*yratio;
x *= xratio;
}
}
}
event.data1 = x;
event.data2 = y;
event.type = EV_GUI_Event;

View file

@ -61,9 +61,14 @@ private:
SDL_Window *Screen;
SDL_Renderer *Renderer;
SDL_Texture *Texture;
union
{
SDL_Texture *Texture;
SDL_Surface *Surface;
};
SDL_Rect UpdateRect;
bool UsingRenderer;
bool NeedPalUpdate;
bool NeedGammaUpdate;
bool NotPaletted;
@ -98,11 +103,9 @@ EXTERN_CVAR (Bool, vid_vsync)
CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Int, vid_displaybits, 8, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Int, vid_displaybits, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
// vid_asyncblit needs a restart to work. SDL doesn't seem to change if the
// frame buffer is changed at run time.
CVAR (Bool, vid_asyncblit, 1, CVAR_NOINITCALL|CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
@ -151,6 +154,7 @@ static MiniModeInfo WinModes[] =
{ 960, 600 }, // 16:10
{ 960, 720 },
{ 1024, 576 }, // 16:9
{ 1024, 600 }, // 17:10
{ 1024, 640 }, // 16:10
{ 1024, 768 },
{ 1088, 612 }, // 16:9
@ -160,6 +164,7 @@ static MiniModeInfo WinModes[] =
{ 1280, 720 }, // 16:9
{ 1280, 800 }, // 16:10
{ 1280, 960 },
{ 1280, 1024 }, // 5:4
{ 1360, 768 }, // 16:9
{ 1400, 787 }, // 16:9
{ 1400, 875 }, // 16:10
@ -168,6 +173,13 @@ static MiniModeInfo WinModes[] =
{ 1600, 1000 }, // 16:10
{ 1600, 1200 },
{ 1920, 1080 },
{ 1920, 1200 },
{ 2048, 1536 },
{ 2560, 1440 },
{ 2560, 1600 },
{ 2880, 1800 },
{ 3840, 2160 },
{ 5120, 2880 }
};
static cycle_t BlitCycles;
@ -175,10 +187,34 @@ static cycle_t SDLFlipCycles;
// CODE --------------------------------------------------------------------
void ScaleWithAspect (int &w, int &h, int Width, int Height)
{
int resRatio = CheckRatio (Width, Height);
int screenRatio;
CheckRatio (w, h, &screenRatio);
if (resRatio == screenRatio)
return;
double yratio;
switch(resRatio)
{
case 0: yratio = 4./3.; break;
case 1: yratio = 16./9.; break;
case 2: yratio = 16./10.; break;
case 3: yratio = 17./10.; break;
case 4: yratio = 5./4.; break;
default: return;
}
double y = w/yratio;
if (y > h)
w = h*yratio;
else
h = y;
}
SDLVideo::SDLVideo (int parm)
{
IteratorBits = 0;
IteratorFS = false;
}
SDLVideo::~SDLVideo ()
@ -189,38 +225,18 @@ void SDLVideo::StartModeIterator (int bits, bool fs)
{
IteratorMode = 0;
IteratorBits = bits;
IteratorFS = fs;
}
bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
{
if (IteratorBits != 8)
return false;
if (!IteratorFS)
{
if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0]))
{
*width = WinModes[IteratorMode].Width;
*height = WinModes[IteratorMode].Height;
++IteratorMode;
return true;
}
}
else
{
SDL_DisplayMode mode = {}, oldmode = {};
if(IteratorMode != 0)
SDL_GetDisplayMode(vid_adapter, IteratorMode-1, &oldmode);
do
{
if (SDL_GetDisplayMode(vid_adapter, IteratorMode, &mode) != 0)
return false;
++IteratorMode;
} while(mode.w == oldmode.w && mode.h == oldmode.h);
*width = mode.w;
*height = mode.h;
if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0]))
{
*width = WinModes[IteratorMode].Width;
*height = WinModes[IteratorMode].Height;
++IteratorMode;
return true;
}
return false;
@ -431,8 +447,19 @@ void SDLFB::Update ()
void *pixels;
int pitch;
if (SDL_LockTexture (Texture, NULL, &pixels, &pitch))
return;
if (UsingRenderer)
{
if (SDL_LockTexture (Texture, NULL, &pixels, &pitch))
return;
}
else
{
if (SDL_LockSurface (Surface))
return;
pixels = Surface->pixels;
pitch = Surface->pitch;
}
if (NotPaletted)
{
@ -440,29 +467,38 @@ void SDLFB::Update ()
pixels, pitch, Width, Height,
FRACUNIT, FRACUNIT, 0, 0);
}
#if 0
else
{
if (Screen->pitch == Pitch)
if (pitch == Pitch)
{
memcpy (Screen->pixels, MemBuffer, Width*Height);
memcpy (pixels, MemBuffer, Width*Height);
}
else
{
for (int y = 0; y < Height; ++y)
{
memcpy ((BYTE *)Screen->pixels+y*Screen->pitch, MemBuffer+y*Pitch, Width);
memcpy ((BYTE *)pixels+y*pitch, MemBuffer+y*Pitch, Width);
}
}
}
#endif
SDL_UnlockTexture (Texture);
if (UsingRenderer)
{
SDL_UnlockTexture (Texture);
SDLFlipCycles.Clock();
SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect);
SDL_RenderPresent(Renderer);
SDLFlipCycles.Unclock();
SDLFlipCycles.Clock();
SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect);
SDL_RenderPresent(Renderer);
SDLFlipCycles.Unclock();
}
else
{
SDL_UnlockSurface (Surface);
SDLFlipCycles.Clock();
SDL_UpdateWindowSurface (Screen);
SDLFlipCycles.Unclock();
}
BlitCycles.Unclock();
@ -503,7 +539,6 @@ void SDLFB::UpdateColors ()
}
GPfx.SetPalette (palette);
}
#if 0
else
{
SDL_Color colors[256];
@ -520,9 +555,8 @@ void SDLFB::UpdateColors ()
256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r],
FlashAmount);
}
SDL_SetPalette (Screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256);
SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256);
}
#endif
}
PalEntry *SDLFB::GetPalette ()
@ -592,24 +626,48 @@ void SDLFB::ResetSDLRenderer ()
SDL_DestroyRenderer (Renderer);
}
Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE|
(vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0));
if (!Renderer)
return;
Texture = SDL_CreateTexture (Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, Width, Height);
//if (Screen->format->palette == NULL)
UsingRenderer = !vid_forcesurface;
if (UsingRenderer)
{
NotPaletted = true;
Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE|
(vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0));
if (!Renderer)
return;
Uint32 format;
SDL_QueryTexture(Texture, &format, NULL, NULL, NULL);
Uint32 fmt;
switch(vid_displaybits)
{
default: fmt = SDL_PIXELFORMAT_ARGB8888; break;
case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break;
case 24: fmt = SDL_PIXELFORMAT_RGB888; break;
case 16: fmt = SDL_PIXELFORMAT_RGB565; break;
case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break;
}
Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height);
Uint32 Rmask, Gmask, Bmask, Amask;
int bpp;
SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
GPfx.SetFormat (bpp, Rmask, Gmask, Bmask);
{
NotPaletted = true;
Uint32 format;
SDL_QueryTexture(Texture, &format, NULL, NULL, NULL);
Uint32 Rmask, Gmask, Bmask, Amask;
int bpp;
SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
GPfx.SetFormat (bpp, Rmask, Gmask, Bmask);
}
}
else
{
Surface = SDL_GetWindowSurface (Screen);
if (Surface->format->palette == NULL)
{
NotPaletted = true;
GPfx.SetFormat (Surface->format->BitsPerPixel, Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask);
}
else
NotPaletted = false;
}
// Calculate update rectangle
@ -618,8 +676,9 @@ void SDLFB::ResetSDLRenderer ()
int w, h;
SDL_GetWindowSize (Screen, &w, &h);
UpdateRect.w = w;
UpdateRect.h = w*Height/Width;
UpdateRect.x = 0;
UpdateRect.h = h;
ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height);
UpdateRect.x = (w - UpdateRect.w)/2;
UpdateRect.y = (h - UpdateRect.h)/2;
}
else

View file

@ -18,5 +18,4 @@ class SDLVideo : public IVideo
private:
int IteratorMode;
int IteratorBits;
bool IteratorFS;
};