#include #include #include #include #include #include #include int sleepNanos(long int ns) { struct timespec time; if (ns < 0) return 0; 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; AudioContext aud; int16_t audioBuffer[834 * 2]; } GameState; int onFrame(VB *sim) { static uint8_t leftEye[384*224]; static uint8_t rightEye[384*224]; GameState *state; void *samples; uint32_t samplePairs; state = vbGetUserData(sim); vbGetPixels(sim, leftEye, 1, 384, rightEye, 1, 384); gfxUpdateLeftEye(state->gfx, leftEye); gfxUpdateRightEye(state->gfx, rightEye); samples = vbGetSamples(sim, NULL, &samplePairs); audioUpdate(&state->aud, samples, samplePairs * 4); vbSetSamples(sim, samples, 834); gfxRender(state->gfx); return 1; } #define MAX_STEP_CLOCKS 20000000 int runGame(VB *sim, GraphicsContext *gfx) { uint32_t clocks; SDL_Event event; GameState state; ControllerState ctrl; uint64_t ticks, prevTicks; state.gfx = gfx; audioInit(&state.aud); vbSetSamples(sim, &state.audioBuffer, 834); vbSetUserData(sim, &state); vbSetFrameCallback(sim, &onFrame); ctrlInit(&ctrl); gfxUpdateLeftEye(gfx, LEFT_EYE_DEFAULT); gfxUpdateRightEye(gfx, RIGHT_EYE_DEFAULT); while (1) { clocks = MAX_STEP_CLOCKS; prevTicks = tickNs(); vbEmulate(sim, &clocks); ticks = tickNs(); sleepNanos(((MAX_STEP_CLOCKS - clocks) * 50) - (ticks - prevTicks)); while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { return 0; } if (event.type == SDL_KEYDOWN) { ctrlKeyDown(&ctrl, event.key.keysym.sym); } if (event.type == SDL_KEYUP) { ctrlKeyUp(&ctrl, event.key.keysym.sym); } } vbSetKeys(sim, ctrlKeys(&ctrl)); } }