| 1 | |
| 2 | #include <dlfcn.h> |
| 3 | #include <string.h> |
| 4 | //#include <cpu-features.h> |
| 5 | |
| 6 | #include "m64p_types.h" |
| 7 | #include "m64p_plugin.h" |
| 8 | |
| 9 | #include "gles2N64.h" |
| 10 | #include "Debug.h" |
| 11 | #include "OpenGL.h" |
| 12 | #include "N64.h" |
| 13 | #include "RSP.h" |
| 14 | #include "RDP.h" |
| 15 | #include "VI.h" |
| 16 | #include "Config.h" |
| 17 | #include "Textures.h" |
| 18 | #include "ShaderCombiner.h" |
| 19 | #include "3DMath.h" |
| 20 | #include "FrameSkipper.h" |
| 21 | #include "ticks.h" |
| 22 | |
| 23 | //#include "ae_bridge.h" |
| 24 | |
| 25 | ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL; |
| 26 | |
| 27 | static FrameSkipper frameSkipper; |
| 28 | |
| 29 | u32 last_good_ucode = (u32) -1; |
| 30 | void (*CheckInterrupts)( void ); |
| 31 | void (*renderCallback)() = NULL; |
| 32 | |
| 33 | extern "C" { |
| 34 | |
| 35 | EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, |
| 36 | void *Context, void (*DebugCallback)(void *, int, const char *)) |
| 37 | { |
| 38 | printf("GLES2N64 Plugin StartUp\n"); |
| 39 | ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) |
| 40 | dlsym(CoreLibHandle, "ConfigGetSharedDataFilepath"); |
| 41 | |
| 42 | #ifdef __NEON_OPT |
| 43 | /* if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && |
| 44 | (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)*/ |
| 45 | { |
| 46 | MathInitNeon(); |
| 47 | gSPInitNeon(); |
| 48 | } |
| 49 | #endif |
| 50 | return M64ERR_SUCCESS; |
| 51 | } |
| 52 | |
| 53 | EXPORT m64p_error CALL PluginShutdown(void) |
| 54 | { |
| 55 | } |
| 56 | |
| 57 | EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, |
| 58 | int *PluginVersion, int *APIVersion, const char **PluginNamePtr, |
| 59 | int *Capabilities) |
| 60 | { |
| 61 | /* set version info */ |
| 62 | if (PluginType != NULL) |
| 63 | *PluginType = M64PLUGIN_GFX; |
| 64 | |
| 65 | if (PluginVersion != NULL) |
| 66 | *PluginVersion = PLUGIN_VERSION; |
| 67 | |
| 68 | if (APIVersion != NULL) |
| 69 | *APIVersion = PLUGIN_API_VERSION; |
| 70 | |
| 71 | if (PluginNamePtr != NULL) |
| 72 | *PluginNamePtr = PLUGIN_NAME; |
| 73 | |
| 74 | if (Capabilities != NULL) |
| 75 | { |
| 76 | *Capabilities = 0; |
| 77 | } |
| 78 | |
| 79 | return M64ERR_SUCCESS; |
| 80 | } |
| 81 | |
| 82 | EXPORT void CALL ChangeWindow (void) |
| 83 | { |
| 84 | } |
| 85 | |
| 86 | EXPORT void CALL MoveScreen (int xpos, int ypos) |
| 87 | { |
| 88 | } |
| 89 | |
| 90 | EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info) |
| 91 | { |
| 92 | printf("InitateGFX\n"); |
| 93 | DMEM = Gfx_Info.DMEM; |
| 94 | IMEM = Gfx_Info.IMEM; |
| 95 | RDRAM = Gfx_Info.RDRAM; |
| 96 | |
| 97 | REG.MI_INTR = (u32*) Gfx_Info.MI_INTR_REG; |
| 98 | REG.DPC_START = (u32*) Gfx_Info.DPC_START_REG; |
| 99 | REG.DPC_END = (u32*) Gfx_Info.DPC_END_REG; |
| 100 | REG.DPC_CURRENT = (u32*) Gfx_Info.DPC_CURRENT_REG; |
| 101 | REG.DPC_STATUS = (u32*) Gfx_Info.DPC_STATUS_REG; |
| 102 | REG.DPC_CLOCK = (u32*) Gfx_Info.DPC_CLOCK_REG; |
| 103 | REG.DPC_BUFBUSY = (u32*) Gfx_Info.DPC_BUFBUSY_REG; |
| 104 | REG.DPC_PIPEBUSY = (u32*) Gfx_Info.DPC_PIPEBUSY_REG; |
| 105 | REG.DPC_TMEM = (u32*) Gfx_Info.DPC_TMEM_REG; |
| 106 | |
| 107 | REG.VI_STATUS = (u32*) Gfx_Info.VI_STATUS_REG; |
| 108 | REG.VI_ORIGIN = (u32*) Gfx_Info.VI_ORIGIN_REG; |
| 109 | REG.VI_WIDTH = (u32*) Gfx_Info.VI_WIDTH_REG; |
| 110 | REG.VI_INTR = (u32*) Gfx_Info.VI_INTR_REG; |
| 111 | REG.VI_V_CURRENT_LINE = (u32*) Gfx_Info.VI_V_CURRENT_LINE_REG; |
| 112 | REG.VI_TIMING = (u32*) Gfx_Info.VI_TIMING_REG; |
| 113 | REG.VI_V_SYNC = (u32*) Gfx_Info.VI_V_SYNC_REG; |
| 114 | REG.VI_H_SYNC = (u32*) Gfx_Info.VI_H_SYNC_REG; |
| 115 | REG.VI_LEAP = (u32*) Gfx_Info.VI_LEAP_REG; |
| 116 | REG.VI_H_START = (u32*) Gfx_Info.VI_H_START_REG; |
| 117 | REG.VI_V_START = (u32*) Gfx_Info.VI_V_START_REG; |
| 118 | REG.VI_V_BURST = (u32*) Gfx_Info.VI_V_BURST_REG; |
| 119 | REG.VI_X_SCALE = (u32*) Gfx_Info.VI_X_SCALE_REG; |
| 120 | REG.VI_Y_SCALE = (u32*) Gfx_Info.VI_Y_SCALE_REG; |
| 121 | |
| 122 | CheckInterrupts = Gfx_Info.CheckInterrupts; |
| 123 | |
| 124 | Config_LoadConfig(); |
| 125 | Config_LoadRomConfig(Gfx_Info.HEADER); |
| 126 | |
| 127 | ticksInitialize(); |
| 128 | if( config.autoFrameSkip ) |
| 129 | frameSkipper.setSkips( FrameSkipper::AUTO, config.maxFrameSkip ); |
| 130 | else |
| 131 | frameSkipper.setSkips( FrameSkipper::MANUAL, config.maxFrameSkip ); |
| 132 | |
| 133 | OGL_Start(); |
| 134 | |
| 135 | return 1; |
| 136 | } |
| 137 | |
| 138 | EXPORT void CALL ProcessDList(void) |
| 139 | { |
| 140 | OGL.frame_dl++; |
| 141 | |
| 142 | if (frameSkipper.willSkipNext()) |
| 143 | { |
| 144 | OGL.frameSkipped++; |
| 145 | RSP.busy = FALSE; |
| 146 | RSP.DList++; |
| 147 | |
| 148 | /* avoid hang on frameskip */ |
| 149 | *REG.MI_INTR |= MI_INTR_DP; |
| 150 | CheckInterrupts(); |
| 151 | *REG.MI_INTR |= MI_INTR_SP; |
| 152 | CheckInterrupts(); |
| 153 | return; |
| 154 | } |
| 155 | |
| 156 | OGL.consecutiveSkips = 0; |
| 157 | RSP_ProcessDList(); |
| 158 | OGL.mustRenderDlist = true; |
| 159 | } |
| 160 | |
| 161 | EXPORT void CALL ProcessRDPList(void) |
| 162 | { |
| 163 | } |
| 164 | |
| 165 | EXPORT void CALL ResizeVideoOutput(int Width, int Height) |
| 166 | { |
| 167 | } |
| 168 | |
| 169 | EXPORT void CALL RomClosed (void) |
| 170 | { |
| 171 | OGL_Stop(); // paulscode, OGL_Stop missing from Yongzh's code |
| 172 | } |
| 173 | |
| 174 | EXPORT int CALL RomOpen (void) |
| 175 | { |
| 176 | RSP_Init(); |
| 177 | OGL.frame_vsync = 0; |
| 178 | OGL.frame_dl = 0; |
| 179 | OGL.frame_prevdl = -1; |
| 180 | OGL.mustRenderDlist = false; |
| 181 | |
| 182 | frameSkipper.setTargetFPS(config.romPAL ? 50 : 60); |
| 183 | return 1; |
| 184 | } |
| 185 | |
| 186 | EXPORT void CALL RomResumed(void) |
| 187 | { |
| 188 | frameSkipper.start(); |
| 189 | } |
| 190 | |
| 191 | EXPORT void CALL ShowCFB (void) |
| 192 | { |
| 193 | } |
| 194 | |
| 195 | EXPORT void CALL UpdateScreen (void) |
| 196 | { |
| 197 | frameSkipper.update(); |
| 198 | |
| 199 | //has there been any display lists since last update |
| 200 | if (OGL.frame_prevdl == OGL.frame_dl) return; |
| 201 | |
| 202 | OGL.frame_prevdl = OGL.frame_dl; |
| 203 | |
| 204 | if (OGL.frame_dl > 0) OGL.frame_vsync++; |
| 205 | |
| 206 | if (OGL.mustRenderDlist) |
| 207 | { |
| 208 | OGL.screenUpdate=true; |
| 209 | VI_UpdateScreen(); |
| 210 | OGL.mustRenderDlist = false; |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | EXPORT void CALL ViStatusChanged (void) |
| 215 | { |
| 216 | } |
| 217 | |
| 218 | EXPORT void CALL ViWidthChanged (void) |
| 219 | { |
| 220 | } |
| 221 | |
| 222 | /****************************************************************** |
| 223 | Function: FrameBufferRead |
| 224 | Purpose: This function is called to notify the dll that the |
| 225 | frame buffer memory is beening read at the given address. |
| 226 | DLL should copy content from its render buffer to the frame buffer |
| 227 | in N64 RDRAM |
| 228 | DLL is responsible to maintain its own frame buffer memory addr list |
| 229 | DLL should copy 4KB block content back to RDRAM frame buffer. |
| 230 | Emulator should not call this function again if other memory |
| 231 | is read within the same 4KB range |
| 232 | |
| 233 | Since depth buffer is also being watched, the reported addr |
| 234 | may belong to depth buffer |
| 235 | input: addr rdram address |
| 236 | val val |
| 237 | size 1 = uint8, 2 = uint16, 4 = uint32 |
| 238 | output: none |
| 239 | *******************************************************************/ |
| 240 | |
| 241 | EXPORT void CALL FBRead(u32 addr) |
| 242 | { |
| 243 | } |
| 244 | |
| 245 | /****************************************************************** |
| 246 | Function: FrameBufferWrite |
| 247 | Purpose: This function is called to notify the dll that the |
| 248 | frame buffer has been modified by CPU at the given address. |
| 249 | |
| 250 | Since depth buffer is also being watched, the reported addr |
| 251 | may belong to depth buffer |
| 252 | |
| 253 | input: addr rdram address |
| 254 | val val |
| 255 | size 1 = uint8, 2 = uint16, 4 = uint32 |
| 256 | output: none |
| 257 | *******************************************************************/ |
| 258 | |
| 259 | EXPORT void CALL FBWrite(u32 addr, u32 size) |
| 260 | { |
| 261 | } |
| 262 | |
| 263 | /************************************************************************ |
| 264 | Function: FBGetFrameBufferInfo |
| 265 | Purpose: This function is called by the emulator core to retrieve frame |
| 266 | buffer information from the video plugin in order to be able |
| 267 | to notify the video plugin about CPU frame buffer read/write |
| 268 | operations |
| 269 | |
| 270 | size: |
| 271 | = 1 byte |
| 272 | = 2 word (16 bit) <-- this is N64 default depth buffer format |
| 273 | = 4 dword (32 bit) |
| 274 | |
| 275 | when frame buffer information is not available yet, set all values |
| 276 | in the FrameBufferInfo structure to 0 |
| 277 | |
| 278 | input: FrameBufferInfo pinfo[6] |
| 279 | pinfo is pointed to a FrameBufferInfo structure which to be |
| 280 | filled in by this function |
| 281 | output: Values are return in the FrameBufferInfo structure |
| 282 | Plugin can return up to 6 frame buffer info |
| 283 | ************************************************************************/ |
| 284 | |
| 285 | EXPORT void CALL FBGetFrameBufferInfo(void *p) |
| 286 | { |
| 287 | } |
| 288 | |
| 289 | // paulscode, API changed this to "ReadScreen2" in Mupen64Plus 1.99.4 |
| 290 | EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front) |
| 291 | { |
| 292 | /* TODO: 'int front' was added in 1.99.4. What to do with this here? */ |
| 293 | OGL_ReadScreen(dest, width, height); |
| 294 | } |
| 295 | |
| 296 | EXPORT void CALL SetRenderingCallback(void (*callback)()) |
| 297 | { |
| 298 | renderCallback = callback; |
| 299 | } |
| 300 | |
| 301 | EXPORT void CALL SetFrameSkipping(bool autoSkip, int maxSkips) |
| 302 | { |
| 303 | frameSkipper.setSkips( |
| 304 | autoSkip ? FrameSkipper::AUTO : FrameSkipper::MANUAL, |
| 305 | maxSkips); |
| 306 | } |
| 307 | |
| 308 | EXPORT void CALL SetStretchVideo(bool stretch) |
| 309 | { |
| 310 | config.stretchVideo = stretch; |
| 311 | } |
| 312 | |
| 313 | EXPORT void CALL StartGL() |
| 314 | { |
| 315 | OGL_Start(); |
| 316 | } |
| 317 | |
| 318 | EXPORT void CALL StopGL() |
| 319 | { |
| 320 | OGL_Stop(); |
| 321 | } |
| 322 | |
| 323 | EXPORT void CALL ResizeGL(int width, int height) |
| 324 | { |
| 325 | const float ratio = (config.romPAL ? 9.0f/11.0f : 0.75f); |
| 326 | int videoWidth = width; |
| 327 | int videoHeight = height; |
| 328 | |
| 329 | if (!config.stretchVideo) { |
| 330 | videoWidth = (int) (height / ratio); |
| 331 | if (videoWidth > width) { |
| 332 | videoWidth = width; |
| 333 | videoHeight = (int) (width * ratio); |
| 334 | } |
| 335 | } |
| 336 | int x = (width - videoWidth) / 2; |
| 337 | int y = (height - videoHeight) / 2; |
| 338 | |
| 339 | OGL_ResizeWindow(x, y, videoWidth, videoHeight); |
| 340 | } |
| 341 | |
| 342 | } // extern "C" |
| 343 | |