Got rid of SDL emulation's last remnants in native OS X backend

This commit is contained in:
alexey.lysiuk 2014-12-27 15:42:56 +02:00
parent 1aa00f1b0e
commit 8b6966dd36

View file

@ -1176,6 +1176,8 @@ namespace
- (void)changeVideoResolution:(bool)fullscreen width:(int)width height:(int)height useHiDPI:(bool)hiDPI; - (void)changeVideoResolution:(bool)fullscreen width:(int)width height:(int)height useHiDPI:(bool)hiDPI;
- (void)useHiDPI:(bool)hiDPI; - (void)useHiDPI:(bool)hiDPI;
- (bool)fullscreen;
- (void)setupSoftwareRenderingWithWidth:(int)width height:(int)height; - (void)setupSoftwareRenderingWithWidth:(int)width height:(int)height;
- (void*)softwareRenderingBuffer; - (void*)softwareRenderingBuffer;
@ -1570,6 +1572,12 @@ static bool s_fullscreenNewAPI;
} }
- (bool)fullscreen
{
return m_fullscreen;
}
- (void)setupSoftwareRenderingWithWidth:(int)width height:(int)height - (void)setupSoftwareRenderingWithWidth:(int)width height:(int)height
{ {
if (0 == m_softwareRenderingTexture) if (0 == m_softwareRenderingTexture)
@ -1803,132 +1811,6 @@ bool I_SetCursor(FTexture* cursorpic)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
extern "C"
{
typedef enum
{
SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */
SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */
SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
} SDL_WindowFlags;
struct SDL_Window
{
uint32_t flags;
int w, h;
int pitch;
void *pixels;
};
SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int width, int height, uint32_t flags)
{
[appCtrl changeVideoResolution:(SDL_WINDOW_FULLSCREEN_DESKTOP & flags)
width:width
height:height
useHiDPI:vid_hidpi];
static SDL_Window result;
if (!(SDL_WINDOW_OPENGL & flags))
{
[appCtrl setupSoftwareRenderingWithWidth:width
height:height];
}
result.flags = flags;
result.w = width;
result.h = height;
result.pitch = width * BYTES_PER_PIXEL;
result.pixels = [appCtrl softwareRenderingBuffer];
return &result;
}
void SDL_DestroyWindow(SDL_Window *window)
{
ZD_UNUSED(window);
}
uint32_t SDL_GetWindowFlags(SDL_Window *window)
{
return window->flags;
}
int SDL_SetWindowFullscreen(SDL_Window* window, uint32_t flags)
{
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == (flags & SDL_WINDOW_FULLSCREEN_DESKTOP))
return 0;
if (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP)
{
window->flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP;
}
else
{
window->flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
[appCtrl changeVideoResolution:(SDL_WINDOW_FULLSCREEN_DESKTOP & flags)
width:window->w
height:window->h
useHiDPI:vid_hidpi];
return 0;
}
int SDL_UpdateWindowSurface(SDL_Window *screen)
{
assert(NULL != screen);
if (rbOpts.dirty)
{
glViewport(rbOpts.shiftX, rbOpts.shiftY, rbOpts.width, rbOpts.height);
// TODO: Figure out why the following glClear() call is needed
// to avoid drawing of garbage in fullscreen mode when
// in-game's aspect ratio is different from display one
glClear(GL_COLOR_BUFFER_BIT);
rbOpts.dirty = false;
}
const int width = screen->w;
const int height = screen->h;
#ifdef __LITTLE_ENDIAN__
static const GLenum format = GL_RGBA;
#else // __BIG_ENDIAN__
static const GLenum format = GL_ABGR_EXT;
#endif // __LITTLE_ENDIAN__
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
width, height, 0, format, GL_UNSIGNED_BYTE, screen->pixels);
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(width, 0.0f);
glVertex2f(width, 0.0f);
glTexCoord2f(width, height);
glVertex2f(width, height);
glTexCoord2f(0.0f, height);
glVertex2f(0.0f, height);
glEnd();
glFlush();
[[NSOpenGLContext currentContext] flushBuffer];
return 0;
}
} // extern "C"
// ---------------------------------------------------------------------------
class CocoaVideo : public IVideo class CocoaVideo : public IVideo
{ {
public: public:
@ -1953,8 +1835,6 @@ public:
CocoaFrameBuffer(int width, int height, bool fullscreen); CocoaFrameBuffer(int width, int height, bool fullscreen);
~CocoaFrameBuffer(); ~CocoaFrameBuffer();
virtual bool IsValid();
virtual bool Lock(bool buffer); virtual bool Lock(bool buffer);
virtual void Unlock(); virtual void Unlock();
virtual void Update(); virtual void Update();
@ -1973,8 +1853,6 @@ public:
virtual void SetVSync(bool vsync); virtual void SetVSync(bool vsync);
void SetFullscreen(bool fullscreen);
private: private:
PalEntry m_palette[256]; PalEntry m_palette[256];
bool m_needPaletteUpdate; bool m_needPaletteUpdate;
@ -1988,7 +1866,7 @@ private:
bool m_isUpdatePending; bool m_isUpdatePending;
SDL_Window *Screen; void Flip();
void UpdateColors(); void UpdateColors();
}; };
@ -2132,87 +2010,42 @@ bool CocoaVideo::NextMode(int* width, int* height, bool* letterbox)
return false; return false;
} }
DFrameBuffer* CocoaVideo::CreateFrameBuffer(int width, int height, bool fullscreen, DFrameBuffer* old) DFrameBuffer* CocoaVideo::CreateFrameBuffer(const int width, const int height, const bool fullscreen, DFrameBuffer* const old)
{ {
static int retry = 0; PalEntry flashColor = 0;
static int owidth, oheight; int flashAmount = 0;
PalEntry flashColor;
int flashAmount;
if (old != NULL) if (old != NULL)
{ // Reuse the old framebuffer if its attributes are the same {
CocoaFrameBuffer *fb = static_cast<CocoaFrameBuffer *> (old); if ( width == old->GetWidth()
if (fb->GetWidth() == width && && height == old->GetHeight())
fb->GetHeight() == height)
{ {
if (fb->IsFullscreen() != fullscreen) [appCtrl changeVideoResolution:fullscreen
{ width:width
fb->SetFullscreen (fullscreen); height:height
} useHiDPI:vid_hidpi];
return old; return old;
} }
old->GetFlash (flashColor, flashAmount);
old->GetFlash(flashColor, flashAmount);
old->ObjectFlags |= OF_YesReallyDelete; old->ObjectFlags |= OF_YesReallyDelete;
if (screen == old) screen = NULL;
if (old == screen)
{
screen = NULL;
}
delete old; delete old;
} }
else
{
flashColor = 0;
flashAmount = 0;
}
CocoaFrameBuffer *fb = new CocoaFrameBuffer (width, height, fullscreen); CocoaFrameBuffer* fb = new CocoaFrameBuffer(width, height, fullscreen);
retry = 0; fb->SetFlash(flashColor, flashAmount);
// If we could not create the framebuffer, try again with slightly
// different parameters in this order:
// 1. Try with the closest size
// 2. Try in the opposite screen mode with the original size
// 3. Try in the opposite screen mode with the closest size
// This is a somewhat confusing mass of recursion here.
while (fb == NULL || !fb->IsValid ())
{
if (fb != NULL)
{
delete fb;
}
switch (retry)
{
case 0:
owidth = width;
oheight = height;
case 2:
// Try a different resolution. Hopefully that will work.
I_ClosestResolution (&width, &height, 8);
break;
case 1:
// Try changing fullscreen mode. Maybe that will work.
width = owidth;
height = oheight;
fullscreen = !fullscreen;
break;
default:
// I give up!
I_FatalError ("Could not create new screen (%d x %d)", owidth, oheight);
}
++retry;
fb = static_cast<CocoaFrameBuffer *>(CreateFrameBuffer (width, height, fullscreen, NULL));
}
fb->SetFlash (flashColor, flashAmount);
return fb; return fb;
} }
void CocoaVideo::SetWindowedScale (float scale) void CocoaVideo::SetWindowedScale(float scale)
{ {
} }
@ -2225,14 +2058,13 @@ CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen)
, m_flashAmount(0) , m_flashAmount(0)
, m_isUpdatePending(false) , m_isUpdatePending(false)
{ {
FString caption; [appCtrl changeVideoResolution:fullscreen
caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); width:width
height:height
useHiDPI:vid_hidpi];
Screen = SDL_CreateWindow (caption, 0, 0, [appCtrl setupSoftwareRenderingWithWidth:width
width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); height:height];
if (Screen == NULL)
return;
GPfx.SetFormat(32, 0x000000FF, 0x0000FF00, 0x00FF0000); GPfx.SetFormat(32, 0x000000FF, 0x0000FF00, 0x00FF0000);
@ -2248,30 +2080,21 @@ CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen)
} }
CocoaFrameBuffer::~CocoaFrameBuffer () CocoaFrameBuffer::~CocoaFrameBuffer()
{ {
if(Screen)
{
SDL_DestroyWindow (Screen);
}
} }
bool CocoaFrameBuffer::IsValid () int CocoaFrameBuffer::GetPageCount()
{
return DFrameBuffer::IsValid() && Screen != NULL;
}
int CocoaFrameBuffer::GetPageCount ()
{ {
return 1; return 1;
} }
bool CocoaFrameBuffer::Lock (bool buffered) bool CocoaFrameBuffer::Lock(bool buffered)
{ {
return DSimpleCanvas::Lock (); return DSimpleCanvas::Lock(buffered);
} }
void CocoaFrameBuffer::Unlock () void CocoaFrameBuffer::Unlock()
{ {
if (m_isUpdatePending && LockCount == 1) if (m_isUpdatePending && LockCount == 1)
{ {
@ -2284,7 +2107,7 @@ void CocoaFrameBuffer::Unlock ()
} }
} }
void CocoaFrameBuffer::Update () void CocoaFrameBuffer::Update()
{ {
if (LockCount != 1) if (LockCount != 1)
{ {
@ -2296,7 +2119,7 @@ void CocoaFrameBuffer::Update ()
return; return;
} }
DrawRateStuff (); DrawRateStuff();
Buffer = NULL; Buffer = NULL;
LockCount = 0; LockCount = 0;
@ -2310,18 +2133,18 @@ void CocoaFrameBuffer::Update ()
Width, Height, FRACUNIT, FRACUNIT, 0, 0); Width, Height, FRACUNIT, FRACUNIT, 0, 0);
FlipCycles.Clock(); FlipCycles.Clock();
SDL_UpdateWindowSurface(Screen); Flip();
FlipCycles.Unclock(); FlipCycles.Unclock();
BlitCycles.Unclock(); BlitCycles.Unclock();
if (m_needGammaUpdate) if (m_needGammaUpdate)
{ {
bool Windowed = false; CalcGamma(rgamma == 0.0f ? m_gamma : m_gamma * rgamma, m_gammaTable[0]);
m_needGammaUpdate = false; CalcGamma(ggamma == 0.0f ? m_gamma : m_gamma * ggamma, m_gammaTable[1]);
CalcGamma((Windowed || rgamma == 0.f) ? m_gamma : (m_gamma * rgamma), m_gammaTable[0]); CalcGamma(bgamma == 0.0f ? m_gamma : m_gamma * bgamma, m_gammaTable[2]);
CalcGamma((Windowed || ggamma == 0.f) ? m_gamma : (m_gamma * ggamma), m_gammaTable[1]);
CalcGamma((Windowed || bgamma == 0.f) ? m_gamma : (m_gamma * bgamma), m_gammaTable[2]); m_needGammaUpdate = false;
m_needPaletteUpdate = true; m_needPaletteUpdate = true;
} }
@ -2353,7 +2176,7 @@ void CocoaFrameBuffer::UpdateColors()
GPfx.SetPalette(palette); GPfx.SetPalette(palette);
} }
PalEntry *CocoaFrameBuffer::GetPalette () PalEntry *CocoaFrameBuffer::GetPalette()
{ {
return m_palette; return m_palette;
} }
@ -2396,17 +2219,12 @@ void CocoaFrameBuffer::GetFlashedPalette(PalEntry pal[256])
} }
} }
void CocoaFrameBuffer::SetFullscreen (bool fullscreen) bool CocoaFrameBuffer::IsFullscreen()
{ {
SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); return [appCtrl fullscreen];
} }
bool CocoaFrameBuffer::IsFullscreen () void CocoaFrameBuffer::SetVSync(bool vsync)
{
return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
}
void CocoaFrameBuffer::SetVSync (bool vsync)
{ {
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
const long value = vsync ? 1 : 0; const long value = vsync ? 1 : 0;
@ -2418,6 +2236,48 @@ void CocoaFrameBuffer::SetVSync (bool vsync)
forParameter:NSOpenGLCPSwapInterval]; forParameter:NSOpenGLCPSwapInterval];
} }
void CocoaFrameBuffer::Flip()
{
assert(NULL != screen);
if (rbOpts.dirty)
{
glViewport(rbOpts.shiftX, rbOpts.shiftY, rbOpts.width, rbOpts.height);
// TODO: Figure out why the following glClear() call is needed
// to avoid drawing of garbage in fullscreen mode when
// in-game's aspect ratio is different from display one
glClear(GL_COLOR_BUFFER_BIT);
rbOpts.dirty = false;
}
#ifdef __LITTLE_ENDIAN__
static const GLenum format = GL_RGBA;
#else // __BIG_ENDIAN__
static const GLenum format = GL_ABGR_EXT;
#endif // __LITTLE_ENDIAN__
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
Width, Height, 0, format, GL_UNSIGNED_BYTE, [appCtrl softwareRenderingBuffer]);
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(Width, 0.0f);
glVertex2f(Width, 0.0f);
glTexCoord2f(Width, Height);
glVertex2f(Width, Height);
glTexCoord2f(0.0f, Height);
glVertex2f(0.0f, Height);
glEnd();
glFlush();
[[NSOpenGLContext currentContext] flushBuffer];
}
ADD_STAT(blit) ADD_STAT(blit)
{ {