1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-06-25 22:09:35 +00:00

Allow non-0 default framebuffer

This commit is contained in:
Logan McNaughton 2018-04-03 08:08:06 -07:00
parent 44068412f4
commit e80577e105
27 changed files with 87 additions and 559 deletions

View File

@ -112,7 +112,7 @@ void ColorBufferToRDRAM::_initFBTexture(void)
// check if everything is OK
assert(!gfxContext.isFramebufferError());
gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle::null);
gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle::defaultFramebuffer);
m_bufferReader.reset(gfxContext.createColorBufferReader(m_pTexture));
}

View File

@ -122,7 +122,7 @@ void DepthBufferToRDRAM::init()
// check if everything is OK
assert(!gfxContext.isFramebufferError());
assert(!gfxContext.isError());
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
}
void DepthBufferToRDRAM::destroy() {

View File

@ -621,7 +621,7 @@ void Debugger::_drawFrameBuffer(FrameBuffer * _pBuffer)
const s32 vOffset = (wnd.getScreenHeight() - wnd.getHeight()) / 2 + wnd.getHeightOffset() + wnd.getHeight()*3/8;
s32 dstCoord[4] = { hOffset, vOffset, hOffset + (s32)wnd.getWidth()*5/8, vOffset + (s32)wnd.getHeight()*5/8 };
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
drawer.clearColorBuffer(clearColor);
@ -1287,7 +1287,7 @@ void Debugger::draw()
_drawDebugInfo(pBuffer);
}
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pBuffer->m_FBO);
gDP.changed |= CHANGED_SCISSOR;
}

View File

@ -253,7 +253,7 @@ CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer)
gfxContext.blitFramebuffers(blitParams);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
m_resolved = true;
@ -304,7 +304,7 @@ CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer)
gfxContext.blitFramebuffers(blitParams);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
m_copied = true;

View File

@ -36,7 +36,7 @@ void displayLoadProgress(const wchar_t *format, ...)
FrameBuffer* pBuffer = frameBufferList().getCurrent();
if (pBuffer != nullptr)
gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle::null);
gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle::defaultFramebuffer);
GraphicsDrawer & drawer = dwnd().getDrawer();
drawer.clearColorBuffer(nullptr);

View File

@ -9,6 +9,9 @@
void DisplayWindow::start()
{
_start(); // TODO: process initialization error
graphics::ObjectHandle::defaultFramebuffer = _getDefaultFramebuffer();
gfxContext.init();
m_drawer._initData();
m_buffersSwapCount = 0;

View File

@ -75,6 +75,7 @@ private:
virtual bool _resizeWindow() = 0;
virtual void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) = 0;
virtual void _readScreen2(void * _dest, int * _width, int * _height, int _front) = 0;
virtual graphics::ObjectHandle _getDefaultFramebuffer() = 0;
};
inline

View File

