int MFInput_Thread(void *) { // poll input at high frequency... uint64 freq = MFSystem_GetRTCFrequency(); uint64 interval = freq / gInputFrequency; uint64 now = MFSystem_ReadRTC(); uint64 nextSample = now + interval; while(!bInputTerminate) { MFThread_LockMutex(gInputMutex); bThreadUpdate = true; MFInput_Update(); bThreadUpdate = false; // build events for(uint32 i=0; i<MFInput_MaxInputID; ++i) { if(!gDeviceStatus[IDD_Gamepad][i] == IDS_Ready) continue; for(uint32 j=0; j<GamepadType_Max; ++j) { if(gNumEvents[IDD_Gamepad][i] >= MaxEvents) break; MFGamepadState &state = gGamepadStates[i]; MFGamepadState &prev = gPrevGamepadStates[i]; if(state.values[j] == prev.values[j]) continue; MFInputEvent &e = gInputEvents[IDD_Gamepad][i][gNumEvents[IDD_Gamepad][i]++]; e.timestamp = now; e.event = MFIE_Change; e.input = j; e.state = state.values[j]; e.prevState = prev.values[j]; } } MFThread_ReleaseMutex(gInputMutex); // uint64 updateTime = MFSystem_ReadRTC(); // MFDebug_Log(0, MFStr("Input update: %dus", (uint32)((updateTime - now) * 1000000LL / MFSystem_GetRTCFrequency()))); uint32 ms = (uint32)((nextSample - now) * 1000LL / freq); MFThread_Sleep(ms); now = MFSystem_ReadRTC(); do nextSample += interval; while(now >= nextSample); } bInputTerminate = false; return 0; }
void Timer::Init(Timer *pRefTimer) { accumulator = 0; lastUpdate = 0; thisCall = lastCall = MFSystem_ReadRTC(); freq = MFSystem_GetRTCFrequency(); FPS = 60.0; deltaD = 1.0/60.0; deltaF = 1.0f/60.0f; smoothDeltaF = 1.0f/60.0f; rate = 1.0f; fixed = false; pReferenceTimer = pRefTimer; }
bool MFModule_InitModules() { uint64 timer = 0; for(int a=0; a<gNumModules; ++a) { uint64 bit = 1ULL << a; if(!(gModuleInitComplete & bit) && (gModuleInitComplete & gModules[a].prerequisites) == gModules[a].prerequisites) { MFInitStatus complete = MFAIC_Failed; if((gModules[a].prerequisites & gModuleInitFailed) == 0) { MFDebug_Message(MFStr("Init %s...", gModules[a].pModuleName)); timer = MFSystem_ReadRTC(); complete = gModules[a].pInitFunction(); } else { // list pre-requisite failures if(MFModule_IsModuleInitialised(MFModule_GetBuiltinModuleID(MFBIM_MFString))) { MFDebug_Message(MFStr("Prerequisite failure")); } } if(complete == MFAIC_Succeeded) { uint64 initTime = (MFSystem_ReadRTC() - timer) * 1000 / MFSystem_GetRTCFrequency(); gModuleInitComplete |= bit; // if logging is initialised MFDebug_Message(MFStr("Init %s complete in %dms", gModules[a].pModuleName, (int)initTime)); } else if(complete == MFAIC_Failed) { uint64 initTime = (MFSystem_ReadRTC() - timer) * 1000 / MFSystem_GetRTCFrequency(); gModuleInitComplete |= bit; gModuleInitFailed |= bit; // if logging is initialised MFDebug_Error(MFStr("Init %s FAILED in %dms!", gModules[a].pModuleName, (int)initTime)); } } } if(gModuleInitComplete == (1ULL << gNumModules) - 1) { gFujiInitialised = true; if(gModuleInitFailed) { MFDebug_Message("Fuji initialisation completed with errors..."); // list the failed modules //... } else { MFDebug_Message("Fuji initialisation complete!"); } MFHeap_Mark(); // let the game perform any post-init work if(pSystemCallbacks[MFCB_InitDone]) pSystemCallbacks[MFCB_InitDone](); // init the timedelta to the moment after initialisation completes MFSystem_UpdateTimeDelta(); return true; } return false; }
void MFCallstack_Draw() { MFCALLSTACK; if(drawCallstack) { const MFDisplaySettings *pDisplaySettings = MFDisplay_GetDisplaySettings(); float width = (float)pDisplaySettings->width; float height = (float)pDisplaySettings->height; float xoffset = width / 10.0f; float yoffset = height / 6.0f; MFView_Push(); MFRect rect = { 0.f, 0.f, width, height }; MFView_SetOrtho(&rect); float rtcFreq = 1000000.f / (float)MFSystem_GetRTCFrequency(); MFVector callstackPos = MakeVector(xoffset, yoffset, 0.f, 0.f); // sort the calls qsort(gpProfiles, gNumProfileFunctions, sizeof(gpProfiles[0]), MFCallstack_SortPred); // if(!drawCallstackMeter) { // just draw the callstack profiling information.. MFPrimitive_DrawUntexturedQuad(callstackPos.x - 10.f, callstackPos.y - 10.f, (width - callstackPos.x) + 10, callstackPos.y + (float)gNumProfileFunctions*16.0f + 10, MakeVector(0, 0, 0, 0.8f)); for(int a=0; a<gNumProfileFunctions; a++) { uint32 microseconds = uint32((float)gpProfiles[a]->totalTime * rtcFreq); uint32 percent = uint32((float)microseconds / 166.66666f); // MFVector colour = gProfileColours[gpProfiles[a]->functionColour]; MFVector colour = MFVector::one; MFFont_DrawTextf(MFFont_GetDebugFont(), callstackPos, 16.0f, colour, "%s", gpProfiles[a]->pFunctionName); MFFont_DrawTextf(MFFont_GetDebugFont(), callstackPos + MakeVector((width - xoffset) - 250.0f, 0, 0), 16.0f, colour, "- %dus (%d%%) %d calls", microseconds, percent, gpProfiles[a]->numCalls); callstackPos.y += 16.0f; } } /* else { // draw a meter up the top of the screen representing the frame.. MFPrimitive_DrawUntexturedQuad(callstackPos.x - 10.f, callstackPos.y - 10.f, width - callstackPos.x + 10, callstackPos.y + (float)(gNumProfileTotals+1)*16.0f + 18, MakeVector(0, 0, 0, 0.8f)); MFVector meterPos = MakeVector(xoffset - 8.f, yoffset*0.5f - 15.0f, 0.0f); MFVector meterDimensions = MakeVector(width - (xoffset-8.0f)*2.0f, 20.0f, 0.0f); // draw the meter container MFPrimitive_DrawUntexturedQuad(meterPos.x - 2.0f, meterPos.y - 2.0f, meterPos.x + meterDimensions.x + 2.0f, meterPos.y + meterDimensions.y + 2.0f, MakeVector(1.0f, 1.0f, 1.0f, 0.8f)); MFPrimitive_DrawUntexturedQuad(meterPos.x, meterPos.y, meterPos.x + meterDimensions.x, meterPos.y + meterDimensions.y, MakeVector(0.0f, 0.0f, 0.0f, 1.0f)); // draw the overhead counter uint32 frameDuration = uint32(gBeginTime - gLastBeginTime); float frameTime = (float)frameDuration * rtcFreq; MFCallstackInternal_DrawMeterBlock(meterPos, meterDimensions, (float)(gEndTime - gLastBeginTime) / (float)frameTime, 1.0f, MakeVector(0.0f, 1.0f, 1.0f, 1.0f)); MFCallstackInternal_DrawMeterLabel(callstackPos, MakeVector(0.0f, 1.0f, 1.0f, 1.0f), "Frame Overhead/VSync", NULL); callstackPos.y += 24.0f; // draw all the totals for(int a=0; a<gNumProfileTotals; a++) { uint32 microseconds = uint32((float)gpProfiles[a]->totalTime * rtcFreq); uint32 percent = uint32((float)microseconds / 166.66666f); MFCallstackInternal_DrawMeterLabel(callstackPos, gProfileColours[a % gProfileColourCount], gProfileTotals[a].pFunctionName, MFStr("- %dus (%d%%) %d calls", microseconds, percent, gProfileTotals[a].numCalls)); callstackPos.y += 16.0f; } // draw all the function profiles float totalTime = (float)(gBeginTime - gLastBeginTime); for(int a=0; a<gNumProfileResults; a++) { int colour = MFCallstackInternal_GetTotalIndex(a); MFCallstackInternal_DrawMeterBlock(meterPos, meterDimensions, (float)(gProfileResults[a].startTime - gLastBeginTime) / totalTime, (float)(gProfileResults[a].endTime - gLastBeginTime) / totalTime, gProfileColours[colour % gProfileColourCount]); } } */ MFView_Pop(); } }