Mercurial > audlegacy-plugins
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 |