comparison src/projectm-1.0/main.cxx @ 2251:708f89aaee06

Automated merge with ssh://hg.atheme.org//hg/audacious-plugins
author Eugene Paskevich <eugene@raptor.kiev.ua>
date Wed, 19 Dec 2007 12:23:30 +0200
parents ff0a27216c6a
children ace0b59f541a
comparison
equal deleted inserted replaced
2250:94dae4df1e10 2251:708f89aaee06
1 /* 1 /*
2 projectM v1.01 - xmms-projectm.sourceforge.net 2 * main.cxx: plugin glue to libprojectm
3 -------------------------------------------------- 3 * Copyright (c) 2008 William Pitcock <nenolod@sacredspiral.co.uk>
4 4 * Portions copyright (c) 2004-2006 Peter Sperl
5 Lead Developers: Carmelo Piccione (carmelo.piccione@gmail.com) & 5 *
6 Peter Sperl (peter@sperl.com) 6 * This program is free software; you may distribute it under the terms
7 7 * of the GNU General Public License; version 2.
8 We have also been advised by some professors at CMU, namely Roger B. Dannenberg. 8 */
9 http://www-2.cs.cmu.edu/~rbd/
10
11 The inspiration for this program was Milkdrop by Ryan Geiss. Obviously.
12
13 This code is distributed under the GPL.
14
15
16 THANKS FOR THE CODE!!!
17 -------------------------------------------------
18 The base for this program was andy@nobugs.org's XMMS plugin tutorial
19 http://www.xmms.org/docs/vis-plugin.html
20
21 We used some FFT code by Takuya OOURA instead of XMMS' built-in fft code
22 fftsg.c - http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html
23
24 and some beat detection code was inspired by Frederic Patin @
25 www.gamedev.net/reference/programming/features/beatdetection/
26
27 */
28 9
29 #include <stdio.h> 10 #include <stdio.h>
30 #include <string.h> 11 #include <string.h>
31 #include <string> 12 #include <string>
32 #include <stdlib.h> 13 #include <stdlib.h>
33 #include <unistd.h> 14 #include <unistd.h>
34 #include <fcntl.h> 15 #include <fcntl.h>
35 #include <SDL/SDL.h> 16 #include <SDL/SDL.h>
36 #include <SDL/SDL_thread.h> 17 #include <SDL/SDL_thread.h>
37 18
38 extern "C" { 19 extern "C"
20 {
39 #include <audacious/util.h> 21 #include <audacious/util.h>
40 #include <audacious/plugin.h> 22 #include <audacious/plugin.h>
23 #include <audacious/playlist.h>
41 #include <audacious/auddrct.h> 24 #include <audacious/auddrct.h>
42 } 25 }
43 26
44 #include <math.h> 27 #include <math.h>
45 #include "ConfigFile.h" 28 #include "ConfigFile.h"
46 29
47 #include <libprojectM/projectM.hpp> 30 #include <libprojectM/projectM.hpp>
48 31
49 #include "sdltoprojectM.h" 32 #include "sdltoprojectM.h"
50 #include "video_init.h"
51 33
52 #include <GL/gl.h> 34 #include <GL/gl.h>
53 #define CONFIG_FILE "/share/projectM/config.inp" 35 #define CONFIG_FILE "/share/projectM/config.inp"
54 36
55 // Forward declarations 37 // Forward declarations
56 extern "C" void projectM_xmms_init(void); 38 extern "C" void projectM_xmms_init(void);
57 extern "C" void projectM_cleanup(void); 39 extern "C" void projectM_cleanup(void);
58 extern "C" void projectM_about(void);
59 extern "C" void projectM_configure(void);
60 extern "C" void projectM_playback_start(void);
61 extern "C" void projectM_playback_stop(void);
62 extern "C" void projectM_render_pcm(gint16 pcm_data[2][512]); 40 extern "C" void projectM_render_pcm(gint16 pcm_data[2][512]);
63 extern "C" void projectM_render_freq(gint16 pcm_data[2][256]); 41 extern "C" int worker_func(void *);
64 extern "C" int worker_func(void*);
65 std::string read_config(); 42 std::string read_config();
66 void saveSnapshotToFile();
67 43
68 extern "C" VisPlugin projectM_vtable; 44 extern "C" VisPlugin projectM_vtable;
69 45
70 //extern preset_t * active_preset; 46 int SDLThreadWrapper(void *);
71 47 void handle_playback_trigger(void *, void *);
72 //FILE * debugFile = fopen("./dwrite-dump", "wb"); 48
73 49 class projectMPlugin
74 // Our worker thread 50 {
75 SDL_Thread *worker_thread = NULL; 51 private:
76 SDL_sem *sem = NULL; 52 projectM *pm;
77 SDL_Event event; 53
78 54 gint wvw, wvh, fvw, fvh;
79 SDL_Surface *screen; 55 gboolean fullscreen;
80 56 gboolean error;
81 57
82 projectM * globalPM = NULL; 58 SDL_Event event;
83 59 SDL_Surface *screen;
84 int maxsamples=512; 60 SDL_Thread *worker_thread;
85 61 SDL_sem *sem;
86 int texsize=512; 62
87 int gx=32,gy=24; 63 public:
88 int wvw=400,wvh=400; 64 projectMPlugin()
89 int fvw=1024,fvh=768; 65 {
90 int fps=35, fullscreen=0; 66 std::string configFile = read_config();
91 67 ConfigFile config(configFile);
92 // char *title; 68
93 69 this->wvw = config.read<int>("Window Width", 512);
94 gint disable_projectm(void *something) { 70 this->wvh = config.read<int>("Window Height", 512);
95 projectM_vtable.disable_plugin(&projectM_vtable); 71
96 return 0; 72 this->fullscreen = FALSE;
97 } 73 if (config.read("Fullscreen", true))
98 74 this->fullscreen = TRUE;
99 Uint32 get_xmms_title(Uint32 something, void *somethingelse) { 75
100 static char check_title = 1; 76 /* initialise SDL */
101 static int last_pos; 77 if (SDL_Init(SDL_INIT_VIDEO) < 0)
102 static char *last_title = NULL; 78 {
103 int pos; 79 this->error++;
104 char *title = NULL; 80 return;
105 81 }
106 //Nice optimization, but we want the title no matter what so I can display it when the song changes 82
107 #if 0 83 SDL_WM_SetCaption("projectM", "audacious");
108 if(!(globalPM->showtitle%2)) { 84 SDL_EnableUNICODE(1);
109 /* Repeat less often when not showing title */ 85
110 return 1000; 86 this->sem = SDL_CreateSemaphore(0);
111 } 87
112 #endif 88 /* XXX */
113 89 aud_hook_associate("playback begin", handle_playback_trigger, NULL);
114 pos = audacious_drct_pl_get_pos(); 90 }
115 /* Only check every 1 second for title change, otherwise check pos */ 91
116 if(check_title || pos != last_pos) { 92 ~projectMPlugin()
117 title = audacious_drct_pl_get_title(pos); 93 {
118 if(title && (!last_title || strcmp(last_title,title))) { 94 if (!this->sem)
119 //globalPM->renderer->title = title; 95 return;
120 //globalPM->renderer->drawtitle = 1; 96
121 97 SDL_SemWait(this->sem);
122 std::string titlepp(title); 98
123 globalPM->projectM_setTitle(titlepp); 99 if (this->worker_thread)
124 g_free(last_title); 100 SDL_WaitThread(this->worker_thread, NULL);
125 last_title = title; 101
126 } else if(title && last_title != title) { 102 SDL_DestroySemaphore(this->sem);
127 /* New copy of last title */ 103 SDL_Quit();
128 g_free(title); 104
129 } 105 this->sem = 0;
130 check_title = !check_title; 106 this->worker_thread = 0;
131 } 107
132 last_pos = pos; 108 delete this->pm;
133 /* Repeat every 500ms */ 109 this->pm = 0;
134 return 500; 110
135 } 111 aud_hook_dissociate("playback begin", handle_playback_trigger);
136 112 }
137 int capture = 0; 113
138 114 int run(void *unused)
139 int worker_func(void*) 115 {
140 { 116 if (error)
141 // char projectM_data[1024]; 117 return -1;
142 SDL_TimerID title_timer = NULL; 118
143 std::string config_file; 119 std::string configFile = read_config();
144 config_file = read_config(); 120 this->initDisplay(this->wvw, this->wvh, &this->fvw, &this->fvh, this->fullscreen);
145 ConfigFile config(config_file); 121 this->pm = new projectM(configFile);
146 122 this->pm->projectM_resetGL(this->wvw, this->wvh);
147 int wvw = config.read<int>( "Window Width", 512 ); 123
148 int wvh = config.read<int>( "Window Height", 512 ); 124 SDL_SemPost(this->sem);
149 125
150 int fullscreen = 0; 126 while (SDL_SemValue(this->sem) == 1)
151 if (config.read("Fullscreen", true)) fullscreen = 1; 127 {
152 else fullscreen = 0; 128 projectMEvent evt;
153 129 projectMKeycode key;
154 init_display(wvw,wvh,&fvw,&fvh,fullscreen); 130 projectMModifier mod;
155 SDL_WM_SetCaption("projectM v1.00", "projectM v1.00"); 131
156 132 SDL_Event event;
157 /** Initialise projectM */ 133 while (SDL_PollEvent(&event))
158 134 {
159 globalPM = new projectM(config_file); 135 evt = sdl2pmEvent(event);
160 SDL_SemPost(sem); 136
161 title_timer = SDL_AddTimer(500, get_xmms_title, NULL); 137 key = sdl2pmKeycode(event.key.keysym.sym);
162 /** Initialise the thread */ 138 mod = sdl2pmModifier(event.key.keysym.mod);
163 // SDL_SemTryWait(sem); 139
164 while ( SDL_SemValue(sem)==1 ) { 140 switch (evt)
165 projectMEvent evt; 141 {
166 projectMKeycode key; 142 case PROJECTM_KEYDOWN:
167 projectMModifier mod; 143 switch (key)
168 144 {
169 /** Process SDL events */ 145 case PROJECTM_K_c:
170 SDL_Event event; 146 this->takeScreenshot();
171 while ( SDL_PollEvent( &event ) ) { 147 break;
172 /** Translate into projectM codes and process */ 148
173 evt = sdl2pmEvent( event ); 149 case PROJECTM_K_f:
174 150 int w, h;
175 key = sdl2pmKeycode( event.key.keysym.sym ); 151 if (fullscreen == 0)
176 mod = sdl2pmModifier( event.key.keysym.mod ); 152 {
177 153 w = fvw;
178 if ( evt == PROJECTM_KEYDOWN ) { 154 h = fvh;
179 155 fullscreen = 1;
180 if(key == PROJECTM_K_c) 156 }
181 { 157 else
182 //SDL_SaveBMP(screen, "/home/pete/1.bmp"); 158 {
183 saveSnapshotToFile(); 159 w = wvw;
184 } 160 h = wvh;
185 if(key == PROJECTM_K_v) 161 fullscreen = 0;
186 { 162 }
187 // capture++; 163
188 } 164 this->resizeDisplay(w, h, fullscreen);
189 if(key == PROJECTM_K_f) 165 this->pm->projectM_resetGL(w, h);
190 { 166
191 167 break;
192 168
193 int w, h; 169 default:
194 if (fullscreen == 0) { 170 this->pm->key_handler(evt, key, mod);
195 w = fvw; 171 break;
196 h = fvh; 172 }
197 fullscreen = 1; 173
198 } else { 174 break;
199 w = wvw; 175
200 h = wvh; 176 case PROJECTM_VIDEORESIZE:
201 fullscreen = 0; 177 wvw = event.resize.w;
202 } 178 wvh = event.resize.h;
203 179 this->resizeDisplay(wvw, wvh, fullscreen);
204 resize_display(w, h, fullscreen); 180 this->pm->projectM_resetGL(wvw, wvh);
205 globalPM->projectM_resetGL( w, h ); 181
182 break;
183
184 case PROJECTM_VIDEOQUIT:
185 std::cerr << "XXX: PROJECTM_VIDEOQUIT is not implemented yet!" << std::endl;
186 break;
187
188 default:
189 break;
206 } 190 }
207 else globalPM->key_handler(evt,key,mod); 191 }
208 192
209 } 193 this->pm->renderFrame();
210 else if ( evt == PROJECTM_VIDEORESIZE ) 194
211 { 195 SDL_GL_SwapBuffers();
212 196 }
213 197
214 198 return 0;
215 wvw=event.resize.w; 199 }
216 wvh=event.resize.h; 200
217 201 void launchThread()
218 202 {
219 resize_display(wvw,wvh,fullscreen); 203 /* SDL sucks and won't let you use C++ functors... */
220 globalPM->projectM_resetGL( wvw, wvh ); 204 this->worker_thread = SDL_CreateThread(SDLThreadWrapper, NULL);
221 205 }
222 } 206
223 else if ( evt == PROJECTM_VIDEOQUIT ) { 207 void addPCMData(gint16 pcm_data[2][512])
224 208 {
225 (void) g_idle_add ((GSourceFunc) disable_projectm, NULL); 209 if (SDL_SemValue(this->sem) == 1)
226 } 210 this->pm->pcm->addPCM16(pcm_data);
227 } 211 }
228 212
229 /** Add the waveform data */ 213 void initDisplay(gint width, gint height, gint *rwidth, gint *rheight, gboolean fullscreen)
230 214 {
231 215 this->wvw = width;
232 /** Render the new frame */ 216 this->wvh = height;
233 // strcpy(title,xmms_remote_get_playlist_title(projectM_vtable.xmms_session, xmms_remote_get_playlist_pos(projectM_vtable.xmms_session))); 217 this->fvw = *rwidth;
234 218 this->fvw = *rheight;
235 //printf("%s\n",title); 219 this->fullscreen = fullscreen;
236 // strcpy(globalPM->title,title); 220
237 221 const SDL_VideoInfo *info = NULL;
238 globalPM->renderFrame(); 222 int bpp;
239 223 int flags;
240 224
241 225 info = SDL_GetVideoInfo();
242 SDL_GL_SwapBuffers(); 226 if (!info)
243 227 {
244 if (capture % 2 == 1) saveSnapshotToFile(); 228 this->error++;
245 // SDL_SemPost(sem); 229 return;
246 } 230 }
247 231
248 if(title_timer) 232 /* initialize fullscreen resolution to something "sane" */
249 SDL_RemoveTimer(title_timer); 233 *rwidth = width;
250 delete globalPM; 234 *rheight = height;
251 235
252 236 bpp = info->vfmt->BitsPerPixel;
253 return 0; 237 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
254 } 238 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
255 239 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
256 extern "C" void projectM_xmms_init(void) 240
257 { 241 if (this->fullscreen)
258 242 flags = SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN;
259 /* First, initialize SDL's video subsystem. */ 243 else
260 // std::cerr << "sdl init begin" << std::endl; 244 flags = SDL_OPENGL | SDL_HWSURFACE | SDL_RESIZABLE;
261 if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0 ) { 245
262 /* Failed, exit. */ 246 this->screen = SDL_SetVideoMode(width, height, bpp, flags);
263 fprintf( stderr, "Video initialization failed: %s\n", 247 if (!this->screen)
264 SDL_GetError( ) ); 248 this->error++;
265 //projectM_vtable.disable_plugin (&projectM_vtable); 249 }
266 return; 250
267 251 void resizeDisplay(gint width, gint height, gboolean fullscreen)
268 } 252 {
269 sem = SDL_CreateSemaphore(0); 253 this->fullscreen = fullscreen;
270 // printf("projectM plugin: Initializing\n"); 254
271 255 int flags;
272 SDL_EnableUNICODE(1); 256
273 257 if (this->fullscreen)
274 worker_thread = SDL_CreateThread ( *worker_func, NULL); 258 flags = SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN;
275 259 else
276 } 260 flags = SDL_OPENGL | SDL_HWSURFACE | SDL_RESIZABLE;
277 261
278 262 this->screen = SDL_SetVideoMode(width, height, 0, flags);
263 if (this->screen == 0)
264 return;
265
266 SDL_ShowCursor(this->fullscreen ? SDL_DISABLE : SDL_ENABLE);
267 }
268
269 void triggerPlaybackBegin(PlaylistEntry *entry)
270 {
271 std::string title(entry->title);
272 this->pm->projectM_setTitle(title);
273 }
274
275 void takeScreenshot(void)
276 {
277 static int frame = 1;
278
279 std::string dumpPath(g_get_home_dir());
280 dumpPath.append("/.projectM/");
281
282 gchar *frame_ = g_strdup_printf("%.8d.bmp", frame);
283 dumpPath.append(frame_);
284 g_free(frame_);
285
286 SDL_Surface *bitmap;
287
288 GLint viewport[4];
289 long bytewidth;
290 GLint width, height;
291 long bytes;
292
293 glReadBuffer(GL_FRONT);
294 glGetIntegerv(GL_VIEWPORT, viewport);
295
296 width = viewport[2];
297 height = viewport[3];
298
299 bytewidth = width * 4;
300 bytewidth = (bytewidth + 3) & ~3;
301 bytes = bytewidth * height;
302
303 bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0);
304 glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, bitmap->pixels);
305
306 SDL_SaveBMP(bitmap, dumpPath.c_str());
307
308 SDL_FreeSurface(bitmap);
309
310 frame++;
311 }
312 };
313
314 /* glue to implementation section */
315 projectMPlugin *thePlugin = 0;
316
317 /* SDL sucks and won't let you use proper C++ functors. :( */
318 int SDLThreadWrapper(void *unused)
319 {
320 return thePlugin->run(unused);
321 }
322
323 void handle_playback_trigger(gpointer plentry_p, gpointer unused)
324 {
325 PlaylistEntry *entry = reinterpret_cast<PlaylistEntry *>(plentry_p);
326
327 if (!thePlugin)
328 return;
329
330 thePlugin->triggerPlaybackBegin(entry);
331 }
332
333 extern "C" void projectM_xmms_init(void)
334 {
335 thePlugin = new projectMPlugin;
336 thePlugin->launchThread();
337 }
279 338
280 extern "C" void projectM_cleanup(void) 339 extern "C" void projectM_cleanup(void)
281 { 340 {
282 341 if (!thePlugin)
283 if(!sem) return; 342 return;
284 SDL_SemWait(sem); 343
285 if(worker_thread) SDL_WaitThread(worker_thread, NULL); 344 delete thePlugin;
286 // SDL_KillThread(worker_thread); 345 }
287 //printf("killed thread\n"); 346
288
289 SDL_DestroySemaphore(sem);
290 //printf("Destroy Mutex\n");
291 SDL_Quit();
292
293 sem = NULL;
294 worker_thread = NULL;
295
296 // printf("projectM plugin: Cleanup completed\n");
297 }
298 extern "C" void projectM_about(void)
299 {
300 printf("projectM plugin: About\n");
301 }
302 extern "C" void projectM_configure(void)
303 {
304 printf("projectM plugin: Configure\n");
305 }
306 extern "C" void projectM_playback_start(void)
307 {//thread_control = GO;
308 printf("projectM plugin: Playback starting\n");
309 }
310 extern "C" void projectM_playback_stop(void)
311 {//thread_control = STOP;
312 printf("projectM plugin: Playback stopping\n");
313 }
314 extern "C" void projectM_render_pcm(gint16 pcm_data[2][512]) 347 extern "C" void projectM_render_pcm(gint16 pcm_data[2][512])
315 { 348 {
316 //SDL_mutexP(mutex); while ( SDL_SemValue(sem)==1 ) 349 if (!thePlugin)
317 if ( SDL_SemValue(sem)==1 ) 350 return;
318 globalPM->pcm->addPCM16(pcm_data); 351
319 352 thePlugin->addPCMData(pcm_data);
320 //SDL_mutexV(mutex); 353 }
321 354
322 } 355 /********************************************************************************
323 356 * XXX: This code is from projectM and still needs to be rewritten! *
324 extern "C" void projectM_render_freq(gint16 freq_data[2][256]) 357 ********************************************************************************/
325 {
326 printf("NO GOOD\n");
327 }
328
329 std::string read_config() 358 std::string read_config()
330 { 359 {
331 360
332 // int n; 361 // int n;
333 362
334 char num[512]; 363 char num[512];
335 FILE *in; 364 FILE *in;
336 FILE *out; 365 FILE *out;
337 366
338 char* home; 367 char *home;
339 char projectM_home[1024]; 368 char projectM_home[1024];
340 char projectM_config[1024]; 369 char projectM_config[1024];
341 370
342 strcpy(projectM_config, PROJECTM_PREFIX); 371 strcpy(projectM_config, PROJECTM_PREFIX);
343 strcpy(projectM_config+strlen(PROJECTM_PREFIX), CONFIG_FILE); 372 strcpy(projectM_config + strlen(PROJECTM_PREFIX), CONFIG_FILE);
344 projectM_config[strlen(PROJECTM_PREFIX)+strlen(CONFIG_FILE)]='\0'; 373 projectM_config[strlen(PROJECTM_PREFIX) + strlen(CONFIG_FILE)] = '\0';
345 //printf("dir:%s \n",projectM_config); 374 //printf("dir:%s \n",projectM_config);
346 home=getenv("HOME"); 375 home = getenv("HOME");
347 strcpy(projectM_home, home); 376 strcpy(projectM_home, home);
348 strcpy(projectM_home+strlen(home), "/.projectM/config.inp"); 377 strcpy(projectM_home + strlen(home), "/.projectM/config.inp");
349 projectM_home[strlen(home)+strlen("/.projectM/config.inp")]='\0'; 378 projectM_home[strlen(home) + strlen("/.projectM/config.inp")] = '\0';
350 379
351 380
352 if ((in = fopen(projectM_home, "r")) != 0) 381 if ((in = fopen(projectM_home, "r")) != 0)
353 { 382 {
354 //printf("reading ~/.projectM/config.inp \n"); 383 //printf("reading ~/.projectM/config.inp \n");
355 fclose(in); 384 fclose(in);
356 return std::string(projectM_home); 385 return std::string(projectM_home);
357 } 386 }
358 else 387 else
359 { 388 {
360 printf("trying to create ~/.projectM/config.inp \n"); 389 printf("trying to create ~/.projectM/config.inp \n");
361 390
362 strcpy(projectM_home, home); 391 strcpy(projectM_home, home);
363 strcpy(projectM_home+strlen(home), "/.projectM"); 392 strcpy(projectM_home + strlen(home), "/.projectM");
364 projectM_home[strlen(home)+strlen("/.projectM")]='\0'; 393 projectM_home[strlen(home) + strlen("/.projectM")] = '\0';
365 mkdir(projectM_home,0755); 394 mkdir(projectM_home, 0755);
366 395
367 strcpy(projectM_home, home); 396 strcpy(projectM_home, home);
368 strcpy(projectM_home+strlen(home), "/.projectM/config.inp"); 397 strcpy(projectM_home + strlen(home), "/.projectM/config.inp");
369 projectM_home[strlen(home)+strlen("/.projectM/config.inp")]='\0'; 398 projectM_home[strlen(home) + strlen("/.projectM/config.inp")] = '\0';
370 399
371 if((out = fopen(projectM_home,"w"))!=0) 400 if ((out = fopen(projectM_home, "w")) != 0)
372 { 401 {
373 402
374 if ((in = fopen(projectM_config, "r")) != 0) 403 if ((in = fopen(projectM_config, "r")) != 0)
375 { 404 {
376 405
377 while(fgets(num,80,in)!=NULL) 406 while (fgets(num, 80, in) != NULL)
378 { 407 {
379 fputs(num,out); 408 fputs(num, out);
380 } 409 }
381 fclose(in); 410 fclose(in);
382 fclose(out); 411 fclose(out);
383 412
384 413
385 if ((in = fopen(projectM_home, "r")) != 0) 414 if ((in = fopen(projectM_home, "r")) != 0)
386 { 415 {
387 printf("created ~/.projectM/config.inp successfully\n"); 416 printf("created ~/.projectM/config.inp successfully\n");
388 fclose(in); 417 fclose(in);
389 return std::string(projectM_home); 418 return std::string(projectM_home);
390 } 419 }
391 else{printf("This shouldn't happen, using implementation defualts\n");abort();} 420 else
392 } 421 {
393 else{printf("Cannot find projectM default config, using implementation defaults\n");abort();} 422 printf("This shouldn't happen, using implementation defualts\n");
394 } 423 abort();
395 else 424 }
396 { 425 }
397 printf("Cannot create ~/.projectM/config.inp, using default config file\n"); 426 else
398 if ((in = fopen(projectM_config, "r")) != 0) 427 {
399 { printf("Successfully opened default config file\n"); 428 printf("Cannot find projectM default config, using implementation defaults\n");
400 fclose(in); 429 abort();
401 return std::string(projectM_config);} 430 }
402 else{ printf("Using implementation defaults, your system is really messed up, I'm suprised we even got this far\n"); abort();} 431 }
403 } 432 else
404 433 {
405 } 434 printf("Cannot create ~/.projectM/config.inp, using default config file\n");
406 435 if ((in = fopen(projectM_config, "r")) != 0)
407 abort(); 436 {
408 } 437 printf("Successfully opened default config file\n");
409 438 fclose(in);
410 int frame = 1; 439 return std::string(projectM_config);
411 440 }
412 441 else
413 void saveSnapshotToFile() 442 {
414 { 443 printf("Using implementation defaults, your system is really messed up, I'm suprised we even got this far\n");
415 char dumpPath[512]; 444 abort();
416 char Home[512]; 445 }
417 //char *home; 446 }
418 447
419 SDL_Surface * bitmap; 448 }
420 449
421 GLint viewport[4]; 450 abort();
422 long bytewidth; 451 }
423 GLint width, height;
424 long bytes;
425
426 glReadBuffer(GL_FRONT);
427 glGetIntegerv(GL_VIEWPORT, viewport);
428
429 width = viewport[2];
430 height = viewport[3];
431
432 bytewidth = width * 4;
433 bytewidth = (bytewidth + 3) & ~3;
434 bytes = bytewidth * height;
435
436 /*
437 glFinish();
438 glPixelStorei(GL_PACK_ALIGNMENT, 4);
439 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
440 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
441 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
442 */
443
444
445 bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,0,0,0,0);
446 glReadPixels(0, 0, width, height,
447 GL_BGRA,
448 GL_UNSIGNED_INT_8_8_8_8_REV,
449 bitmap->pixels);
450
451 sprintf(dumpPath, "/.projectM/%.8d.bmp", frame++);
452 // home=getenv("HOME");
453 strcpy(Home, getenv("HOME"));
454 strcpy(Home+strlen(Home), dumpPath);
455 Home[strlen(Home)]='\0';
456 SDL_SaveBMP(bitmap, Home);
457
458 SDL_FreeSurface(bitmap);
459
460
461 }
462