2 * Copyright (C) 2004-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program 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
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "vis_milkdrop/Plugin.h"
22 #include "../../addons/include/xbmc_vis_dll.h"
23 #include "XmlDocument.h"
27 CPlugin* g_plugin=NULL;
30 #define PRESETS_DIR "zip://special%3A%2F%2Fxbmc%2Faddons%2Fvisualization.milkdrop%2Fpresets%2F"
32 bool g_UserPackFolder;
33 std::string g_configFile;
35 int lastPresetIndx =0;
36 char lastPresetDir[1024] = "";
37 bool lastLockedStatus = false;
39 // Sets a new preset file or directory and make it active. Also recovers last state of the preset if it is the same as last time
40 void SetPresetDir(const char *pack)
42 int len = strlen(pack);
43 if (len >= 4 && strcmp(pack + len - 4, ".zip") == 0)
46 strcpy(g_plugin->m_szPresetDir, PRESETS_DIR);
47 strcat(g_plugin->m_szPresetDir, pack);
48 strcat(g_plugin->m_szPresetDir, "/");
50 else if (len >= 4 && strcmp(pack + len - 4, ".rar") == 0)
53 strcpy(g_plugin->m_szPresetDir, PRESETS_DIR);
54 strcat(g_plugin->m_szPresetDir, pack);
55 strcat(g_plugin->m_szPresetDir, "/");
60 strcpy(g_plugin->m_szPresetDir, pack);
62 if (strcmp (g_plugin->m_szPresetDir, lastPresetDir) == 0)
64 // If we have a valid last preset state AND the preset file(dir) is the same as last time
65 g_plugin->UpdatePresetList();
66 g_plugin->m_bHoldPreset = lastLockedStatus;
67 g_plugin->m_nCurrentPreset = lastPresetIndx;
68 strcpy(g_plugin->m_szCurrentPresetFile, g_plugin->m_szPresetDir);
69 strcat(g_plugin->m_szCurrentPresetFile, g_plugin->m_pPresetAddr[g_plugin->m_nCurrentPreset]);
70 g_plugin->LoadPreset(g_plugin->m_szCurrentPresetFile, g_plugin->m_fBlendTimeUser);
73 // If it is the first run or a newly chosen preset pack we choose a random preset as first
74 g_plugin->LoadRandomPreset(g_plugin->m_fBlendTimeUser);
81 g_plugin = new CPlugin;
82 g_plugin->PluginPreInitialize(0, 0);
86 extern "C" ADDON_STATUS ADDON_Create(void* hdl, void* props)
89 return ADDON_STATUS_UNKNOWN;
91 VIS_PROPS* visprops = (VIS_PROPS*)props;
92 _mkdir(visprops->profile);
95 if(!g_plugin || !g_plugin->PluginInitialize((LPDIRECT3DDEVICE9)visprops->device, visprops->x, visprops->y, visprops->width, visprops->height, visprops->pixelRatio))
96 return ADDON_STATUS_UNKNOWN;
98 return ADDON_STATUS_NEED_SAVEDSETTINGS; // We need some settings to be saved later before we quit this plugin
101 extern "C" void Start(int iChannels, int iSamplesPerSec, int iBitsPerSample, const char* szSongName)
105 extern "C" void ADDON_Stop()
109 g_plugin->PluginQuit();
115 unsigned char waves[2][512];
117 //-- Audiodata ----------------------------------------------------------------
118 // Called by XBMC to pass new audio data to the vis
119 //-----------------------------------------------------------------------------
120 extern "C" void AudioData(const float* pAudioData, int iAudioDataLength, float *pFreqData, int iFreqDataLength)
125 for (int i=0; i < iAudioDataLength; i+=2)
127 waves[0][ipos] = char (pAudioData[i] * 255.0f);
128 waves[1][ipos] = char (pAudioData[i+1] * 255.0f);
130 if (ipos >= 512) break;
135 extern "C" void Render()
137 g_plugin->PluginRender(waves[0], waves[1]);
141 extern "C" void GetInfo(VIS_INFO* pInfo)
143 pInfo->bWantsFreq = false;
144 pInfo->iSyncDelay = 0;
147 //-- OnAction -----------------------------------------------------------------
148 // Handle XBMC actions such as next preset, lock preset, album art changed etc
149 //-----------------------------------------------------------------------------
150 extern "C" bool OnAction(long flags, const void *param)
153 if (flags == VIS_ACTION_NEXT_PRESET)
155 g_plugin->LoadNextPreset(g_plugin->m_fBlendTimeUser);
158 else if (flags == VIS_ACTION_PREV_PRESET)
160 g_plugin->LoadPreviousPreset(g_plugin->m_fBlendTimeUser);
163 else if (flags == VIS_ACTION_LOAD_PRESET && param)
165 g_plugin->m_nCurrentPreset = *(int *)param;
166 strcpy(g_plugin->m_szCurrentPresetFile, g_plugin->m_szPresetDir); // note: m_szPresetDir always ends with '\'
167 strcat(g_plugin->m_szCurrentPresetFile, g_plugin->m_pPresetAddr[g_plugin->m_nCurrentPreset]);
168 g_plugin->LoadPreset(g_plugin->m_szCurrentPresetFile, g_plugin->m_fBlendTimeUser);
171 else if (flags == VIS_ACTION_LOCK_PRESET)
173 g_plugin->m_bHoldPreset = !g_plugin->m_bHoldPreset;
176 else if (flags == VIS_ACTION_RANDOM_PRESET)
178 g_plugin->LoadRandomPreset(g_plugin->m_fBlendTimeUser);
187 //-- GetPresets ---------------------------------------------------------------
188 // Return a list of presets to XBMC for display
189 //-----------------------------------------------------------------------------
190 extern "C" unsigned int GetPresets(char ***presets)
192 if (!presets || !g_plugin) return 0;
193 *presets = g_plugin->m_pPresetAddr;
194 return g_plugin->m_nPresets;
197 //-- GetPreset ----------------------------------------------------------------
198 // Return the index of the current playing preset
199 //-----------------------------------------------------------------------------
200 extern "C" unsigned GetPreset()
203 return g_plugin->m_nCurrentPreset;
207 //-- IsLocked -----------------------------------------------------------------
208 // Returns true if this add-on use settings
209 //-----------------------------------------------------------------------------
210 extern "C" bool IsLocked()
213 return g_plugin->m_bHoldPreset;
218 //-- Destroy-------------------------------------------------------------------
219 // Do everything before unload of this add-on
220 // !!! Add-on master function !!!
221 //-----------------------------------------------------------------------------
222 extern "C" void ADDON_Destroy()
227 //-- HasSettings --------------------------------------------------------------
228 // Returns true if this add-on use settings
229 // !!! Add-on master function !!!
230 //-----------------------------------------------------------------------------
231 extern "C" bool ADDON_HasSettings()
236 //-- GetStatus ---------------------------------------------------------------
237 // Returns the current Status of this visualisation
238 // !!! Add-on master function !!!
239 //-----------------------------------------------------------------------------
240 extern "C" ADDON_STATUS ADDON_GetStatus()
242 return ADDON_STATUS_OK;
245 //-- GetSettings --------------------------------------------------------------
246 // Return the settings for XBMC to display
247 //-----------------------------------------------------------------------------
249 extern "C" unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet)
254 //-- FreeSettings --------------------------------------------------------------
255 // Free the settings struct passed from XBMC
256 //-----------------------------------------------------------------------------
258 extern "C" void ADDON_FreeSettings()
262 //-- UpdateSetting ------------------------------------------------------------
263 // Handle setting change request from XBMC
264 //-----------------------------------------------------------------------------
265 extern "C" ADDON_STATUS ADDON_SetSetting(const char* id, const void* value)
267 if (!id || !value || !g_plugin)
268 return ADDON_STATUS_UNKNOWN;
270 if (strcmp(id, "###GetSavedSettings") == 0) // We have some settings to be saved in the settings.xml file
272 if (strcmp((char*)value, "0") == 0)
274 strcpy((char*)id, "lastpresetfolder");
275 strcpy((char*)value, g_plugin->m_szPresetDir);
277 if (strcmp((char*)value, "1") == 0)
279 strcpy((char*)id, "lastlockedstatus");
280 strcpy((char*)value, (g_plugin->m_bHoldPreset ? "true" : "false"));
282 if (strcmp((char*)value, "2") == 0)
284 strcpy((char*)id, "lastpresetidx");
285 sprintf ((char*)value, "%i", g_plugin->m_nCurrentPreset);
287 if (strcmp((char*)value, "3") == 0)
289 strcpy((char*)id, "###End");
291 return ADDON_STATUS_OK;
293 // It is now time to set the settings got from xmbc
294 if (strcmp(id, "Use Preset") == 0)
295 OnAction(34, &value);
296 else if (strcmp(id, "Automatic Blend Time") == 0)
297 g_plugin->m_fBlendTimeAuto = (float)(*(int*)value + 1);
298 else if (strcmp(id, "Time Between Presets") == 0)
299 g_plugin->m_fTimeBetweenPresets = (float)(*(int*)value*5 + 5);
300 else if (strcmp(id, "Additional Random Time") == 0)
301 g_plugin->m_fTimeBetweenPresetsRand = (float)(*(int*)value*5 + 5);
302 else if (strcmp(id, "Enable Hard Cuts") == 0)
303 g_plugin->m_bHardCutsDisabled = *(bool*)value == false;
304 else if (strcmp(id, "Loudness Threshold For Hard Cuts") == 0)
305 g_plugin->m_fHardCutLoudnessThresh = (float)(*(int*)value)/5.0f + 1.25f;
306 else if (strcmp(id, "Average Time Between Hard Cuts") == 0)
307 g_plugin->m_fHardCutHalflife = (float)*(int*)value*5 + 5;
308 else if (strcmp(id, "Maximum Refresh Rate") == 0)
309 g_plugin->m_max_fps_fs = *(int*)value*5 + 20;
310 else if (strcmp(id, "Enable Stereo 3d") == 0)
311 g_plugin->m_bAlways3D = *(bool*)value;
312 else if (strcmp(id, "lastlockedstatus") == 0)
313 lastLockedStatus = *(bool*)value;
314 else if (strcmp(id, "lastpresetidx") == 0)
315 lastPresetIndx = *(int*)value;
316 else if (strcmp(id, "lastpresetfolder") == 0)
317 strcpy(lastPresetDir, (char*)value);
318 else if (strcmp(id, "Preset Shuffle Mode") == 0)
319 g_plugin->m_bSequentialPresetOrder = !*(bool*)value;
320 else if (strcmp(id, "Preset Pack") == 0)
322 if (*(int*)value == 0)
324 g_UserPackFolder = false;;
325 SetPresetDir ("WA51-presets(265).zip");
327 else if (*(int*)value == 1)
329 g_UserPackFolder = false;
330 SetPresetDir ("Winamp-presets(436).zip");
332 else if (*(int*)value == 2)
333 g_UserPackFolder = true;
335 else if (strcmp(id, "User Preset Folder") ==0 )
337 if (g_UserPackFolder) SetPresetDir ((char*)value);
340 return ADDON_STATUS_UNKNOWN;
342 return ADDON_STATUS_OK;
345 //-- GetSubModules ------------------------------------------------------------
346 // Return any sub modules supported by this vis
347 //-----------------------------------------------------------------------------
348 extern "C" unsigned int GetSubModules(char ***names)
350 return 0; // this vis supports 0 sub modules