EXPORT void CALL UpdateScreen (void) { frameSkipper.update(); //has there been any display lists since last update if (OGL.frame_prevdl == OGL.frame_dl) return; OGL.frame_prevdl = OGL.frame_dl; if (OGL.frame_dl > 0) OGL.frame_vsync++; if (OGL.mustRenderDlist) { if(config.printFPS) { static unsigned int lastTick=0; static int frames=0; unsigned int nowTick = SDL_GetTicks(); frames++; if(lastTick + 5000 <= nowTick) { printf("Video: %.3f VI/S\n", frames/5.0); frames = 0; lastTick = nowTick; } } OGL.screenUpdate=true; VI_UpdateScreen(); OGL.mustRenderDlist = false; } }
EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info) { DMEM = Gfx_Info.DMEM; IMEM = Gfx_Info.IMEM; RDRAM = Gfx_Info.RDRAM; REG.MI_INTR = (u32*) Gfx_Info.MI_INTR_REG; REG.DPC_START = (u32*) Gfx_Info.DPC_START_REG; REG.DPC_END = (u32*) Gfx_Info.DPC_END_REG; REG.DPC_CURRENT = (u32*) Gfx_Info.DPC_CURRENT_REG; REG.DPC_STATUS = (u32*) Gfx_Info.DPC_STATUS_REG; REG.DPC_CLOCK = (u32*) Gfx_Info.DPC_CLOCK_REG; REG.DPC_BUFBUSY = (u32*) Gfx_Info.DPC_BUFBUSY_REG; REG.DPC_PIPEBUSY = (u32*) Gfx_Info.DPC_PIPEBUSY_REG; REG.DPC_TMEM = (u32*) Gfx_Info.DPC_TMEM_REG; REG.VI_STATUS = (u32*) Gfx_Info.VI_STATUS_REG; REG.VI_ORIGIN = (u32*) Gfx_Info.VI_ORIGIN_REG; REG.VI_WIDTH = (u32*) Gfx_Info.VI_WIDTH_REG; REG.VI_INTR = (u32*) Gfx_Info.VI_INTR_REG; REG.VI_V_CURRENT_LINE = (u32*) Gfx_Info.VI_V_CURRENT_LINE_REG; REG.VI_TIMING = (u32*) Gfx_Info.VI_TIMING_REG; REG.VI_V_SYNC = (u32*) Gfx_Info.VI_V_SYNC_REG; REG.VI_H_SYNC = (u32*) Gfx_Info.VI_H_SYNC_REG; REG.VI_LEAP = (u32*) Gfx_Info.VI_LEAP_REG; REG.VI_H_START = (u32*) Gfx_Info.VI_H_START_REG; REG.VI_V_START = (u32*) Gfx_Info.VI_V_START_REG; REG.VI_V_BURST = (u32*) Gfx_Info.VI_V_BURST_REG; REG.VI_X_SCALE = (u32*) Gfx_Info.VI_X_SCALE_REG; REG.VI_Y_SCALE = (u32*) Gfx_Info.VI_Y_SCALE_REG; CheckInterrupts = Gfx_Info.CheckInterrupts; Config_LoadConfig(); Config_LoadRomConfig(Gfx_Info.HEADER); ticksInitialize(); if( config.autoFrameSkip ) frameSkipper.setSkips( FrameSkipper::AUTO, config.maxFrameSkip ); else frameSkipper.setSkips( FrameSkipper::MANUAL, config.maxFrameSkip ); OGL_Start(); return 1; }
EXPORT int CALL RomOpen (void) { RSP_Init(); OGL.frame_vsync = 0; OGL.frame_dl = 0; OGL.frame_prevdl = -1; OGL.mustRenderDlist = false; frameSkipper.setTargetFPS(config.romPAL ? 50 : 60); return 1; }
EXPORT void CALL ProcessDList(void) { OGL.frame_dl++; if (config.autoFrameSkip) { OGL_UpdateFrameTime(); if (OGL.consecutiveSkips < 1) { unsigned t = 0; for(int i = 0; i < OGL_FRAMETIME_NUM; i++) t += OGL.frameTime[i]; t *= config.targetFPS; if (config.romPAL) t = (t * 5) / 6; if (t > (OGL_FRAMETIME_NUM * 1000)) { OGL.consecutiveSkips++; OGL.frameSkipped++; RSP.busy = FALSE; RSP.DList++; /* avoid hang on frameskip */ *REG.MI_INTR |= MI_INTR_DP; CheckInterrupts(); *REG.MI_INTR |= MI_INTR_SP; CheckInterrupts(); return; } } } else if (frameSkipper.willSkipNext()) { OGL.frameSkipped++; RSP.busy = FALSE; RSP.DList++; /* avoid hang on frameskip */ *REG.MI_INTR |= MI_INTR_DP; CheckInterrupts(); *REG.MI_INTR |= MI_INTR_SP; CheckInterrupts(); return; } OGL.consecutiveSkips = 0; RSP_ProcessDList(); OGL.mustRenderDlist = true; }
EXPORT void CALL UpdateScreen (void) { frameSkipper.update(); //has there been any display lists since last update if (OGL.frame_prevdl == OGL.frame_dl) return; OGL.frame_prevdl = OGL.frame_dl; if (OGL.frame_dl > 0) OGL.frame_vsync++; if (OGL.mustRenderDlist) { OGL.screenUpdate=true; VI_UpdateScreen(); OGL.mustRenderDlist = false; } }
EXPORT void CALL ProcessDList(void) { OGL.frame_dl++; if (frameSkipper.willSkipNext()) { OGL.frameSkipped++; RSP.busy = FALSE; RSP.DList++; /* avoid hang on frameskip */ *REG.MI_INTR |= MI_INTR_DP; CheckInterrupts(); *REG.MI_INTR |= MI_INTR_SP; CheckInterrupts(); return; } OGL.consecutiveSkips = 0; RSP_ProcessDList(); OGL.mustRenderDlist = true; }
EXPORT void CALL SetFrameSkipping(bool autoSkip, int maxSkips) { frameSkipper.setSkips( autoSkip ? FrameSkipper::AUTO : FrameSkipper::MANUAL, maxSkips); }
EXPORT void CALL RomResumed(void) { frameSkipper.start(); }