@ -55,7 +55,7 @@ FrameBuffer::FrameBuffer()
, m_pSubTexture(nullptr)
, m_copied(false)
, m_pFrameBufferCopyTexture(nullptr)
, m_copyFBO(ObjectHandle::null)
, m_copyFBO(ObjectHandle::defaultFramebuffer)
{
m_loadTileOrigin.uls = m_loadTileOrigin.ult = 0;
m_pTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0);
@ -337,7 +337,7 @@ void FrameBuffer::resolveMultisampledTexture(bool _bForce)
gfxContext.blitFramebuffers(blitParams);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
frameBufferList().setCurrentDrawBuffer();
m_resolved = true;
@ -416,7 +416,7 @@ CachedTexture * FrameBuffer::_getSubTexture(u32 _t)
gfxContext.blitFramebuffers(blitParams);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
frameBufferList().setCurrentDrawBuffer();
@ -457,7 +457,7 @@ CachedTexture * FrameBuffer::_copyFrameBufferTexture()
gfxContext.blitFramebuffers(blitParams);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
frameBufferList().setCurrentDrawBuffer();
m_copied = true;
@ -544,12 +544,12 @@ void FrameBufferList::init()
{
m_pCurrent = nullptr;
m_pCopy = nullptr;
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
m_prevColorImageHeight = 0;
}
void FrameBufferList::destroy() {
gfxContext.bindFramebuffer(bufferTarget::FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
m_list.clear();
m_pCurrent = nullptr;
m_pCopy = nullptr;
@ -783,7 +783,7 @@ void FrameBufferList::removeAux()
while (iter->isAuxiliary()) {
if (&(*iter) == m_pCurrent) {
m_pCurrent = nullptr;
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
}
iter = m_list.erase(iter);
if (iter == m_list.end())
@ -798,7 +798,7 @@ void FrameBufferList::removeBuffer(u32 _address )
if (iter->m_startAddress == _address) {
if (&(*iter) == m_pCurrent) {
m_pCurrent = nullptr;
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
}
m_list.erase(iter);
return;
@ -812,7 +812,7 @@ void FrameBufferList::removeBuffers(u32 _width)
while (iter->m_width == _width) {
if (&(*iter) == m_pCurrent) {
m_pCurrent = nullptr;
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
}
iter = m_list.erase(iter);
if (iter == m_list.end())
@ -929,7 +929,7 @@ void FrameBufferList::_renderScreenSizeBuffer()
const s32 vOffset = (screenHeight - wndHeight) / 2 + wndHeightOffset;
s32 dstCoord[4] = { hOffset, vOffset, hOffset + static_cast<s32>(wndWidth), vOffset + static_cast<s32>(wndHeight) };
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
drawer.clearColorBuffer(clearColor);
@ -957,7 +957,7 @@ void FrameBufferList::_renderScreenSizeBuffer()
drawer.blitOrCopyTexturedRect(blitParams);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
wnd.swapBuffers();
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pBuffer->m_FBO);
@ -1229,7 +1229,7 @@ void FrameBufferList::renderBuffer()
readBuffer = pFilteredBuffer->m_FBO;
}
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
drawer.clearColorBuffer(clearColor);
@ -1287,7 +1287,7 @@ void FrameBufferList::renderBuffer()
drawer.copyTexturedRect(blitParams);
}
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
wnd.swapBuffers();
if (m_pCurrent != nullptr) {

View File

@ -3,5 +3,6 @@
namespace graphics {
ObjectHandle ObjectHandle::null;
ObjectHandle ObjectHandle::defaultFramebuffer;
}

View File

@ -18,6 +18,7 @@ namespace graphics {
void reset() { m_name = 0; }
static ObjectHandle null;
static ObjectHandle defaultFramebuffer;
private:
u32 m_name;
};

View File

@ -35,6 +35,7 @@ private:
void _changeWindow() override;
void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) override {}
void _readScreen2(void * _dest, int * _width, int * _height, int _front) override;
graphics::ObjectHandle _getDefaultFramebuffer() override;
};
DisplayWindow & DisplayWindow::get()
@ -215,3 +216,10 @@ void DisplayWindowMupen64plus::_readScreen2(void * _dest, int * _width, int * _h
free(pBufferData);
}
graphics::ObjectHandle DisplayWindowMupen64plus::_getDefaultFramebuffer()
{
if (CoreVideo_GL_GetDefaultFramebuffer != nullptr)
return graphics::ObjectHandle(CoreVideo_GL_GetDefaultFramebuffer());
return graphics::ObjectHandle::null;
}

View File

@ -26,6 +26,7 @@ private:
void _changeWindow() override;
void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) override;
void _readScreen2(void * _dest, int * _width, int * _height, int _front) override {}
graphics::ObjectHandle _getDefaultFramebuffer() override;
HGLRC hRC;
HDC hDC;
@ -162,7 +163,7 @@ void DisplayWindowWindows::_saveScreenshot()
unsigned char * pixelData = NULL;
GLint oldMode;
glGetIntegerv(GL_READ_BUFFER, &oldMode);
gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, graphics::ObjectHandle::null);
gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, graphics::ObjectHandle::defaultFramebuffer);
glReadBuffer(GL_FRONT);
pixelData = (unsigned char*)malloc(m_screenWidth * m_screenHeight * 3);
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
@ -285,7 +286,7 @@ void DisplayWindowWindows::_readScreen(void **_pDest, long *_pWidth, long *_pHei
#ifndef GLESX
GLint oldMode;
glGetIntegerv(GL_READ_BUFFER, &oldMode);
gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, graphics::ObjectHandle::null);
gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, graphics::ObjectHandle::defaultFramebuffer);
glReadBuffer(GL_FRONT);
glReadPixels(0, m_heightOffset, m_width, m_height, GL_BGR_EXT, GL_UNSIGNED_BYTE, *_pDest);
if (graphics::BufferAttachmentParam(oldMode) == graphics::bufferAttachment::COLOR_ATTACHMENT0) {
@ -298,3 +299,8 @@ void DisplayWindowWindows::_readScreen(void **_pDest, long *_pWidth, long *_pHei
glReadPixels(0, m_heightOffset, m_width, m_height, GL_RGB, GL_UNSIGNED_BYTE, *_pDest);
#endif
}
graphics::ObjectHandle DisplayWindowWindows::_getDefaultFramebuffer()
{
return graphics::ObjectHandle::null;
}

View File

@ -1432,7 +1432,7 @@ void GraphicsDrawer::drawOSD()
m_osdMessages.empty())
return;
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
DisplayWindow & wnd = DisplayWindow::get();
const s32 X = (wnd.getScreenWidth() - wnd.getWidth()) / 2;

View File

@ -115,13 +115,13 @@ void PostProcessor::_preDraw(FrameBuffer * _pBuffer)
m_pTextureOriginal = _pBuffer->m_pTexture;
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER,
ObjectHandle::null);
ObjectHandle::defaultFramebuffer);
}
void PostProcessor::_postDraw()
{
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER,
ObjectHandle::null);
ObjectHandle::defaultFramebuffer);
gfxContext.resetShaderProgram();
}

View File

@ -80,7 +80,7 @@ void TexrectDrawer::init()
// check if everything is OK
assert(!gfxContext.isFramebufferError());
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
m_programTex.reset(gfxContext.createTexrectDrawerDrawShader());
m_programClear.reset(gfxContext.createTexrectDrawerClearShader());

View File

@ -2271,7 +2271,7 @@ void _copyDepthBuffer()
// Restore objects
if (pTmpBuffer->m_pDepthBuffer != nullptr)
pTmpBuffer->m_pDepthBuffer->setDepthAttachment(fbList.getCurrent()->m_FBO, bufferTarget::READ_FRAMEBUFFER);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
// Set back current depth buffer
dbList.saveBuffer(gDP.depthImageAddress);

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - m64p_common.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2009 Richard Goedeken *
* *
* This program is free software; you can redistribute it and/or modify *

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - m64p_config.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2009 Richard Goedeken *
* *
* This program is free software; you can redistribute it and/or modify *

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - m64p_debugger.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2009 Richard Goedeken *
* *
* This program is free software; you can redistribute it and/or modify *

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - m64p_frontend.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2009 Richard Goedeken *
* *
* This program is free software; you can redistribute it and/or modify *

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - m64p_plugin.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2002 Hacktarux *
* Copyright (C) 2009 Richard Goedeken *
* *

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - m64p_types.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2012 CasualJames *
* Copyright (C) 2009 Richard Goedeken *
* *
@ -30,7 +30,7 @@
/* necessary headers */
#include <stdint.h>
#if defined(WIN32) || defined(WIN64)
#include <windows.h>
#include <windows.h>
#endif
/* DLL handles and function declaration specifiers */
@ -184,6 +184,20 @@ typedef struct {
* Empty or NULL string results in the core generating a default save file with empty content.
*/
char* (*get_gb_cart_ram)(void* cb_data, int controller_num);
/* Allow the frontend to specify the DD IPL ROM file to load
* cb_data: points to frontend-defined callback data.
* Returns a NULL-terminated string owned by the core specifying the DD IPL ROM filename to load
* Empty or NULL string results in disabled 64DD.
*/
char* (*get_dd_rom)(void* cb_data);
/* Allow the frontend to specify the DD disk file to load
* cb_data: points to frontend-defined callback data.
* Returns a NULL-terminated string owned by the core specifying the DD disk filename to load
* Empty or NULL string results in no DD disk being loaded (eg. empty disk drive).
*/
char* (*get_dd_disk)(void* cb_data);
} m64p_media_loader;
/* ----------------------------------------- */
@ -384,6 +398,7 @@ typedef struct {
m64p_error (*VidExtFuncSetCaption)(const char *);
m64p_error (*VidExtFuncToggleFS)(void);
m64p_error (*VidExtFuncResizeWindow)(int, int);
uint32_t (*VidExtFuncGLGetDefaultFramebuffer)(void);
} m64p_video_extension_functions;
#endif /* define M64P_TYPES_H */

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - m64p_vidext.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2009 Richard Goedeken *
* *
* This program is free software; you can redistribute it and/or modify *
@ -146,6 +146,20 @@ typedef m64p_error (*ptr_VidExt_GL_SwapBuffers)(void);
EXPORT m64p_error CALL VidExt_GL_SwapBuffers(void);
#endif
/* VidExt_GL_GetDefaultFramebuffer()
*
* On some platforms (for instance, iOS) the default framebuffer object
* depends on the surface being rendered to, and might be different from 0.
* This function should be called after VidExt_SetVideoMode to retrieve the
* name of the default FBO.
* Calling this function may have performance implications
* and it should not be called every time the default FBO is bound.
*/
typedef uint32_t (*ptr_VidExt_GL_GetDefaultFramebuffer)(void);
#if defined(M64P_CORE_PROTOTYPES)
EXPORT uint32_t CALL VidExt_GL_GetDefaultFramebuffer(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,38 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - api/vidext.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2009 Richard Goedeken *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* This file contains the definitions for the video extension functions which
* will be called from other Core modules.
*/
#if !defined(API_VIDEXT_H)
#define API_VIDEXT_H
#include "m64p_types.h"
/* global function for use by frontend.c */
extern m64p_error OverrideVideoFunctions(m64p_video_extension_functions *VideoFunctionStruct);
/* these functions are only used by the core */
extern int VidExt_InFullscreenMode(void);
extern int VidExt_VideoRunning(void);
#endif /* API_VIDEXT_H */

View File

@ -1,486 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <SDL_config.h>
#include <SDL_surface.h>
#ifndef USE_GLES
#ifndef SDL_VIDEO_OPENGL
#error SDL is not build with OpenGL support. Try USE_GLES=1
#endif
#else // !USE_GLES
#ifndef SDL_VIDEO_OPENGL_ES2
#error SDL is not build with OpenGL ES2 support. Try USE_GLES=0
#endif
#endif // !USE_GLES
typedef struct SDL_VideoInfo
{
Uint32 hw_available:1;
Uint32 wm_available:1;
Uint32 UnusedBits1:6;
Uint32 UnusedBits2:1;
Uint32 blit_hw:1;
Uint32 blit_hw_CC:1;
Uint32 blit_hw_A:1;
Uint32 blit_sw:1;
Uint32 blit_sw_CC:1;
Uint32 blit_sw_A:1;
Uint32 blit_fill:1;
Uint32 UnusedBits3:16;
Uint32 video_mem;
SDL_PixelFormat *vfmt;
int current_w;
int current_h;
} SDL_VideoInfo;
#define SDL_FULLSCREEN 0x00800000
#define SDL_RESIZABLE 0x01000000
#define SDL_NOFRAME 0x02000000
#define SDL_OPENGL 0x04000000
#define SDL_HWSURFACE 0x08000001 /**< \note Not used */
#define SDL_BUTTON_WHEELUP 4
#define SDL_BUTTON_WHEELDOWN 5
int initialized_video = 0;
static SDL_Window *SDL_VideoWindow = NULL;
static SDL_Surface *SDL_VideoSurface = NULL;
static SDL_Surface *SDL_PublicSurface = NULL;
static SDL_Rect SDL_VideoViewport;
static char *wm_title = NULL;
static Uint32 SDL_VideoFlags = 0;
static SDL_GLContext *SDL_VideoContext = NULL;
static SDL_Surface *SDL_VideoIcon;
static void
SDL_WM_SetCaption(const char *title, const char *icon)
{
if (wm_title) {
SDL_free(wm_title);
}
if (title) {
wm_title = SDL_strdup(title);
} else {
wm_title = NULL;
}
SDL_SetWindowTitle(SDL_VideoWindow, wm_title);
}
static int
GetVideoDisplay()
{
const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY");
if ( !variable ) {
variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
}
if ( variable ) {
return SDL_atoi(variable);
} else {
return 0;
}
}
static const SDL_VideoInfo *
SDL_GetVideoInfo(void)
{
static SDL_VideoInfo info;
SDL_DisplayMode mode;
/* Memory leak, compatibility code, who cares? */
if (!info.vfmt && SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode) == 0) {
info.vfmt = SDL_AllocFormat(mode.format);
info.current_w = mode.w;
info.current_h = mode.h;
}
return &info;
}
static SDL_Rect **
SDL_ListModes(const SDL_PixelFormat * format, Uint32 flags)
{
int i, nmodes;
SDL_Rect **modes;
if (!initialized_video) {
return NULL;
}
if (!(flags & SDL_FULLSCREEN)) {
return (SDL_Rect **) (-1);
}
if (!format) {
format = SDL_GetVideoInfo()->vfmt;
}
/* Memory leak, but this is a compatibility function, who cares? */
nmodes = 0;
modes = NULL;
for (i = 0; i < SDL_GetNumDisplayModes(GetVideoDisplay()); ++i) {
SDL_DisplayMode mode;
int bpp;
SDL_GetDisplayMode(GetVideoDisplay(), i, &mode);
if (!mode.w || !mode.h) {
return (SDL_Rect **) (-1);
}
/* Copied from src/video/SDL_pixels.c:SDL_PixelFormatEnumToMasks */
if (SDL_BYTESPERPIXEL(mode.format) <= 2) {
bpp = SDL_BITSPERPIXEL(mode.format);
} else {
bpp = SDL_BYTESPERPIXEL(mode.format) * 8;
}
if (bpp != format->BitsPerPixel) {
continue;
}
if (nmodes > 0 && modes[nmodes - 1]->w == mode.w
&& modes[nmodes - 1]->h == mode.h) {
continue;
}
modes = SDL_realloc(modes, (nmodes + 2) * sizeof(*modes));
if (!modes) {
return NULL;
}
modes[nmodes] = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect));
if (!modes[nmodes]) {
return NULL;
}
modes[nmodes]->x = 0;
modes[nmodes]->y = 0;
modes[nmodes]->w = mode.w;
modes[nmodes]->h = mode.h;
++nmodes;
}
if (modes) {
modes[nmodes] = NULL;
}
return modes;
}
static void
SDL_GL_SwapBuffers(void)
{
SDL_GL_SwapWindow(SDL_VideoWindow);
}
static int
SDL_WM_ToggleFullScreen(SDL_Surface * surface)
{
int window_w;
int window_h;
if (!SDL_PublicSurface) {
SDL_SetError("SDL_SetVideoMode() hasn't been called");
return 0;
}
/* Do the physical mode switch */
if (SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN) {
if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) {
return 0;
}
SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
} else {
if (SDL_SetWindowFullscreen(SDL_VideoWindow, 1) < 0) {
return 0;
}
SDL_PublicSurface->flags |= SDL_FULLSCREEN;
}
/* Center the public surface in the window surface */
SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h);
SDL_VideoViewport.x = 0;
SDL_VideoViewport.y = 0;
SDL_VideoViewport.w = window_w;
SDL_VideoViewport.h = window_h;
/* We're done! */
return 1;
}
static int
SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags)
{
int w, h;
/* We can't resize something we don't have... */
if (!SDL_PublicSurface) {
return -1;
}
/* We probably have to recreate the window in fullscreen mode */
if (flags & SDL_FULLSCREEN) {
return -1;
}
/* I don't think there's any change we can gracefully make in flags */
if (flags != SDL_VideoFlags) {
return -1;
}
if (bpp != SDL_VideoSurface->format->BitsPerPixel) {
return -1;
}
/* Resize the window */
SDL_GetWindowSize(SDL_VideoWindow, &w, &h);
if (w != width || h != height) {
SDL_SetWindowSize(SDL_VideoWindow, width, height);
}
SDL_VideoSurface->w = width;
SDL_VideoSurface->h = height;
return 0;
}
static int
SDL_CompatEventFilter(void *userdata, SDL_Event * event)
{
SDL_Event fake;
switch (event->type) {
case SDL_WINDOWEVENT:
switch (event->window.event) {
case SDL_WINDOWEVENT_CLOSE:
fake.type = SDL_QUIT;
SDL_PushEvent(&fake);
break;
}
case SDL_TEXTINPUT:
{
/* FIXME: Generate an old style key repeat event if needed */
//printf("TEXTINPUT: '%s'\n", event->text.text);
break;
}
case SDL_MOUSEMOTION:
{
event->motion.x -= SDL_VideoViewport.x;
event->motion.y -= SDL_VideoViewport.y;
break;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
event->button.x -= SDL_VideoViewport.x;
event->button.y -= SDL_VideoViewport.y;
break;
}
case SDL_MOUSEWHEEL:
{
Uint8 button;
int x, y;
if (event->wheel.y == 0) {
break;
}
SDL_GetMouseState(&x, &y);
if (event->wheel.y > 0) {
button = SDL_BUTTON_WHEELUP;
} else {
button = SDL_BUTTON_WHEELDOWN;
}
fake.button.button = button;
fake.button.x = x;
fake.button.y = y;
fake.button.windowID = event->wheel.windowID;
fake.type = SDL_MOUSEBUTTONDOWN;
fake.button.state = SDL_PRESSED;
SDL_PushEvent(&fake);
fake.type = SDL_MOUSEBUTTONUP;
fake.button.state = SDL_RELEASED;
SDL_PushEvent(&fake);
break;
}
}
return 1;
}
static void
GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
{
int display = GetVideoDisplay();
const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
const char *center = SDL_getenv("SDL_VIDEO_CENTERED");
if (window) {
if (SDL_sscanf(window, "%d,%d", x, y) == 2) {
return;
}
if (SDL_strcmp(window, "center") == 0) {
center = window;
}
}
if (center) {
*x = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
*y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
}
}
static void SDL2_DestroyWindow(void)
{
/* Destroy existing window */
SDL_PublicSurface = NULL;
if (SDL_VideoSurface) {
SDL_VideoSurface->flags &= ~SDL_DONTFREE;
SDL_FreeSurface(SDL_VideoSurface);
SDL_VideoSurface = NULL;
}
if (SDL_VideoContext) {
/* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */
SDL_GL_DeleteContext(SDL_VideoContext);
SDL_VideoContext = NULL;
}
if (SDL_VideoWindow) {
SDL_DestroyWindow(SDL_VideoWindow);
SDL_VideoWindow = NULL;
}
}
static SDL_Surface *
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
{
SDL_DisplayMode desktop_mode;
int display = GetVideoDisplay();
int window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
int window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
Uint32 window_flags;
Uint32 surface_flags;
if (!initialized_video) {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
return NULL;
}
initialized_video = 1;
}
SDL_GetDesktopDisplayMode(display, &desktop_mode);
if (width == 0) {
width = desktop_mode.w;
}
if (height == 0) {
height = desktop_mode.h;
}
if (bpp == 0) {
bpp = SDL_BITSPERPIXEL(desktop_mode.format);
}
/* See if we can simply resize the existing window and surface */
if (SDL_ResizeVideoMode(width, height, bpp, flags) == 0) {
return SDL_PublicSurface;
}
/* Destroy existing window */
if (SDL_VideoWindow)
SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y);
SDL2_DestroyWindow();
/* Set up the event filter */
if (!SDL_GetEventFilter(NULL, NULL)) {
SDL_SetEventFilter(SDL_CompatEventFilter, NULL);
}
#ifndef USE_GLES
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
#else // !USE_GLES
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif // !USE_GLES
/* Create a new window */
window_flags = SDL_WINDOW_SHOWN;
if (flags & SDL_FULLSCREEN) {
window_flags |= SDL_WINDOW_FULLSCREEN;
}
if (flags & SDL_OPENGL) {
window_flags |= SDL_WINDOW_OPENGL;
}
if (flags & SDL_RESIZABLE) {
window_flags |= SDL_WINDOW_RESIZABLE;
}
if (flags & SDL_NOFRAME) {
window_flags |= SDL_WINDOW_BORDERLESS;
}
GetEnvironmentWindowPosition(width, height, &window_x, &window_y);
SDL_VideoWindow =
SDL_CreateWindow(wm_title, window_x, window_y, width, height,
window_flags);
if (!SDL_VideoWindow) {
return NULL;
}
SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon);
window_flags = SDL_GetWindowFlags(SDL_VideoWindow);
surface_flags = 0;
if (window_flags & SDL_WINDOW_FULLSCREEN) {
surface_flags |= SDL_FULLSCREEN;
}
if ((window_flags & SDL_WINDOW_OPENGL) && (flags & SDL_OPENGL)) {
surface_flags |= SDL_OPENGL;
}
if (window_flags & SDL_WINDOW_RESIZABLE) {
surface_flags |= SDL_RESIZABLE;
}
if (window_flags & SDL_WINDOW_BORDERLESS) {
surface_flags |= SDL_NOFRAME;
}
SDL_VideoFlags = flags;
/* If we're in OpenGL mode, just create a stub surface and we're done! */
if (flags & SDL_OPENGL) {
SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow);
if (!SDL_VideoContext) {
return NULL;
}
if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) {
return NULL;
}
SDL_VideoSurface =
SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0);
if (!SDL_VideoSurface) {
return NULL;
}
SDL_VideoSurface->flags |= surface_flags;
SDL_PublicSurface = SDL_VideoSurface;
return SDL_PublicSurface;
}
/* We're finally done! */
return NULL;
}

