rocket/example_bass/example_bass.cpp
Erik Faye-Lund e3ee8c2432 Merge branch 'work/for-master' into work/example-fixes
Conflicts:
	example_bass/example_bass.cpp
2011-01-26 00:16:27 +01:00

243 lines
5.5 KiB
C++

/* Copyright (C) 2007-2008 Erik Faye-Lund and Egbert Teeselink
* For conditions of distribution and use, see copyright notice in COPYING
* sdl+opengl examle by rasmus/loonies http://visualizethis.tumblr.com 2011
*/
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <SDL.h>
#undef main /* avoid SDL's nasty SDLmain hack */
#include <SDL_opengl.h>
#include <bass.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include "../sync/sync.h"
static const float bpm = 150.0f; /* beats per minute */
static const int rpb = 8; /* rows per beat */
static const double row_rate = (double(bpm) / 60) * rpb;
static double bass_get_row(HSTREAM h)
{
QWORD pos = BASS_ChannelGetPosition(h, BASS_POS_BYTE);
double time = BASS_ChannelBytes2Seconds(h, pos);
return time * row_rate;
}
#ifndef SYNC_PLAYER
static void bass_pause(void *d, int flag)
{
HSTREAM h = *((HSTREAM *)d);
if (flag)
BASS_ChannelPause(h);
else
BASS_ChannelPlay(h, false);
}
static void bass_set_row(void *d, int row)
{
HSTREAM h = *((HSTREAM *)d);
QWORD pos = BASS_ChannelSeconds2Bytes(h, row / row_rate);
BASS_ChannelSetPosition(h, pos, BASS_POS_BYTE);
}
static int bass_is_playing(void *d)
{
HSTREAM h = *((HSTREAM *)d);
return BASS_ChannelIsActive(h) == BASS_ACTIVE_PLAYING;
}
static struct sync_cb bass_cb = {
bass_pause,
bass_set_row,
bass_is_playing
};
#endif /* !defined(SYNC_PLAYER) */
static void die(const char *fmt, ...)
{
char temp[4096];
va_list va;
va_start(va, fmt);
vsnprintf(temp, sizeof(temp), fmt, va);
va_end(va);
#if !defined(_WIN32) || defined(_CONSOLE)
fprintf(stderr, "*** error: %s\n", temp);
#else
MessageBox(NULL, temp, NULL, MB_OK | MB_ICONERROR);
#endif
exit(EXIT_FAILURE);
}
static const unsigned int width = 800;
static const unsigned int height = 600;
SDL_Surface *setup_sdl()
{
if (SDL_Init(SDL_INIT_VIDEO))
die("%s", SDL_GetError());
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
return SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
}
void draw_cube()
{
glBegin(GL_QUADS);
// Front Face
glColor3ub(255, 0, 0);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glColor3ub(0, 255, 0);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glColor3ub(0, 0, 255);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glColor3ub(255, 255, 0);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glColor3ub(255, 0, 255);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glColor3ub(255, 255, 255);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
}
int main(int argc, char *argv[])
{
SDL_Surface *screen;
HSTREAM stream;
const struct sync_track *clear_r, *clear_g, *clear_b;
const struct sync_track *cam_rot, *cam_dist;
screen = 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))
sync_connect(rocket, "localhost", SYNC_DEFAULT_PORT);
#endif
/* draw */
glClearColor(sync_get_val(clear_r, row),
sync_get_val(clear_g, row),
sync_get_val(clear_b, row), 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float rot = sync_get_val(cam_rot, row);
float dist = 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
sync_save_tracks(rocket);
#endif
sync_destroy_device(rocket);
BASS_StreamFree(stream);
BASS_Free();
SDL_Quit();
return 0;
}