Path: blob/master/libmupen64plus/mupen64plus-video-z64/src/maingl.cpp
2 views
/*1* z642*3* Copyright (C) 2007 ziggy4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (at your option) any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License along16* with this program; if not, write to the Free Software Foundation, Inc.,17* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.18*19**/2021#include "rdp.h"22#include "rgl.h"23#include "osal_dynamiclib.h"24#include <SDL.h>2526#define THREADED2728#define PLUGIN_VERSION 0x02000029#define VIDEO_PLUGIN_API_VERSION 0x02020030#define CONFIG_API_VERSION 0x02000031#define VIDEXT_API_VERSION 0x0300003233#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff)3435GFX_INFO gfx;3637void (*render_callback)(int) = NULL;38static void (*l_DebugCallback)(void *, int, const char *) = NULL;39static void *l_DebugCallContext = NULL;404142/* definitions of pointers to Core video extension functions */43ptr_VidExt_Init CoreVideo_Init = NULL;44ptr_VidExt_Quit CoreVideo_Quit = NULL;45ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes = NULL;46ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode = NULL;47ptr_VidExt_SetCaption CoreVideo_SetCaption = NULL;48ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen = NULL;49ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow = NULL;50ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress = NULL;51ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute = NULL;52ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers = NULL;5354/* definitions of pointers to Core config functions */55ptr_ConfigOpenSection ConfigOpenSection = NULL;56ptr_ConfigSetParameter ConfigSetParameter = NULL;57ptr_ConfigGetParameter ConfigGetParameter = NULL;58ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL;59ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL;60ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL;61ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL;62ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL;63ptr_ConfigGetParamInt ConfigGetParamInt = NULL;64ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL;65ptr_ConfigGetParamBool ConfigGetParamBool = NULL;66ptr_ConfigGetParamString ConfigGetParamString = NULL;6768#ifdef THREADED69volatile static int waiting;70SDL_sem * rdpCommandSema;71SDL_sem * rdpCommandCompleteSema;72SDL_Thread * rdpThread;73int rdpThreadFunc(void * dummy)74{75while (1) {76SDL_SemWait(rdpCommandSema);77waiting = 1;78if (rglNextStatus == RGL_STATUS_CLOSED)79rglUpdateStatus();80else81rdp_process_list();82if (!rglSettings.async)83SDL_SemPost(rdpCommandCompleteSema);8485if (rglStatus == RGL_STATUS_CLOSED) {86rdpThread = NULL;87return 0;88}89}90return 0;91}9293void rdpSignalFullSync()94{95SDL_SemPost(rdpCommandCompleteSema);96}97void rdpWaitFullSync()98{99SDL_SemWait(rdpCommandCompleteSema);100}101102void rdpPostCommand()103{104int sync = rdp_store_list();105SDL_SemPost(rdpCommandSema);106if (!rglSettings.async)107SDL_SemWait(rdpCommandCompleteSema);108else if (sync) {109rdpWaitFullSync();110*gfx.MI_INTR_REG |= 0x20;111gfx.CheckInterrupts();112}113114waiting = 0;115}116117void rdpCreateThread()118{119if (!rdpCommandSema) {120rdpCommandSema = SDL_CreateSemaphore(0);121rdpCommandCompleteSema = SDL_CreateSemaphore(0);122}123if (!rdpThread) {124LOG("Creating rdp thread\n");125#if SDL_VERSION_ATLEAST(2,0,0)126rdpThread = SDL_CreateThread(rdpThreadFunc, "z64rdp", 0);127#else128rdpThread = SDL_CreateThread(rdpThreadFunc, 0);129#endif130}131}132#endif133134void rdp_log(m64p_msg_level level, const char *msg, ...)135{136char buf[1024];137va_list args;138va_start(args, msg);139vsnprintf(buf, 1023, msg, args);140buf[1023]='\0';141va_end(args);142if (l_DebugCallback)143{144l_DebugCallback(l_DebugCallContext, level, buf);145}146}147148#ifdef __cplusplus149extern "C" {150#endif151152EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,153void (*DebugCallback)(void *, int, const char *))154{155///* first thing is to set the callback function for debug info */156l_DebugCallback = DebugCallback;157l_DebugCallContext = Context;158159/* Get the core Video Extension function pointers from the library handle */160CoreVideo_Init = (ptr_VidExt_Init) osal_dynlib_getproc(CoreLibHandle, "VidExt_Init");161CoreVideo_Quit = (ptr_VidExt_Quit) osal_dynlib_getproc(CoreLibHandle, "VidExt_Quit");162CoreVideo_ListFullscreenModes = (ptr_VidExt_ListFullscreenModes) osal_dynlib_getproc(CoreLibHandle, "VidExt_ListFullscreenModes");163CoreVideo_SetVideoMode = (ptr_VidExt_SetVideoMode) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetVideoMode");164CoreVideo_SetCaption = (ptr_VidExt_SetCaption) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetCaption");165CoreVideo_ToggleFullScreen = (ptr_VidExt_ToggleFullScreen) osal_dynlib_getproc(CoreLibHandle, "VidExt_ToggleFullScreen");166CoreVideo_ResizeWindow = (ptr_VidExt_ResizeWindow) osal_dynlib_getproc(CoreLibHandle, "VidExt_ResizeWindow");167CoreVideo_GL_GetProcAddress = (ptr_VidExt_GL_GetProcAddress) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_GetProcAddress");168CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SetAttribute");169CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SwapBuffers");170171if (!CoreVideo_Init || !CoreVideo_Quit || !CoreVideo_ListFullscreenModes || !CoreVideo_SetVideoMode ||172!CoreVideo_SetCaption || !CoreVideo_ToggleFullScreen || !CoreVideo_GL_GetProcAddress ||173!CoreVideo_GL_SetAttribute || !CoreVideo_GL_SwapBuffers || !CoreVideo_ResizeWindow)174{175rdp_log(M64MSG_ERROR, "Couldn't connect to Core video functions");176return M64ERR_INCOMPATIBLE;177}178179/* attach and call the CoreGetAPIVersions function, check Config and Video Extension API versions for compatibility */180ptr_CoreGetAPIVersions CoreAPIVersionFunc;181CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions");182if (CoreAPIVersionFunc == NULL)183{184rdp_log(M64MSG_ERROR, "Core emulator broken; no CoreAPIVersionFunc() function found.");185return M64ERR_INCOMPATIBLE;186}187int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion;188(*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL);189if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000))190{191rdp_log(M64MSG_ERROR, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)",192VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION));193return M64ERR_INCOMPATIBLE;194}195if ((VidextAPIVersion & 0xffff0000) != (VIDEXT_API_VERSION & 0xffff0000))196{197rdp_log(M64MSG_ERROR, "Emulator core Video Extension API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)",198VERSION_PRINTF_SPLIT(VidextAPIVersion), VERSION_PRINTF_SPLIT(VIDEXT_API_VERSION));199return M64ERR_INCOMPATIBLE;200}201202/* Get the core config function pointers from the library handle */203ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection");204ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter");205ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter");206ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt");207ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat");208ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool");209ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString");210ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt");211ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat");212ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool");213ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString");214if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter ||215!ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||216!ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString)217{218rdp_log(M64MSG_ERROR, "Couldn't connect to Core configuration functions");219return M64ERR_INCOMPATIBLE;220}221222rglReadSettings();223224return M64ERR_SUCCESS;225}226227EXPORT m64p_error CALL PluginShutdown(void)228{229return M64ERR_SUCCESS;230}231232EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)233{234/* set version info */235if (PluginType != NULL)236*PluginType = M64PLUGIN_GFX;237238if (PluginVersion != NULL)239*PluginVersion = PLUGIN_VERSION;240241if (APIVersion != NULL)242*APIVersion = VIDEO_PLUGIN_API_VERSION;243244if (PluginNamePtr != NULL)245*PluginNamePtr = "Z64gl";246247if (Capabilities != NULL)248{249*Capabilities = 0;250}251252return M64ERR_SUCCESS;253}254255EXPORT void CALL SetRenderingCallback(void (*callback)(int))256{257render_callback = callback;258}259260EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front)261{262LOG("ReadScreen\n");263*width = rglSettings.resX;264*height = rglSettings.resY;265if (dest)266{267GLint oldMode;268glGetIntegerv( GL_READ_BUFFER, &oldMode );269if (front)270glReadBuffer( GL_FRONT );271else272glReadBuffer( GL_BACK );273glReadPixels( 0, 0, rglSettings.resX, rglSettings.resY,274GL_BGRA, GL_UNSIGNED_BYTE, dest );275glReadBuffer( oldMode );276}277}278279EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info)280{281LOG("InitiateGFX\n");282gfx = Gfx_Info;283memset(rdpTiles, 0, sizeof(rdpTiles));284memset(rdpTmem, 0, 0x1000);285memset(&rdpState, 0, sizeof(rdpState));286#ifdef THREADED287if (rglSettings.threaded)288rdpCreateThread();289#endif290return true;291}292293EXPORT void CALL MoveScreen (int xpos, int ypos)294{295}296297EXPORT void CALL ChangeWindow()298{299}300301EXPORT void CALL ProcessDList(void)302{303}304305306EXPORT void CALL ProcessRDPList(void)307{308#ifdef THREADED309if (rglSettings.threaded) {310rdpCreateThread();311rdpPostCommand();312} else313#endif314{315rdp_process_list();316}317318return;319}320321EXPORT void CALL ResizeVideoOutput(int Width, int Height)322{323}324325EXPORT void CALL RomClosed (void)326{327#ifdef THREADED328if (rglSettings.threaded) {329rglNextStatus = RGL_STATUS_CLOSED;330do331rdpPostCommand();332while (rglStatus != RGL_STATUS_CLOSED);333} else334#endif335{336rglNextStatus = rglStatus = RGL_STATUS_CLOSED;337rglCloseScreen();338}339}340341EXPORT int CALL RomOpen()342{343int success = 1;344#ifdef THREADED345if (rglSettings.threaded) {346rdpCreateThread();347//while (rglStatus != RGL_STATUS_CLOSED);348rglNextStatus = RGL_STATUS_WINDOWED;349}350else351#endif352{353rglNextStatus = rglStatus = RGL_STATUS_WINDOWED;354success = rglOpenScreen();355}356return success;357}358359EXPORT void CALL ShowCFB (void)360{361}362363EXPORT void CALL UpdateScreen (void)364{365#ifdef THREADED366if (rglSettings.threaded) {367rdpPostCommand();368} else369#endif370{371rglUpdate();372}373}374375EXPORT void CALL ViStatusChanged (void)376{377}378379EXPORT void CALL ViWidthChanged (void)380{381}382383#ifdef __cplusplus384}385#endif386387388389