View File

@ -47,6 +47,7 @@ extern ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress;
extern ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute;
extern ptr_VidExt_GL_GetAttribute CoreVideo_GL_GetAttribute;
extern ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers;
extern ptr_VidExt_GL_GetDefaultFramebuffer CoreVideo_GL_GetDefaultFramebuffer;
extern ptr_PluginGetVersion CoreGetVersion;

View File

@ -43,6 +43,7 @@ ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress = nullptr;
ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute = nullptr;
ptr_VidExt_GL_GetAttribute CoreVideo_GL_GetAttribute = nullptr;
ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers = nullptr;
ptr_VidExt_GL_GetDefaultFramebuffer CoreVideo_GL_GetDefaultFramebuffer = nullptr;
ptr_PluginGetVersion CoreGetVersion = nullptr;
@ -85,6 +86,7 @@ m64p_error PluginAPI::PluginStartup(m64p_dynlib_handle _CoreLibHandle)
CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) DLSYM(_CoreLibHandle, "VidExt_GL_SetAttribute");
CoreVideo_GL_GetAttribute = (ptr_VidExt_GL_GetAttribute) DLSYM(_CoreLibHandle, "VidExt_GL_GetAttribute");
CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) DLSYM(_CoreLibHandle, "VidExt_GL_SwapBuffers");
CoreVideo_GL_GetDefaultFramebuffer = (ptr_VidExt_GL_GetDefaultFramebuffer) DLSYM(_CoreLibHandle, "VidExt_GL_GetDefaultFramebuffer");
CoreGetVersion = (ptr_PluginGetVersion) DLSYM(_CoreLibHandle, "PluginGetVersion");