Path: blob/master/libmupen64plus/mupen64plus-video-glide64/src/Gfx1.3.h
2 views
/*1* Glide64 - Glide video plugin for Nintendo 64 emulators.2* Copyright (c) 2002 Dave20013*4* This program is free software; you can redistribute it and/or modify5* it under the terms of the GNU General Public License as published by6* the Free Software Foundation; either version 2 of the License, or7* any later version.8*9* This program is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12* GNU General Public License for more details.13*14* You should have received a copy of the GNU General Public15* Licence along with this program; if not, write to the Free16* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,17* Boston, MA 02110-1301, USA18*/1920//****************************************************************21//22// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)23// Project started on December 29th, 200124//25// To modify Glide64:26// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.27// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.28//29// Official Glide64 development channel: #Glide64 on EFnet30//31// Original author: Dave2001 ([email protected])32// Other authors: Gonetz, Gugaman33//34//****************************************************************3536// ** NOTE: this file has been modified from it's original version, which can be37// downloaded along with Project64 **3839/**********************************************************************************40Common gfx plugin spec, version #1.3 maintained by zilmar ([email protected])4142All questions or suggestions should go through the mailing list.43http://www.egroups.com/group/Plugin64-Dev44***********************************************************************************4546Notes:47------4849Setting the approprate bits in the MI_INTR_REG and calling CheckInterrupts which50are both passed to the DLL in InitiateGFX will generate an Interrupt from with in51the plugin.5253The Setting of the RSP flags and generating an SP interrupt should not be done in54the plugin5556**********************************************************************************/5758// THIS FILE IS A PRECOMPILED HEADER TO DECREASE BUILD TIME. INCLUDE ALL STANDARD59// .H FILES HERE6061#ifndef _GFX_H_INCLUDED__62#define _GFX_H_INCLUDED__63#include "m64p.h"6465#if defined(WIN32) && defined(GCC)66// ZIGGY ARRRRGG what a pain in the #$@$67//# include "Gfx #1.3-mangling.h"68#ifdef GCC69#include <stdio.h>70//#define printf(...)71#endif72#endif7374#define _WIN32_WINNT 0x04007576#ifdef _WIN3277#include <windows.h>78#else // _WIN3279#include "winlnxdefs.h"80#endif // _WIN3281#include <stdio.h>8283#include <ostream>84#include <fstream>8586#include <cstddef> // offsetof87#ifndef _WIN3288#include <cmath>89#endif90#ifdef _WIN3291#include <io.h>92#include <direct.h>93#include <mmsystem.h>94#include <commctrl.h>95#endif // _WIN3296#include <time.h>97#include <glide.h>98#include <g3ext.h>99#include "rdp.h"100101#if defined(__cplusplus)102extern "C" {103#endif104105// tooltips have an error on debug mode, this can be overcome by clicking ignore,106// but I'd rather just disable tooltips altogether since nobody else should107// have the debug version anyway.108#ifndef _DEBUG109//#ifndef __INTEL_COMPILER // tooltips don't work with intel compiler110#define USE_TOOLTIPS111//#endif112#endif113114#ifndef VPDEBUG115# define _FINAL_RELEASE_116#endif117// #ifdef WIN32118// # define _FINAL_RELEASE_119// #else120// //# define _FINAL_RELEASE_121// #endif122123//********124// Logging125126// ********************************127// ** TAKE OUT BEFORE RELEASE!!! **128//#define LOGGING // log of spec functions called129//#define LOG_KEY // says "Key!!!" in the log when space bar is pressed130131//#define LOG_UCODE132133//#define ALTTAB_FIX134135//#define EXTREME_LOGGING // lots of logging136// note that some of these things are inserted/removed137// from within the code & may not be changed by this define.138139//#define TLUT_LOGGING // log every entry of the TLUT?140// ********************************141142#define FPS // fps counter able? (not enabled necessarily)143144#define LOGNOTKEY // Log if not pressing:145#ifdef WIN32146#define LOGKEY VK_LCONTROL // this key147#else148#include <SDL.h>149#define LOGKEY KMOD_LCTRL150inline int GetAsyncKeyState(int key) {151return (SDL_GetModState() & key) != 0;152}153#endif154155#define LOG_COMMANDS // log the whole 64-bit command as (0x........, 0x........)156157#define CATCH_EXCEPTIONS // catch exceptions so it doesn't freeze and will report158// "The gfx plugin has caused an exception" instead.159160#define FLUSH // flush the file buffer. slower logging, but makes sure161// the command is logged before continuing (in case of162// crash or exception, the log will not be cut short)163#ifndef _FINAL_RELEASE_164#define RDP_LOGGING // Allow logging (will not log unless checked, but allows the option)165// Logging functions will not be compiled if this is not present.166//#define RDP_ERROR_LOG167#endif168169#define FPS_FRAMES 10 // Number of frames in which to make an FPS count170171//#define SHOW_FULL_TEXVIEWER // shows the entire contents of the texture in the cache viewer,172// usually used to debug clamping issues.173174175// Usually enabled176#define LARGE_TEXTURE_HANDLING // allow large-textured objects to be split?177178#ifdef ALTTAB_FIX179extern HHOOK hhkLowLevelKybd;180extern LRESULT CALLBACK LowLevelKeyboardProc(int nCode,181WPARAM wParam, LPARAM lParam);182#endif183184// Simulations185//#define SIMULATE_VOODOO1186//#define SIMULATE_BANSHEE187//********188189#ifdef EXT_LOGGING190extern std::ofstream extlog;191#define EXT(x) extlog.open("ext.txt",ios::app); extlog << x; extlog.close();192#else193#define EXT(x)194#endif195196#ifndef _FINAL_RELEASE_197#define UNIMP_LOG // Keep enabled, option in dialog198#define BRIGHT_RED // Keep enabled, option in dialog199#endif200201#define COLORED_DEBUGGER // ;) pretty colors202203#ifdef FPS204extern LARGE_INTEGER perf_freq;205extern LARGE_INTEGER fps_last;206extern LARGE_INTEGER fps_next;207extern float fps;208extern DWORD fps_count;209#endif210211// rdram mask at 0x400000 bytes (bah, not right for majora's mask)212//#define BMASK 0x7FFFFF213extern unsigned long BMASK;214#define WMASK 0x3FFFFF215#define DMASK 0x1FFFFF216217extern int num_tmu;218extern int max_tex_size;219extern long sup_mirroring;220extern BOOL sup_32bit_tex;221extern DWORD update_screen_count;222223extern DWORD resolutions[0x18][2];224225//#define PERFORMANCE226#ifdef PERFORMANCE227extern __int64 perf_cur;228extern __int64 perf_next;229#endif230231#ifdef LOGGING232extern std::ofstream loga;233#define LOG(x) loga.open("log.txt",ios::app); loga << x; loga.flush(); loga.close();234#else235#define LOG(x) WriteLog(M64MSG_VERBOSE, "%s", x);236#endif237238239#ifdef RDP_LOGGING240extern int dumping;241extern BOOL log_open;242extern std::ofstream rdp_log;243//#define rdp_log std::cerr;244#define OPEN_RDP_LOG() EXT("OPEN_RDP_LOG ()\n"); if (settings.logging && !log_open) { /*rdp_log.open ("rdp.txt");*/ log_open=TRUE; }245#define CLOSE_RDP_LOG() EXT("CLOSE_RDP_LOG ()\n"); if (settings.logging && log_open) { /*rdp_log.close ();*/ log_open=FALSE; }246247#ifdef LOGNOTKEY248#define RDP(x) EXT("RDP (...)\n"); if (dumping && settings.logging && log_open) { if (!(GetAsyncKeyState(LOGKEY)&0x8000)) { fprintf(stderr, x);/*rdp_log << x; rdp_log.flush();*/ } }249#else250#define RDP(x) EXT("RDP (...)\n"); if (dumping && settings.logging && log_open) { fprintf(stderr, x);/*rdp_log << x; rdp_log.flush();*/ }251#endif252253#else254#define OPEN_RDP_LOG()255#define CLOSE_RDP_LOG()256#define RDP(x)257#endif258259260#ifdef RDP_ERROR_LOG261extern BOOL elog_open;262extern std::ofstream rdp_err;263//#define rdp_err std::cerr264#define OPEN_RDP_E_LOG() EXT("OPEN_RDP_E_LOG ()\n"); if (settings.elogging && !elog_open) { /*rdp_err.open ("rdp_e.txt");*/ elog_open=TRUE; }265#define CLOSE_RDP_E_LOG() EXT("CLOSE_RDP_LOG ()\n"); if (settings.elogging && elog_open) { /*rdp_err.close (); */elog_open=FALSE; }266#define RDP_E(x) if (dumping && settings.elogging) { FRDP_E (x); }267#else268#define OPEN_RDP_E_LOG()269#define CLOSE_RDP_E_LOG()270#define RDP_E(x)271#endif272273274#ifdef RDP_LOGGING275__inline void FRDP (const char *fmt, ...)276{277#ifdef RDP_LOGGING278if (!dumping || !settings.logging || !log_open) return;279280#ifdef LOGNOTKEY281if (GetAsyncKeyState(LOGKEY)&0x8000) return;282#endif283284va_list ap;285va_start(ap, fmt);286vsprintf(out_buf, fmt, ap);287RDP (out_buf);288va_end(ap);289#endif290}291__inline void FRDP_E (const char *fmt, ...)292{293#ifdef RDP_ERROR_LOG294if (!dumping || !settings.elogging || !elog_open) return;295296#ifdef LOGNOTKEY297if (GetAsyncKeyState(LOGKEY)&0x8000) return;298#endif299300sprintf (out_buf, "%08x: (%08x, %08x) ", rdp.pc[rdp.pc_i]-8, rdp.cmd0, rdp.cmd1);301rdp_err << out_buf;302303va_list ap2;304va_start(ap2, fmt);305vsprintf(out_buf, fmt, ap2);306// rdp_err << out_buf;307// rdp_err.flush();308fprintf(stderr, out_buf);309va_end(ap2);310#endif311}312313#else314#ifndef GCC315#define FRDP(...)316#define FRDP_E(...)317#else // _WIN32318inline void FRDP (const char *fmt, ...) {}319inline void FRDP_E (const char *fmt, ...) {}320#endif // _WIN32321#endif322323324extern BOOL fullscreen;325extern BOOL romopen;326extern BOOL to_fullscreen;327extern BOOL debugging;328extern HINSTANCE hInstance;329330extern BOOL evoodoo;331extern BOOL ev_fullscreen;332333extern BOOL exception;334335extern PROPSHEETHEADER m_PropSheet;336extern PROPSHEETPAGE m_psp[3];337338339BOOL InitGfx (BOOL);340void ReleaseGfx ();341void DrawFrameBuffer ();342343// The highest 8 bits are the segment # (1-16), and the lower 24 bits are the offset to344// add to it.345__inline DWORD segoffset (DWORD so)346{347return (rdp.segment[(so>>24)&0x0f] + (so&BMASK))&BMASK;348}349350/* Plugin types */351#define PLUGIN_TYPE_GFX 2352353//TODO: remove354//#define EXPORT __declspec(dllexport)355//#define CALL _cdecl356357/***** Structures *****/358typedef struct {359WORD Version; /* Set to 0x0103 */360WORD Type; /* Set to PLUGIN_TYPE_GFX */361char Name[100]; /* Name of the DLL */362363/* If DLL supports memory these memory options then set them to TRUE or FALSE364if it does not support it */365BOOL NormalMemory; /* a normal BYTE array */366BOOL MemoryBswaped; /* a normal BYTE array where the memory has been pre367bswap on a dword (32 bits) boundry */368} PLUGIN_INFO;369370#if 0371//TODO: remove372373typedef struct {374HWND hWnd; /* Render window */375HWND hStatusBar; /* if render window does not have a status bar then this is NULL */376377BOOL MemoryBswaped; // If this is set to TRUE, then the memory has been pre378// bswap on a dword (32 bits) boundry379// eg. the first 8 bytes are stored like this:380// 4 3 2 1 8 7 6 5381382BYTE * HEADER; // This is the rom header (first 40h bytes of the rom383// This will be in the same memory format as the rest of the memory.384BYTE * RDRAM;385BYTE * DMEM;386BYTE * IMEM;387388DWORD * MI_INTR_REG;389390DWORD * DPC_START_REG;391DWORD * DPC_END_REG;392DWORD * DPC_CURRENT_REG;393DWORD * DPC_STATUS_REG;394DWORD * DPC_CLOCK_REG;395DWORD * DPC_BUFBUSY_REG;396DWORD * DPC_PIPEBUSY_REG;397DWORD * DPC_TMEM_REG;398399DWORD * VI_STATUS_REG;400DWORD * VI_ORIGIN_REG;401DWORD * VI_WIDTH_REG;402DWORD * VI_INTR_REG;403DWORD * VI_V_CURRENT_LINE_REG;404DWORD * VI_TIMING_REG;405DWORD * VI_V_SYNC_REG;406DWORD * VI_H_SYNC_REG;407DWORD * VI_LEAP_REG;408DWORD * VI_H_START_REG;409DWORD * VI_V_START_REG;410DWORD * VI_V_BURST_REG;411DWORD * VI_X_SCALE_REG;412DWORD * VI_Y_SCALE_REG;413414void (*CheckInterrupts)( void );415} GFX_INFO;416#endif417418extern GFX_INFO gfx;419extern BOOL no_dlist;420421typedef GrContext_t (FX_CALL *GRWINOPENEXT)( FxU32 hWnd,422GrScreenResolution_t resolution,423GrScreenRefresh_t refresh,424GrColorFormat_t format,425GrOriginLocation_t origin,426GrPixelFormat_t pixelformat,427int nColBuffers,428int nAuxBuffers) ;429430typedef void (FX_CALL *GRTEXBUFFEREXT)( GrChipID_t tmu,431FxU32 startAddress,432GrLOD_t lodmin,433GrLOD_t lodmax,434GrAspectRatio_t aspect,435GrTextureFormat_t fmt,436FxU32 evenOdd) ;437438typedef void (FX_CALL *GRAUXBUFFEREXT)( GrBuffer_t buffer ) ;439440typedef void (FX_CALL *GRCOLORCOMBINEEXT) (GrCCUColor_t a,441GrCombineMode_t a_mode,442GrCCUColor_t b,443GrCombineMode_t b_mode,444GrCCUColor_t c,445FxBool c_invert,446GrCCUColor_t d,447FxBool d_invert,448FxU32 shift,449FxBool invert) ;450451typedef void (FX_CALL *GRTEXCOLORCOMBINEEXT) (GrChipID_t tmu,452GrTCCUColor_t a,453GrCombineMode_t a_mode,454GrTCCUColor_t b,455GrCombineMode_t b_mode,456GrTCCUColor_t c,457FxBool c_invert,458GrTCCUColor_t d,459FxBool d_invert,460FxU32 shift,461FxBool invert);462463typedef void (FX_CALL *GRCONSTANTCOLORVALUEEXT)464(GrChipID_t tmu,465GrColor_t value);466467typedef void (FX_CALL *GRSTIPPLE)( FxI32 mode) ;468469typedef void (FX_CALL *GRCONFIGWRAPPEREXT)(HINSTANCE instance, HWND hwnd);470471typedef GrScreenResolution_t (FX_CALL *GRWRAPPERFULLSCREENRESOLUTIONEXT)();472473// ZIGGY framebuffer copy extension474// allow to copy the depth or color buffer from back/front to front/back475// (GL has separate back and front depth buffer, unlike glide, so this extension476// makes sense only in a wrapper)477#define GR_FBCOPY_MODE_DEPTH 0478#define GR_FBCOPY_MODE_COLOR 1479#define GR_FBCOPY_BUFFER_BACK 0480#define GR_FBCOPY_BUFFER_FRONT 1481typedef void (FX_CALL *GRFRAMEBUFFERCOPYEXT)(int x, int y, int w, int h,482int buffer_from, int buffer_to, int mode);483484extern GRFRAMEBUFFERCOPYEXT grFramebufferCopyExt;485486extern GRTEXBUFFEREXT grTextureBufferExt;487extern GRTEXBUFFEREXT grTextureAuxBufferExt;488extern GRAUXBUFFEREXT grAuxBufferExt;489extern GRSTIPPLE grStippleModeExt;490extern GRSTIPPLE grStipplePatternExt;491492#ifndef GR_STIPPLE_DISABLE493#define GR_STIPPLE_DISABLE 0x0494#define GR_STIPPLE_PATTERN 0x1495#define GR_STIPPLE_ROTATE 0x2496#endif497498void ReadSettings ();499void ReadSpecialSettings (const char name[21]);500void WriteSettings ();501502#if 0503//TODO: remove504/******************************************************************505Function: CaptureScreen506Purpose: This function dumps the current frame to a file507input: pointer to the directory to save the file to508output: none509*******************************************************************/510EXPORT void CALL CaptureScreen ( char * Directory );511512/******************************************************************513Function: ChangeWindow514Purpose: to change the window between fullscreen and window515mode. If the window was in fullscreen this should516change the screen to window mode and vice vesa.517input: none518output: none519*******************************************************************/520EXPORT void CALL ChangeWindow (void);521522/******************************************************************523Function: CloseDLL524Purpose: This function is called when the emulator is closing525down allowing the dll to de-initialise.526input: none527output: none528*******************************************************************/529EXPORT void CALL CloseDLL (void);530531/******************************************************************532Function: DllAbout533Purpose: This function is optional function that is provided534to give further information about the DLL.535input: a handle to the window that calls this function536output: none537*******************************************************************/538EXPORT void CALL DllAbout ( HWND hParent );539540/******************************************************************541Function: DllConfig542Purpose: This function is optional function that is provided543to allow the user to configure the dll544input: a handle to the window that calls this function545output: none546*******************************************************************/547EXPORT void CALL DllConfig ( HWND hParent );548549/******************************************************************550Function: DllTest551Purpose: This function is optional function that is provided552to allow the user to test the dll553input: a handle to the window that calls this function554output: none555*******************************************************************/556EXPORT void CALL DllTest ( HWND hParent );557558559EXPORT void CALL ReadScreen(void **dest, int *width, int *height);560561/******************************************************************562Function: DrawScreen563Purpose: This function is called when the emulator receives a564WM_PAINT message. This allows the gfx to fit in when565it is being used in the desktop.566input: none567output: none568*******************************************************************/569EXPORT void CALL DrawScreen (void);570571/******************************************************************572Function: GetDllInfo573Purpose: This function allows the emulator to gather information574about the dll by filling in the PluginInfo structure.575input: a pointer to a PLUGIN_INFO stucture that needs to be576filled by the function. (see def above)577output: none578*******************************************************************/579EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo );580581/******************************************************************582Function: InitiateGFX583Purpose: This function is called when the DLL is started to give584information from the emulator that the n64 graphics585uses. This is not called from the emulation thread.586Input: Gfx_Info is passed to this function which is defined587above.588Output: TRUE on success589FALSE on failure to initialise590591** note on interrupts **:592To generate an interrupt set the appropriate bit in MI_INTR_REG593and then call the function CheckInterrupts to tell the emulator594that there is a waiting interrupt.595*******************************************************************/596EXPORT BOOL CALL InitiateGFX (GFX_INFO Gfx_Info);597598/******************************************************************599Function: MoveScreen600Purpose: This function is called in response to the emulator601receiving a WM_MOVE passing the xpos and ypos passed602from that message.603input: xpos - the x-coordinate of the upper-left corner of the604client area of the window.605ypos - y-coordinate of the upper-left corner of the606client area of the window.607output: none608*******************************************************************/609EXPORT void CALL MoveScreen (int xpos, int ypos);610611/******************************************************************612Function: ProcessDList613Purpose: This function is called when there is a Dlist to be614processed. (High level GFX list)615input: none616output: none617*******************************************************************/618EXPORT void CALL ProcessDList(void);619620/******************************************************************621Function: ProcessRDPList622Purpose: This function is called when there is a Dlist to be623processed. (Low level GFX list)624input: none625output: none626*******************************************************************/627EXPORT void CALL ProcessRDPList(void);628629/******************************************************************630Function: RomClosed631Purpose: This function is called when a rom is closed.632input: none633output: none634*******************************************************************/635EXPORT void CALL RomClosed (void);636637/******************************************************************638Function: RomOpen639Purpose: This function is called when a rom is open. (from the640emulation thread)641input: none642output: none643*******************************************************************/644EXPORT void CALL RomOpen (void);645646/******************************************************************647Function: ShowCFB648Purpose: Useally once Dlists are started being displayed, cfb is649ignored. This function tells the dll to start displaying650them again.651input: none652output: none653*******************************************************************/654EXPORT void CALL ShowCFB (void);655656/******************************************************************657Function: UpdateScreen658Purpose: This function is called in response to a vsync of the659screen were the VI bit in MI_INTR_REG has already been660set661input: none662output: none663*******************************************************************/664EXPORT void CALL UpdateScreen (void);665666/******************************************************************667Function: ViStatusChanged668Purpose: This function is called to notify the dll that the669ViStatus registers value has been changed.670input: none671output: none672*******************************************************************/673EXPORT void CALL ViStatusChanged (void);674675/******************************************************************676Function: ViWidthChanged677Purpose: This function is called to notify the dll that the678ViWidth registers value has been changed.679input: none680output: none681*******************************************************************/682EXPORT void CALL ViWidthChanged (void);683684685/******************************************************************686Function: FrameBufferWrite687Purpose: This function is called to notify the dll that the688frame buffer has been modified by CPU at the given address.689input: addr rdram address690val val691size 1 = BYTE, 2 = WORD, 4 = DWORD692output: none693*******************************************************************/694EXPORT void CALL FBWrite(DWORD, DWORD);695696typedef struct697{698DWORD addr;699DWORD val;700DWORD size; // 1 = BYTE, 2 = WORD, 4=DWORD701} FrameBufferModifyEntry;702703/******************************************************************704Function: FrameBufferWriteList705Purpose: This function is called to notify the dll that the706frame buffer has been modified by CPU at the given address.707input: FrameBufferModifyEntry *plist708size = size of the plist, max = 1024709output: none710*******************************************************************/711EXPORT void CALL FBWList(FrameBufferModifyEntry *plist, DWORD size);712713/******************************************************************714Function: FrameBufferRead715Purpose: This function is called to notify the dll that the716frame buffer memory is beening read at the given address.717DLL should copy content from its render buffer to the frame buffer718in N64 RDRAM719DLL is responsible to maintain its own frame buffer memory addr list720DLL should copy 4KB block content back to RDRAM frame buffer.721Emulator should not call this function again if other memory722is read within the same 4KB range723input: addr rdram address724val val725size 1 = BYTE, 2 = WORD, 4 = DWORD726output: none727*******************************************************************/728EXPORT void CALL FBRead(DWORD addr);729730/************************************************************************731Function: FBGetFrameBufferInfo732Purpose: This function is called by the emulator core to retrieve depth733buffer information from the video plugin in order to be able734to notify the video plugin about CPU depth buffer read/write735operations736737size:738= 1 byte739= 2 word (16 bit) <-- this is N64 default depth buffer format740= 4 dword (32 bit)741742when depth buffer information is not available yet, set all values743in the FrameBufferInfo structure to 0744745input: FrameBufferInfo *pinfo746pinfo is pointed to a FrameBufferInfo structure which to be747filled in by this function748output: Values are return in the FrameBufferInfo structure749************************************************************************/750EXPORT void CALL FBGetFrameBufferInfo(void *pinfo);751752/******************************************************************753NOTE: THIS HAS BEEN ADDED FOR MUPEN64PLUS AND IS NOT PART OF THE754ORIGINAL SPEC755Function: SetConfigDir756Purpose: To pass the location where config files should be read/757written to.758input: path to config directory759output: none760*******************************************************************/761EXPORT void CALL SetConfigDir( char *configDir );762763/******************************************************************764NOTE: THIS HAS BEEN ADDED FOR MUPEN64PLUS AND IS NOT PART OF THE765ORIGINAL SPEC766Function: SetRenderingCallback767Purpose: Allows emulator to register a callback function that will768be called by the graphics plugin just before the the769frame buffers are swapped.770This was added as a way for the emulator to draw emulator-771specific things to the screen, e.g. On-screen display.772input: pointer to callback function. The function expects773to receive the current window width and height.774output: none775*******************************************************************/776EXPORT void CALL SetRenderingCallback(void (*callback)());777#endif778#if defined(__cplusplus)779}780#endif781#endif //_GFX_H_INCLUDED__782783784785