Mercurial > audlegacy-plugins
changeset 3040:f13b61c91ada
go back to the SDL version
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Tue, 14 Apr 2009 14:47:25 -0500 |
parents | f856ff6a0055 |
children | d6fa54737096 |
files | src/projectm-1.0/ConfigFile.cxx src/projectm-1.0/ConfigFile.h src/projectm-1.0/Makefile src/projectm-1.0/gtk_projectm_impl.cxx src/projectm-1.0/gtk_projectm_impl.h src/projectm-1.0/main.cxx src/projectm-1.0/main_visplugin.c src/projectm-1.0/sdltoprojectM.h src/projectm-1.0/video_init.cxx src/projectm-1.0/video_init.h |
diffstat | 10 files changed, 1137 insertions(+), 344 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/projectm-1.0/ConfigFile.cxx Tue Apr 14 14:47:25 2009 -0500 @@ -0,0 +1,142 @@ +// ConfigFile.cpp + +#include "ConfigFile.h" + +using std::string; + +ConfigFile::ConfigFile( string filename, string delimiter, + string comment, string sentry ) + : myDelimiter(delimiter), myComment(comment), mySentry(sentry) +{ + // Construct a ConfigFile, getting keys and values from given file + + std::ifstream in( filename.c_str() ); + + if( !in ) throw file_not_found( filename ); + + in >> (*this); +} + + +ConfigFile::ConfigFile() + : myDelimiter( string(1,'=') ), myComment( string(1,'#') ) +{ + // Construct a ConfigFile without a file; empty +} + + +void ConfigFile::remove( const string& key ) +{ + // Remove key and its value + myContents.erase( myContents.find( key ) ); + return; +} + + +bool ConfigFile::keyExists( const string& key ) const +{ + // Indicate whether key is found + mapci p = myContents.find( key ); + return ( p != myContents.end() ); +} + + +/* static */ +void ConfigFile::trim( string& s ) +{ + // Remove leading and trailing whitespace + static const char whitespace[] = " \n\t\v\r\f"; + s.erase( 0, s.find_first_not_of(whitespace) ); + s.erase( s.find_last_not_of(whitespace) + 1U ); +} + + +std::ostream& operator<<( std::ostream& os, const ConfigFile& cf ) +{ + // Save a ConfigFile to os + for( ConfigFile::mapci p = cf.myContents.begin(); + p != cf.myContents.end(); + ++p ) + { + os << p->first << " " << cf.myDelimiter << " "; + os << p->second << std::endl; + } + return os; +} + + +std::istream& operator>>( std::istream& is, ConfigFile& cf ) +{ + // Load a ConfigFile from is + // Read in keys and values, keeping internal whitespace + typedef string::size_type pos; + const string& delim = cf.myDelimiter; // separator + const string& comm = cf.myComment; // comment + const string& sentry = cf.mySentry; // end of file sentry + const pos skip = delim.length(); // length of separator + + string nextline = ""; // might need to read ahead to see where value ends + + while( is || nextline.length() > 0 ) + { + // Read an entire line at a time + string line; + if( nextline.length() > 0 ) + { + line = nextline; // we read ahead; use it now + nextline = ""; + } + else + { + std::getline( is, line ); + } + + // Ignore comments + line = line.substr( 0, line.find(comm) ); + + // Check for end of file sentry + if( sentry != "" && line.find(sentry) != string::npos ) return is; + + // Parse the line if it contains a delimiter + pos delimPos = line.find( delim ); + if( delimPos < string::npos ) + { + // Extract the key + string key = line.substr( 0, delimPos ); + line.replace( 0, delimPos+skip, "" ); + + // See if value continues on the next line + // Stop at blank line, next line with a key, end of stream, + // or end of file sentry + bool terminate = false; + while( !terminate && is ) + { + std::getline( is, nextline ); + terminate = true; + + string nlcopy = nextline; + ConfigFile::trim(nlcopy); + if( nlcopy == "" ) continue; + + nextline = nextline.substr( 0, nextline.find(comm) ); + if( nextline.find(delim) != string::npos ) + continue; + if( sentry != "" && nextline.find(sentry) != string::npos ) + continue; + + nlcopy = nextline; + ConfigFile::trim(nlcopy); + if( nlcopy != "" ) line += "\n"; + line += nextline; + terminate = false; + } + + // Store key and value + ConfigFile::trim(key); + ConfigFile::trim(line); + cf.myContents[key] = line; // overwrites if key is repeated + } + } + + return is; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/projectm-1.0/ConfigFile.h Tue Apr 14 14:47:25 2009 -0500 @@ -0,0 +1,253 @@ +// ConfigFile.h +// Class for reading named values from configuration files +// Richard J. Wagner v2.1 24 May 2004 wagnerr@umich.edu + +// Copyright (c) 2004 Richard J. Wagner +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +// Typical usage +// ------------- +// +// Given a configuration file "settings.inp": +// atoms = 25 +// length = 8.0 # nanometers +// name = Reece Surcher +// +// Named values are read in various ways, with or without default values: +// ConfigFile config( "settings.inp" ); +// int atoms = config.read<int>( "atoms" ); +// double length = config.read( "length", 10.0 ); +// string author, title; +// config.readInto( author, "name" ); +// config.readInto( title, "title", string("Untitled") ); +// +// See file example.cpp for more examples. + +#ifndef CONFIGFILE_H +#define CONFIGFILE_H + +#include <string> +#include <map> +#include <iostream> +#include <fstream> +#include <sstream> + +using std::string; + +class ConfigFile { +// Data +protected: + string myDelimiter; // separator between key and value + string myComment; // separator between value and comments + string mySentry; // optional string to signal end of file + std::map<string,string> myContents; // extracted keys and values + + typedef std::map<string,string>::iterator mapi; + typedef std::map<string,string>::const_iterator mapci; + +// Methods +public: + ConfigFile( string filename, + string delimiter = "=", + string comment = "#", + string sentry = "EndConfigFile" ); + ConfigFile(); + + // Search for key and read value or optional default value + template<class T> T read( const string& key ) const; // call as read<T> + template<class T> T read( const string& key, const T& value ) const; + template<class T> bool readInto( T& var, const string& key ) const; + template<class T> + bool readInto( T& var, const string& key, const T& value ) const; + + // Modify keys and values + template<class T> void add( string key, const T& value ); + void remove( const string& key ); + + // Check whether key exists in configuration + bool keyExists( const string& key ) const; + + // Check or change configuration syntax + string getDelimiter() const { return myDelimiter; } + string getComment() const { return myComment; } + string getSentry() const { return mySentry; } + string setDelimiter( const string& s ) + { string old = myDelimiter; myDelimiter = s; return old; } + string setComment( const string& s ) + { string old = myComment; myComment = s; return old; } + + // Write or read configuration + friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf ); + friend std::istream& operator>>( std::istream& is, ConfigFile& cf ); + +protected: + template<class T> static string T_as_string( const T& t ); + template<class T> static T string_as_T( const string& s ); + static void trim( string& s ); + + +// Exception types +public: + struct file_not_found { + string filename; + file_not_found( const string& filename_ = string() ) + : filename(filename_) {} }; + struct key_not_found { // thrown only by T read(key) variant of read() + string key; + key_not_found( const string& key_ = string() ) + : key(key_) {} }; +}; + + +/* static */ +template<class T> +string ConfigFile::T_as_string( const T& t ) +{ + // Convert from a T to a string + // Type T must support << operator + std::ostringstream ost; + ost << t; + return ost.str(); +} + + +/* static */ +template<class T> +T ConfigFile::string_as_T( const string& s ) +{ + // Convert from a string to a T + // Type T must support >> operator + T t; + std::istringstream ist(s); + ist >> t; + return t; +} + + +/* static */ +template<> +inline string ConfigFile::string_as_T<string>( const string& s ) +{ + // Convert from a string to a string + // In other words, do nothing + return s; +} + + +/* static */ +template<> +inline bool ConfigFile::string_as_T<bool>( const string& s ) +{ + // Convert from a string to a bool + // Interpret "false", "F", "no", "n", "0" as false + // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true + bool b = true; + string sup = s; + for( string::iterator p = sup.begin(); p != sup.end(); ++p ) + *p = toupper(*p); // make string all caps + if( sup==string("FALSE") || sup==string("F") || + sup==string("NO") || sup==string("N") || + sup==string("0") || sup==string("NONE") ) + b = false; + return b; +} + + +template<class T> +T ConfigFile::read( const string& key ) const +{ + // Read the value corresponding to key + mapci p = myContents.find(key); + if( p == myContents.end() ) throw key_not_found(key); + return string_as_T<T>( p->second ); +} + + +template<class T> +T ConfigFile::read( const string& key, const T& value ) const +{ + // Return the value corresponding to key or given default value + // if key is not found + mapci p = myContents.find(key); + if( p == myContents.end() ) return value; + return string_as_T<T>( p->second ); +} + + +template<class T> +bool ConfigFile::readInto( T& var, const string& key ) const +{ + // Get the value corresponding to key and store in var + // Return true if key is found + // Otherwise leave var untouched + mapci p = myContents.find(key); + bool found = ( p != myContents.end() ); + if( found ) var = string_as_T<T>( p->second ); + return found; +} + + +template<class T> +bool ConfigFile::readInto( T& var, const string& key, const T& value ) const +{ + // Get the value corresponding to key and store in var + // Return true if key is found + // Otherwise set var to given default + mapci p = myContents.find(key); + bool found = ( p != myContents.end() ); + if( found ) + var = string_as_T<T>( p->second ); + else + var = value; + return found; +} + + +template<class T> +void ConfigFile::add( string key, const T& value ) +{ + // Add a key with given value + string v = T_as_string( value ); + trim(key); + trim(v); + myContents[key] = v; + return; +} + +#endif // CONFIGFILE_H + +// Release notes: +// v1.0 21 May 1999 +// + First release +// + Template read() access only through non-member readConfigFile() +// + ConfigurationFileBool is only built-in helper class +// +// v2.0 3 May 2002 +// + Shortened name from ConfigurationFile to ConfigFile +// + Implemented template member functions +// + Changed default comment separator from % to # +// + Enabled reading of multiple-line values +// +// v2.1 24 May 2004 +// + Made template specializations inline to avoid compiler-dependent linkage +// + Allowed comments within multiple-line values +// + Enabled blank line termination for multiple-line values +// + Added optional sentry to detect end of configuration file +// + Rewrote messy trimWhitespace() function as elegant trim()
--- a/src/projectm-1.0/Makefile Tue Apr 14 09:39:10 2009 +0200 +++ b/src/projectm-1.0/Makefile Tue Apr 14 14:47:25 2009 -0500 @@ -1,7 +1,9 @@ PLUGIN = projectm-1.0${PLUGIN_SUFFIX} -SRCS = gtk_projectm_impl.cxx \ - main.c +SRCS = main.cxx \ + video_init.cxx \ + ConfigFile.cxx \ + main_visplugin.c include ../../buildsys.mk include ../../extra.mk @@ -10,5 +12,5 @@ CFLAGS += ${PLUGIN_CFLAGS} CXXFLAGS += ${PLUGIN_CFLAGS} -CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MOWGLI_CFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${ARCH_DEFINES} ${XML_CPPFLAGS} ${GTKGLEXT_CFLAGS} ${LIBPROJECTM1_CFLAGS} -I../.. -LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${GTKGLEXT_LIBS} ${LIBPROJECTM1_LIBS} +CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MOWGLI_CFLAGS} ${DBUS_CFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${PANGO_CFLAGS} ${ARCH_DEFINES} ${XML_CPPFLAGS} ${SDL_CFLAGS} ${LIBPROJECTM1_CFLAGS} -I../../intl -I../.. +LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${PANGO_LIBS} ${SDL_LIBS} ${LIBPROJECTM1_LIBS}
--- a/src/projectm-1.0/gtk_projectm_impl.cxx Tue Apr 14 09:39:10 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,313 +0,0 @@ -/* - * gtk_projectm_impl.cxx: GTK+ ProjectM Implementation. - * Copyright (c) 2008 William Pitcock <nenolod@sacredspiral.co.uk> - * Portions copyright (c) 2004-2006 Peter Sperl - * - * This program is free software; you may distribute it under the terms - * of the GNU General Public License; version 2. - */ - -#include <stdio.h> -#include <string.h> -#include <string> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <gtk/gtk.h> -#include <gtk/gtkgl.h> - -#include "gtk_projectm_impl.h" - -#include <math.h> - -#include <libprojectM/projectM.hpp> -#include <libprojectM/event.h> - -#include <GL/gl.h> -#define CONFIG_FILE "/share/projectM/config.inp" - -// Forward declarations -static std::string read_config(); - -int SDLThreadWrapper(void *); -void handle_playback_trigger(void *, void *); - -static void _gtk_projectm_realize_impl(GtkWidget *widget, gpointer data); -static gboolean _gtk_projectm_redraw_impl(GtkWidget *widget); -static gboolean _gtk_projectm_expose_impl(GtkWidget *widget, GdkEventExpose *event, gpointer data); -static gboolean _gtk_projectm_configure_impl(GtkWidget *widget, GdkEventConfigure *event, gpointer data); -static void _gtk_projectm_destroy_impl(GtkWidget *widget); - -struct _GtkProjectMPrivate { - projectM *pm; - GdkGLConfig *glconfig; - GtkWidget *drawing_area; - gint idle_id; - GTimer *timer; - gint frames; -}; - -extern "C" GtkWidget * -gtk_projectm_new(void) -{ - struct _GtkProjectMPrivate *priv = g_slice_new0(struct _GtkProjectMPrivate); - - gtk_gl_init(NULL, NULL); - - priv->glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode) (GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE)); - if (!priv->glconfig) - return NULL; - - priv->drawing_area = gtk_drawing_area_new(); - gtk_widget_set_size_request(priv->drawing_area, 512, 512); - gtk_widget_set_gl_capability(priv->drawing_area, priv->glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); - gtk_widget_add_events(priv->drawing_area, GDK_VISIBILITY_NOTIFY_MASK); - - g_signal_connect_after(G_OBJECT(priv->drawing_area), "realize", - G_CALLBACK(_gtk_projectm_realize_impl), priv); - g_signal_connect(G_OBJECT(priv->drawing_area), "expose_event", - G_CALLBACK(_gtk_projectm_expose_impl), priv); - g_signal_connect(G_OBJECT(priv->drawing_area), "destroy", - G_CALLBACK(_gtk_projectm_destroy_impl), priv); - - priv->timer = g_timer_new(); - priv->frames = 0; - - g_object_set_data(G_OBJECT(priv->drawing_area), "GtkProjectMPrivate", priv); - - return priv->drawing_area; -} - -extern "C" void -gtk_projectm_add_pcm_data(GtkWidget *widget, gint16 pcm_data[2][512]) -{ - struct _GtkProjectMPrivate *priv = (struct _GtkProjectMPrivate *) g_object_get_data(G_OBJECT(widget), "GtkProjectMPrivate"); - - g_return_if_fail(priv != NULL); - g_return_if_fail(priv->pm != NULL); - - priv->pm->pcm()->addPCM16(pcm_data); -} - -extern "C" void -gtk_projectm_toggle_preset_lock(GtkWidget *widget) -{ - struct _GtkProjectMPrivate *priv = (struct _GtkProjectMPrivate *) g_object_get_data(G_OBJECT(widget), "GtkProjectMPrivate"); - - g_return_if_fail(priv != NULL); - g_return_if_fail(priv->pm != NULL); - - priv->pm->key_handler(PROJECTM_KEYDOWN, PROJECTM_K_l, PROJECTM_KMOD_LSHIFT); -} - -extern "C" void -gtk_projectm_preset_prev(GtkWidget *widget) -{ - struct _GtkProjectMPrivate *priv = (struct _GtkProjectMPrivate *) g_object_get_data(G_OBJECT(widget), "GtkProjectMPrivate"); - - g_return_if_fail(priv != NULL); - g_return_if_fail(priv->pm != NULL); - - priv->pm->key_handler(PROJECTM_KEYDOWN, PROJECTM_K_p, PROJECTM_KMOD_LSHIFT); -} - -extern "C" void -gtk_projectm_preset_next(GtkWidget *widget) -{ - struct _GtkProjectMPrivate *priv = (struct _GtkProjectMPrivate *) g_object_get_data(G_OBJECT(widget), "GtkProjectMPrivate"); - - g_return_if_fail(priv != NULL); - g_return_if_fail(priv->pm != NULL); - - priv->pm->key_handler(PROJECTM_KEYDOWN, PROJECTM_K_n, PROJECTM_KMOD_LSHIFT); -} - -static void -_gtk_projectm_realize_impl(GtkWidget *widget, gpointer data) -{ - GdkGLContext *glcontext = gtk_widget_get_gl_context(widget); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget); - struct _GtkProjectMPrivate *priv = (struct _GtkProjectMPrivate *) data; - - if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) - return; - - std::string configFile = read_config(); - priv->pm = new projectM(configFile); - priv->pm->projectM_resetGL(widget->allocation.width, widget->allocation.height); - - gdk_gl_drawable_swap_buffers(gldrawable); - gdk_gl_drawable_gl_end(gldrawable); - - g_signal_connect(G_OBJECT(widget), "configure_event", - G_CALLBACK(_gtk_projectm_configure_impl), priv); - - priv->idle_id = g_timeout_add (1000 / 30, - (GSourceFunc) _gtk_projectm_redraw_impl, - priv->drawing_area); -} - -static gboolean -_gtk_projectm_configure_impl(GtkWidget *widget, GdkEventConfigure *event, gpointer data) -{ - GdkGLContext *glcontext = gtk_widget_get_gl_context(widget); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget); - struct _GtkProjectMPrivate *priv = (struct _GtkProjectMPrivate *) data; - - if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) - return FALSE; - - priv->pm->projectM_resetGL(widget->allocation.width, widget->allocation.height); - - gdk_gl_drawable_swap_buffers(gldrawable); - gdk_gl_drawable_gl_end(gldrawable); - - return TRUE; -} - -static gboolean -_gtk_projectm_expose_impl(GtkWidget *widget, GdkEventExpose *event, gpointer data) -{ - GdkGLContext *glcontext = gtk_widget_get_gl_context(widget); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget); - struct _GtkProjectMPrivate *priv = (struct _GtkProjectMPrivate *) data; - - if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) - return FALSE; - - priv->pm->renderFrame(); - priv->frames++; - - gdk_gl_drawable_swap_buffers(gldrawable); - gdk_gl_drawable_gl_end(gldrawable); - - gdouble seconds = g_timer_elapsed (priv->timer, NULL); - if (seconds >= 5.0) - { - gdouble fps = priv->frames / seconds; - g_print ("%d frames in %6.3f seconds = %6.3f FPS\n", priv->frames, seconds, fps); - g_timer_reset (priv->timer); - priv->frames = 0; - } - - return TRUE; -} - -static gboolean -_gtk_projectm_redraw_impl(GtkWidget *widget) -{ - gdk_window_invalidate_rect(widget->window, &widget->allocation, FALSE); - - return TRUE; -} - -static void -_gtk_projectm_destroy_impl(GtkWidget *widget) -{ - struct _GtkProjectMPrivate *priv = (struct _GtkProjectMPrivate *) g_object_get_data(G_OBJECT(widget), "GtkProjectMPrivate"); - - if (priv->idle_id) - g_source_remove(priv->idle_id); - - delete priv->pm; - g_free(priv->timer); - g_slice_free(struct _GtkProjectMPrivate, priv); -} - -/******************************************************************************** - * XXX: This code is from projectM and still needs to be rewritten! * - ********************************************************************************/ -static 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(); - } - } - - } - - abort(); -}
--- a/src/projectm-1.0/gtk_projectm_impl.h Tue Apr 14 09:39:10 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * gtk_projectm_impl.h: GTK+ ProjectM Implementation. - * Copyright (c) 2008 William Pitcock <nenolod@sacredspiral.co.uk> - * Portions copyright (c) 2004-2006 Peter Sperl - * - * This program is free software; you may distribute it under the terms - * of the GNU General Public License; version 2. - */ - -#include <stdio.h> -#include <string.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <gtk/gtk.h> -#include <gtk/gtkgl.h> - -G_BEGIN_DECLS - -GtkWidget *gtk_projectm_new(void); -void gtk_projectm_add_pcm_data(GtkWidget *widget, gint16 pcm_data[2][512]); -void gtk_projectm_toggle_preset_lock(GtkWidget *widget); -void gtk_projectm_preset_prev(GtkWidget *widget); -void gtk_projectm_preset_next(GtkWidget *widget); - -G_END_DECLS
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/projectm-1.0/main.cxx Tue Apr 14 14:47:25 2009 -0500 @@ -0,0 +1,462 @@ +/* +projectM v1.01 - xmms-projectm.sourceforge.net +-------------------------------------------------- + +Lead Developers: Carmelo Piccione (carmelo.piccione@gmail.com) & + Peter Sperl (peter@sperl.com) + +We have also been advised by some professors at CMU, namely Roger B. Dannenberg. +http://www-2.cs.cmu.edu/~rbd/ + +The inspiration for this program was Milkdrop by Ryan Geiss. Obviously. + +This code is distributed under the GPL. + + +THANKS FOR THE CODE!!! +------------------------------------------------- +The base for this program was andy@nobugs.org's XMMS plugin tutorial +http://www.xmms.org/docs/vis-plugin.html + +We used some FFT code by Takuya OOURA instead of XMMS' built-in fft code +fftsg.c - http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html + +and some beat detection code was inspired by Frederic Patin @ +www.gamedev.net/reference/programming/features/beatdetection/ + +*/ + +#include <stdio.h> +#include <string.h> +#include <string> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <SDL/SDL.h> +#include <SDL/SDL_thread.h> + +extern "C" { +#include <audacious/util.h> +#include <audacious/plugin.h> +#include <audacious/auddrct.h> +} + +#include <math.h> +#include "ConfigFile.h" + +#include <libprojectM/projectM.hpp> + +#include "sdltoprojectM.h" +#include "video_init.h" + +#include <GL/gl.h> +#define CONFIG_FILE "/share/projectM/config.inp" + +// Forward declarations +extern "C" void projectM_xmms_init(void); +extern "C" void projectM_cleanup(void); +extern "C" void projectM_about(void); +extern "C" void projectM_configure(void); +extern "C" void projectM_playback_start(void); +extern "C" void projectM_playback_stop(void); +extern "C" void projectM_render_pcm(gint16 pcm_data[2][512]); +extern "C" void projectM_render_freq(gint16 pcm_data[2][256]); +extern "C" int worker_func(void*); +std::string read_config(); +void saveSnapshotToFile(); + +extern "C" VisPlugin projectM_vtable; + +//extern preset_t * active_preset; + +//FILE * debugFile = fopen("./dwrite-dump", "wb"); + +// Our worker thread +SDL_Thread *worker_thread = NULL; +SDL_sem *sem = NULL; +SDL_Event event; + +SDL_Surface *screen; + + +projectM * globalPM = NULL; + +int maxsamples=512; + +int texsize=512; +int gx=32,gy=24; +int wvw=400,wvh=400; +int fvw=1024,fvh=768; +int fps=35, fullscreen=0; + +// char *title; + +gint disable_projectm(void *something) { + projectM_vtable.disable_plugin(&projectM_vtable); + return 0; +} + +Uint32 get_xmms_title(Uint32 something, void *somethingelse) { + static char check_title = 1; + static int last_pos; + static char *last_title = NULL; + int pos; + char *title = NULL; + + //Nice optimization, but we want the title no matter what so I can display it when the song changes +#if 0 + if(!(globalPM->showtitle%2)) { + /* Repeat less often when not showing title */ + return 1000; + } +#endif + + pos = audacious_drct_pl_get_pos(); + /* Only check every 1 second for title change, otherwise check pos */ + if(check_title || pos != last_pos) { + title = audacious_drct_pl_get_title(pos); + if(title && (!last_title || strcmp(last_title,title))) { + //globalPM->renderer->title = title; + //globalPM->renderer->drawtitle = 1; + + std::string titlepp(title); + globalPM->projectM_setTitle(titlepp); + g_free(last_title); + last_title = title; + } else if(title && last_title != title) { + /* New copy of last title */ + g_free(title); + } + check_title = !check_title; + } + last_pos = pos; + /* Repeat every 500ms */ + return 500; +} + +int capture = 0; + +int worker_func(void*) +{ +// char projectM_data[1024]; + SDL_TimerID title_timer = NULL; + std::string config_file; + config_file = read_config(); + ConfigFile config(config_file); + + int wvw = config.read<int>( "Window Width", 512 ); + int wvh = config.read<int>( "Window Height", 512 ); + + int fullscreen = 0; + if (config.read("Fullscreen", true)) fullscreen = 1; + else fullscreen = 0; + + init_display(wvw,wvh,&fvw,&fvh,fullscreen); + SDL_WM_SetCaption("projectM v1.00", "projectM v1.00"); + + /** Initialise projectM */ + + globalPM = new projectM(config_file); + SDL_SemPost(sem); + title_timer = SDL_AddTimer(500, get_xmms_title, NULL); + /** Initialise the thread */ + // SDL_SemTryWait(sem); + while ( SDL_SemValue(sem)==1 ) { + projectMEvent evt; + projectMKeycode key; + projectMModifier mod; + + /** Process SDL events */ + SDL_Event event; + while ( SDL_PollEvent( &event ) ) { + /** Translate into projectM codes and process */ + evt = sdl2pmEvent( event ); + + key = sdl2pmKeycode( event.key.keysym.sym ); + mod = sdl2pmModifier( event.key.keysym.mod ); + + if ( evt == PROJECTM_KEYDOWN ) { + + if(key == PROJECTM_K_c) + { + //SDL_SaveBMP(screen, "/home/pete/1.bmp"); + saveSnapshotToFile(); + } + if(key == PROJECTM_K_v) + { + // capture++; + } + if(key == PROJECTM_K_f) + { + + + int w, h; + if (fullscreen == 0) { + w = fvw; + h = fvh; + fullscreen = 1; + } else { + w = wvw; + h = wvh; + fullscreen = 0; + } + + resize_display(w, h, fullscreen); + globalPM->projectM_resetGL( w, h ); + } + else globalPM->key_handler(evt,key,mod); + + } + else if ( evt == PROJECTM_VIDEORESIZE ) + { + + + + wvw=event.resize.w; + wvh=event.resize.h; + + + resize_display(wvw,wvh,fullscreen); + globalPM->projectM_resetGL( wvw, wvh ); + + } + else if ( evt == PROJECTM_VIDEOQUIT ) { + + (void) g_idle_add ((GSourceFunc) disable_projectm, NULL); + } + } + + /** Add the waveform data */ + + + /** Render the new frame */ + // strcpy(title,xmms_remote_get_playlist_title(projectM_vtable.xmms_session, xmms_remote_get_playlist_pos(projectM_vtable.xmms_session))); + + //printf("%s\n",title); + // strcpy(globalPM->title,title); + + globalPM->renderFrame(); + + + + SDL_GL_SwapBuffers(); + + if (capture % 2 == 1) saveSnapshotToFile(); + // SDL_SemPost(sem); + } + + if(title_timer) + SDL_RemoveTimer(title_timer); + delete globalPM; + + + return 0; +} + +extern "C" void projectM_xmms_init(void) +{ + + /* First, initialize SDL's video subsystem. */ + // std::cerr << "sdl init begin" << std::endl; + if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0 ) { + /* Failed, exit. */ + fprintf( stderr, "Video initialization failed: %s\n", + SDL_GetError( ) ); + //projectM_vtable.disable_plugin (&projectM_vtable); + return; + + } + sem = SDL_CreateSemaphore(0); + // printf("projectM plugin: Initializing\n"); + + SDL_EnableUNICODE(1); + + worker_thread = SDL_CreateThread ( *worker_func, NULL); + +} + + + +extern "C" void projectM_cleanup(void) +{ + + if(!sem) return; + SDL_SemWait(sem); + if(worker_thread) SDL_WaitThread(worker_thread, NULL); + // SDL_KillThread(worker_thread); + //printf("killed thread\n"); + + SDL_DestroySemaphore(sem); + //printf("Destroy Mutex\n"); + SDL_Quit(); + + sem = NULL; + worker_thread = NULL; + + // printf("projectM plugin: Cleanup completed\n"); +} +extern "C" void projectM_about(void) +{ + printf("projectM plugin: About\n"); +} +extern "C" void projectM_configure(void) +{ + printf("projectM plugin: Configure\n"); +} +extern "C" void projectM_playback_start(void) +{//thread_control = GO; + printf("projectM plugin: Playback starting\n"); +} +extern "C" void projectM_playback_stop(void) +{//thread_control = STOP; + printf("projectM plugin: Playback stopping\n"); +} +extern "C" void projectM_render_pcm(gint16 pcm_data[2][512]) +{ + //SDL_mutexP(mutex); while ( SDL_SemValue(sem)==1 ) + if ( SDL_SemValue(sem)==1 ) + globalPM->pcm()->addPCM16(pcm_data); + + //SDL_mutexV(mutex); + +} + +extern "C" void projectM_render_freq(gint16 freq_data[2][256]) +{ + printf("NO GOOD\n"); + } + +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();} + } + + } + + abort(); +} + +int frame = 1; + + +void saveSnapshotToFile() +{ + char dumpPath[512]; + char Home[512]; + //char *home; + + SDL_Surface * bitmap; + + GLint viewport[4]; + long bytewidth; + GLint width, height; + long bytes; + + glReadBuffer(GL_FRONT); + glGetIntegerv(GL_VIEWPORT, viewport); + + width = viewport[2]; + height = viewport[3]; + + bytewidth = width * 4; + bytewidth = (bytewidth + 3) & ~3; + bytes = bytewidth * height; + + /* + glFinish(); + glPixelStorei(GL_PACK_ALIGNMENT, 4); + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + */ + + + bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,0,0,0,0); + glReadPixels(0, 0, width, height, + GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, + bitmap->pixels); + + sprintf(dumpPath, "/.projectM/%.8d.bmp", frame++); + // home=getenv("HOME"); + strcpy(Home, getenv("HOME")); + strcpy(Home+strlen(Home), dumpPath); + Home[strlen(Home)]='\0'; + SDL_SaveBMP(bitmap, Home); + + SDL_FreeSurface(bitmap); + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/projectm-1.0/main_visplugin.c Tue Apr 14 14:47:25 2009 -0500 @@ -0,0 +1,28 @@ +#include <audacious/plugin.h> + +extern void projectM_xmms_init(void); +extern void projectM_cleanup(void); +extern void projectM_about(void); +extern void projectM_configure(void); +extern void projectM_playback_start(void); +extern void projectM_playback_stop(void); +extern void projectM_render_pcm(gint16 pcm_data[2][512]); +extern void projectM_render_freq(gint16 pcm_data[2][256]); + +VisPlugin projectM_vtable = { + .description = "projectM v1.0", + .num_pcm_chs_wanted = 2, + .init = projectM_xmms_init, + .cleanup = projectM_cleanup, + .about = projectM_about, + .configure = projectM_configure, + .playback_start = projectM_playback_start, + .playback_stop = projectM_playback_stop, + .render_pcm = projectM_render_pcm, + .render_freq = projectM_render_freq, +}; + +VisPlugin *projectM_vplist[] = { &projectM_vtable, NULL }; + +DECLARE_PLUGIN(projectm, NULL, NULL, NULL, NULL, NULL, NULL, + projectM_vplist, NULL);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/projectm-1.0/sdltoprojectM.h Tue Apr 14 14:47:25 2009 -0500 @@ -0,0 +1,148 @@ +/** + * $Id: sdltoprojectM.h,v 1.1.1.1 2005/12/23 18:42:00 psperl Exp $ + * + * Translates SDL -> projectM variables + * + * $Log: sdltoprojectM.h,v $ + * Revision 1.1.1.1 2005/12/23 18:42:00 psperl + * Initial Import + * + * Revision 1.1 2004/10/08 00:35:28 cvs + * Moved and imported + * + * Revision 1.1.1.1 2004/10/04 12:56:00 cvs + * Imported + * + */ + +#ifndef _SDLTOPROJECTM_H +#define _SDLTOPROJECTM_H + +#include "libprojectM/event.h" +#ifdef WIN32 +#include <SDL.h> +#else +#include <SDL/SDL.h> +#endif + +projectMEvent sdl2pmEvent( SDL_Event event ) { \ + + switch ( event.type ) { \ + case SDL_VIDEORESIZE: + return PROJECTM_VIDEORESIZE; \ + case SDL_KEYUP: \ + return PROJECTM_KEYUP; \ + case SDL_KEYDOWN: \ + return PROJECTM_KEYDOWN; \ + case SDL_QUIT: \ + return PROJECTM_VIDEOQUIT; \ + default: + return PROJECTM_KEYUP; \ + } \ + } \ + +projectMKeycode sdl2pmKeycode( SDLKey keysym ) { \ + switch ( keysym ) { \ + case SDLK_F1: \ + return PROJECTM_K_F1; \ + case SDLK_F2: \ + return PROJECTM_K_F2; \ + case SDLK_F3: \ + return PROJECTM_K_F3; \ + case SDLK_F4: \ + return PROJECTM_K_F4; \ + case SDLK_F5: \ + return PROJECTM_K_F5; \ + case SDLK_F6: \ + return PROJECTM_K_F6; \ + case SDLK_F7: \ + return PROJECTM_K_F7; \ + case SDLK_F8: \ + return PROJECTM_K_F8; \ + case SDLK_F9: \ + return PROJECTM_K_F9; \ + case SDLK_F10: \ + return PROJECTM_K_F10; \ + case SDLK_F11: \ + return PROJECTM_K_F11; \ + case SDLK_F12: \ + return PROJECTM_K_F12; \ + case SDLK_ESCAPE: \ + return PROJECTM_K_ESCAPE; + case SDLK_a: + return PROJECTM_K_a; + case SDLK_b: + return PROJECTM_K_b; + case SDLK_c: + return PROJECTM_K_c; + case SDLK_d: + return PROJECTM_K_d; + case SDLK_e: + return PROJECTM_K_e; + case SDLK_f: + return PROJECTM_K_f; + case SDLK_g: + return PROJECTM_K_g; + case SDLK_h: + return PROJECTM_K_h; + case SDLK_i: + return PROJECTM_K_i; + case SDLK_j: + return PROJECTM_K_j; + case SDLK_k: + return PROJECTM_K_k; + case SDLK_l: + return PROJECTM_K_l; + case SDLK_m: + return PROJECTM_K_m; + case SDLK_n: + return PROJECTM_K_n; + case SDLK_o: + return PROJECTM_K_o; + case SDLK_p: + return PROJECTM_K_p; + case SDLK_q: + return PROJECTM_K_q; + case SDLK_r: + return PROJECTM_K_r; + case SDLK_s: + return PROJECTM_K_s; + case SDLK_t: + return PROJECTM_K_t; + case SDLK_u: + return PROJECTM_K_u; + case SDLK_v: + return PROJECTM_K_v; + case SDLK_w: + return PROJECTM_K_w; + case SDLK_x: + return PROJECTM_K_x; + case SDLK_y: + return PROJECTM_K_y; + case SDLK_z: + return PROJECTM_K_z; + case SDLK_UP: + return PROJECTM_K_UP; + case SDLK_RETURN: + return PROJECTM_K_RETURN; + case SDLK_RIGHT: + return PROJECTM_K_RIGHT; + case SDLK_LEFT: + return PROJECTM_K_LEFT; + case SDLK_DOWN: + return PROJECTM_K_DOWN; + case SDLK_PAGEUP: + return PROJECTM_K_PAGEUP; + case SDLK_PAGEDOWN: + return PROJECTM_K_PAGEDOWN; + + default: \ + return PROJECTM_K_NONE; \ + } \ + } \ + +projectMModifier sdl2pmModifier( SDLMod mod ) { \ + return PROJECTM_KMOD_LSHIFT; \ + } \ + +#endif /** _SDLTOPROJECTM_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/projectm-1.0/video_init.cxx Tue Apr 14 14:47:25 2009 -0500 @@ -0,0 +1,93 @@ +//video_init.c - SDL/Opengl Windowing Creation/Resizing Functions +// +//by Peter Sperl +// +//Opens an SDL Window and creates an OpenGL session +//also able to handle resizing and fullscreening of windows +//just call init_display again with differant variables + +#include <SDL/SDL.h> +#include <GL/gl.h> +#include <GL/glu.h> +#include "video_init.h" +#include <iostream> +extern SDL_Surface *screen; +extern int texsize; + +void resize_display(int w, int h, int f) { + int flags; + if (f) flags = SDL_OPENGL|SDL_HWSURFACE|SDL_FULLSCREEN; + else flags = SDL_OPENGL|SDL_HWSURFACE|SDL_RESIZABLE; +// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( w, h, 0, flags ) ; + if(screen == 0 ) { + fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) ); + return; + } + + SDL_ShowCursor(f ? SDL_DISABLE : SDL_ENABLE); +} + +//init_display +// +//Sets screen to new width and height (w,h) +//Also switches between fullscreen and windowed +//with the boolean f (fullscreen) +void init_display(int w, int h, int *fvw, int *fvh, int f) +{ + + /* Information about the current video settings. */ + const SDL_VideoInfo* info = NULL; + int bpp = 0; + /* Flags we will pass into SDL_SetVideoMode. */ + int flags = 0; + + + /* Let's get some video information. */ + info = SDL_GetVideoInfo( ); + if( !info ) { + /* This should probably never happen. */ + fprintf( stderr, "Video query failed: %s\n", + SDL_GetError( ) ); + // projectM_vtable.disable_plugin (&projectM_vtable); + return; + } + +// printf("Screen Resolution: %d x %d\n", info->current_w, info->current_h); +// XXX + *fvw = w; + *fvh = h; + bpp = info->vfmt->BitsPerPixel; + //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_ACCUM_RED_SIZE, 8 ); + // SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 8 ); + // SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + if (f==0) + flags = SDL_OPENGL|SDL_HWSURFACE|SDL_RESIZABLE; + else flags = SDL_OPENGL|SDL_HWSURFACE|SDL_FULLSCREEN; + screen= SDL_SetVideoMode( w, h, bpp, flags ) ; + if(screen == 0 ) { + /* + * This could happen for a variety of reasons, + * including DISPLAY not being set, the specified + * resolution not being available, etc. + */ + fprintf( stderr, "Video mode set failed: %s\n", + SDL_GetError( ) ); + + // projectM_vtable.disable_plugin (&projectM_vtable); + return; + + } + + // setup_opengl(w,h); + //gluOrtho2D(0, w, 0, h); +} + +