From 7bb3ee3ab105d2d23aa087cb8c6de425ee20e955 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Thu, 13 Jan 2011 12:48:04 +0100 Subject: [PATCH 1/5] example_bass: mark file-local symbols as static --- example_bass/example_bass.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/example_bass/example_bass.cpp b/example_bass/example_bass.cpp index efdd3b1..33e8887 100644 --- a/example_bass/example_bass.cpp +++ b/example_bass/example_bass.cpp @@ -15,11 +15,11 @@ #include "../sync/sync.h" #include "bass.h" -const float bpm = 150.0f; /* beats per minute */ -const int rpb = 8; /* rows per beat */ -const double row_rate = (double(bpm) / 60) * rpb; +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; -double bass_get_row(HSTREAM h) +static double bass_get_row(HSTREAM h) { QWORD pos = BASS_ChannelGetPosition(h, BASS_POS_BYTE); double time = BASS_ChannelBytes2Seconds(h, pos); @@ -28,7 +28,7 @@ double bass_get_row(HSTREAM h) #ifndef SYNC_PLAYER -void bass_pause(void *d, int flag) +static void bass_pause(void *d, int flag) { if (flag) BASS_ChannelPause((HSTREAM)d); @@ -36,18 +36,18 @@ void bass_pause(void *d, int flag) BASS_ChannelPlay((HSTREAM)d, false); } -void bass_set_row(void *d, int row) +static void bass_set_row(void *d, int row) { QWORD pos = BASS_ChannelSeconds2Bytes((HSTREAM)d, row / row_rate); BASS_ChannelSetPosition((HSTREAM)d, pos, BASS_POS_BYTE); } -int bass_is_playing(void *d) +static int bass_is_playing(void *d) { return BASS_ChannelIsActive((HSTREAM)d) == BASS_ACTIVE_PLAYING; } -struct sync_cb bass_cb = { +static struct sync_cb bass_cb = { bass_pause, bass_set_row, bass_is_playing @@ -55,7 +55,7 @@ struct sync_cb bass_cb = { #endif /* !defined(SYNC_PLAYER) */ -void die(const char *fmt, ...) +static void die(const char *fmt, ...) { char temp[4096]; va_list va; @@ -72,8 +72,8 @@ void die(const char *fmt, ...) exit(EXIT_FAILURE); } -const unsigned int width = 800; -const unsigned int height = 600; +static const unsigned int width = 800; +static const unsigned int height = 600; int main(int argc, char *argv[]) { From b45b7af70f4de6a2bb29b9586495bfe28200594c Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Thu, 13 Jan 2011 12:49:45 +0100 Subject: [PATCH 2/5] example_bass: remove superfluous includes While we're at it, switch all standard library includes to C-style rather than C++-style. --- example_bass/example_bass.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/example_bass/example_bass.cpp b/example_bass/example_bass.cpp index 33e8887..b1d946d 100644 --- a/example_bass/example_bass.cpp +++ b/example_bass/example_bass.cpp @@ -6,10 +6,7 @@ #include #include #include -#include -#include -#include -#include +#include #include #include "../sync/sync.h" From 8fb9aa6257ecde870dcadac66f5dd74b5c9838ac Mon Sep 17 00:00:00 2001 From: Rasmus Kaae Date: Thu, 13 Jan 2011 12:34:43 +0100 Subject: [PATCH 3/5] example_bass: port graphics code from D3D to OGL Since BASS is available for MacOS X and Linux as well as Windows, it makes sense to port the example to OpenGL rather than Direct3D9. Use SDL to get an OpenGL context in a portable fashion. --- example_bass/example_bass.cpp | 170 +++++++++++++++++++++++---------------- example_bass/example_bass.vcproj | 8 +- 2 files changed, 105 insertions(+), 73 deletions(-) diff --git a/example_bass/example_bass.cpp b/example_bass/example_bass.cpp index b1d946d..cc24318 100644 --- a/example_bass/example_bass.cpp +++ b/example_bass/example_bass.cpp @@ -1,13 +1,18 @@ /* 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 -#include -#include +#endif +#include +#undef main /* avoid SDL's nasty SDLmain hack */ +#include #include #include +#include #include "../sync/sync.h" #include "bass.h" @@ -60,7 +65,7 @@ static void die(const char *fmt, ...) vsnprintf(temp, sizeof(temp), fmt, va); va_end(va); -#ifdef _CONSOLE +#if !defined(_WIN32) || defined(_CONSOLE) fprintf(stderr, "*** error: %s\n", temp); #else MessageBox(NULL, temp, NULL, MB_OK | MB_ICONERROR); @@ -72,42 +77,83 @@ static void die(const char *fmt, ...) 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[]) { - IDirect3D9 *d3d; - IDirect3DDevice9 *dev; - HWND hwnd; + SDL_Surface *screen; HSTREAM stream; - static D3DPRESENT_PARAMETERS present_parameters = { - width, height, D3DFMT_X8R8G8B8, 3, - D3DMULTISAMPLE_NONE, 0, D3DSWAPEFFECT_DISCARD, - 0, TRUE, 1, D3DFMT_D24S8, 0, 0 - }; - const struct sync_track *clear_r, *clear_g, *clear_b; const struct sync_track *cam_rot, *cam_dist; - /* initialize directx */ - d3d = Direct3DCreate9(D3D_SDK_VERSION); - if (!d3d) - die("update directx, fool."); - - /* create a window */ - hwnd = CreateWindowEx(0, "static", "GNU Rocket Example", - WS_POPUP | WS_VISIBLE, 0, 0, width, height, 0, 0, - GetModuleHandle(0), 0); - if (!hwnd) - die("failed to create window"); - - /* create the device */ - if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, - hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, - &dev))) - die("could not create device. you computer SUCKS!"); + screen = setup_sdl(); /* init BASS */ - if (!BASS_Init(-1, 44100, 0, hwnd, 0)) + if (!BASS_Init(-1, 44100, 0, 0, 0)) die("failed to init bass"); stream = BASS_StreamCreateFile(false, "tune.ogg", 0, 0, 0); if (!stream) @@ -130,11 +176,6 @@ int main(int argc, char *argv[]) cam_rot = sync_get_track(rocket, "cam.rot"), cam_dist = sync_get_track(rocket, "cam.dist"); - LPD3DXMESH cubeMesh = NULL; - if (FAILED(D3DXCreateBox(dev, 1.0f, 1.0f, 1.0f, - &cubeMesh, NULL))) - return -1; - /* let's roll! */ BASS_Start(); BASS_ChannelPlay(stream, false); @@ -149,44 +190,38 @@ int main(int argc, char *argv[]) /* draw */ - D3DXCOLOR clearColor( - sync_get_val(clear_r, row), - sync_get_val(clear_g, row), - sync_get_val(clear_b, row), - 0.0 - ); - - dev->BeginScene(); - dev->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, clearColor, 1.0f, 0); + 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); - D3DXVECTOR3 eye(sin(rot) * dist, 0, cos(rot) * dist); - D3DXVECTOR3 at(0, 0, 0); - D3DXVECTOR3 up(0, 1, 0); - D3DXMATRIX view; - D3DXVECTOR3 dir = eye + at; - D3DXMatrixLookAtLH(&view, &dir, &at, &up); - dev->SetTransform(D3DTS_VIEW, &view); - - D3DXMATRIX proj; - D3DXMatrixPerspectiveFovLH(&proj, D3DXToRadian(60), 4.0f / 3, 0.1f, 1000.f); - dev->SetTransform(D3DTS_PROJECTION, &proj); - cubeMesh->DrawSubset(0); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0f, 4.0f / 3, 0.1f, 100.0f); - dev->EndScene(); - dev->Present(0, 0, 0, 0); + 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 */ - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - if (WM_QUIT == msg.message || - (WM_KEYDOWN == msg.message && - VK_ESCAPE == LOWORD(msg.wParam))) + SDL_Event e; + while (SDL_PollEvent(&e)) { + if (e.type == SDL_QUIT || + (e.type == SDL_KEYDOWN && + e.key.keysym.sym == SDLK_ESCAPE)) done = true; } } @@ -198,10 +233,7 @@ int main(int argc, char *argv[]) BASS_StreamFree(stream); BASS_Free(); - - dev->Release(); - d3d->Release(); - DestroyWindow(hwnd); + SDL_Quit(); return 0; } diff --git a/example_bass/example_bass.vcproj b/example_bass/example_bass.vcproj index bbc170b..9be1978 100644 --- a/example_bass/example_bass.vcproj +++ b/example_bass/example_bass.vcproj @@ -60,7 +60,7 @@ /> Date: Thu, 13 Jan 2011 16:59:16 +0100 Subject: [PATCH 4/5] example_bass: use folders for external deps BASS and SDL both add a set of headers and libs that needs to be included into the project. Allow the user to put these headers in a subfolder called "include" and the libs in a subfolder called "lib". --- README | 13 +++++++------ example_bass/example_bass.cpp | 2 +- example_bass/example_bass.vcproj | 20 ++++++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/README b/README index 16451b1..cdbdd52 100644 --- a/README +++ b/README @@ -14,18 +14,19 @@ select "Build" -> "Build Solution" from the menu to build the editor. Compile Example --------------- GNU Rocket contains an example client called example_bass. This is a simple -Direct3D 9.0 and BASS audio library application, that demonstrates how to +OpenGL, SDL 1.2 and BASS audio library application, that demonstrates how to use the GNU Rocket API. Before compiling the example, you need to make sure you have recent -Microsoft DirectX and BASS SDKs. These can be downloaded from the following -web-sites: +SDL and BASS libraries and includes. These can be downloaded from the +following web-sites: -http://msdn.microsoft.com/directx/ +http://www.libsdl.org/ http://www.un4seen.com/ -The BASS SDK is installed by copying bass.dll, bass.h and bass.lib to the -example_bass-folder. +The header files and libraries can be installed local to the project by +copying all .lib-files to the example_bass/lib/, all .h files to +example_bass/inclide/, and all .dll files to the example_bass/. Once the prerequisites are installed, the example can be compiled much like the editor; by opening examples.sln and selecting "Build" -> "Build Solution" diff --git a/example_bass/example_bass.cpp b/example_bass/example_bass.cpp index cc24318..02f62e4 100644 --- a/example_bass/example_bass.cpp +++ b/example_bass/example_bass.cpp @@ -10,12 +10,12 @@ #include #undef main /* avoid SDL's nasty SDLmain hack */ #include +#include #include #include #include #include "../sync/sync.h" -#include "bass.h" static const float bpm = 150.0f; /* beats per minute */ static const int rpb = 8; /* rows per beat */ diff --git a/example_bass/example_bass.vcproj b/example_bass/example_bass.vcproj index 9be1978..399df16 100644 --- a/example_bass/example_bass.vcproj +++ b/example_bass/example_bass.vcproj @@ -41,6 +41,7 @@ - - From 81e4455f16291b2cb53f5926f45c580553ac3c80 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Thu, 13 Jan 2011 17:20:26 +0100 Subject: [PATCH 5/5] contrib: remove broken c++-wrapper --- contrib/example_bass.cpp | 170 ----------------------------------------------- contrib/sync-cpp.h | 75 --------------------- 2 files changed, 245 deletions(-) delete mode 100644 contrib/example_bass.cpp delete mode 100644 contrib/sync-cpp.h diff --git a/contrib/example_bass.cpp b/contrib/example_bass.cpp deleted file mode 100644 index 497446b..0000000 --- a/contrib/example_bass.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright (C) 2007-2008 Erik Faye-Lund and Egbert Teeselink - * For conditions of distribution and use, see copyright notice in COPYING - */ - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include -#include -#include "bass.h" -#include "sync-cpp.h" - -class BassTimer : public sync::Timer { -public: - BassTimer(HSTREAM stream, float bpm, int rowsPerBeat) : stream(stream) - { - rowRate = (double(bpm) / 60) * rowsPerBeat; - } - - // BASS hooks - void pause() { BASS_ChannelPause(stream); } - void play() { BASS_ChannelPlay(stream, false); } - float getTime() { return float(BASS_ChannelBytes2Seconds(stream, BASS_ChannelGetPosition(stream, BASS_POS_BYTE))); } - float getRow() { return float(getTime() * rowRate); } - void setRow(float row) { BASS_ChannelSetPosition(stream, BASS_ChannelSeconds2Bytes(stream, float(row / rowRate)), BASS_POS_BYTE); } - bool isPlaying() { return (BASS_ChannelIsActive(stream) == BASS_ACTIVE_PLAYING); } -private: - HSTREAM stream; - double rowRate; -}; - -#define WINDOWED 1 -const unsigned int width = 800; -const unsigned int height = 600; - -int main(int argc, char *argv[]) -{ - int ret = 0; - try { - // initialize directx - IDirect3D9 *d3d = Direct3DCreate9(D3D_SDK_VERSION); - if (!d3d) - throw std::string("This application requires DirectX 9"); - - // create a window - HWND hwnd = CreateWindowEx(0, "static", "GNU Rocket Example", - WS_POPUP | WS_VISIBLE, 0, 0, width, height, 0, 0, - GetModuleHandle(0), 0); - - // create the device - IDirect3DDevice9 *device = NULL; - static D3DPRESENT_PARAMETERS present_parameters = {width, - height, D3DFMT_X8R8G8B8, 3, D3DMULTISAMPLE_NONE, 0, - D3DSWAPEFFECT_DISCARD, 0, WINDOWED, 1, D3DFMT_D24S8, - 0, WINDOWED ? 0 : D3DPRESENT_RATE_DEFAULT, 0 - }; - if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, - &present_parameters, &device))) - throw std::string("Failed to create device"); - - // init BASS - int soundDevice = 1; - if (!BASS_Init(soundDevice, 44100, 0, hwnd, 0)) - throw std::string("Failed to init bass"); - - // load tune - HSTREAM stream = BASS_StreamCreateFile(false, "tune.ogg", 0, 0, - BASS_MP3_SETPOS | (!soundDevice ? BASS_STREAM_DECODE : 0)); - if (!stream) - throw std::string("Failed to open tune"); - - // let's just assume 150 BPM (this holds true for the included tune) - float bpm = 150.0f; - - // setup timer and construct sync-device - BassTimer timer(stream, bpm, 8); - std::auto_ptr syncDevice = std::auto_ptr( - sync::createDevice("sync", timer)); - if (!syncDevice.get()) - throw std::string("Failed to connect to host?"); - - // get tracks - sync::Track &clearRTrack = syncDevice->getTrack("clear.r"); - sync::Track &clearGTrack = syncDevice->getTrack("clear.g"); - sync::Track &clearBTrack = syncDevice->getTrack("clear.b"); - - sync::Track &camRotTrack = syncDevice->getTrack("cam.rot"); - sync::Track &camDistTrack = syncDevice->getTrack("cam.dist"); - - LPD3DXMESH cubeMesh = NULL; - if (FAILED(D3DXCreateBox(device, 1.0f, 1.0f, 1.0f, &cubeMesh, NULL))) - return -1; - - // let's roll! - BASS_Start(); - timer.play(); - - bool done = false; - while (!done) { - float row = float(timer.getRow()); - if (!syncDevice->update(row)) - done = true; - - // setup clear color - D3DXCOLOR clearColor(clearRTrack.getValue(row), clearGTrack.getValue(row), clearBTrack.getValue(row), 0.0); - - // paint the window - device->BeginScene(); - device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, clearColor, 1.0f, 0); - -/* D3DXMATRIX world; - device->SetTransform(D3DTS_WORLD, &world); */ - - float rot = camRotTrack.getValue(row); - float dist = camDistTrack.getValue(row); - D3DXVECTOR3 eye(sin(rot) * dist, 0, cos(rot) * dist); - D3DXVECTOR3 at(0, 0, 0); - D3DXVECTOR3 up(0, 1, 0); - D3DXMATRIX view; - D3DXMatrixLookAtLH(&view, &(eye + at), &at, &up); - device->SetTransform(D3DTS_WORLD, &view); - - D3DXMATRIX proj; - D3DXMatrixPerspectiveFovLH(&proj, D3DXToRadian(60), 4.0f / 3, 0.1f, 1000.f); - device->SetTransform(D3DTS_PROJECTION, &proj); - - cubeMesh->DrawSubset(0); - - device->EndScene(); - device->Present(0, 0, 0, 0); - - BASS_Update(0); // decrease the chance of missing vsync - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (WM_QUIT == msg.message) done = true; - if ((WM_KEYDOWN == msg.message) && (VK_ESCAPE == LOWORD(msg.wParam))) done = true; - } - } - - BASS_StreamFree(stream); - BASS_Free(); - - device->Release(); - d3d->Release(); - DestroyWindow(hwnd); - } catch (const std::exception &e) { -#ifdef _CONSOLE - fprintf(stderr, "*** error: %s\n", e.what()); -#else - MessageBox(NULL, e.what(), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); -#endif - ret = -1; - } catch (const std::string &str) { -#ifdef _CONSOLE - fprintf(stderr, "*** error: %s\n", str.c_str()); -#else - MessageBox(NULL, e.what(), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); -#endif - ret = -1; - } - - return ret; -} diff --git a/contrib/sync-cpp.h b/contrib/sync-cpp.h deleted file mode 100644 index 5a7bcbd..0000000 --- a/contrib/sync-cpp.h +++ /dev/null @@ -1,75 +0,0 @@ -#include "../sync/sync.h" -namespace sync { - class Timer { - public: - virtual void pause() = 0; - virtual void play() = 0; - virtual void setRow(float) = 0; - virtual bool isPlaying() = 0; - }; - - static void xpause(void *ptr, int flag) - { - Timer *timer = (Timer *)ptr; - if (flag) - timer->pause(); - else - timer->play(); - } - - static void xset_row(void *ptr, int row) - { - Timer *timer = (Timer *)ptr; - timer->setRow(float(row)); - } - - static int xis_playing(void *ptr) - { - Timer *timer = (Timer *)ptr; - return timer->isPlaying(); - } - - class Track { - public: - float getValue(double row) - { - return sync_get_val(track, row); - } - sync_track *track; - }; - - class Device { - public: - Track getTrack(const char *name) - { - Track track; - track.track = sync_get_track(device, name); - return track; - } - - bool update(double row) - { - sync_update(device, row); - return true; - } - - sync_device *device; - sync_cb cb; - }; - - inline Device *createDevice(const char *prefix, Timer &timer) - { - Device *device = new Device; - device->device = sync_create_device(prefix); - if (!device->device) { - delete device; - return NULL; - } - - device->cb.is_playing = xis_playing; - device->cb.pause = xpause; - device->cb.set_row = xset_row; - sync_set_callbacks(device->device, &device->cb, (void *)&timer); - return device; - } -}