#include #include #include #include #include int sleepNanos(long int ns) { struct timespec time; if (ns < 0) return; time.tv_sec = ns / 1000000000; time.tv_nsec = ns % 1000000000; return nanosleep(&time, NULL); } long int tickNs() { struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time); return (time.tv_sec * 1000000000) + time.tv_nsec; } typedef struct { GraphicsContext *gfx; } GameState; int onFrame(VB *sim) { static uint8_t leftEye[384*224]; static uint8_t rightEye[384*224]; GameState *state; GraphicsContext *gfx; state = vbGetUserData(sim); gfx = state->gfx; vbGetPixels(sim, leftEye, 1, 384, rightEye, 1, 384); gfxUpdateLeftEye(gfx, leftEye); gfxUpdateRightEye(gfx, rightEye); gfxRender(gfx); return 1; } #define MAX_STEP_CLOCKS 20000000 int runGame(VB *sim, GraphicsContext *gfx) { uint32_t clocks; SDL_Event event; GameState state; uint64_t ticks, prevTicks; state.gfx = gfx; vbSetUserData(sim, &state); vbSetFrameCallback(sim, &onFrame); gfxUpdateLeftEye(gfx, LEFT_EYE_DEFAULT); gfxUpdateRightEye(gfx, RIGHT_EYE_DEFAULT); while (1) { clocks = MAX_STEP_CLOCKS; prevTicks = tickNs(); vbEmulate(sim, &clocks); ticks = tickNs(); while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { return 0; } } sleepNanos(((MAX_STEP_CLOCKS - clocks) * 50) - (ticks - prevTicks)); prevTicks = ticks; } }