22726e4d |
1 | /****************************************************************************** |
2 | * Arachnoid Graphics Plugin for Mupen64Plus |
3 | * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ |
4 | * |
5 | * Copyright (C) 2009 Jon Ring |
6 | * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson |
7 | * |
8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License |
10 | * as published by the Free Software Foundation; either version 2 |
11 | * of the License, or (at your option) any later version. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
21 | *****************************************************************************/ |
22 | |
23 | //Includes |
24 | #define M64P_PLUGIN_PROTOTYPES 1 |
25 | #include "m64p.h" |
26 | #include "GraphicsPlugin.h" //Main class |
27 | #include "config/Config.h" //Configuration |
28 | #include "Logger.h" //Debug logger |
29 | #include "MemoryLeakDetector.h" //For detecting memory leaks |
30 | |
31 | #include "m64p_types.h" |
32 | #include "m64p_common.h" |
33 | #include "m64p_plugin.h" |
34 | #include "m64p_config.h" |
35 | #include "m64p_vidext.h" |
36 | |
37 | #include "osal_dynamiclib.h" |
38 | |
39 | //Definitions |
40 | #define PLUGIN_NAME "Arachnoid Video Plugin" |
41 | #define PLUGIN_VERSION 0x020000 |
42 | #define VIDEO_PLUGIN_API_VERSION 0x020200 |
43 | #define CONFIG_API_VERSION 0x020000 |
44 | #define VIDEXT_API_VERSION 0x030000 |
45 | |
46 | #define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff) |
47 | |
48 | #define MI_INTR_DP 0x00000020 //!< RDP Interrupt signal |
49 | #define MI_INTR_SP 0x00000001 //!< RSP Interrupt signal |
50 | |
51 | //----------------------------------------------------------------------------- |
52 | // Global variables |
53 | //----------------------------------------------------------------------------- |
54 | |
55 | char g_cfgFilename[] = "ConfigGraphicsPlugin.cfg"; //!< Name configuration file |
56 | GFX_INFO g_graphicsInfo; //!< Information about window, memory... |
57 | GraphicsPlugin g_graphicsPlugin; //!< Main class for application |
58 | Config g_config(&g_graphicsPlugin); //!< Handles configuration |
59 | |
60 | void (*renderCallback)(int) = NULL; |
61 | |
62 | |
63 | /* definitions of pointers to Core config functions */ |
64 | ptr_ConfigOpenSection ConfigOpenSection = NULL; |
65 | ptr_ConfigSetParameter ConfigSetParameter = NULL; |
66 | ptr_ConfigGetParameter ConfigGetParameter = NULL; |
67 | ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL; |
68 | ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL; |
69 | ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL; |
70 | ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL; |
71 | ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL; |
72 | ptr_ConfigGetParamInt ConfigGetParamInt = NULL; |
73 | ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL; |
74 | ptr_ConfigGetParamBool ConfigGetParamBool = NULL; |
75 | ptr_ConfigGetParamString ConfigGetParamString = NULL; |
76 | |
77 | ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL; |
78 | ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath = NULL; |
79 | ptr_ConfigGetUserDataPath ConfigGetUserDataPath = NULL; |
80 | ptr_ConfigGetUserCachePath ConfigGetUserCachePath = NULL; |
81 | |
82 | /* definitions of pointers to Core video extension functions */ |
83 | ptr_VidExt_Init CoreVideo_Init = NULL; |
84 | ptr_VidExt_Quit CoreVideo_Quit = NULL; |
85 | ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes = NULL; |
86 | ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode = NULL; |
87 | ptr_VidExt_SetCaption CoreVideo_SetCaption = NULL; |
88 | ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen = NULL; |
89 | ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow = NULL; |
90 | ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress = NULL; |
91 | ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute = NULL; |
92 | ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers = NULL; |
93 | |
94 | //----------------------------------------------------------------------------- |
95 | // Mupen64plus 2.0 Common Plugin API Functions |
96 | //----------------------------------------------------------------------------- |
97 | #ifdef __cplusplus |
98 | extern "C" { |
99 | #endif |
100 | EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, |
101 | void (*DebugCallback)(void *, int, const char *)) |
102 | { |
103 | char logMsg[530]; |
104 | Logger::getSingleton().initialize(DebugCallback, Context); |
105 | Logger::getSingleton().printMsg("PluginStartup"); |
106 | |
107 | /* attach and call the CoreGetAPIVersions function, check Config and Video Extension API versions for compatibility */ |
108 | ptr_CoreGetAPIVersions CoreAPIVersionFunc; |
109 | CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions"); |
110 | if (CoreAPIVersionFunc == NULL) |
111 | { |
112 | sprintf(logMsg, "Core emulator broken; no CoreAPIVersionFunc() function found."); |
113 | Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); |
114 | return M64ERR_INCOMPATIBLE; |
115 | } |
116 | int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion; |
117 | (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); |
118 | if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000)) |
119 | { |
120 | sprintf(logMsg, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", |
121 | VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); |
122 | Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); |
123 | return M64ERR_INCOMPATIBLE; |
124 | } |
125 | if ((VidextAPIVersion & 0xffff0000) != (VIDEXT_API_VERSION & 0xffff0000)) |
126 | { |
127 | sprintf(logMsg, "Emulator core Video Extension API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", |
128 | VERSION_PRINTF_SPLIT(VidextAPIVersion), VERSION_PRINTF_SPLIT(VIDEXT_API_VERSION)); |
129 | Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); |
130 | return M64ERR_INCOMPATIBLE; |
131 | } |
132 | |
133 | /* Get the core config function pointers from the library handle */ |
134 | ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); |
135 | ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); |
136 | ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); |
137 | ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt"); |
138 | ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); |
139 | ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); |
140 | ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString"); |
141 | ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt"); |
142 | ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat"); |
143 | ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); |
144 | ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString"); |
145 | |
146 | ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetSharedDataFilepath"); |
147 | ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserConfigPath"); |
148 | ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserDataPath"); |
149 | ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserCachePath"); |
150 | |
151 | if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter || |
152 | !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString || |
153 | !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString || |
154 | !ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath) |
155 | { |
156 | Logger::getSingleton().printMsg("Couldn't connect to Core configuration functions", M64MSG_ERROR); |
157 | return M64ERR_INCOMPATIBLE; |
158 | } |
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 | Logger::getSingleton().printMsg("Couldn't connect to Core video functions", M64MSG_ERROR); |
177 | return M64ERR_INCOMPATIBLE; |
178 | } |
179 | |
180 | //Read configuration |
181 | if (g_config.initialize()) |
182 | { |
183 | g_config.load(); |
184 | g_graphicsPlugin.setConfig(g_config.getConfig()); |
185 | } |
186 | |
187 | return M64ERR_SUCCESS; |
188 | } |
189 | |
190 | EXPORT m64p_error CALL PluginShutdown(void) |
191 | { |
192 | //Close Logger |
193 | Logger::getSingleton().printMsg("CloseDLL\n"); |
194 | Logger::getSingleton().dispose(); |
195 | |
196 | //g_graphicsPlugin.dispose(); |
197 | return M64ERR_SUCCESS; |
198 | } |
199 | |
200 | EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) |
201 | { |
202 | /* set version info */ |
203 | if (PluginType != NULL) |
204 | *PluginType = M64PLUGIN_GFX; |
205 | |
206 | if (PluginVersion != NULL) |
207 | *PluginVersion = PLUGIN_VERSION; |
208 | |
209 | if (APIVersion != NULL) |
210 | *APIVersion = VIDEO_PLUGIN_API_VERSION; |
211 | |
212 | if (PluginNamePtr != NULL) |
213 | *PluginNamePtr = PLUGIN_NAME; |
214 | |
215 | if (Capabilities != NULL) |
216 | { |
217 | *Capabilities = 0; |
218 | } |
219 | |
220 | return M64ERR_SUCCESS; |
221 | } |
222 | |
223 | |
224 | |
225 | //----------------------------------------------------------------------------- |
226 | // Mupen64plus 2.0 Video Plugin API Functions |
227 | //----------------------------------------------------------------------------- |
228 | |
229 | |
230 | //----------------------------------------------------------------------------- |
231 | //* InitiateGFX |
232 | //! This function is called when the DLL is started to give |
233 | //! information from the emulator that the n64 graphics |
234 | //! uses. This is not called from the emulation thread. |
235 | //! @param[in] Gfx_Info Information about rom and emulator |
236 | //! @return true on success, FALSE on failure to initialise |
237 | //! |
238 | //! @note on interrupts : |
239 | //! To generate an interrupt set the appropriate bit in MI_INTR_REG |
240 | //! and then the function CheckInterrupts to tell the emulator |
241 | //! that there is a waiting interrupt. |
242 | //----------------------------------------------------------------------------- |
243 | EXPORT BOOL CALL InitiateGFX(GFX_INFO Gfx_Info) |
244 | { |
245 | Logger::getSingleton().printMsg("InitiateGFX"); |
246 | |
247 | //Save Graphics Info |
248 | memcpy(&g_graphicsInfo, &Gfx_Info, sizeof(GFX_INFO)); |
249 | return true; |
250 | } |
251 | |
252 | //----------------------------------------------------------------------------- |
253 | //* Rom Open |
254 | //! This function is called when a rom is open. (from the emulation thread) |
255 | //----------------------------------------------------------------------------- |
256 | EXPORT int CALL RomOpen() |
257 | { |
258 | Logger::getSingleton().printMsg("RomOpen\n"); |
259 | return g_graphicsPlugin.initialize(&g_graphicsInfo); |
260 | } |
261 | |
262 | //----------------------------------------------------------------------------- |
263 | //* Resize Video Output |
264 | //! This function is called to force us to resize our output OpenGL window. |
265 | //! This is currently unsupported, and should never be called because we do |
266 | //! not pass the RESIZABLE flag to VidExt_SetVideoMode when initializing. |
267 | //----------------------------------------------------------------------------- |
268 | EXPORT void CALL ResizeVideoOutput(int Width, int Height) |
269 | { |
270 | } |
271 | |
272 | //----------------------------------------------------------------------------- |
273 | //* Rom Closed |
274 | //! This function is called when a rom is closed. |
275 | //----------------------------------------------------------------------------- |
276 | EXPORT void CALL RomClosed() |
277 | { |
278 | //Logger::getSingleton().printMsg("RomClosed\n"); |
279 | //Destroy |
280 | g_graphicsPlugin.dispose(); |
281 | } |
282 | |
283 | //----------------------------------------------------------------------------- |
284 | //* Update Screen |
285 | //! This function is called in response to a vsync of the |
286 | //! screen where the VI bit in MI_INTR_REG has already been set |
287 | //----------------------------------------------------------------------------- |
288 | EXPORT void CALL UpdateScreen() |
289 | { |
290 | if (g_config.getConfig()->screenUpdateSetting == SCREEN_UPDATE_VI) |
291 | g_graphicsPlugin.drawScreen(); |
292 | else if (g_config.getConfig()->screenUpdateSetting == SCREEN_UPDATE_CI) |
293 | g_graphicsPlugin.setDrawScreenSignal(); |
294 | else |
295 | { |
296 | Logger::getSingleton().printMsg("Invalid screen update setting!", M64MSG_WARNING); |
297 | g_graphicsPlugin.drawScreen(); |
298 | } |
299 | } |
300 | |
301 | |
302 | //----------------------------------------------------------------------------- |
303 | //* ProcessDList |
304 | //! This function is called when there is a Dlist to be processed. (High level GFX list) |
305 | //----------------------------------------------------------------------------- |
306 | EXPORT void CALL ProcessDList() |
307 | { |
308 | Logger::getSingleton().printMsg("ProcessDList\n"); |
309 | |
310 | try |
311 | { |
312 | g_graphicsPlugin.viStatusChanged(); |
313 | g_graphicsPlugin.processDisplayList(); |
314 | } |
315 | catch (...) |
316 | { |
317 | Logger::getSingleton().printMsg("Unknown Error processing DisplayList", M64MSG_WARNING); |
318 | //MessageBox(0, "Unknown Error processing DisplayList", "Arachnoid Graphics Plugin", MB_OK|MB_SETFOREGROUND); |
319 | |
320 | g_graphicsPlugin.dispose(); |
321 | g_graphicsPlugin.initialize(&g_graphicsInfo); |
322 | |
323 | //Trigger Interupts |
324 | *(g_graphicsInfo.MI_INTR_REG) |= MI_INTR_DP; |
325 | g_graphicsInfo.CheckInterrupts(); |
326 | *(g_graphicsInfo.MI_INTR_REG) |= MI_INTR_SP; |
327 | g_graphicsInfo.CheckInterrupts(); |
328 | } |
329 | } |
330 | |
331 | |
332 | //----------------------------------------------------------------------------- |
333 | //* ProcessRDPList |
334 | //! This function is called when there is a Dlist to be processed. (Low level GFX list) |
335 | //! @todo ProcessRDPList |
336 | //----------------------------------------------------------------------------- |
337 | EXPORT void CALL ProcessRDPList() |
338 | { |
339 | Logger::getSingleton().printMsg("ProcessRDPList\n"); |
340 | //TODO |
341 | } |
342 | |
343 | //----------------------------------------------------------------------------- |
344 | //* Show CFB |
345 | //! Usally once Dlists are started being displayed, cfb is |
346 | //! ignored. This function tells the dll to start displaying |
347 | //! them again. |
348 | //----------------------------------------------------------------------------- |
349 | EXPORT void CALL ShowCFB() |
350 | { |
351 | Logger::getSingleton().printMsg("ShowCFB\n"); |
352 | } |
353 | |
354 | //----------------------------------------------------------------------------- |
355 | //* ViStatusChanged |
356 | //! This function is called to notify the dll that the |
357 | //! ViStatus registers value has been changed. |
358 | //----------------------------------------------------------------------------- |
359 | EXPORT void CALL ViStatusChanged() |
360 | { |
361 | Logger::getSingleton().printMsg("ViStatusChanged"); |
362 | |
363 | //g_graphicsPlugin.viStatusChanged(); |
364 | } |
365 | |
366 | //----------------------------------------------------------------------------- |
367 | //* ViWidthChanged |
368 | //! This function is called to notify the dll that the |
369 | //! ViWidth registers value has been changed. |
370 | //----------------------------------------------------------------------------- |
371 | EXPORT void CALL ViWidthChanged() |
372 | { |
373 | Logger::getSingleton().printMsg("ViWidthChanged"); |
374 | //g_graphicsPlugin.viStatusChanged(); |
375 | } |
376 | |
377 | //----------------------------------------------------------------------------- |
378 | //* MoveScreen |
379 | //! This function is called in response to the emulator |
380 | //! receiving a WM_MOVE passing the xpos and ypos passed |
381 | //! from that message. |
382 | //! @param xpos The x-coordinate of the upper-left corner of the |
383 | //! client area of the window. |
384 | //! @param ypos The y-coordinate of the upper-left corner of the |
385 | //! client area of the window. |
386 | //! @todo MoveScreen |
387 | //----------------------------------------------------------------------------- |
388 | EXPORT void CALL MoveScreen(int xpos, int ypos) |
389 | { |
390 | Logger::getSingleton().printMsg("MoveScreen\n"); |
391 | //TODO |
392 | } |
393 | |
394 | //----------------------------------------------------------------------------- |
395 | //* ChangeWindow |
396 | //! Toggle between fullscreen and window mode |
397 | //----------------------------------------------------------------------------- |
398 | EXPORT void CALL ChangeWindow() |
399 | { |
400 | Logger::getSingleton().printMsg("ChangeWindow\n"); |
401 | //Toggle Fullscreen |
402 | g_graphicsPlugin.toggleFullscreen(); |
403 | } |
404 | |
405 | //----------------------------------------------------------------------------- |
406 | //* ReadScreen2 |
407 | //! This function reads the pixels of the currently displayed screen |
408 | //----------------------------------------------------------------------------- |
409 | EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front) |
410 | { |
411 | g_graphicsPlugin.takeScreenshot(dest, width, height, front); |
412 | } |
413 | |
414 | //----------------------------------------------------------------------------- |
415 | //* SetRenderingCallback |
416 | //! Allows the core to register a callback function that will be called by the |
417 | //! graphics plugin just before the the frame buffers are swapped. |
418 | //----------------------------------------------------------------------------- |
419 | EXPORT void CALL SetRenderingCallback(void (*callback)(int)) |
420 | { |
421 | OpenGLManager::getSingleton().setRenderingCallback(callback); |
422 | } |
423 | |
424 | //----------------------------------------------------------------------------- |
425 | //* FBRead |
426 | //! Read data from frame buffer into emulated RAM space |
427 | //----------------------------------------------------------------------------- |
428 | EXPORT void CALL FBRead(unsigned int addr) |
429 | { |
430 | //TODO |
431 | } |
432 | |
433 | //----------------------------------------------------------------------------- |
434 | //* FBWrite |
435 | //! Write data from emulated RAM space into frame buffer |
436 | //----------------------------------------------------------------------------- |
437 | EXPORT void CALL FBWrite(unsigned int addr, unsigned int size) |
438 | { |
439 | //TODO |
440 | } |
441 | |
442 | //----------------------------------------------------------------------------- |
443 | //* FBWrite |
444 | //! Get some information about the frame buffer |
445 | //----------------------------------------------------------------------------- |
446 | EXPORT void FBGetFrameBufferInfo(void *p) |
447 | { |
448 | //TODO |
449 | } |
450 | |
451 | #ifdef __cplusplus |
452 | } |
453 | #endif |