mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-10 05:35:48 +00:00
git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/trunk@1355 6778bc44-b910-0410-a7a0-be141de4315d
324 lines
9.2 KiB
C++
324 lines
9.2 KiB
C++
#include <iostream>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <string>
|
|
#include <math.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <libvisual/libvisual.h>
|
|
#include <projectM.hpp>
|
|
#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<int>( "Window Width", 512 );
|
|
wvh = config.read<int>( "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();}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|