Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-z64/src/maingl.cpp
2 views
1
/*
2
* z64
3
*
4
* Copyright (C) 2007 ziggy
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License along
17
* with this program; if not, write to the Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
**/
21
22
#include "rdp.h"
23
#include "rgl.h"
24
#include "osal_dynamiclib.h"
25
#include <SDL.h>
26
27
#define THREADED
28
29
#define PLUGIN_VERSION 0x020000
30
#define VIDEO_PLUGIN_API_VERSION 0x020200
31
#define CONFIG_API_VERSION 0x020000
32
#define VIDEXT_API_VERSION 0x030000
33
34
#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff)
35
36
GFX_INFO gfx;
37
38
void (*render_callback)(int) = NULL;
39
static void (*l_DebugCallback)(void *, int, const char *) = NULL;
40
static void *l_DebugCallContext = NULL;
41
42
43
/* definitions of pointers to Core video extension functions */
44
ptr_VidExt_Init CoreVideo_Init = NULL;
45
ptr_VidExt_Quit CoreVideo_Quit = NULL;
46
ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes = NULL;
47
ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode = NULL;
48
ptr_VidExt_SetCaption CoreVideo_SetCaption = NULL;
49
ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen = NULL;
50
ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow = NULL;
51
ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress = NULL;
52
ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute = NULL;
53
ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers = NULL;
54
55
/* definitions of pointers to Core config functions */
56
ptr_ConfigOpenSection ConfigOpenSection = NULL;
57
ptr_ConfigSetParameter ConfigSetParameter = NULL;
58
ptr_ConfigGetParameter ConfigGetParameter = NULL;
59
ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL;
60
ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL;
61
ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL;
62
ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL;
63
ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL;
64
ptr_ConfigGetParamInt ConfigGetParamInt = NULL;
65
ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL;
66
ptr_ConfigGetParamBool ConfigGetParamBool = NULL;
67
ptr_ConfigGetParamString ConfigGetParamString = NULL;
68
69
#ifdef THREADED
70
volatile static int waiting;
71
SDL_sem * rdpCommandSema;
72
SDL_sem * rdpCommandCompleteSema;
73
SDL_Thread * rdpThread;
74
int rdpThreadFunc(void * dummy)
75
{
76
while (1) {
77
SDL_SemWait(rdpCommandSema);
78
waiting = 1;
79
if (rglNextStatus == RGL_STATUS_CLOSED)
80
rglUpdateStatus();
81
else
82
rdp_process_list();
83
if (!rglSettings.async)
84
SDL_SemPost(rdpCommandCompleteSema);
85
86
if (rglStatus == RGL_STATUS_CLOSED) {
87
rdpThread = NULL;
88
return 0;
89
}
90
}
91
return 0;
92
}
93
94
void rdpSignalFullSync()
95
{
96
SDL_SemPost(rdpCommandCompleteSema);
97
}
98
void rdpWaitFullSync()
99
{
100
SDL_SemWait(rdpCommandCompleteSema);
101
}
102
103
void rdpPostCommand()
104
{
105
int sync = rdp_store_list();
106
SDL_SemPost(rdpCommandSema);
107
if (!rglSettings.async)
108
SDL_SemWait(rdpCommandCompleteSema);
109
else if (sync) {
110
rdpWaitFullSync();
111
*gfx.MI_INTR_REG |= 0x20;
112
gfx.CheckInterrupts();
113
}
114
115
waiting = 0;
116
}
117
118
void rdpCreateThread()
119
{
120
if (!rdpCommandSema) {
121
rdpCommandSema = SDL_CreateSemaphore(0);
122
rdpCommandCompleteSema = SDL_CreateSemaphore(0);
123
}
124
if (!rdpThread) {
125
LOG("Creating rdp thread\n");
126
#if SDL_VERSION_ATLEAST(2,0,0)
127
rdpThread = SDL_CreateThread(rdpThreadFunc, "z64rdp", 0);
128
#else
129
rdpThread = SDL_CreateThread(rdpThreadFunc, 0);
130
#endif
131
}
132
}
133
#endif
134
135
void rdp_log(m64p_msg_level level, const char *msg, ...)
136
{
137
char buf[1024];
138
va_list args;
139
va_start(args, msg);
140
vsnprintf(buf, 1023, msg, args);
141
buf[1023]='\0';
142
va_end(args);
143
if (l_DebugCallback)
144
{
145
l_DebugCallback(l_DebugCallContext, level, buf);
146
}
147
}
148
149
#ifdef __cplusplus
150
extern "C" {
151
#endif
152
153
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,
154
void (*DebugCallback)(void *, int, const char *))
155
{
156
///* first thing is to set the callback function for debug info */
157
l_DebugCallback = DebugCallback;
158
l_DebugCallContext = Context;
159
160
/* Get the core Video Extension function pointers from the library handle */
161
CoreVideo_Init = (ptr_VidExt_Init) osal_dynlib_getproc(CoreLibHandle, "VidExt_Init");
162
CoreVideo_Quit = (ptr_VidExt_Quit) osal_dynlib_getproc(CoreLibHandle, "VidExt_Quit");
163
CoreVideo_ListFullscreenModes = (ptr_VidExt_ListFullscreenModes) osal_dynlib_getproc(CoreLibHandle, "VidExt_ListFullscreenModes");
164
CoreVideo_SetVideoMode = (ptr_VidExt_SetVideoMode) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetVideoMode");
165
CoreVideo_SetCaption = (ptr_VidExt_SetCaption) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetCaption");
166
CoreVideo_ToggleFullScreen = (ptr_VidExt_ToggleFullScreen) osal_dynlib_getproc(CoreLibHandle, "VidExt_ToggleFullScreen");
167
CoreVideo_ResizeWindow = (ptr_VidExt_ResizeWindow) osal_dynlib_getproc(CoreLibHandle, "VidExt_ResizeWindow");
168
CoreVideo_GL_GetProcAddress = (ptr_VidExt_GL_GetProcAddress) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_GetProcAddress");
169
CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SetAttribute");
170
CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SwapBuffers");
171
172
if (!CoreVideo_Init || !CoreVideo_Quit || !CoreVideo_ListFullscreenModes || !CoreVideo_SetVideoMode ||
173
!CoreVideo_SetCaption || !CoreVideo_ToggleFullScreen || !CoreVideo_GL_GetProcAddress ||
174
!CoreVideo_GL_SetAttribute || !CoreVideo_GL_SwapBuffers || !CoreVideo_ResizeWindow)
175
{
176
rdp_log(M64MSG_ERROR, "Couldn't connect to Core video functions");
177
return M64ERR_INCOMPATIBLE;
178
}
179
180
/* attach and call the CoreGetAPIVersions function, check Config and Video Extension API versions for compatibility */
181
ptr_CoreGetAPIVersions CoreAPIVersionFunc;
182
CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions");
183
if (CoreAPIVersionFunc == NULL)
184
{
185
rdp_log(M64MSG_ERROR, "Core emulator broken; no CoreAPIVersionFunc() function found.");
186
return M64ERR_INCOMPATIBLE;
187
}
188
int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion;
189
(*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL);
190
if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000))
191
{
192
rdp_log(M64MSG_ERROR, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)",
193
VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION));
194
return M64ERR_INCOMPATIBLE;
195
}
196
if ((VidextAPIVersion & 0xffff0000) != (VIDEXT_API_VERSION & 0xffff0000))
197
{
198
rdp_log(M64MSG_ERROR, "Emulator core Video Extension API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)",
199
VERSION_PRINTF_SPLIT(VidextAPIVersion), VERSION_PRINTF_SPLIT(VIDEXT_API_VERSION));
200
return M64ERR_INCOMPATIBLE;
201
}
202
203
/* Get the core config function pointers from the library handle */
204
ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection");
205
ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter");
206
ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter");
207
ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt");
208
ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat");
209
ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool");
210
ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString");
211
ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt");
212
ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat");
213
ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool");
214
ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString");
215
if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter ||
216
!ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||
217
!ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString)
218
{
219
rdp_log(M64MSG_ERROR, "Couldn't connect to Core configuration functions");
220
return M64ERR_INCOMPATIBLE;
221
}
222
223
rglReadSettings();
224
225
return M64ERR_SUCCESS;
226
}
227
228
EXPORT m64p_error CALL PluginShutdown(void)
229
{
230
return M64ERR_SUCCESS;
231
}
232
233
EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)
234
{
235
/* set version info */
236
if (PluginType != NULL)
237
*PluginType = M64PLUGIN_GFX;
238
239
if (PluginVersion != NULL)
240
*PluginVersion = PLUGIN_VERSION;
241
242
if (APIVersion != NULL)
243
*APIVersion = VIDEO_PLUGIN_API_VERSION;
244
245
if (PluginNamePtr != NULL)
246
*PluginNamePtr = "Z64gl";
247
248
if (Capabilities != NULL)
249
{
250
*Capabilities = 0;
251
}
252
253
return M64ERR_SUCCESS;
254
}
255
256
EXPORT void CALL SetRenderingCallback(void (*callback)(int))
257
{
258
render_callback = callback;
259
}
260
261
EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front)
262
{
263
LOG("ReadScreen\n");
264
*width = rglSettings.resX;
265
*height = rglSettings.resY;
266
if (dest)
267
{
268
GLint oldMode;
269
glGetIntegerv( GL_READ_BUFFER, &oldMode );
270
if (front)
271
glReadBuffer( GL_FRONT );
272
else
273
glReadBuffer( GL_BACK );
274
glReadPixels( 0, 0, rglSettings.resX, rglSettings.resY,
275
GL_BGRA, GL_UNSIGNED_BYTE, dest );
276
glReadBuffer( oldMode );
277
}
278
}
279
280
EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info)
281
{
282
LOG("InitiateGFX\n");
283
gfx = Gfx_Info;
284
memset(rdpTiles, 0, sizeof(rdpTiles));
285
memset(rdpTmem, 0, 0x1000);
286
memset(&rdpState, 0, sizeof(rdpState));
287
#ifdef THREADED
288
if (rglSettings.threaded)
289
rdpCreateThread();
290
#endif
291
return true;
292
}
293
294
EXPORT void CALL MoveScreen (int xpos, int ypos)
295
{
296
}
297
298
EXPORT void CALL ChangeWindow()
299
{
300
}
301
302
EXPORT void CALL ProcessDList(void)
303
{
304
}
305
306
307
EXPORT void CALL ProcessRDPList(void)
308
{
309
#ifdef THREADED
310
if (rglSettings.threaded) {
311
rdpCreateThread();
312
rdpPostCommand();
313
} else
314
#endif
315
{
316
rdp_process_list();
317
}
318
319
return;
320
}
321
322
EXPORT void CALL ResizeVideoOutput(int Width, int Height)
323
{
324
}
325
326
EXPORT void CALL RomClosed (void)
327
{
328
#ifdef THREADED
329
if (rglSettings.threaded) {
330
rglNextStatus = RGL_STATUS_CLOSED;
331
do
332
rdpPostCommand();
333
while (rglStatus != RGL_STATUS_CLOSED);
334
} else
335
#endif
336
{
337
rglNextStatus = rglStatus = RGL_STATUS_CLOSED;
338
rglCloseScreen();
339
}
340
}
341
342
EXPORT int CALL RomOpen()
343
{
344
int success = 1;
345
#ifdef THREADED
346
if (rglSettings.threaded) {
347
rdpCreateThread();
348
//while (rglStatus != RGL_STATUS_CLOSED);
349
rglNextStatus = RGL_STATUS_WINDOWED;
350
}
351
else
352
#endif
353
{
354
rglNextStatus = rglStatus = RGL_STATUS_WINDOWED;
355
success = rglOpenScreen();
356
}
357
return success;
358
}
359
360
EXPORT void CALL ShowCFB (void)
361
{
362
}
363
364
EXPORT void CALL UpdateScreen (void)
365
{
366
#ifdef THREADED
367
if (rglSettings.threaded) {
368
rdpPostCommand();
369
} else
370
#endif
371
{
372
rglUpdate();
373
}
374
}
375
376
EXPORT void CALL ViStatusChanged (void)
377
{
378
}
379
380
EXPORT void CALL ViWidthChanged (void)
381
{
382
}
383
384
#ifdef __cplusplus
385
}
386
#endif
387
388
389