gzdoom-gles/src/sdl/hardware.cpp
Christoph Oelckers 5e6f709dbf - Changed: When the screen is being deleted the 'screen' variable should be
set to NULL before performing the delete. Otherwise, in some abnormal
  situations, it could happen that the destroyed screen object is still
  being accessed.
- Fixed: V_Shutdown didn't set OF_YesReallyDelete before deleting screen.


SVN r870 (trunk)
2008-03-30 08:58:36 +00:00

218 lines
5.7 KiB
C++

/*
** hardware.cpp
** Somewhat OS-independant interface to the screen, mouse, keyboard, and stick
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include <SDL.h>
#include "hardware.h"
#include "i_video.h"
#include "i_system.h"
#include "c_console.h"
#include "c_cvars.h"
#include "c_dispatch.h"
#include "sdlvideo.h"
#include "v_text.h"
EXTERN_CVAR (Bool, ticker)
EXTERN_CVAR (Bool, fullscreen)
EXTERN_CVAR (Float, vid_winscale)
IVideo *Video;
void I_ShutdownGraphics ()
{
if (screen)
{
DFrameBuffer *s = screen;
screen = NULL;
s->ObjectFlags |= OF_YesReallyDelete;
delete s;
}
if (Video)
delete Video, Video = NULL;
}
void I_InitGraphics ()
{
UCVarValue val;
val.Bool = !!Args->CheckParm ("-devparm");
ticker.SetGenericRepDefault (val, CVAR_Bool);
Video = new SDLVideo (0);
if (Video == NULL)
I_FatalError ("Failed to initialize display");
atterm (I_ShutdownGraphics);
Video->SetWindowedScale (vid_winscale);
}
/** Remaining code is common to Win32 and Linux **/
// VIDEO WRAPPERS ---------------------------------------------------------
DFrameBuffer *I_SetMode (int &width, int &height, DFrameBuffer *old)
{
bool fs = false;
switch (Video->GetDisplayType ())
{
case DISPLAY_WindowOnly:
fs = false;
break;
case DISPLAY_FullscreenOnly:
fs = true;
break;
case DISPLAY_Both:
fs = fullscreen;
break;
}
DFrameBuffer *res = Video->CreateFrameBuffer (width, height, fs, old);
/* Right now, CreateFrameBuffer cannot return NULL
if (res == NULL)
{
I_FatalError ("Mode %dx%d is unavailable\n", width, height);
}
*/
return res;
}
bool I_CheckResolution (int width, int height, int bits)
{
int twidth, theight;
Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen);
while (Video->NextMode (&twidth, &theight, NULL))
{
if (width == twidth && height == theight)
return true;
}
return false;
}
void I_ClosestResolution (int *width, int *height, int bits)
{
int twidth, theight;
int cwidth = 0, cheight = 0;
int iteration;
DWORD closest = 4294967295u;
for (iteration = 0; iteration < 2; iteration++)
{
Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen);
while (Video->NextMode (&twidth, &theight, NULL))
{
if (twidth == *width && theight == *height)
return;
if (iteration == 0 && (twidth < *width || theight < *height))
continue;
DWORD dist = (twidth - *width) * (twidth - *width)
+ (theight - *height) * (theight - *height);
if (dist < closest)
{
closest = dist;
cwidth = twidth;
cheight = theight;
}
}
if (closest != 4294967295u)
{
*width = cwidth;
*height = cheight;
return;
}
}
}
extern int NewWidth, NewHeight, NewBits, DisplayBits;
CUSTOM_CVAR (Bool, fullscreen, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
NewWidth = screen->GetWidth();
NewHeight = screen->GetHeight();
NewBits = DisplayBits;
setmodeneeded = true;
}
CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
if (self < 1.f)
{
self = 1.f;
}
else if (Video)
{
Video->SetWindowedScale (self);
NewWidth = screen->GetWidth();
NewHeight = screen->GetHeight();
NewBits = DisplayBits;
setmodeneeded = true;
}
}
CCMD (vid_listmodes)
{
static const char *ratios[5] = { "", " - 16:9", " - 16:10", "", " - 5:4" };
int width, height, bits;
bool letterbox;
if (Video == NULL)
{
return;
}
for (bits = 1; bits <= 32; bits++)
{
Video->StartModeIterator (bits, screen->IsFullscreen());
while (Video->NextMode (&width, &height, &letterbox))
{
bool thisMode = (width == DisplayWidth && height == DisplayHeight && bits == DisplayBits);
int ratio = CheckRatio (width, height);
Printf (thisMode ? PRINT_BOLD : PRINT_HIGH,
"%s%4d x%5d x%3d%s%s\n",
thisMode || !(ratio & 3) ? "" : TEXTCOLOR_GOLD,
width, height, bits,
ratios[ratio],
thisMode || !letterbox ? "" : TEXTCOLOR_BROWN " LB"
);
}
}
}
CCMD (vid_currentmode)
{
Printf ("%dx%dx%d\n", DisplayWidth, DisplayHeight, DisplayBits);
}