int sync_update(struct sync_device *d, int row, struct sync_cb *cb, void *cb_param) { if (d->sock == INVALID_SOCKET) return -1; /* look for new commands */ while (socket_poll(d->sock)) { unsigned char cmd = 0, flag; uint32_t new_row; if (xrecv(d->sock, (char *)&cmd, 1, 0)) goto sockerr; switch (cmd) { case SET_KEY: if (handle_set_key_cmd(d->sock, d)) goto sockerr; break; case DELETE_KEY: if (handle_del_key_cmd(d->sock, d)) goto sockerr; break; case SET_ROW: if (xrecv(d->sock, (char *)&new_row, sizeof(new_row), 0)) goto sockerr; if (cb && cb->set_row) cb->set_row(cb_param, ntohl(new_row)); break; case PAUSE: if (xrecv(d->sock, (char *)&flag, 1, 0)) goto sockerr; if (cb && cb->pause) cb->pause(cb_param, flag); break; case SAVE_TRACKS: sync_save_tracks(d); break; default: fprintf(stderr, "unknown cmd: %02x\n", cmd); goto sockerr; } } if (cb && cb->is_playing && cb->is_playing(cb_param)) { if (d->row != row && d->sock != INVALID_SOCKET) { unsigned char cmd = SET_ROW; uint32_t nrow = htonl(row); if (xsend(d->sock, (char*)&cmd, 1, 0) || xsend(d->sock, (char*)&nrow, sizeof(nrow), 0)) goto sockerr; d->row = row; } } return 0; sockerr: closesocket(d->sock); d->sock = INVALID_SOCKET; return -1; }
int main(int argc, char *argv[]) { #ifndef SYNC_PLAYER bool should_save = false; // whether to save tracks when done. // don't save unless we actually connect. #endif HSTREAM stream; const struct sync_track *clear_r, *clear_g, *clear_b; const struct sync_track *cam_rot, *cam_dist; setup_sdl(); /* init BASS */ if (!BASS_Init(-1, 44100, 0, 0, 0)) die("failed to init bass"); stream = BASS_StreamCreateFile(false, "tune.ogg", 0, 0, BASS_STREAM_PRESCAN); if (!stream) die("failed to open tune"); sync_device *rocket = sync_create_device("sync"); if (!rocket) die("out of memory?"); #ifndef SYNC_PLAYER if (sync_connect(rocket, "localhost", SYNC_DEFAULT_PORT)) die("failed to connect to host"); #endif /* get tracks */ clear_r = sync_get_track(rocket, "clear.r"); clear_g = sync_get_track(rocket, "clear.g"); clear_b = sync_get_track(rocket, "clear.b"); cam_rot = sync_get_track(rocket, "cam.rot"), cam_dist = sync_get_track(rocket, "cam.dist"); /* let's roll! */ BASS_Start(); BASS_ChannelPlay(stream, false); bool done = false; while (!done) { double row = bass_get_row(stream); #ifndef SYNC_PLAYER if (sync_update(rocket, (int)floor(row), &bass_cb, (void *)&stream)) { if (sync_connect(rocket, "localhost", SYNC_DEFAULT_PORT) == 0) should_save = true; } #endif /* draw */ glClearColor(float(sync_get_val(clear_r, row)), float(sync_get_val(clear_g, row)), float(sync_get_val(clear_b, row)), 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float rot = float(sync_get_val(cam_rot, row)); float dist = float(sync_get_val(cam_dist, row)); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, 4.0f / 3, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); gluLookAt(sin(rot) * dist, 0, cos(rot) * dist, 0, 0, 0, 0, 1, 0); glEnable(GL_DEPTH_TEST); draw_cube(); glPopMatrix(); SDL_GL_SwapBuffers(); BASS_Update(0); /* decrease the chance of missing vsync */ SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)) done = true; } } #ifndef SYNC_PLAYER if(should_save) //don't clobber if user just ran it then hit Esc sync_save_tracks(rocket); #endif sync_destroy_device(rocket); BASS_StreamFree(stream); BASS_Free(); SDL_Quit(); return 0; }