mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-08 12:15:33 +00:00
Preset subdirs (#385)
Scanning textures/presets dirs for textures and scanning preset dir for presets. Scanning is now done recursively, so presets and textures can be organized into subdirectories instead of needing to be flattened into a single directory. On POSIX systems makes use of [ftw](https://linux.die.net/man/3/ftw) which should be relatively efficient. Otherwise falls back to recursing with `dirent` (for windows). Probably should have made an autoconf check for `ftw` instead of doing `#ifdef WIN32`. * Scan subdirectories in presets directory * remove preset subdir config * Recursively scan for textures too, add c++-17 compatibility * Refactor directory scanning code so it's reused by texture loader and preset loader. Make cross-platform (maybe) * filescanner in makefile * extension filter for file loader * make extensions match up' * need string.h * Add FileScanner.cpp to win build (maybe) * scan all dirs * #ifndef #ifdef is def fun * bogus comment * bleh * bleh * itunes plugin with c++17 * EyeTunes needs to know about the FileScanner Co-authored-by: milkdropper.com <milkdropper.com@gmail.com> Co-authored-by: milkdropper <59471060+milkdropper@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
e51b2c7d63
commit
e49720ecfa
@ -11,7 +11,6 @@ CLEANFILES=dist
|
||||
# aka /usr/local/share/projectM
|
||||
pm_data_dir = $(pkgdatadir)
|
||||
pm_font_dir = $(pm_data_dir)/fonts
|
||||
pm_presets_dir = $(pm_data_dir)/presets
|
||||
|
||||
# files to install
|
||||
pm_data__DATA = src/libprojectM/config.inp
|
||||
@ -19,13 +18,8 @@ pm_font__DATA = fonts/Vera.ttf fonts/VeraMono.ttf
|
||||
|
||||
# find and install all preset files
|
||||
install-data-local:
|
||||
if ENABLE_PRESET_SUBDIRS
|
||||
find "$(PRESETSDIR)" -type d -exec $(MKDIR_P) "$(DESTDIR)/$(pm_data_dir)/{}" \;
|
||||
find "$(PRESETSDIR)" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)/$(pm_data_dir)/{}" \;
|
||||
else
|
||||
test -z $(DESTDIR)$(pkgdatadir) || $(MKDIR_P) $(DESTDIR)$(pm_presets_dir)
|
||||
find "$(PRESETSDIR)" -type f -print0 | LC_ALL=C sort -z | xargs -0 '-I{}' $(INSTALL_DATA) '{}' $(DESTDIR)$(pm_presets_dir)
|
||||
endif
|
||||
|
||||
# from https://stackoverflow.com/questions/30897170/ac-subst-does-not-expand-variable answer: https://stackoverflow.com/a/30960268
|
||||
# ptomato https://stackoverflow.com/users/172999/ptomato
|
||||
|
||||
10
configure.ac
10
configure.ac
@ -32,7 +32,6 @@ AS_IF([test "x$enable_emscripten" = "xyes" || test "x$EMSCRIPTEN" = "xyes"], [
|
||||
enable_threading=no
|
||||
enable_gles=yes
|
||||
enable_sdl=yes
|
||||
enable_preset_subdirs=no
|
||||
], [
|
||||
dnl Running in a normal OS (not emscripten)
|
||||
AX_CHECK_GL
|
||||
@ -127,13 +126,6 @@ AC_ARG_ENABLE([gles],
|
||||
AC_DEFINE([USE_GLES], [1], [Define USE_GLES])
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE([preset_subdirs],
|
||||
AS_HELP_STRING([--enable-preset-subdirs], [Organize presets into subdirectories.]),
|
||||
[], [enable_preset_subdirs=no])
|
||||
AS_IF([test "x$enable_preset_subdirs" = "xyes"], [
|
||||
AC_DEFINE([ENABLE_PRESET_SUBDIRS], [1], [Define ENABLE_PRESET_SUBDIRS])
|
||||
])
|
||||
|
||||
dnl LLVM
|
||||
dnl unfortuately AX_LLVM macro seems to be out of date, so we're going to rely on the user to make sure LLVM is installed correctly
|
||||
AC_ARG_ENABLE([llvm],
|
||||
@ -228,7 +220,6 @@ AM_CONDITIONAL([ENABLE_QT], [test "x$enable_qt" = "xyes"])
|
||||
AM_CONDITIONAL([ENABLE_JACK], [test "x$enable_jack" = "xyes"])
|
||||
AM_CONDITIONAL([ENABLE_PULSEAUDIO], [test "x$enable_pulseaudio" = "xyes"])
|
||||
AM_CONDITIONAL([ENABLE_EMSCRIPTEN], [test "x$enable_emscripten" = "xyes"])
|
||||
AM_CONDITIONAL([ENABLE_PRESET_SUBDIRS], [test "x$enable_preset_subdirs" = "xyes"])
|
||||
|
||||
|
||||
my_CFLAGS="-Wall -Wchar-subscripts -Wformat-security -Wpointer-arith -Wshadow -Wsign-compare -Wtype-limits"
|
||||
@ -277,5 +268,4 @@ Jack: ${enable_jack}
|
||||
OpenGLES: ${enable_gles}
|
||||
Emscripten: ${enable_emscripten}
|
||||
llvm: ${enable_llvm}
|
||||
Preset subdirs: ${enable_preset_subdirs}
|
||||
])
|
||||
|
||||
@ -132,6 +132,7 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)../src\libprojectM\TimeKeeper.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)../src\libprojectM\timer.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)../src\libprojectM\wipemalloc.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)../src\libprojectM\FileScanner.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)../msvc\glew.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)../msvc\glew.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsC</CompileAs>
|
||||
@ -166,4 +167,4 @@
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\libprojectM\MilkdropPresetFactory\PresetFrameIO.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\libprojectM\PresetFactory.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\libprojectM\ConfigFile.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\libprojectM\FileScanner.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\libprojectM\fftsg.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\libprojectM\KeyHandler.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\libprojectM\PCM.cpp" />
|
||||
|
||||
@ -213,7 +213,7 @@ inline std::string parseExtension(const std::string & filename) {
|
||||
const std::size_t start = filename.find_last_of('.');
|
||||
|
||||
if (start == std::string::npos || start >= (filename.length()-1))
|
||||
return "";
|
||||
return {};
|
||||
std::string ext = filename.substr(start+1, filename.length());
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||
return ext;
|
||||
|
||||
180
src/libprojectM/FileScanner.cpp
Normal file
180
src/libprojectM/FileScanner.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
//
|
||||
// FileScanner.cpp
|
||||
// libprojectM
|
||||
//
|
||||
//
|
||||
|
||||
#include "FileScanner.hpp"
|
||||
|
||||
FileScanner::FileScanner() {}
|
||||
|
||||
FileScanner::FileScanner(std::vector<std::string> &rootDirs, std::vector<std::string> &extensions) : _rootDirs(rootDirs), _extensions(extensions) {}
|
||||
|
||||
void FileScanner::scan(ScanCallback cb) {
|
||||
#ifdef WIN32
|
||||
for (auto dir : _rootDirs)
|
||||
scanGeneric(cb, dir.c_str());
|
||||
#else
|
||||
scanPosix(cb);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FileScanner::handleDirectoryError(std::string dir) {
|
||||
#ifdef WIN32
|
||||
std::cerr << "[PresetLoader] warning: errno unsupported on win32 platforms. fix me" << std::endl;
|
||||
#else
|
||||
|
||||
std::cerr << dir << " scan error: ";
|
||||
|
||||
switch ( errno )
|
||||
{
|
||||
case ENOENT:
|
||||
std::cerr << "ENOENT error. The path \"" << dir << "\" probably does not exist. \"man open\" for more info." << std::endl;
|
||||
break;
|
||||
case ENOMEM:
|
||||
std::cerr << "out of memory!" << std::endl;
|
||||
abort();
|
||||
case ENOTDIR:
|
||||
std::cerr << "directory specified is not a directory! Trying to continue..." << std::endl;
|
||||
break;
|
||||
case ENFILE:
|
||||
std::cerr << "Your system has reached its open file limit. Trying to continue..." << std::endl;
|
||||
break;
|
||||
case EMFILE:
|
||||
std::cerr << "too many files in use by projectM! Bailing!" << std::endl;
|
||||
break;
|
||||
case EACCES:
|
||||
std::cerr << "permissions issue reading the specified preset directory." << std::endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string FileScanner::extensionMatches(std::string &filename) {
|
||||
// returns file name without extension
|
||||
// TODO: optimize me
|
||||
|
||||
std::string lowerCaseFileName(filename);
|
||||
std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower);
|
||||
|
||||
// Remove extension
|
||||
for (auto ext : _extensions)
|
||||
{
|
||||
size_t found = lowerCaseFileName.find(ext);
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
std::string name = filename;
|
||||
name.replace(int(found), ext.size(), "");
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
// generic implementation using dirent
|
||||
void FileScanner::scanGeneric(ScanCallback cb, const char *currentDir) {
|
||||
DIR * m_dir;
|
||||
|
||||
// Allocate a new a stream given the current directory name
|
||||
if ((m_dir = opendir(currentDir)) == NULL)
|
||||
{
|
||||
return; // no files found in here
|
||||
}
|
||||
|
||||
struct dirent * dir_entry;
|
||||
|
||||
while ((dir_entry = readdir(m_dir)) != NULL)
|
||||
{
|
||||
// Convert char * to friendly string
|
||||
std::string filename(dir_entry->d_name);
|
||||
|
||||
if (filename.length() > 0 && filename[0] == '.')
|
||||
continue;
|
||||
|
||||
std::string fullPath = std::string(currentDir) + PATH_SEPARATOR + filename;
|
||||
|
||||
if (dir_entry->d_type == DT_DIR) {
|
||||
// recurse into dir
|
||||
scanGeneric(cb, fullPath.c_str());
|
||||
continue;
|
||||
} else if (dir_entry->d_type != DT_REG && dir_entry->d_type != DT_LNK) {
|
||||
// not regular file/link
|
||||
continue;
|
||||
}
|
||||
|
||||
auto nameMatched = extensionMatches(filename);
|
||||
if (! nameMatched.empty())
|
||||
cb(fullPath, nameMatched);
|
||||
}
|
||||
|
||||
if (m_dir)
|
||||
{
|
||||
closedir(m_dir);
|
||||
m_dir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
// more optimized posix "fts" directory traversal
|
||||
int fts_compare(const FTSENT** one, const FTSENT** two) {
|
||||
return (strcmp((*one)->fts_name, (*two)->fts_name));
|
||||
}
|
||||
#endif
|
||||
|
||||
void FileScanner::scanPosix(ScanCallback cb) {
|
||||
#ifndef WIN32
|
||||
|
||||
// efficient directory traversal
|
||||
FTS* fileSystem = NULL;
|
||||
FTSENT *node = NULL;
|
||||
|
||||
// list of directories to scan
|
||||
auto rootDirCount = _rootDirs.size();
|
||||
char **dirList = (char **)malloc(sizeof(char*) * (rootDirCount + 1));
|
||||
for (unsigned long i = 0; i < rootDirCount; i++) {
|
||||
dirList[i] = (char *) _rootDirs[i].c_str();
|
||||
}
|
||||
dirList[rootDirCount] = NULL;
|
||||
|
||||
// initialize file hierarchy traversal
|
||||
fileSystem = fts_open(dirList, FTS_LOGICAL|FTS_NOCHDIR|FTS_NOSTAT, &fts_compare);
|
||||
if (fileSystem == NULL) {
|
||||
std::string s;
|
||||
for (int i = 0; i < _rootDirs.size(); i++)
|
||||
s += _rootDirs[i] + ' ';
|
||||
handleDirectoryError(s);
|
||||
|
||||
free(dirList);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string path, name, nameMatched;
|
||||
|
||||
// traverse dirList
|
||||
while( (node = fts_read(fileSystem)) != NULL) {
|
||||
switch (node->fts_info) {
|
||||
case FTS_F:
|
||||
case FTS_SL:
|
||||
case FTS_NSOK:
|
||||
// found a file
|
||||
path = std::string(node->fts_path);
|
||||
name = std::string(node->fts_name);
|
||||
|
||||
// check extension
|
||||
nameMatched = extensionMatches(name);
|
||||
if (! nameMatched.empty())
|
||||
cb(path, nameMatched);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
fts_close(fileSystem);
|
||||
free(dirList);
|
||||
|
||||
#endif
|
||||
}
|
||||
60
src/libprojectM/FileScanner.hpp
Normal file
60
src/libprojectM/FileScanner.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// FileScanner.hpp
|
||||
// libprojectM
|
||||
//
|
||||
// Cross-platform directory traversal with filtering by extension
|
||||
|
||||
#ifndef FileScanner_hpp
|
||||
#define FileScanner_hpp
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include "Common.hpp"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "dirent.h"
|
||||
#else
|
||||
#include <fts.h>
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
extern "C"
|
||||
{
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
extern "C"
|
||||
{
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef std::function<void (std::string &path, std::string &name)> ScanCallback;
|
||||
|
||||
class FileScanner {
|
||||
public:
|
||||
FileScanner();
|
||||
FileScanner(std::vector<std::string> &rootDirs, std::vector<std::string> &extensions);
|
||||
|
||||
void scan(ScanCallback cb);
|
||||
std::string extensionMatches(std::string &filename);
|
||||
|
||||
private:
|
||||
std::vector<std::string> _rootDirs;
|
||||
std::vector<std::string> _extensions;
|
||||
|
||||
void scanGeneric(ScanCallback cb, const char *dir);
|
||||
void scanPosix(ScanCallback cb);
|
||||
void handleDirectoryError(std::string dir);
|
||||
};
|
||||
|
||||
|
||||
#endif /* FileScanner_hpp */
|
||||
@ -24,12 +24,12 @@ libprojectM_la_LIBADD = \
|
||||
libprojectM_la_SOURCES = ConfigFile.cpp Preset.cpp PresetLoader.cpp timer.cpp \
|
||||
KeyHandler.cpp PresetChooser.cpp TimeKeeper.cpp PCM.cpp PresetFactory.cpp \
|
||||
fftsg.cpp wipemalloc.cpp PipelineMerger.cpp PresetFactoryManager.cpp projectM.cpp \
|
||||
TestRunner.cpp TestRunner.hpp \
|
||||
TestRunner.cpp TestRunner.hpp FileScanner.cpp FileScanner.hpp\
|
||||
Common.hpp PipelineMerger.hpp PresetLoader.hpp\
|
||||
HungarianMethod.hpp Preset.hpp RandomNumberGenerators.hpp\
|
||||
IdleTextures.hpp PresetChooser.hpp TimeKeeper.hpp\
|
||||
KeyHandler.hpp PresetFactory.hpp projectM.hpp\
|
||||
BackgroundWorker.h \
|
||||
BackgroundWorker.h \
|
||||
PCM.hpp PresetFactoryManager.hpp\
|
||||
projectM.hpp projectM-opengl.h \
|
||||
ConfigFile.h \
|
||||
|
||||
@ -71,7 +71,7 @@ void InitCond::evaluate(bool evalUser)
|
||||
/* WIP */
|
||||
void InitCond::init_cond_to_string()
|
||||
{
|
||||
int string_length;
|
||||
unsigned long string_length;
|
||||
char string[MAX_TOKEN_SIZE];
|
||||
|
||||
/* Create a string "param_name=val" */
|
||||
|
||||
@ -115,9 +115,7 @@ MilkdropPreset::~MilkdropPreset()
|
||||
|
||||
int MilkdropPreset::add_per_pixel_eqn(char * name, Expr * gen_expr)
|
||||
{
|
||||
|
||||
PerPixelEqn * per_pixel_eqn = NULL;
|
||||
int index;
|
||||
Param * param = NULL;
|
||||
|
||||
assert(gen_expr);
|
||||
@ -134,7 +132,7 @@ int MilkdropPreset::add_per_pixel_eqn(char * name, Expr * gen_expr)
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
index = per_pixel_eqn_tree.size();
|
||||
auto index = per_pixel_eqn_tree.size();
|
||||
|
||||
/* Create the per pixel equation given the index, parameter, and general expression */
|
||||
if ((per_pixel_eqn = new PerPixelEqn(index, param, gen_expr)) == NULL)
|
||||
@ -143,8 +141,6 @@ int MilkdropPreset::add_per_pixel_eqn(char * name, Expr * gen_expr)
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Insert the per pixel equation into the preset per pixel database */
|
||||
std::pair<std::map<int, PerPixelEqn*>::iterator, bool> inserteeOption = per_pixel_eqn_tree.insert
|
||||
(std::make_pair(per_pixel_eqn->index, per_pixel_eqn));
|
||||
|
||||
@ -61,16 +61,14 @@ public:
|
||||
|
||||
/// Load a MilkdropPreset by filename with input and output buffers specified.
|
||||
/// \param absoluteFilePath the absolute file path of a MilkdropPreset to load from the file system
|
||||
/// \param MilkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name
|
||||
/// \param MilkdropPresetInputs a reference to read only projectM engine variables
|
||||
/// \param MilkdropPresetOutputs initialized and filled with data parsed from a MilkdropPreset
|
||||
/// \param milkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name
|
||||
/// \param presetOutputs initialized and filled with data parsed from a MilkdropPreset
|
||||
MilkdropPreset(MilkdropPresetFactory *factory, const std::string & absoluteFilePath, const std::string & milkdropPresetName, PresetOutputs & presetOutputs);
|
||||
|
||||
/// Load a MilkdropPreset from an input stream with input and output buffers specified.
|
||||
/// \param in an already initialized input stream to read the MilkdropPreset file from
|
||||
/// \param MilkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name
|
||||
/// \param MilkdropPresetInputs a reference to read only projectM engine variables
|
||||
/// \param MilkdropPresetOutputs initialized and filled with data parsed from a MilkdropPreset
|
||||
/// \param milkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name
|
||||
/// \param presetOutputs initialized and filled with data parsed from a MilkdropPreset
|
||||
MilkdropPreset(MilkdropPresetFactory *factory, std::istream & in, const std::string & milkdropPresetName, PresetOutputs & presetOutputs);
|
||||
|
||||
~MilkdropPreset();
|
||||
@ -110,13 +108,11 @@ public:
|
||||
/// \returns A MilkdropPreset output instance with values computed from most recent evaluateFrame()
|
||||
PresetOutputs & presetOutputs() const
|
||||
{
|
||||
|
||||
return _presetOutputs;
|
||||
}
|
||||
|
||||
const PresetInputs & presetInputs() const
|
||||
{
|
||||
|
||||
return _presetInputs;
|
||||
}
|
||||
|
||||
|
||||
@ -188,8 +188,7 @@ PresetOutputs* MilkdropPresetFactory::createPresetOutputs(int gx, int gy)
|
||||
presetOutputs->bSolarize = 0;
|
||||
presetOutputs->bInvert = 0;
|
||||
presetOutputs->bMotionVectorsOn = 1;
|
||||
|
||||
presetOutputs->fWarpAnimSpeed = 0;
|
||||
presetOutputs->fWarpAnimSpeed = 0;
|
||||
presetOutputs->fWarpScale = 0;
|
||||
presetOutputs->fShader = 0;
|
||||
|
||||
|
||||
@ -21,18 +21,16 @@ class DLLEXPORT PresetInputs;
|
||||
class MilkdropPresetFactory : public PresetFactory {
|
||||
|
||||
public:
|
||||
|
||||
MilkdropPresetFactory(int gx, int gy);
|
||||
|
||||
virtual ~MilkdropPresetFactory();
|
||||
// called by ~MilkdropPreset
|
||||
void releasePreset(Preset *preset);
|
||||
|
||||
std::unique_ptr<Preset> allocate(const std::string & url, const std::string & name = std::string(),
|
||||
const std::string & author = std::string());
|
||||
|
||||
std::string supportedExtensions() const { return "milk prjm"; }
|
||||
|
||||
// called by ~MilkdropPreset
|
||||
void releasePreset(Preset *preset);
|
||||
std::string supportedExtensions() const { return ".milk .prjm"; }
|
||||
|
||||
private:
|
||||
static PresetOutputs* createPresetOutputs(int gx, int gy);
|
||||
@ -40,7 +38,6 @@ private:
|
||||
int gx;
|
||||
int gy;
|
||||
PresetOutputs * _presetOutputsCache;
|
||||
//PresetInputs _presetInputs;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -42,7 +42,7 @@ void PerPixelEqn::evaluate(int mesh_i, int mesh_j)
|
||||
assign_expr->eval( mesh_i, mesh_j );
|
||||
}
|
||||
|
||||
PerPixelEqn::PerPixelEqn(int _index, Param * param, Expr * gen_expr):index(_index)
|
||||
PerPixelEqn::PerPixelEqn(unsigned long _index, Param * param, Expr * gen_expr):index(_index)
|
||||
{
|
||||
assert(index >= 0);
|
||||
assert(param != 0);
|
||||
|
||||
@ -56,7 +56,7 @@ public:
|
||||
void evaluate(int mesh_i, int mesh_j);
|
||||
virtual ~PerPixelEqn();
|
||||
|
||||
PerPixelEqn(int index, Param * param, Expr * gen_expr);
|
||||
PerPixelEqn(unsigned long index, Param * param, Expr * gen_expr);
|
||||
|
||||
Expr *assign_expr;
|
||||
};
|
||||
|
||||
@ -29,7 +29,7 @@ public:
|
||||
virtual std::unique_ptr<Preset> allocate(const std::string & url, const std::string & name = std::string(),
|
||||
const std::string & author = std::string());
|
||||
|
||||
virtual std::string supportedExtensions() const { return "so dylib"; }
|
||||
virtual std::string supportedExtensions() const { return ".so .dylib"; }
|
||||
|
||||
private:
|
||||
PresetLibrary * loadLibrary(const std::string & url);
|
||||
|
||||
@ -81,7 +81,7 @@ void PresetFactoryManager::registerFactory(const std::string & extensions, Prese
|
||||
std::unique_ptr<Preset> PresetFactoryManager::allocate(const std::string & url, const std::string & name)
|
||||
{
|
||||
try {
|
||||
const std::string extension = parseExtension (url);
|
||||
const std::string extension = "." + parseExtension(url);
|
||||
|
||||
return factory(extension).allocate(url, name);
|
||||
} catch (const PresetFactoryException & e) {
|
||||
@ -98,7 +98,7 @@ PresetFactory & PresetFactoryManager::factory(const std::string & extension) {
|
||||
|
||||
if (!extensionHandled(extension)) {
|
||||
std::ostringstream os;
|
||||
os << "No preset factory associated with \"" << extension << "\"." << std::endl;
|
||||
os << "No preset factory associated with \"" << extension << "\"." << std::endl;
|
||||
throw PresetFactoryException(os.str());
|
||||
}
|
||||
return *_factoryMap[extension];
|
||||
@ -107,3 +107,11 @@ PresetFactory & PresetFactoryManager::factory(const std::string & extension) {
|
||||
bool PresetFactoryManager::extensionHandled(const std::string & extension) const {
|
||||
return _factoryMap.count(extension);
|
||||
}
|
||||
|
||||
std::vector<std::string> PresetFactoryManager::extensionsHandled() const {
|
||||
std::vector<std::string> retval;
|
||||
for (auto const& element : _factoryMap) {
|
||||
retval.push_back(element.first);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -49,6 +49,8 @@ class PresetFactoryManager {
|
||||
/// \returns true if a factory exists, false otherwise
|
||||
bool extensionHandled(const std::string & extension) const;
|
||||
std::unique_ptr<Preset> allocate(const std::string & url, const std::string & name);
|
||||
std::vector<std::string> extensionsHandled() const;
|
||||
|
||||
|
||||
private:
|
||||
int _gx, _gy;
|
||||
|
||||
@ -15,29 +15,19 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
|
||||
#ifdef __unix__
|
||||
extern "C"
|
||||
{
|
||||
#include <errno.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
extern "C"
|
||||
{
|
||||
#include <errno.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <cassert>
|
||||
#include "fatal.h"
|
||||
|
||||
#include "Common.hpp"
|
||||
|
||||
PresetLoader::PresetLoader (int gx, int gy, std::string dirname = std::string()) :_dirname ( dirname ), _dir ( 0 )
|
||||
PresetLoader::PresetLoader (int gx, int gy, std::string dirname = std::string()) :_dirname ( dirname )
|
||||
{
|
||||
_presetFactoryManager.initialize(gx,gy);
|
||||
_presetFactoryManager.initialize(gx,gy);
|
||||
|
||||
std::vector<std::string> dirs{_dirname};
|
||||
std::vector<std::string> extensions = _presetFactoryManager.extensionsHandled();
|
||||
fileScanner = FileScanner(dirs, extensions);
|
||||
|
||||
// Do one scan
|
||||
if ( _dirname != std::string() )
|
||||
rescan();
|
||||
@ -45,106 +35,59 @@ PresetLoader::PresetLoader (int gx, int gy, std::string dirname = std::string())
|
||||
clear();
|
||||
}
|
||||
|
||||
PresetLoader::~PresetLoader()
|
||||
{
|
||||
if ( _dir )
|
||||
closedir ( _dir );
|
||||
}
|
||||
PresetLoader::~PresetLoader() {}
|
||||
|
||||
void PresetLoader::setScanDirectory ( std::string dirname )
|
||||
{
|
||||
_dirname = dirname;
|
||||
}
|
||||
|
||||
void PresetLoader::addScannedPresetFile(const std::string &path, const std::string &name) {
|
||||
auto ext = parseExtension(path);
|
||||
if (ext.empty())
|
||||
return;
|
||||
|
||||
ext = "." + ext;
|
||||
|
||||
// Verify extension is projectm or milkdrop
|
||||
if (!_presetFactoryManager.extensionHandled(ext))
|
||||
return;
|
||||
|
||||
// std::cout << "Loading preset file " << path << std::endl;
|
||||
|
||||
_entries.push_back(path);
|
||||
_presetNames.push_back(name + ext);
|
||||
}
|
||||
|
||||
void PresetLoader::rescan()
|
||||
{
|
||||
// std::cerr << "Rescanning..." << std::endl;
|
||||
|
||||
// Clear the directory entry collection
|
||||
clear();
|
||||
|
||||
// Clear the directory entry collection
|
||||
clear();
|
||||
|
||||
// If directory already opened, close it first
|
||||
if ( _dir )
|
||||
{
|
||||
closedir ( _dir );
|
||||
_dir = 0;
|
||||
}
|
||||
|
||||
// Allocate a new a stream given the current directory name
|
||||
if ( ( _dir = opendir ( _dirname.c_str() ) ) == NULL )
|
||||
{
|
||||
handleDirectoryError();
|
||||
return; // no files loaded. _entries is empty
|
||||
}
|
||||
|
||||
struct dirent * dir_entry;
|
||||
std::set<std::string> alphaSortedFileSet;
|
||||
std::set<std::string> alphaSortedPresetNameSet;
|
||||
|
||||
while ( ( dir_entry = readdir ( _dir ) ) != NULL )
|
||||
{
|
||||
if (dir_entry->d_name[0] == 0)
|
||||
continue;
|
||||
|
||||
std::ostringstream out;
|
||||
// Convert char * to friendly string
|
||||
std::string filename ( dir_entry->d_name );
|
||||
|
||||
// Verify extension is projectm or milkdrop
|
||||
if (!_presetFactoryManager.extensionHandled(parseExtension(filename)))
|
||||
continue;
|
||||
|
||||
if ( filename.length() > 0 && filename[0] == '.' )
|
||||
continue;
|
||||
|
||||
// Create full path name
|
||||
out << _dirname << PATH_SEPARATOR << filename;
|
||||
|
||||
// Add to our directory entry collection
|
||||
alphaSortedFileSet.insert ( out.str() );
|
||||
alphaSortedPresetNameSet.insert ( filename );
|
||||
|
||||
// the directory entry struct is freed elsewhere
|
||||
}
|
||||
|
||||
// Push all entries in order from the file set to the file entries member (which is an indexed vector)
|
||||
for ( std::set<std::string>::iterator pos = alphaSortedFileSet.begin();
|
||||
pos != alphaSortedFileSet.end();++pos )
|
||||
_entries.push_back ( *pos );
|
||||
|
||||
// Push all preset names in similar fashion
|
||||
for ( std::set<std::string>::iterator pos = alphaSortedPresetNameSet.begin();
|
||||
pos != alphaSortedPresetNameSet.end();++pos )
|
||||
_presetNames.push_back ( *pos );
|
||||
|
||||
// Give all presets equal rating of 3 - why 3? I don't know
|
||||
_ratings = std::vector<RatingList>(TOTAL_RATING_TYPES, RatingList( _presetNames.size(), 3 ));
|
||||
_ratingsSums = std::vector<int>(TOTAL_RATING_TYPES, 3 * _presetNames.size());
|
||||
|
||||
|
||||
assert ( _entries.size() == _presetNames.size() );
|
||||
|
||||
// scan for presets
|
||||
using namespace std::placeholders;
|
||||
fileScanner.scan(std::bind(&PresetLoader::addScannedPresetFile, this, _1, _2));
|
||||
|
||||
// Give all presets equal rating of 3 - why 3? I don't know
|
||||
_ratings = std::vector<RatingList>(TOTAL_RATING_TYPES, RatingList( _presetNames.size(), 3 ));
|
||||
_ratingsSums = std::vector<int>(TOTAL_RATING_TYPES, 3 *_presetNames.size());
|
||||
|
||||
assert ( _entries.size() == _presetNames.size() );
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Preset> PresetLoader::loadPreset ( unsigned int index ) const
|
||||
std::unique_ptr<Preset> PresetLoader::loadPreset ( PresetIndex index ) const
|
||||
{
|
||||
|
||||
// Check that index isn't insane
|
||||
assert ( index < _entries.size() );
|
||||
return _presetFactoryManager.allocate
|
||||
( _entries[index], _presetNames[index] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Preset> PresetLoader::loadPreset ( const std::string & url ) const
|
||||
{
|
||||
// std::cout << "Loading preset " << url << std::endl;
|
||||
|
||||
try {
|
||||
/// @bug probably should not use url for preset name
|
||||
return _presetFactoryManager.allocate
|
||||
@ -157,40 +100,7 @@ std::unique_ptr<Preset> PresetLoader::loadPreset ( const std::string & url ) co
|
||||
return std::unique_ptr<Preset>();
|
||||
}
|
||||
|
||||
void PresetLoader::handleDirectoryError()
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
std::cerr << "[PresetLoader] warning: errno unsupported on win32 platforms. fix me" << std::endl;
|
||||
#else
|
||||
|
||||
switch ( errno )
|
||||
{
|
||||
case ENOENT:
|
||||
std::cerr << "[PresetLoader] ENOENT error. The path \"" << this->_dirname << "\" probably does not exist. \"man open\" for more info." << std::endl;
|
||||
break;
|
||||
case ENOMEM:
|
||||
std::cerr << "[PresetLoader] out of memory! Are you running Windows?" << std::endl;
|
||||
abort();
|
||||
case ENOTDIR:
|
||||
std::cerr << "[PresetLoader] directory specified is not a preset directory! Trying to continue..." << std::endl;
|
||||
break;
|
||||
case ENFILE:
|
||||
std::cerr << "[PresetLoader] Your system has reached its open file limit. Trying to continue..." << std::endl;
|
||||
break;
|
||||
case EMFILE:
|
||||
std::cerr << "[PresetLoader] too many files in use by projectM! Bailing!" << std::endl;
|
||||
break;
|
||||
case EACCES:
|
||||
std::cerr << "[PresetLoader] permissions issue reading the specified preset directory." << std::endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PresetLoader::setRating(unsigned int index, int rating, const PresetRatingType ratingType)
|
||||
void PresetLoader::setRating(PresetIndex index, int rating, const PresetRatingType ratingType)
|
||||
{
|
||||
const unsigned int ratingTypeIndex = static_cast<unsigned int>(ratingType);
|
||||
assert (index < _ratings[ratingTypeIndex].size());
|
||||
@ -199,11 +109,9 @@ void PresetLoader::setRating(unsigned int index, int rating, const PresetRatingT
|
||||
|
||||
_ratings[ratingTypeIndex][index] = rating;
|
||||
_ratingsSums[ratingType] += rating;
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned int PresetLoader::addPresetURL ( const std::string & url, const std::string & presetName, const std::vector<int> & ratings)
|
||||
unsigned long PresetLoader::addPresetURL ( const std::string & url, const std::string & presetName, const std::vector<int> & ratings)
|
||||
{
|
||||
_entries.push_back(url);
|
||||
_presetNames.push_back ( presetName );
|
||||
@ -220,9 +128,8 @@ unsigned int PresetLoader::addPresetURL ( const std::string & url, const std::st
|
||||
return _entries.size()-1;
|
||||
}
|
||||
|
||||
void PresetLoader::removePreset ( unsigned int index )
|
||||
void PresetLoader::removePreset ( PresetIndex index )
|
||||
{
|
||||
|
||||
_entries.erase ( _entries.begin() + index );
|
||||
_presetNames.erase ( _presetNames.begin() + index );
|
||||
|
||||
@ -230,21 +137,19 @@ void PresetLoader::removePreset ( unsigned int index )
|
||||
_ratingsSums[i] -= _ratings[i][index];
|
||||
_ratings[i].erase ( _ratings[i].begin() + index );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const std::string & PresetLoader::getPresetURL ( unsigned int index ) const
|
||||
const std::string & PresetLoader::getPresetURL ( PresetIndex index ) const
|
||||
{
|
||||
return _entries[index];
|
||||
}
|
||||
|
||||
const std::string & PresetLoader::getPresetName ( unsigned int index ) const
|
||||
const std::string & PresetLoader::getPresetName ( PresetIndex index ) const
|
||||
{
|
||||
return _presetNames[index];
|
||||
}
|
||||
|
||||
int PresetLoader::getPresetRating ( unsigned int index, const PresetRatingType ratingType ) const
|
||||
int PresetLoader::getPresetRating ( PresetIndex index, const PresetRatingType ratingType ) const
|
||||
{
|
||||
return _ratings[ratingType][index];
|
||||
}
|
||||
@ -258,23 +163,19 @@ const std::vector<int> & PresetLoader::getPresetRatingsSums() const {
|
||||
return _ratingsSums;
|
||||
}
|
||||
|
||||
void PresetLoader::setPresetName(unsigned int index, std::string name) {
|
||||
void PresetLoader::setPresetName(PresetIndex index, std::string name) {
|
||||
_presetNames[index] = name;
|
||||
}
|
||||
|
||||
void PresetLoader::insertPresetURL ( unsigned int index, const std::string & url, const std::string & presetName, const RatingList & ratings)
|
||||
void PresetLoader::insertPresetURL ( PresetIndex index, const std::string & url, const std::string & presetName, const RatingList & ratings)
|
||||
{
|
||||
_entries.insert ( _entries.begin() + index, url );
|
||||
_presetNames.insert ( _presetNames.begin() + index, presetName );
|
||||
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < _ratingsSums.size();i++) {
|
||||
_ratingsSums[i] += _ratings[i][index];
|
||||
_ratings[i].insert ( _ratings[i].begin() + index, ratings[i] );
|
||||
}
|
||||
|
||||
assert ( _entries.size() == _presetNames.size() );
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -5,34 +5,18 @@
|
||||
#include <memory> // for auto pointers
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "dirent.h"
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "PresetFactoryManager.hpp"
|
||||
#include "FileScanner.hpp"
|
||||
|
||||
class Preset;
|
||||
class PresetFactory;
|
||||
|
||||
typedef std::size_t PresetIndex;
|
||||
|
||||
class PresetLoader {
|
||||
public:
|
||||
|
||||
|
||||
/// Initializes the preset loader with the target directory specified
|
||||
PresetLoader(int gx, int gy, std::string dirname);
|
||||
|
||||
@ -40,21 +24,21 @@ class PresetLoader {
|
||||
|
||||
/// Load a preset by specifying its unique identifier given when the preset url
|
||||
/// was added to this loader
|
||||
std::unique_ptr<Preset> loadPreset(unsigned int index) const;
|
||||
std::unique_ptr<Preset> loadPreset(PresetIndex index) const;
|
||||
std::unique_ptr<Preset> loadPreset ( const std::string & url ) const;
|
||||
/// Add a preset to the loader's collection.
|
||||
/// \param url an url referencing the preset
|
||||
/// \param presetName a name for the preset
|
||||
/// \param rating an integer representing the goodness of the preset
|
||||
/// \param ratings an list representing the goodness ratings
|
||||
/// \returns The unique index assigned to the preset in the collection. Used with loadPreset
|
||||
unsigned int addPresetURL ( const std::string & url, const std::string & presetName, const RatingList & ratings);
|
||||
unsigned long addPresetURL(const std::string & url, const std::string & presetName, const RatingList & ratings);
|
||||
|
||||
/// Add a preset to the loader's collection.
|
||||
/// \param index insertion index
|
||||
/// \param url an url referencing the preset
|
||||
/// \param presetName a name for the preset
|
||||
/// \param rating an integer representing the goodness of the preset
|
||||
void insertPresetURL (unsigned int index, const std::string & url, const std::string & presetName, const RatingList & ratings);
|
||||
/// \param ratings an list representing the goodness ratings
|
||||
void insertPresetURL (PresetIndex index, const std::string & url, const std::string & presetName, const RatingList & ratings);
|
||||
|
||||
/// Clears all presets from the collection
|
||||
inline void clear() {
|
||||
@ -72,19 +56,19 @@ class PresetLoader {
|
||||
|
||||
/// Removes a preset from the loader
|
||||
/// \param index the unique identifier of the preset url to be removed
|
||||
void removePreset(unsigned int index);
|
||||
void removePreset(PresetIndex index);
|
||||
|
||||
/// Sets the rating of a preset to a new value
|
||||
void setRating(unsigned int index, int rating, const PresetRatingType ratingType);
|
||||
void setRating(PresetIndex index, int rating, const PresetRatingType ratingType);
|
||||
|
||||
/// Get a preset rating given an index
|
||||
int getPresetRating ( unsigned int index, const PresetRatingType ratingType) const;
|
||||
int getPresetRating ( PresetIndex index, const PresetRatingType ratingType) const;
|
||||
|
||||
/// Get a preset url given an index
|
||||
const std::string & getPresetURL ( unsigned int index) const;
|
||||
const std::string & getPresetURL ( PresetIndex index) const;
|
||||
|
||||
/// Get a preset name given an index
|
||||
const std::string & getPresetName ( unsigned int index) const;
|
||||
const std::string & getPresetName ( PresetIndex index) const;
|
||||
|
||||
/// Returns the number of presets in the active directory
|
||||
inline std::size_t size() const {
|
||||
@ -101,11 +85,12 @@ class PresetLoader {
|
||||
|
||||
/// Rescans the active preset directory
|
||||
void rescan();
|
||||
void setPresetName(unsigned int index, std::string name);
|
||||
private:
|
||||
void handleDirectoryError();
|
||||
void setPresetName(PresetIndex index, std::string name);
|
||||
|
||||
protected:
|
||||
void addScannedPresetFile(const std::string &path, const std::string &name);
|
||||
|
||||
std::string _dirname;
|
||||
DIR * _dir;
|
||||
std::vector<int> _ratingsSums;
|
||||
mutable PresetFactoryManager _presetFactoryManager;
|
||||
|
||||
@ -115,8 +100,8 @@ class PresetLoader {
|
||||
|
||||
// Indexed by ratingType, preset position.
|
||||
std::vector<RatingList> _ratings;
|
||||
|
||||
|
||||
|
||||
FileScanner fileScanner;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,29 +1,13 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "projectM-opengl.h"
|
||||
|
||||
#include "SOIL2/SOIL2.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "dirent.h"
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#ifdef EMSCRIPTEN
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include "TextureManager.hpp"
|
||||
#include "Common.hpp"
|
||||
#include "IdleTextures.hpp"
|
||||
#include "Texture.hpp"
|
||||
|
||||
/* OpenGL ES 2.0 cant handle converting textures fro GL_RGB to GL_RGBA via glTexImage2D
|
||||
http://docs.gl/es2/glTexImage2D
|
||||
|
||||
@ -44,8 +28,8 @@ So because of this, we switch to a PerlinNoiseWithAlpha class to generate the no
|
||||
|
||||
|
||||
TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX, const int texsizeY, std::string datadir):
|
||||
presetsURL(_presetsURL)
|
||||
{
|
||||
presetsURL(_presetsURL) {
|
||||
|
||||
extensions.push_back(".jpg");
|
||||
extensions.push_back(".dds");
|
||||
extensions.push_back(".png");
|
||||
@ -53,6 +37,13 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
extensions.push_back(".bmp");
|
||||
extensions.push_back(".dib");
|
||||
|
||||
std::vector<std::string> dirsToScan{datadir + "/presets", datadir + "/textures", _presetsURL};
|
||||
FileScanner fileScanner = FileScanner(dirsToScan, extensions);
|
||||
|
||||
// scan for textures
|
||||
using namespace std::placeholders;
|
||||
fileScanner.scan(std::bind(&TextureManager::loadTexture, this, _1, _2));
|
||||
|
||||
Preload();
|
||||
// if not data directory specified from user code
|
||||
// we use the built-in default directory (unix prefix based)
|
||||
@ -63,10 +54,6 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
datadir = DATADIR_PATH;
|
||||
#endif /** WIN32 */
|
||||
|
||||
loadTextureDir(datadir + "/presets");
|
||||
loadTextureDir(datadir + "/textures");
|
||||
loadTextureDir(_presetsURL);
|
||||
|
||||
// Create main texture ans associated samplers
|
||||
mainTexture = new Texture("main", texsizeX, texsizeY, false);
|
||||
mainTexture->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
@ -233,12 +220,12 @@ TextureSamplerDesc TextureManager::getTexture(const std::string fullName, const
|
||||
// Remove extension
|
||||
std::string lowerCaseFileName(fullName);
|
||||
std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower);
|
||||
for (size_t x = 0; x < extensions.size(); x++)
|
||||
for (auto ext : extensions)
|
||||
{
|
||||
size_t found = lowerCaseFileName.find(extensions[x]);
|
||||
size_t found = lowerCaseFileName.find(ext);
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
fileName.replace(int(found), extensions[x].size(), "");
|
||||
fileName.replace(int(found), ext.size(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -272,25 +259,29 @@ TextureSamplerDesc TextureManager::tryLoadingTexture(const std::string name)
|
||||
|
||||
ExtractTextureSettings(name, wrap_mode, filter_mode, unqualifiedName);
|
||||
|
||||
for (size_t x = 0; x < extensions.size(); x++)
|
||||
for (auto ext : extensions)
|
||||
{
|
||||
std::string filename = unqualifiedName + extensions[x];
|
||||
std::string filename = unqualifiedName + ext;
|
||||
std::string fullURL = presetsURL + PATH_SEPARATOR + filename;
|
||||
|
||||
texDesc = loadTexture(name, fullURL);
|
||||
texDesc = loadTexture(fullURL, name);
|
||||
|
||||
if (texDesc.first != NULL)
|
||||
{
|
||||
std::cerr << "Located texture " << name << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Failed to locate texture " << name << std::endl;
|
||||
|
||||
return texDesc;
|
||||
}
|
||||
|
||||
TextureSamplerDesc TextureManager::loadTexture(const std::string name, const std::string fileName)
|
||||
TextureSamplerDesc TextureManager::loadTexture(const std::string fileName, const std::string name)
|
||||
{
|
||||
int width, height;
|
||||
// std::cout << "Loading texture " << name << " at " << fileName << std::endl;
|
||||
|
||||
unsigned int tex = SOIL_load_OGL_texture(
|
||||
fileName.c_str(),
|
||||
@ -313,64 +304,16 @@ TextureSamplerDesc TextureManager::loadTexture(const std::string name, const std
|
||||
Sampler * sampler = newTexture->getSampler(wrap_mode, filter_mode);
|
||||
|
||||
if (textures.find(name) != textures.end()) {
|
||||
// found duplicate.. this could be optimized
|
||||
delete textures[name];
|
||||
}
|
||||
|
||||
textures[name] = newTexture;
|
||||
// std::cout << "Loaded texture " << name << std::endl;
|
||||
|
||||
return TextureSamplerDesc(newTexture, sampler);
|
||||
}
|
||||
|
||||
|
||||
void TextureManager::loadTextureDir(const std::string &dirname)
|
||||
{
|
||||
DIR * m_dir;
|
||||
|
||||
// Allocate a new a stream given the current directory name
|
||||
if ((m_dir = opendir(dirname.c_str())) == NULL)
|
||||
{
|
||||
// std::cout<<"No Textures Loaded from "<<dirname<<std::endl;
|
||||
return; // no files loaded. m_entries is empty
|
||||
}
|
||||
|
||||
struct dirent * dir_entry;
|
||||
|
||||
while ((dir_entry = readdir(m_dir)) != NULL)
|
||||
{
|
||||
// Convert char * to friendly string
|
||||
std::string filename(dir_entry->d_name);
|
||||
|
||||
if (filename.length() > 0 && filename[0] == '.')
|
||||
continue;
|
||||
|
||||
std::string lowerCaseFileName(filename);
|
||||
std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower);
|
||||
|
||||
// Remove extension
|
||||
for (size_t x = 0; x < extensions.size(); x++)
|
||||
{
|
||||
size_t found = lowerCaseFileName.find(extensions[x]);
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
std::string name = filename;
|
||||
name.replace(int(found), extensions[x].size(), "");
|
||||
|
||||
// Create full path name
|
||||
std::string fullname = dirname + PATH_SEPARATOR + filename;
|
||||
loadTexture(name, fullname);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_dir)
|
||||
{
|
||||
closedir(m_dir);
|
||||
m_dir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
TextureSamplerDesc TextureManager::getRandomTextureName(std::string random_id)
|
||||
{
|
||||
GLint wrap_mode;
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
#include "projectM-opengl.h"
|
||||
#include "Texture.hpp"
|
||||
#include "FileScanner.hpp"
|
||||
|
||||
|
||||
class TextureManager
|
||||
@ -17,7 +18,6 @@ class TextureManager
|
||||
Texture * mainTexture;
|
||||
|
||||
std::vector<std::string> random_textures;
|
||||
void loadTextureDir(const std::string & dirname);
|
||||
TextureSamplerDesc loadTexture(const std::string name, const std::string imageUrl);
|
||||
void ExtractTextureSettings(const std::string qualifiedName, GLint &_wrap_mode, GLint &_filter_mode, std::string & name);
|
||||
std::vector<std::string> extensions;
|
||||
|
||||
@ -57,8 +57,8 @@ void Waveform::Draw(RenderContext &context)
|
||||
std::transform(&value1[0], &value1[samples], &value1[0], bind2nd(std::multiplies<float>(), mult));
|
||||
std::transform(&value2[0], &value2[samples], &value2[0], bind2nd(std::multiplies<float>(), mult));
|
||||
#else
|
||||
std::transform(&value1[0], &value1[samples], &value1[0], std::bind2nd(std::multiplies<float>(), mult));
|
||||
std::transform(&value2[0], &value2[samples], &value2[0], std::bind2nd(std::multiplies<float>(), mult));
|
||||
std::transform(&value1[0], &value1[samples], &value1[0], std::bind(std::multiplies<float>(), std::placeholders::_1, mult));
|
||||
std::transform(&value2[0], &value2[samples], &value2[0], std::bind(std::multiplies<float>(), std::placeholders::_1, mult));
|
||||
#endif /** WIN32 */
|
||||
|
||||
WaveformContext waveContext(samples, context.beatDetect);
|
||||
|
||||
@ -128,6 +128,10 @@
|
||||
1687174A20C33DF400947E7E /* Pipeline.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 1687173520C33DF400947E7E /* Pipeline.hpp */; };
|
||||
1687174B20C33DF400947E7E /* ShaderEngine.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 1687173620C33DF400947E7E /* ShaderEngine.hpp */; };
|
||||
1687174E20C33E1000947E7E /* RenderContext.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 1687174D20C33E1000947E7E /* RenderContext.hpp */; };
|
||||
169BC64724CC4D16007B7829 /* FileScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 169BC64524CC4D16007B7829 /* FileScanner.cpp */; };
|
||||
169BC64824CC4D16007B7829 /* FileScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 169BC64524CC4D16007B7829 /* FileScanner.cpp */; };
|
||||
169BC64924CC4D16007B7829 /* FileScanner.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 169BC64624CC4D16007B7829 /* FileScanner.hpp */; };
|
||||
169BC64A24CC4D16007B7829 /* FileScanner.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 169BC64624CC4D16007B7829 /* FileScanner.hpp */; };
|
||||
16A49E5E207A7CAE00E508EA /* ConfigFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16178ABD207A68A500D3B0C8 /* ConfigFile.cpp */; };
|
||||
16A49E62207A7CAE00E508EA /* fftsg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16178AB5207A68A400D3B0C8 /* fftsg.cpp */; };
|
||||
16A49E69207A7CAE00E508EA /* PCM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16178AC1207A68A600D3B0C8 /* PCM.cpp */; };
|
||||
@ -264,6 +268,8 @@
|
||||
168C689320BB1FE0000AFC1B /* HLSLTree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HLSLTree.cpp; path = Renderer/hlslparser/src/HLSLTree.cpp; sourceTree = "<group>"; };
|
||||
168C689420BB1FE0000AFC1B /* HLSLTokenizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HLSLTokenizer.cpp; path = Renderer/hlslparser/src/HLSLTokenizer.cpp; sourceTree = "<group>"; };
|
||||
168C689520BB1FE0000AFC1B /* CodeWriter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CodeWriter.cpp; path = Renderer/hlslparser/src/CodeWriter.cpp; sourceTree = "<group>"; };
|
||||
169BC64524CC4D16007B7829 /* FileScanner.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FileScanner.cpp; sourceTree = "<group>"; };
|
||||
169BC64624CC4D16007B7829 /* FileScanner.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FileScanner.hpp; sourceTree = "<group>"; };
|
||||
16A49E57207A7C8C00E508EA /* libprojectM.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libprojectM.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -417,6 +423,8 @@
|
||||
16178AB8207A68A500D3B0C8 /* TimeKeeper.cpp */,
|
||||
16178AB6207A68A400D3B0C8 /* timer.cpp */,
|
||||
16178ABC207A68A500D3B0C8 /* wipemalloc.cpp */,
|
||||
169BC64524CC4D16007B7829 /* FileScanner.cpp */,
|
||||
169BC64624CC4D16007B7829 /* FileScanner.hpp */,
|
||||
);
|
||||
name = libProjectM;
|
||||
sourceTree = "<group>";
|
||||
@ -558,6 +566,7 @@
|
||||
1687174E20C33E1000947E7E /* RenderContext.hpp in Headers */,
|
||||
1687174B20C33DF400947E7E /* ShaderEngine.hpp in Headers */,
|
||||
1687173C20C33DF400947E7E /* RenderItemMatcher.hpp in Headers */,
|
||||
169BC64924CC4D16007B7829 /* FileScanner.hpp in Headers */,
|
||||
1687174A20C33DF400947E7E /* Pipeline.hpp in Headers */,
|
||||
1687174120C33DF400947E7E /* Renderer.hpp in Headers */,
|
||||
1687173920C33DF400947E7E /* Renderable.hpp in Headers */,
|
||||
@ -585,6 +594,7 @@
|
||||
1612CA0F207A878900862A3A /* resource.h in Headers */,
|
||||
1612CA00207A878900862A3A /* cocoatoprojectM.h in Headers */,
|
||||
1612CA07207A878900862A3A /* wipemalloc.h in Headers */,
|
||||
169BC64A24CC4D16007B7829 /* FileScanner.hpp in Headers */,
|
||||
1612CA06207A878900862A3A /* sdltoprojectM.h in Headers */,
|
||||
1612CA09207A878900862A3A /* fftsg.h in Headers */,
|
||||
1612CA0E207A878900862A3A /* projectM-opengl.h in Headers */,
|
||||
@ -756,6 +766,7 @@
|
||||
166854482105E4FC0042793A /* Filters.hpp in Sources */,
|
||||
1668544B2105E4FC0042793A /* PerlinNoise.hpp in Sources */,
|
||||
1668544C2105E4FC0042793A /* PerPixelMesh.hpp in Sources */,
|
||||
169BC64724CC4D16007B7829 /* FileScanner.cpp in Sources */,
|
||||
1668544D2105E4FC0042793A /* Pipeline.hpp in Sources */,
|
||||
1668544E2105E4FC0042793A /* PipelineContext.hpp in Sources */,
|
||||
1668544F2105E4FC0042793A /* Renderable.hpp in Sources */,
|
||||
@ -803,6 +814,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
16A49E5E207A7CAE00E508EA /* ConfigFile.cpp in Sources */,
|
||||
169BC64824CC4D16007B7829 /* FileScanner.cpp in Sources */,
|
||||
16A49E62207A7CAE00E508EA /* fftsg.cpp in Sources */,
|
||||
16A49E69207A7CAE00E508EA /* PCM.cpp in Sources */,
|
||||
1612C9EC207A860000862A3A /* KeyHandler.cpp in Sources */,
|
||||
@ -911,7 +923,7 @@
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 1;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"GL_SILENCE_DEPRECATION=1",
|
||||
|
||||
@ -463,14 +463,14 @@ template <class RandomAccessIterator>
|
||||
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
|
||||
const unsigned P)
|
||||
{
|
||||
return ::std::random_shuffle(first, last);
|
||||
return random_shuffle(first, last);
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator, class RandomNumberGenerator>
|
||||
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
|
||||
RandomNumberGenerator &rgen, const unsigned P)
|
||||
{
|
||||
return ::std::random_shuffle(first, last, rgen);
|
||||
return random_shuffle(first, last, rgen);
|
||||
}
|
||||
|
||||
template <class ForwardIterator, class T>
|
||||
|
||||
@ -121,7 +121,7 @@
|
||||
C37EBD3D19A0112900220265 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
C37EBD3F19A0112900220265 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
C37EBD4619A0112900220265 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
C37EBD5A19A0118600220265 /* iTunes Visualizer.pkg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iTunes Visualizer.pkg"; sourceTree = "<group>"; };
|
||||
C37EBD5A19A0118600220265 /* iTunes Visualizer.pkg */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.installer-pkg"; path = "iTunes Visualizer.pkg"; sourceTree = "<group>"; };
|
||||
C37EBD5C19A0146F00220265 /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; name = images; path = ../images; sourceTree = "<group>"; };
|
||||
C37EBD5E19A0164400220265 /* selectViz.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = selectViz.png; path = images/selectViz.png; sourceTree = "<group>"; };
|
||||
C37EBD6019A01BEE00220265 /* projectM Visualizer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "projectM Visualizer.entitlements"; sourceTree = "<group>"; };
|
||||
@ -640,7 +640,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
@ -697,7 +697,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
|
||||
@ -117,6 +117,7 @@
|
||||
files = (
|
||||
168F715921124C0E001806E7 /* config.inp in Support files */,
|
||||
168F715A21124C14001806E7 /* fonts in Support files */,
|
||||
169BC64224CC3FCA007B7829 /* presets in Support files */,
|
||||
);
|
||||
name = "Support files";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -294,7 +295,6 @@
|
||||
168F714621120210001806E7 /* Frameworks */,
|
||||
168F714721120210001806E7 /* Resources */,
|
||||
168F7155211248DE001806E7 /* Executable */,
|
||||
168F715721124BBB001806E7 /* Copy Presets */,
|
||||
168F715821124BFC001806E7 /* Support files */,
|
||||
168F715B21124CD1001806E7 /* Frameworks */,
|
||||
168F715D21124CF8001806E7 /* Generate Installer Package */,
|
||||
@ -418,22 +418,6 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
168F715721124BBB001806E7 /* Copy Presets */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"$(SRCROOT)/../../presets",
|
||||
);
|
||||
name = "Copy Presets";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/presets",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/bash;
|
||||
shellScript = "POUT=\"$BUILT_PRODUCTS_DIR\"/\"$CONTENTS_FOLDER_PATH/Resources/presets\"\nPIN=\"$SRCROOT\"/../../presets\n\nmkdir -p \"$POUT\"\nfor preset_dir in \"$PIN/\"*; do\n cp \"$preset_dir/\"* \"$POUT/\"\ndone\necho \"Copied presets to $POUT\"\n";
|
||||
};
|
||||
168F715D21124CF8001806E7 /* Generate Installer Package */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 12;
|
||||
|
||||
Reference in New Issue
Block a user