Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Mupen64plus-core - api/vidext.c *
- * 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 Core video extension functions which will be exported
- * outside of the core library.
- */
- #include <stdlib.h>
- #include <string.h>
- #include <SDL.h>
- #define M64P_CORE_PROTOTYPES 1
- #include "m64p_types.h"
- #include "m64p_vidext.h"
- #include "vidext.h"
- #include "callbacks.h"
- #ifdef HAVE_EGL
- #include "egl_windows.h"
- #endif
- #include "../osd/osd.h"
- #if SDL_VERSION_ATLEAST(2,0,0)
- #include "vidext_sdl2_compat.h"
- #endif
- /* local variables */
- static m64p_video_extension_functions l_ExternalVideoFuncTable = {10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
- static int l_VideoExtensionActive = 0;
- static int l_VideoOutputActive = 0;
- static int l_Fullscreen = 0;
- static SDL_Surface *l_pScreen = NULL;
- /* global function for use by frontend.c */
- m64p_error OverrideVideoFunctions(m64p_video_extension_functions *VideoFunctionStruct)
- {
- /* check input data */
- if (VideoFunctionStruct == NULL)
- return M64ERR_INPUT_ASSERT;
- if (VideoFunctionStruct->Functions < 11)
- return M64ERR_INPUT_INVALID;
- /* disable video extension if any of the function pointers are NULL */
- if (VideoFunctionStruct->VidExtFuncInit == NULL ||
- VideoFunctionStruct->VidExtFuncQuit == NULL ||
- VideoFunctionStruct->VidExtFuncListModes == NULL ||
- VideoFunctionStruct->VidExtFuncSetMode == NULL ||
- VideoFunctionStruct->VidExtFuncGLGetProc == NULL ||
- VideoFunctionStruct->VidExtFuncGLSetAttr == NULL ||
- VideoFunctionStruct->VidExtFuncGLGetAttr == NULL ||
- VideoFunctionStruct->VidExtFuncGLSwapBuf == NULL ||
- VideoFunctionStruct->VidExtFuncSetCaption == NULL ||
- VideoFunctionStruct->VidExtFuncToggleFS == NULL ||
- VideoFunctionStruct->VidExtFuncResizeWindow == NULL)
- {
- l_ExternalVideoFuncTable.Functions = 11;
- memset(&l_ExternalVideoFuncTable.VidExtFuncInit, 0, 11 * sizeof(void *));
- l_VideoExtensionActive = 0;
- return M64ERR_SUCCESS;
- }
- /* otherwise copy in the override function pointers */
- memcpy(&l_ExternalVideoFuncTable, VideoFunctionStruct, sizeof(m64p_video_extension_functions));
- l_VideoExtensionActive = 1;
- return M64ERR_SUCCESS;
- }
- int VidExt_InFullscreenMode(void)
- {
- return l_Fullscreen;
- }
- int VidExt_VideoRunning(void)
- {
- return l_VideoOutputActive;
- }
- /* video extension functions to be called by the video plugin */
- EXPORT m64p_error CALL VidExt_Init(void)
- {
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- return (*l_ExternalVideoFuncTable.VidExtFuncInit)();
- if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
- {
- DebugMessage(M64MSG_ERROR, "SDL video subsystem init failed: %s", SDL_GetError());
- return M64ERR_SYSTEM_FAIL;
- }
- return M64ERR_SUCCESS;
- }
- EXPORT m64p_error CALL VidExt_Quit(void)
- {
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- {
- m64p_error rval = (*l_ExternalVideoFuncTable.VidExtFuncQuit)();
- if (rval == M64ERR_SUCCESS)
- {
- l_VideoOutputActive = 0;
- StateChanged(M64CORE_VIDEO_MODE, M64VIDEO_NONE);
- }
- return rval;
- }
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- #ifdef HAVE_EGL
- destroy_egl_windows();
- #endif
- SDL_ShowCursor(SDL_ENABLE);
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
- l_pScreen = NULL;
- l_VideoOutputActive = 0;
- StateChanged(M64CORE_VIDEO_MODE, M64VIDEO_NONE);
- return M64ERR_SUCCESS;
- }
- EXPORT m64p_error CALL VidExt_ListFullscreenModes(m64p_2d_size *SizeArray, int *NumSizes)
- {
- const SDL_VideoInfo *videoInfo;
- unsigned int videoFlags;
- SDL_Rect **modes;
- int i;
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- return (*l_ExternalVideoFuncTable.VidExtFuncListModes)(SizeArray, NumSizes);
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- /* get a list of SDL video modes */
- videoFlags = SDL_OPENGL | SDL_FULLSCREEN;
- if ((videoInfo = SDL_GetVideoInfo()) == NULL)
- {
- DebugMessage(M64MSG_ERROR, "SDL_GetVideoInfo query failed: %s", SDL_GetError());
- return M64ERR_SYSTEM_FAIL;
- }
- if(videoInfo->hw_available)
- videoFlags |= SDL_HWSURFACE;
- else
- videoFlags |= SDL_SWSURFACE;
- modes = SDL_ListModes(NULL, videoFlags);
- if (modes == (SDL_Rect **) 0 || modes == (SDL_Rect **) -1)
- {
- DebugMessage(M64MSG_WARNING, "No fullscreen SDL video modes available");
- *NumSizes = 0;
- return M64ERR_SUCCESS;
- }
- i = 0;
- while (i < *NumSizes && modes[i] != NULL)
- {
- SizeArray[i].uiWidth = modes[i]->w;
- SizeArray[i].uiHeight = modes[i]->h;
- i++;
- }
- *NumSizes = i;
- return M64ERR_SUCCESS;
- }
- EXPORT m64p_error CALL VidExt_SetVideoMode(int Width, int Height, int BitsPerPixel, m64p_video_mode ScreenMode, m64p_video_flags Flags)
- {
- const SDL_VideoInfo *videoInfo;
- int videoFlags = 0;
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- {
- m64p_error rval = (*l_ExternalVideoFuncTable.VidExtFuncSetMode)(Width, Height, BitsPerPixel, ScreenMode, Flags);
- l_Fullscreen = (rval == M64ERR_SUCCESS && ScreenMode == M64VIDEO_FULLSCREEN);
- l_VideoOutputActive = (rval == M64ERR_SUCCESS);
- if (l_VideoOutputActive)
- {
- StateChanged(M64CORE_VIDEO_MODE, ScreenMode);
- StateChanged(M64CORE_VIDEO_SIZE, (Width << 16) | Height);
- }
- return rval;
- }
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- /* Get SDL video flags to use */
- if (ScreenMode == M64VIDEO_WINDOWED)
- {
- videoFlags = SDL_OPENGL;
- if (Flags & M64VIDEOFLAG_SUPPORT_RESIZING)
- videoFlags |= SDL_RESIZABLE;
- }
- else if (ScreenMode == M64VIDEO_FULLSCREEN)
- {
- videoFlags = SDL_OPENGL | SDL_FULLSCREEN;
- }
- else
- {
- return M64ERR_INPUT_INVALID;
- }
- if ((videoInfo = SDL_GetVideoInfo()) == NULL)
- {
- DebugMessage(M64MSG_ERROR, "SDL_GetVideoInfo query failed: %s", SDL_GetError());
- return M64ERR_SYSTEM_FAIL;
- }
- if (videoInfo->hw_available)
- videoFlags |= SDL_HWSURFACE;
- else
- videoFlags |= SDL_SWSURFACE;
- /* set the mode */
- if (BitsPerPixel > 0)
- DebugMessage(M64MSG_INFO, "Setting %i-bit video mode: %ix%i", BitsPerPixel, Width, Height);
- else
- DebugMessage(M64MSG_INFO, "Setting video mode: %ix%i", Width, Height);
- #ifdef HAVE_EGL
- l_pScreen = SDL_SetVideoMode(Width, Height, 16, SDL_HWSURFACE);
- create_egl_windows();
- #else
- l_pScreen = SDL_SetVideoMode(Width, Height, BitsPerPixel, videoFlags);
- #endif
- if (l_pScreen == NULL)
- {
- DebugMessage(M64MSG_ERROR, "SDL_SetVideoMode failed: %s", SDL_GetError());
- return M64ERR_SYSTEM_FAIL;
- }
- SDL_ShowCursor(SDL_DISABLE);
- l_Fullscreen = (ScreenMode == M64VIDEO_FULLSCREEN);
- l_VideoOutputActive = 1;
- StateChanged(M64CORE_VIDEO_MODE, ScreenMode);
- StateChanged(M64CORE_VIDEO_SIZE, (Width << 16) | Height);
- return M64ERR_SUCCESS;
- }
- EXPORT m64p_error CALL VidExt_ResizeWindow(int Width, int Height)
- {
- const SDL_VideoInfo *videoInfo;
- int videoFlags = 0;
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- {
- m64p_error rval;
- // shut down the OSD
- //osd_exit();
- // re-create the OGL context
- rval = (*l_ExternalVideoFuncTable.VidExtFuncResizeWindow)(Width, Height);
- if (rval == M64ERR_SUCCESS)
- {
- StateChanged(M64CORE_VIDEO_SIZE, (Width << 16) | Height);
- // re-create the On-Screen Display
- //osd_init(Width, Height);
- }
- return rval;
- }
- if (!l_VideoOutputActive || !SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- if (l_Fullscreen)
- {
- DebugMessage(M64MSG_ERROR, "VidExt_ResizeWindow() called in fullscreen mode.");
- return M64ERR_INVALID_STATE;
- }
- /* Get SDL video flags to use */
- videoFlags = SDL_OPENGL | SDL_RESIZABLE;
- if ((videoInfo = SDL_GetVideoInfo()) == NULL)
- {
- DebugMessage(M64MSG_ERROR, "SDL_GetVideoInfo query failed: %s", SDL_GetError());
- return M64ERR_SYSTEM_FAIL;
- }
- if (videoInfo->hw_available)
- videoFlags |= SDL_HWSURFACE;
- else
- videoFlags |= SDL_SWSURFACE;
- // destroy the On-Screen Display
- //osd_exit();
- /* set the re-sizing the screen will create a new OpenGL context */
- l_pScreen = SDL_SetVideoMode(Width, Height, 0, videoFlags);
- if (l_pScreen == NULL)
- {
- DebugMessage(M64MSG_ERROR, "SDL_SetVideoMode failed: %s", SDL_GetError());
- return M64ERR_SYSTEM_FAIL;
- }
- StateChanged(M64CORE_VIDEO_SIZE, (Width << 16) | Height);
- // re-create the On-Screen Display
- //osd_init(Width, Height);
- return M64ERR_SUCCESS;
- }
- EXPORT m64p_error CALL VidExt_SetCaption(const char *Title)
- {
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- return (*l_ExternalVideoFuncTable.VidExtFuncSetCaption)(Title);
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- SDL_WM_SetCaption(Title, "M64+ Video");
- return M64ERR_SUCCESS;
- }
- EXPORT m64p_error CALL VidExt_ToggleFullScreen(void)
- {
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- {
- m64p_error rval = (*l_ExternalVideoFuncTable.VidExtFuncToggleFS)();
- if (rval == M64ERR_SUCCESS)
- {
- l_Fullscreen = !l_Fullscreen;
- StateChanged(M64CORE_VIDEO_MODE, l_Fullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED);
- }
- return rval;
- }
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- /* TODO:
- * SDL_WM_ToggleFullScreen doesn't work under Windows and others
- * (see http://wiki.libsdl.org/moin.cgi/FAQWindows for explanation).
- * Instead, we should call SDL_SetVideoMode with the SDL_FULLSCREEN flag.
- * (see http://sdl.beuc.net/sdl.wiki/SDL_SetVideoMode), but on Windows
- * this resets the OpenGL context and video plugins don't support it yet.
- * Uncomment the next line to test it: */
- //return VidExt_SetVideoMode(l_pScreen->w, l_pScreen->h, l_pScreen->format->BitsPerPixel, l_Fullscreen ? M64VIDEO_WINDOWED : M64VIDEO_FULLSCREEN);
- if (SDL_WM_ToggleFullScreen(l_pScreen) == 1)
- {
- l_Fullscreen = !l_Fullscreen;
- StateChanged(M64CORE_VIDEO_MODE, l_Fullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED);
- return M64ERR_SUCCESS;
- }
- return M64ERR_SYSTEM_FAIL;
- }
- EXPORT void * CALL VidExt_GL_GetProcAddress(const char* Proc)
- {
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- return (*l_ExternalVideoFuncTable.VidExtFuncGLGetProc)(Proc);
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return NULL;
- return SDL_GL_GetProcAddress(Proc);
- }
- typedef struct {
- m64p_GLattr m64Attr;
- SDL_GLattr sdlAttr;
- } GLAttrMapNode;
- static const GLAttrMapNode GLAttrMap[] = {
- { M64P_GL_DOUBLEBUFFER, SDL_GL_DOUBLEBUFFER },
- { M64P_GL_BUFFER_SIZE, SDL_GL_BUFFER_SIZE },
- { M64P_GL_DEPTH_SIZE, SDL_GL_DEPTH_SIZE },
- { M64P_GL_RED_SIZE, SDL_GL_RED_SIZE },
- { M64P_GL_GREEN_SIZE, SDL_GL_GREEN_SIZE },
- { M64P_GL_BLUE_SIZE, SDL_GL_BLUE_SIZE },
- { M64P_GL_ALPHA_SIZE, SDL_GL_ALPHA_SIZE },
- #if SDL_VERSION_ATLEAST(1,3,0)
- { M64P_GL_SWAP_CONTROL, SDL_RENDERER_PRESENTVSYNC },
- #else
- { M64P_GL_SWAP_CONTROL, SDL_GL_SWAP_CONTROL },
- #endif
- { M64P_GL_MULTISAMPLEBUFFERS, SDL_GL_MULTISAMPLEBUFFERS },
- { M64P_GL_MULTISAMPLESAMPLES, SDL_GL_MULTISAMPLESAMPLES }};
- static const int mapSize = sizeof(GLAttrMap) / sizeof(GLAttrMapNode);
- EXPORT m64p_error CALL VidExt_GL_SetAttribute(m64p_GLattr Attr, int Value)
- {
- int i;
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- return (*l_ExternalVideoFuncTable.VidExtFuncGLSetAttr)(Attr, Value);
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- for (i = 0; i < mapSize; i++)
- {
- if (GLAttrMap[i].m64Attr == Attr)
- {
- if (SDL_GL_SetAttribute(GLAttrMap[i].sdlAttr, Value) != 0)
- return M64ERR_SYSTEM_FAIL;
- return M64ERR_SUCCESS;
- }
- }
- return M64ERR_INPUT_INVALID;
- }
- EXPORT m64p_error CALL VidExt_GL_GetAttribute(m64p_GLattr Attr, int *pValue)
- {
- int i;
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- return (*l_ExternalVideoFuncTable.VidExtFuncGLGetAttr)(Attr, pValue);
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- for (i = 0; i < mapSize; i++)
- {
- if (GLAttrMap[i].m64Attr == Attr)
- {
- int NewValue = 0;
- if (SDL_GL_GetAttribute(GLAttrMap[i].sdlAttr, &NewValue) != 0)
- return M64ERR_SYSTEM_FAIL;
- *pValue = NewValue;
- return M64ERR_SUCCESS;
- }
- }
- return M64ERR_INPUT_INVALID;
- }
- EXPORT m64p_error CALL VidExt_GL_SwapBuffers(void)
- {
- /* call video extension override if necessary */
- if (l_VideoExtensionActive)
- return (*l_ExternalVideoFuncTable.VidExtFuncGLSwapBuf)();
- if (!SDL_WasInit(SDL_INIT_VIDEO))
- return M64ERR_NOT_INIT;
- #ifdef HAVE_EGL
- egl_swap_buffers();
- #else
- SDL_GL_SwapBuffers();
- #endif
- return M64ERR_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement