mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
Got rid of SDL emulation's last remnants in native OS X backend
This commit is contained in:
parent
1aa00f1b0e
commit
8b6966dd36
1 changed files with 95 additions and 235 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue