1 /*
2  * projectM -- Milkdrop-esque visualisation SDK
3  * Copyright (C)2003-2007 projectM Team
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  * See 'LICENSE.txt' included within this release
19  *
20  */
21 /**
22  * $Id: projectM.hpp,v 1.1.1.1 2005/12/23 18:05:11 psperl Exp $
23  *
24  * Encapsulation of ProjectM engine
25  *
26  * $Log$
27  */
28 
29 #ifndef _PROJECTM_HPP
30 #define _PROJECTM_HPP
31 
32 #ifdef WIN32
33 #include "dirent.h"
34 #else
35 #include <dirent.h>
36 #endif /** WIN32 */
37 #include <cmath>
38 #include <cstdio>
39 #include <string>
40 #include <cstdlib>
41 #ifndef WIN32
42 #include <unistd.h>
43 #endif
44 #include <sys/types.h>
45 
46 #ifdef __APPLE__
47 //#include <MacWindows.h>
48 //#include <gl.h>
49 //#include <glu.h>
50 #else
51 #ifdef WIN32
52 #include <windows.h>
53 #endif /** WIN32 */
54 
55 #endif /** MACOS */
56 #ifdef WIN322
57 #define inline
58 #endif /** WIN32 */
59 
60 #ifdef WIN32
61 // libs required for win32
62 #pragma comment(lib, "psapi.lib")
63 #pragma comment(lib, "kernel32.lib")
64 #endif /** WIN32 */
65 
66 #include "dlldefs.h"
67 #include "event.h"
68 #include "fatal.h"
69 
70 class PipelineContext;
71 #include "PCM.hpp"
72 class BeatDetect;
73 class PCM;
74 class Func;
75 class Renderer;
76 class Preset;
77 class PresetIterator;
78 class PresetChooser;
79 class PresetLoader;
80 class TimeKeeper;
81 class Pipeline;
82 class RenderItemMatcher;
83 class MasterRenderItemMerge;
84 
85 #include "Common.hpp"
86 
87 #include <memory>
88 #ifdef WIN32
89 #pragma warning (disable:4244)
90 #pragma warning (disable:4305)
91 #endif /** WIN32 */
92 
93 #ifdef __APPLE__2
94 #define inline
95 #endif
96 
97 /** KEEP THIS UP TO DATE! */
98 #define PROJECTM_VERSION "2.0.00"
99 #define PROJECTM_TITLE "projectM 2.0.00"
100 
101 /** Interface types */
102 typedef enum {
103     MENU_INTERFACE,
104     SHELL_INTERFACE,
105     EDITOR_INTERFACE,
106     DEFAULT_INTERFACE,
107     BROWSER_INTERFACE
108   } interface_t;
109 
110 /// A functor class that allows users of this library to specify random preset behavior
111 class RandomizerFunctor {
112 
113    public:
114 	RandomizerFunctor(PresetChooser & chooser) ;
115 	virtual ~RandomizerFunctor();
116    	virtual double operator() (int index);
117    private:
118 	const PresetChooser & m_chooser;
119 };
120 
121 class DLLEXPORT projectM
122 {
123 public:
124 	static const int FLAG_NONE = 0;
125 	static const int FLAG_DISABLE_PLAYLIST_LOAD = 1 << 0;
126 
127     struct Settings {
128         int meshX;
129         int meshY;
130         int fps;
131         int textureSize;
132         int windowWidth;
133         int windowHeight;
134         std::string presetURL;
135         std::string titleFontURL;
136         std::string menuFontURL;
137         std::string datadir;
138         int smoothPresetDuration;
139         int presetDuration;
140         float beatSensitivity;
141         bool aspectCorrection;
142         float easterEgg;
143         bool shuffleEnabled;
144         bool softCutRatingsEnabled;
145 
SettingsprojectM::Settings146         Settings() :
147             meshX(32),
148             meshY(24),
149             fps(35),
150             textureSize(512),
151             windowWidth(512),
152             windowHeight(512),
153             smoothPresetDuration(10),
154             presetDuration(15),
155             beatSensitivity(10.0),
156             aspectCorrection(true),
157             easterEgg(0.0),
158             shuffleEnabled(true),
159             softCutRatingsEnabled(false) {}
160     };
161 
162   projectM(std::string config_file, int flags = FLAG_NONE);
163   projectM(Settings settings, int flags = FLAG_NONE);
164 
165   void projectM_resetGL( int width, int height );
166   void projectM_resetTextures();
167   void projectM_setTitle( std::string title );
168   void renderFrame();
169   unsigned initRenderToTexture();
170   void key_handler( projectMEvent event,
171 		    projectMKeycode keycode, projectMModifier modifier );
172 
173   virtual ~projectM();
174 
175   void changeTextureSize(int size);
176   void changePresetDuration(int seconds);
177   void getMeshSize(int *w, int *h);
178 
settings() const179   const Settings & settings() const {
180 		return _settings;
181   }
182 
183   /// Writes a settings configuration to the specified file
184   static bool writeConfig(const std::string & configFile, const Settings & settings);
185 
186 
187   /// Sets preset iterator position to the passed in index
188   void selectPresetPosition(unsigned int index);
189 
190   /// Plays a preset immediately
191   void selectPreset(unsigned int index, bool hardCut = true);
192 
193   /// Removes a preset from the play list. If it is playing then it will continue as normal until next switch
194   void removePreset(unsigned int index);
195 
196   /// Sets the randomization functor. If set to null, the traversal will move in order according to the playlist
197   void setRandomizer(RandomizerFunctor * functor);
198 
199   /// Tell projectM to play a particular preset when it chooses to switch
200   /// If the preset is locked the queued item will be not switched to until the lock is released
201   /// Subsequent calls to this function effectively nullifies previous calls.
202   void queuePreset(unsigned int index);
203 
204   /// Returns true if a preset is queued up to play next
205   bool isPresetQueued() const;
206 
207   /// Removes entire playlist, The currently loaded preset will end up sticking until new presets are added
208   void clearPlaylist();
209 
210   /// Turn on or off a lock that prevents projectM from switching to another preset
211   void setPresetLock(bool isLocked);
212 
213   /// Returns true if the active preset is locked
214   bool isPresetLocked() const;
215 
216   /// Returns index of currently active preset. In the case where the active
217   /// preset was removed from the playlist, this function will return the element
218   /// before active preset (thus the next in order preset is invariant with respect
219   /// to the removal)
220   bool selectedPresetIndex(unsigned int & index) const;
221 
222   /// Add a preset url to the play list. Appended to bottom. Returns index of preset
223   unsigned int addPresetURL(const std::string & presetURL, const std::string & presetName, const RatingList & ratingList);
224 
225   /// Insert a preset url to the play list at the suggested index.
226   void insertPresetURL(unsigned int index,
227 			       const std::string & presetURL, const std::string & presetName, const RatingList & ratingList);
228 
229   /// Returns true if the selected preset position points to an actual preset in the
230   /// currently loaded playlist
231   bool presetPositionValid() const;
232 
233   /// Returns the url associated with a preset index
234   std::string getPresetURL(unsigned int index) const;
235 
236   /// Returns the preset name associated with a preset index
237   std::string getPresetName ( unsigned int index ) const;
238 
239   void changePresetName ( unsigned int index, std::string name );
240 
241   /// Returns the rating associated with a preset index
242   int getPresetRating (unsigned int index, const PresetRatingType ratingType) const;
243 
244   void changePresetRating (unsigned int index, int rating, const PresetRatingType ratingType);
245 
246   /// Returns the size of the play list
247   unsigned int getPlaylistSize() const;
248 
249   void evaluateSecondPreset();
250 
setShuffleEnabled(bool value)251   inline void setShuffleEnabled(bool value)
252   {
253 	  _settings.shuffleEnabled = value;
254 
255 	/// idea@ call a virtualfunction shuffleChanged()
256   }
257 
258 
isShuffleEnabled() const259   inline bool isShuffleEnabled() const
260   {
261 	return _settings.shuffleEnabled;
262   }
263 
264   /// Occurs when active preset has switched. Switched to index is returned
presetSwitchedEvent(bool isHardCut,size_t index) const265   virtual void presetSwitchedEvent(bool isHardCut, size_t index) const {};
shuffleEnabledValueChanged(bool isEnabled) const266   virtual void shuffleEnabledValueChanged(bool isEnabled) const {};
presetSwitchFailedEvent(bool hardCut,unsigned int index,const std::string & message) const267   virtual void presetSwitchFailedEvent(bool hardCut, unsigned int index, const std::string & message) const {};
268 
269 
270   /// Occurs whenever preset rating has changed via changePresetRating() method
presetRatingChanged(unsigned int index,int rating,PresetRatingType ratingType) const271   virtual void presetRatingChanged(unsigned int index, int rating, PresetRatingType ratingType) const {};
272 
273 
pcm()274   inline PCM * pcm() {
275 	  return _pcm;
276   }
277   void *thread_func(void *vptr_args);
pipelineContext()278   PipelineContext & pipelineContext() { return *_pipelineContext; }
pipelineContext2()279   PipelineContext & pipelineContext2() { return *_pipelineContext2; }
280 
281 
282   void selectPrevious(const bool);
283   void selectNext(const bool);
284   void selectRandom(const bool);
285 
getWindowWidth()286   int getWindowWidth() { return _settings.windowWidth; }
getWindowHeight()287   int getWindowHeight() { return _settings.windowHeight; }
getErrorLoadingCurrentPreset() const288   bool getErrorLoadingCurrentPreset() const { return errorLoadingCurrentPreset; }
289 
290 private:
291   PCM * _pcm;
292   double sampledPresetDuration();
293   BeatDetect * beatDetect;
294   Renderer *renderer;
295   PipelineContext * _pipelineContext;
296   PipelineContext * _pipelineContext2;
297   Settings _settings;
298 
299 
300   int wvw;      //windowed dimensions
301   int wvh;
302 
303   /** Timing information */
304   int mspf;
305   int timed;
306   int timestart;
307   int count;
308   float fpsstart;
309 
310   void readConfig(const std::string &configFile);
311   void readSettings(const Settings &settings);
312   void projectM_init(int gx, int gy, int fps, int texsize, int width, int height);
313   void projectM_reset();
314 
315   void projectM_initengine();
316   void projectM_resetengine();
317 
318   /// Initializes preset loading / management libraries
319   int initPresetTools(int gx, int gy);
320 
321   /// Deinitialize all preset related tools. Usually done before projectM cleanup
322   void destroyPresetTools();
323 
324   void default_key_handler( projectMEvent event, projectMKeycode keycode );
325   /// The current position of the directory iterator
326   PresetIterator * m_presetPos;
327 
328   /// Required by the preset chooser. Manages a loaded preset directory
329   PresetLoader * m_presetLoader;
330 
331   /// Provides accessor functions to choose presets
332   PresetChooser * m_presetChooser;
333 
334   /// Currently loaded preset
335   std::unique_ptr<Preset> m_activePreset;
336 
337   /// Destination preset when smooth preset switching
338   std::unique_ptr<Preset> m_activePreset2;
339 
340   TimeKeeper *timeKeeper;
341 
342   int m_flags;
343 
344   RenderItemMatcher * _matcher;
345   MasterRenderItemMerge * _merger;
346 
347   bool running;
348   bool errorLoadingCurrentPreset;
349 
350   Pipeline* currentPipe;
351 
352   std::string switchPreset(std::unique_ptr<Preset> & targetPreset);
353   void switchPreset(const bool hardCut);
354 
355 
356 
357 };
358 #endif
359