- 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) if (Video != NULL)
{ {
while ((haveMode = Video->NextMode (&width, &height, &letterbox)) && 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 "templates.h"
#include "s_sound.h" #include "s_sound.h"
void ScaleWithAspect (int &w, int &h, int Width, int Height);
static void I_CheckGUICapture (); static void I_CheckGUICapture ();
static void I_CheckNativeMouse (); static void I_CheckNativeMouse ();
@ -318,6 +320,33 @@ void MessagePump (const SDL_Event &sev)
int x, y; int x, y;
SDL_GetMouseState (&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.data1 = x;
event.data2 = y; event.data2 = y;
event.type = EV_GUI_Event; event.type = EV_GUI_Event;

View file

@ -61,9 +61,14 @@ private:
SDL_Window *Screen; SDL_Window *Screen;
SDL_Renderer *Renderer; SDL_Renderer *Renderer;
union
{
SDL_Texture *Texture; SDL_Texture *Texture;
SDL_Surface *Surface;
};
SDL_Rect UpdateRect; SDL_Rect UpdateRect;
bool UsingRenderer;
bool NeedPalUpdate; bool NeedPalUpdate;
bool NeedGammaUpdate; bool NeedGammaUpdate;
bool NotPaletted; bool NotPaletted;
@ -98,11 +103,9 @@ EXTERN_CVAR (Bool, vid_vsync)
CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) 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 CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
// frame buffer is changed at run time.
CVAR (Bool, vid_asyncblit, 1, CVAR_NOINITCALL|CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Float, rgamma, 1.f, 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, 600 }, // 16:10
{ 960, 720 }, { 960, 720 },
{ 1024, 576 }, // 16:9 { 1024, 576 }, // 16:9
{ 1024, 600 }, // 17:10
{ 1024, 640 }, // 16:10 { 1024, 640 }, // 16:10
{ 1024, 768 }, { 1024, 768 },
{ 1088, 612 }, // 16:9 { 1088, 612 }, // 16:9
@ -160,6 +164,7 @@ static MiniModeInfo WinModes[] =
{ 1280, 720 }, // 16:9 { 1280, 720 }, // 16:9
{ 1280, 800 }, // 16:10 { 1280, 800 }, // 16:10
{ 1280, 960 }, { 1280, 960 },
{ 1280, 1024 }, // 5:4
{ 1360, 768 }, // 16:9 { 1360, 768 }, // 16:9
{ 1400, 787 }, // 16:9 { 1400, 787 }, // 16:9
{ 1400, 875 }, // 16:10 { 1400, 875 }, // 16:10
@ -168,6 +173,13 @@ static MiniModeInfo WinModes[] =
{ 1600, 1000 }, // 16:10 { 1600, 1000 }, // 16:10
{ 1600, 1200 }, { 1600, 1200 },
{ 1920, 1080 }, { 1920, 1080 },
{ 1920, 1200 },
{ 2048, 1536 },
{ 2560, 1440 },
{ 2560, 1600 },
{ 2880, 1800 },
{ 3840, 2160 },
{ 5120, 2880 }
}; };
static cycle_t BlitCycles; static cycle_t BlitCycles;
@ -175,10 +187,34 @@ static cycle_t SDLFlipCycles;
// CODE -------------------------------------------------------------------- // 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) SDLVideo::SDLVideo (int parm)
{ {
IteratorBits = 0; IteratorBits = 0;
IteratorFS = false;
} }
SDLVideo::~SDLVideo () SDLVideo::~SDLVideo ()
@ -189,7 +225,6 @@ void SDLVideo::StartModeIterator (int bits, bool fs)
{ {
IteratorMode = 0; IteratorMode = 0;
IteratorBits = bits; IteratorBits = bits;
IteratorFS = fs;
} }
bool SDLVideo::NextMode (int *width, int *height, bool *letterbox) bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
@ -197,8 +232,6 @@ bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
if (IteratorBits != 8) if (IteratorBits != 8)
return false; return false;
if (!IteratorFS)
{
if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0])) if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0]))
{ {
*width = WinModes[IteratorMode].Width; *width = WinModes[IteratorMode].Width;
@ -206,23 +239,6 @@ bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
++IteratorMode; ++IteratorMode;
return true; 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;
return true;
}
return false; return false;
} }
@ -431,8 +447,19 @@ void SDLFB::Update ()
void *pixels; void *pixels;
int pitch; int pitch;
if (UsingRenderer)
{
if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) if (SDL_LockTexture (Texture, NULL, &pixels, &pitch))
return; return;
}
else
{
if (SDL_LockSurface (Surface))
return;
pixels = Surface->pixels;
pitch = Surface->pitch;
}
if (NotPaletted) if (NotPaletted)
{ {
@ -440,29 +467,38 @@ void SDLFB::Update ()
pixels, pitch, Width, Height, pixels, pitch, Width, Height,
FRACUNIT, FRACUNIT, 0, 0); FRACUNIT, FRACUNIT, 0, 0);
} }
#if 0
else else
{ {
if (Screen->pitch == Pitch) if (pitch == Pitch)
{ {
memcpy (Screen->pixels, MemBuffer, Width*Height); memcpy (pixels, MemBuffer, Width*Height);
} }
else else
{ {
for (int y = 0; y < Height; ++y) 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
if (UsingRenderer)
{
SDL_UnlockTexture (Texture); SDL_UnlockTexture (Texture);
SDLFlipCycles.Clock(); SDLFlipCycles.Clock();
SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect);
SDL_RenderPresent(Renderer); SDL_RenderPresent(Renderer);
SDLFlipCycles.Unclock(); SDLFlipCycles.Unclock();
}
else
{
SDL_UnlockSurface (Surface);
SDLFlipCycles.Clock();
SDL_UpdateWindowSurface (Screen);
SDLFlipCycles.Unclock();
}
BlitCycles.Unclock(); BlitCycles.Unclock();
@ -503,7 +539,6 @@ void SDLFB::UpdateColors ()
} }
GPfx.SetPalette (palette); GPfx.SetPalette (palette);
} }
#if 0
else else
{ {
SDL_Color colors[256]; SDL_Color colors[256];
@ -520,9 +555,8 @@ void SDLFB::UpdateColors ()
256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r], 256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r],
FlashAmount); FlashAmount);
} }
SDL_SetPalette (Screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256); SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256);
} }
#endif
} }
PalEntry *SDLFB::GetPalette () PalEntry *SDLFB::GetPalette ()
@ -592,14 +626,25 @@ void SDLFB::ResetSDLRenderer ()
SDL_DestroyRenderer (Renderer); SDL_DestroyRenderer (Renderer);
} }
UsingRenderer = !vid_forcesurface;
if (UsingRenderer)
{
Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE|
(vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0));
if (!Renderer) if (!Renderer)
return; return;
Texture = SDL_CreateTexture (Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, Width, Height); 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);
//if (Screen->format->palette == NULL)
{ {
NotPaletted = true; NotPaletted = true;
@ -611,6 +656,19 @@ void SDLFB::ResetSDLRenderer ()
SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); 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 // Calculate update rectangle
if (IsFullscreen ()) if (IsFullscreen ())
@ -618,8 +676,9 @@ void SDLFB::ResetSDLRenderer ()
int w, h; int w, h;
SDL_GetWindowSize (Screen, &w, &h); SDL_GetWindowSize (Screen, &w, &h);
UpdateRect.w = w; UpdateRect.w = w;
UpdateRect.h = w*Height/Width; UpdateRect.h = h;
UpdateRect.x = 0; ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height);
UpdateRect.x = (w - UpdateRect.w)/2;
UpdateRect.y = (h - UpdateRect.h)/2; UpdateRect.y = (h - UpdateRect.h)/2;
} }
else else

View file

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