#include #include #include #include #include #include #include #include #include #include #include #include #include "lvtoprojectM.h" #include "ConfigFile.h" #define CONFIG_FILE "/share/projectM/config.inp" std::string read_config(); int texsize=512; int gx=32,gy=24; int wvw=512,wvh=512; int fvw=1024,fvh=768; int fps=30, fullscreen=0; /* Private context sensitive data goes here, */ typedef struct { projectM *PM; } ProjectmPrivate; extern "C" int lv_projectm_init (VisPluginData *plugin); extern "C" int lv_projectm_cleanup (VisPluginData *plugin); extern "C" int lv_projectm_requisition (VisPluginData *plugin, int *width, int *height); extern "C" int lv_projectm_dimension (VisPluginData *plugin, VisVideo *video, int width, int height); extern "C" int lv_projectm_events (VisPluginData *plugin, VisEventQueue *events); extern "C" VisPalette *lv_projectm_palette (VisPluginData *plugin); extern "C" int lv_projectm_render (VisPluginData *plugin, VisVideo *video, VisAudio *audio); VISUAL_PLUGIN_API_VERSION_VALIDATOR /* Main plugin stuff */ /* The get_plugin_info function provides the libvisual plugin registry, and plugin loader * with the very basic plugin information */ extern "C" const VisPluginInfo *get_plugin_info (int *count) { /* Initialize the plugin specific data structure * with pointers to the functions that represent * the plugin interface it's implementation, more info: * http://libvisual.sourceforge.net/newdocs/docs/html/struct__VisActorPlugin.html */ static VisActorPlugin actor[1]; static VisPluginInfo info[1]; actor[0].requisition = lv_projectm_requisition; actor[0].palette = lv_projectm_palette; actor[0].render = lv_projectm_render; actor[0].vidoptions.depth = VISUAL_VIDEO_DEPTH_GL; /* We want GL clearly */ info[0].type = (char*)VISUAL_PLUGIN_TYPE_ACTOR; info[0].plugname = (char*)"projectM"; info[0].name = (char*)"libvisual projectM"; info[0].author = (char*)"Peter Sperl"; info[0].version = (char*)"1.1"; info[0].about = (char*)"projectM"; info[0].help = (char*)""; info[0].init = lv_projectm_init; info[0].cleanup = lv_projectm_cleanup; info[0].events = lv_projectm_events; info[0].plugin = VISUAL_OBJECT (&actor[0]); *count = sizeof (info) / sizeof (*info); VISUAL_VIDEO_ATTRIBUTE_OPTIONS_GL_ENTRY(actor[0].vidoptions, VISUAL_GL_ATTRIBUTE_ALPHA_SIZE, 8); VISUAL_VIDEO_ATTRIBUTE_OPTIONS_GL_ENTRY(actor[0].vidoptions, VISUAL_GL_ATTRIBUTE_DEPTH_SIZE, 16); VISUAL_VIDEO_ATTRIBUTE_OPTIONS_GL_ENTRY(actor[0].vidoptions, VISUAL_GL_ATTRIBUTE_DOUBLEBUFFER, 1); VISUAL_VIDEO_ATTRIBUTE_OPTIONS_GL_ENTRY(actor[0].vidoptions, VISUAL_GL_ATTRIBUTE_RED_SIZE, 8); VISUAL_VIDEO_ATTRIBUTE_OPTIONS_GL_ENTRY(actor[0].vidoptions, VISUAL_GL_ATTRIBUTE_GREEN_SIZE, 8); VISUAL_VIDEO_ATTRIBUTE_OPTIONS_GL_ENTRY(actor[0].vidoptions, VISUAL_GL_ATTRIBUTE_BLUE_SIZE, 8); return info; } /* This function is called before we really start rendering, it's the init function */ extern "C" int lv_projectm_init (VisPluginData *plugin) { char projectM_data[1024]; ProjectmPrivate *priv; std::string config_file; config_file = read_config(); ConfigFile config(config_file); wvw = config.read( "Window Width", 512 ); wvh = config.read( "Window Height", 512 ); fullscreen = 0; /* Allocate the projectm private data structure, and register it as a private */ priv = new ProjectmPrivate; visual_mem_set (priv, 0, sizeof (ProjectmPrivate)); //priv = visual_mem_new0 (ProjectmPrivate, 1); visual_object_set_private (VISUAL_OBJECT (plugin), priv); //FIXME priv->PM = new projectM(config_file); //globalPM = (projectM *)wipemalloc( sizeof( projectM ) ); return 0; } extern "C" int lv_projectm_cleanup (VisPluginData *plugin) { ProjectmPrivate *priv = (ProjectmPrivate*)visual_object_get_private (VISUAL_OBJECT (plugin)); /* Cleanup, and thus also free our private */ visual_mem_free (priv->PM); visual_mem_free (priv); return 0; } /* This is used to ask a plugin if it can handle a certain size, and if not, to * set the size it wants by putting a value in width, height that represents the * required size */ extern "C" int lv_projectm_requisition (VisPluginData *plugin, int *width, int *height) { int reqw, reqh; /* Size negotiate with the window */ reqw = *width; reqh = *height; if (reqw < 64) reqw = 64; if (reqh < 64) reqh = 64; *width = reqw; *height = reqh; return 0; } extern "C" int lv_projectm_dimension (VisPluginData *plugin, VisVideo *video, int width, int height) { ProjectmPrivate *priv = (ProjectmPrivate*)visual_object_get_private (VISUAL_OBJECT (plugin)); visual_video_set_dimension (video, width, height); priv->PM->projectM_resetGL( width, height ); return 0; } /* This is the main event loop, where all kind of events can be handled, more information * regarding these can be found at: * http://libvisual.sourceforge.net/newdocs/docs/html/union__VisEvent.html */ extern "C" int lv_projectm_events (VisPluginData *plugin, VisEventQueue *events) { ProjectmPrivate *priv = (ProjectmPrivate*)visual_object_get_private (VISUAL_OBJECT (plugin)); VisEvent ev; VisParamEntry *param; projectMEvent evt; projectMKeycode key; projectMModifier mod; while (visual_event_queue_poll (events, &ev)) { switch (ev.type) { case VISUAL_EVENT_KEYUP: evt = lv2pmEvent( ev.type ); key = lv2pmKeycode( ev.event.keyboard.keysym.sym ); mod = lv2pmModifier( ev.event.keyboard.keysym.mod ); priv->PM->key_handler(PROJECTM_KEYDOWN, key,mod); break; case VISUAL_EVENT_RESIZE: lv_projectm_dimension (plugin, ev.event.resize.video, ev.event.resize.width, ev.event.resize.height); break; case VISUAL_EVENT_NEWSONG: priv->PM->projectM_setTitle(ev.event.newsong.songinfo->songname); break; default: /* to avoid warnings */ break; } } return 0; } /* Using this function we can update the palette when we're in 8bits mode, which * we aren't with projectm, so just ignore :) */ extern "C" VisPalette *lv_projectm_palette (VisPluginData *plugin) { return (VisPalette *) NULL; } /* This is where the real rendering happens! This function is what we call, many times * a second to get our graphical frames. */ extern "C" int lv_projectm_render (VisPluginData *plugin, VisVideo *video, VisAudio *audio) { ProjectmPrivate *priv = (ProjectmPrivate*)visual_object_get_private (VISUAL_OBJECT (plugin)); VisBuffer pcmb; float pcm[2][512]; int i; if (video->parent != NULL) lv_projectm_dimension (plugin, video->parent, video->parent->width, video->parent->height); else lv_projectm_dimension (plugin, video, video->width, video->height); visual_buffer_set_data_pair (&pcmb, pcm[0], sizeof (pcm[0])); visual_audio_get_sample (audio, &pcmb, (char*)VISUAL_AUDIO_CHANNEL_LEFT); visual_buffer_set_data_pair (&pcmb, pcm[1], sizeof (pcm[1])); visual_audio_get_sample (audio, &pcmb, (char*)VISUAL_AUDIO_CHANNEL_RIGHT); priv->PM->pcm()->addPCMfloat(*pcm,512); priv->PM->renderFrame(); return 0; } std::string read_config() { int n; char num[512]; FILE *in; FILE *out; char* home; char projectM_home[1024]; char projectM_config[1024]; strcpy(projectM_config, PROJECTM_PREFIX); strcpy(projectM_config+strlen(PROJECTM_PREFIX), CONFIG_FILE); projectM_config[strlen(PROJECTM_PREFIX)+strlen(CONFIG_FILE)]='\0'; printf("dir:%s \n",projectM_config); home=getenv("HOME"); strcpy(projectM_home, home); strcpy(projectM_home+strlen(home), "/.projectM/config.inp"); projectM_home[strlen(home)+strlen("/.projectM/config.inp")]='\0'; if ((in = fopen(projectM_home, "r")) != 0) { printf("reading ~/.projectM/config.inp \n"); fclose(in); return std::string(projectM_home); } else { printf("trying to create ~/.projectM/config.inp \n"); strcpy(projectM_home, home); strcpy(projectM_home+strlen(home), "/.projectM"); projectM_home[strlen(home)+strlen("/.projectM")]='\0'; mkdir(projectM_home,0755); strcpy(projectM_home, home); strcpy(projectM_home+strlen(home), "/.projectM/config.inp"); projectM_home[strlen(home)+strlen("/.projectM/config.inp")]='\0'; if((out = fopen(projectM_home,"w"))!=0) { if ((in = fopen(projectM_config, "r")) != 0) { while(fgets(num,80,in)!=NULL) { fputs(num,out); } fclose(in); fclose(out); if ((in = fopen(projectM_home, "r")) != 0) { printf("created ~/.projectM/config.inp successfully\n"); fclose(in); return std::string(projectM_home); } else{printf("This shouldn't happen, using implementation defualts\n");abort();} } else{printf("Cannot find projectM default config, using implementation defaults\n");abort();} } else { printf("Cannot create ~/.projectM/config.inp, using default config file\n"); if ((in = fopen(projectM_config, "r")) != 0) { printf("Successfully opened default config file\n"); fclose(in); return std::string(projectM_config);} else{ printf("Using implementation defaults, your system is really messed up, I'm suprised we even got this far\n"); abort();} } } }