Entirely removed native presets.

The native presets did not build anymore due to refactorings, cause other build issues on Windows (e.g. require linking to psapi.lib) and would need a complete makeover anyway.
This commit is contained in:
Kai Blaschke
2022-09-15 18:15:00 +02:00
committed by Kai Blaschke
parent 98b10f5ec6
commit d97feb22f6
25 changed files with 0 additions and 1810 deletions

View File

@ -91,7 +91,6 @@ using the `-D` switch.
| `ENABLE_SDL` | `ON` | `SDL2` | Builds and installs the standalone SDL visualizer application. Also required for Emscripten and the tests. |
| `ENABLE_GLES` | `OFF` | `GLES` | Use OpenGL ES 3 profile for rendering instead of the Core profile. |
| `ENABLE_THREADING` | `ON` | `pthreads` | Enable multithreading support. If enabled, will cause an error if pthreads are not available. |
| `ENABLE_NATIVE_PRESETS` | `OFF` | | Builds and installs the binary (native) preset libraries. |
| `ENABLE_PRESETS` | `ON` | | Installs several thousand shipped presets. |
| `ENABLE_PULSEAUDIO` | `OFF` | `Qt5`, `Pulseaudio` | Build the Qt5-based Pulseaudio visualizer application. |
| `ENABLE_JACK` | `OFF` | `Qt5`, `JACK` | Build the Qt5-based JACK visualizer application. |

View File

@ -316,16 +316,6 @@ LLVM (https://github.com/projectM-visualizer/projectm/pull/360).
Made up of everything in `src/libprojectM/Renderer`. These files compose the `libRenderer` sub-library.
#### Native Presets
These are not built by default.
Native presets are visualizations that are implemented in C++ instead of `.milk` preset files. They are completely
optional. Milkdrop presets are also technically optional but the whole thing is basically useless without them.
If you don't want native presets, and you probably don't, don't bother with them. To enable loading and building these
presets, add `-DENABLE_NATIVE_PRESETS=ON` to the CMake configuration command.
### Assets
`libprojectM` can either have a configuration hard-coded or load from a configuration file. It's up to each application

View File

@ -48,7 +48,6 @@ cmake_dependent_option(ENABLE_SHARED_LINKING "Link the SDL test UI against the s
option(ENABLE_DOXYGEN "Build and install Doxygen source code documentation in PROJECTM_DATADIR_PATH/docs." OFF)
option(ENABLE_CXX_INTERFACE "Enable exporting all C++ symbols, not only the C API, in the shared library. Warning: This is not very portable." OFF)
option(ENABLE_PRESETS "Build and install bundled presets" ON)
option(ENABLE_NATIVE_PRESETS "Build and install native preset loading support and preset libraries written in C/C++" OFF)
option(BUILD_TESTING "Build the libprojectM test suite" OFF)
cmake_dependent_option(ENABLE_SDL_UI "Build the SDL2-based developer test UI" OFF "NOT ENABLE_EMSCRIPTEN" OFF)
cmake_dependent_option(ENABLE_GLES "Enable OpenGL ES support" OFF "NOT ENABLE_EMSCRIPTEN" ON)
@ -209,7 +208,6 @@ message(STATUS "Features:")
message(STATUS "==============================================")
message(STATUS "")
message(STATUS " Presets: ${ENABLE_PRESETS}")
message(STATUS " Native presets: ${ENABLE_NATIVE_PRESETS}")
message(STATUS " Threading: ${ENABLE_THREADING}")
message(STATUS " SDL2: ${ENABLE_SDL_UI}")
if(ENABLE_SDL_UI)

View File

@ -69,8 +69,5 @@
/* Define USE_THREADS */
#cmakedefine01 USE_THREADS
/* Define ENABLE_NATIVE_PRESETS */
#cmakedefine ENABLE_NATIVE_PRESETS
/* Version number of package */
#define VERSION "@PROJECT_VERSION@"

View File

@ -1,3 +1,2 @@
add_subdirectory(libprojectM)
add_subdirectory(NativePresets)
add_subdirectory(sdl-test-ui)

View File

@ -1 +0,0 @@
*.dylib

View File

@ -1,70 +0,0 @@
if(NOT ENABLE_PRESETS OR NOT ENABLE_NATIVE_PRESETS)
return()
endif()
# Using a macro to reduce repetition.
macro(add_native_preset name)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_library(${name}_static STATIC ${name}.cpp)
set_target_properties(${name}_static PROPERTIES
OUTPUT_NAME ${name}
)
target_link_libraries(${name}_static
PRIVATE
projectM_static
GLM::GLM
)
install(TARGETS ${name}_static
LIBRARY DESTINATION "${PROJECTM_DATADIR_PATH}/presets"
RUNTIME DESTINATION "${PROJECTM_DATADIR_PATH}/presets"
ARCHIVE DESTINATION "${PROJECTM_DATADIR_PATH}/presets"
COMPONENT Presets
)
endif()
add_library(${name}_shared SHARED ${name}.cpp)
target_compile_definitions(${name}_shared
PRIVATE
${name}_EXPORTS
)
set_target_properties(${name}_shared PROPERTIES
OUTPUT_NAME ${name}
)
# On Windows, libprojectM is only built statically.
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_link_libraries(${name}_shared
PRIVATE
projectM_static
)
else()
target_link_libraries(${name}_shared
PRIVATE
projectM_shared
)
endif()
target_link_libraries(${name}_shared
PRIVATE
GLM::GLM
)
install(TARGETS ${name}_shared
LIBRARY DESTINATION "${PROJECTM_DATADIR_PATH}/presets"
RUNTIME DESTINATION "${PROJECTM_DATADIR_PATH}/presets"
ARCHIVE DESTINATION "${PROJECTM_DATADIR_PATH}/presets"
COMPONENT Presets
)
endmacro()
add_native_preset(MstressJuppyDancer)
add_native_preset(RLGFractalDrop7c)
add_native_preset(RovastarDarkSecret)
add_native_preset(RovastarDriftingChaos)
add_native_preset(RovastarFractalSpiral)
add_native_preset(RovastarFractopiaFrantic)

View File

@ -1,219 +0,0 @@
#include <cmath>
#include "Pipeline.hpp"
#include "Transformation.hpp"
#include "MilkdropCompatability.hpp"
#include "Waveform.hpp"
#include "NativePreset.hpp"
class Dancer : public Waveform
{
public:
float meanbass;
float meanmid;
float meantreb;
float mi2_prg;
float gam;
float mi_prg;
float ba_prg;
float tr_prg;
float dim;
float xpos;
float ypos;
float rand_offset1;
float rand_offset2;
float rand_offset3;
Dancer():Waveform(16)
{
thick = true;
smoothing = 0.5;
meanbass = 0;
meanmid = 0;
meantreb = 0;
mi2_prg = 0;
gam = 0;
mi_prg = 0;
ba_prg = 0;
tr_prg = 0;
dim = (rand()%20)*.01;
//dim *= 0.5;
dim += 0.4;
ypos = ((rand()%60)*.01)-0.3;
xpos = ((rand()%60)*.01)-0.3;
xpos+=(1-dim) * 0.5;
ypos+=(1-dim) * 0.5;
rand_offset1= (rand()%200)*.01;
rand_offset2= (rand()%400)*.01;
rand_offset3= (rand()%600)*.01;
}
ColoredPoint PerPoint(ColoredPoint p, const WaveformContext context)
{
meanbass = 0.01*(meanbass*99+context.music->bass);
meantreb = 0.01*(meantreb*99+context.music->treb);
meanmid = 0.01*(meanmid*99+context.music->mid);
float bassdiff = (context.music->bass - meanbass)*15;
float trebdiff = (context.music->treb - meantreb)*15;
float middiff = (context.music->mid - meanmid)*15;
float ba = min(above(bassdiff,0)*bassdiff*.005,.11);
float tr = min(above(trebdiff,0)*trebdiff*.005,.11);
float mi = min(above(middiff,0)*middiff*.005,.11);
mi2_prg = mi2_prg+mi;
gam = std::abs(gam-above(mi2_prg,5));
mi2_prg= if_milk(above(mi2_prg,5),0,mi2_prg);
float s = context.sample_int;
//Gambe
p.x= if_milk(equal(int(s),1),.4,.4);
p.y= if_milk(equal(int(s),1),.2+((ba+tr)*.5)*gam,.2+((ba+tr)*.5)*gam);
p.x= if_milk(equal(int(s),2),.5+sin(ba*100)*.03,p.x);
p.y= if_milk(equal(int(s),2),.4,p.y);
p.x= if_milk(equal(int(s),3),.6,p.x);
p.y= if_milk(equal(int(s),3),.2+((ba+tr)*.5)*(1-gam),p.y);
p.x= if_milk(equal(int(s),4),.5+sin(ba*100)*.03,p.x);
p.y= if_milk(equal(int(s),4),.4,p.y);
//Corpo
p.x= if_milk(equal(int(s),5),.5,p.x);
p.y= if_milk(equal(int(s),5),.6,p.y);
//Braccia
p.x= if_milk(equal(int(s),6),.4-mi*.23,p.x);
p.y= if_milk(equal(int(s),6),.5+mi,p.y);
p.x= if_milk(equal(int(s),7),.5,p.x);
p.y= if_milk(equal(int(s),7),.6,p.y);
p.x= if_milk(equal(int(s),8),.6+tr*.23,p.x);
p.y= if_milk(equal(int(s),8),.5+tr,p.y);
p.x= if_milk(equal(int(s),9),.5,p.x);
p.y= if_milk(equal(int(s),9),.6,p.y);
//Testa
p.x= if_milk(equal(int(s),10),.5,p.x);
p.y= if_milk(equal(int(s),10),.62,p.y);
p.x= if_milk(equal(int(s),11),.47-ba*.23,p.x);
p.y= if_milk(equal(int(s),11),.62,p.y);
p.x= if_milk(equal(int(s),12),.47-ba*.23,p.x);
p.y= if_milk(equal(int(s),12),.67+ba*.23,p.y);
p.x= if_milk(equal(int(s),13),.53+ba*.23,p.x);
p.y= if_milk(equal(int(s),13),.67+ba*.23,p.y);
p.x= if_milk(equal(int(s),14),.53+ba*.23,p.x);
p.y= if_milk(equal(int(s),14),.62,p.y);
p.x= if_milk(equal(int(s),15),.50,p.x);
p.y= if_milk(equal(int(s),15),.62,p.y);
mi_prg= if_milk(above(mi_prg,5),0,mi_prg+mi*.1);
ba_prg= if_milk(above(ba_prg,5),0,ba_prg+ba*.1);
tr_prg= if_milk(above(tr_prg,5),0,tr_prg+tr*.1);
float temp_dim = dim + 0.2 * sin(mi_prg + rand_offset1);
float temp_xpos = xpos + 0.2 * cos(ba_prg + rand_offset2);
float temp_ypos = ypos + 0.2* sin(tr_prg + rand_offset3);
p.x=p.x*temp_dim+temp_xpos;
p.y=p.y*temp_dim+temp_ypos;
float hm=context.sample+mi2_prg;
float ht=context.sample+tr_prg;
float hb=context.sample+ba_prg;
p.r=hm;
p.g=ht;
p.b=hb;
p.a=.8;
return p;
}
};
class MstressJuppyDancer : public Pipeline
{
public:
Dancer dancer[10];
float q1,meanmid,middiff,mi_prg,gam, bass;
MstressJuppyDancer() : Pipeline()
{
for(int x = 0; x< 10; x++)
drawables.push_back(&dancer[x]);
textureWrap = false;
screenDecay = 0.3;
q1 = 0;
meanmid = 0;
middiff = 0;
mi_prg = 0;
gam = 0;
}
virtual void Render(const BeatDetect &music, const PipelineContext &context)
{
meanmid = 0.01*(meanmid*99+music.mid);
middiff = (music.mid - meanmid)*15;
float mi = min(above(middiff,0)*middiff*.005,.11);
mi_prg = mi_prg+mi;
gam = std::abs(gam-above(mi_prg,.5));
mi_prg= if_milk(above(mi_prg,.5),0,mi_prg);
q1 = gam;
bass = music.bass;
}
virtual PixelPoint PerPixel(PixelPoint p, const PerPixelContext context)
{
float sx = -below(p.y,0.8)*.001;
float dx = .01*bass*(1-q1*2)*below(p.y,0.8);
float rot= .051*below(p.y,0.8);
float cx=trunc(p.x*16)/16;
float cy=trunc(p.y*16)/16;
Transforms::Scale(p,context,sx,1,cx,cy);
Transforms::Rotate(p,context,rot,cx,cy);
Transforms::Transform(p,context,dx,0);
return p;
}
};
typedef NativePreset<MstressJuppyDancer> MstressJuppyDancerPreset;
extern "C" MstressJuppyDancerPreset * create(const char * url) {
return new MstressJuppyDancerPreset(std::string(url));
}
extern "C" void destroy(MstressJuppyDancerPreset * preset) {
delete preset;
}

View File

@ -1,161 +0,0 @@
/*
* RovastarFractalSpiral.hpp
*
* Created on: Jun 22, 2008
* Author: pete
*/
#include "Pipeline.hpp"
#include "Transformation.hpp"
#include "MilkdropCompatability.hpp"
#include "VideoEcho.hpp"
#include "NativePreset.hpp"
#include "MilkdropWaveform.hpp"
class RLGFractalDrop7c : public Pipeline
{
public:
Shape shape1,shape2,shape3,shape4;
MilkdropWaveform wave;
VideoEcho videoEcho;
float movement, t1, t2, t3, t4;
RLGFractalDrop7c() : Pipeline()
{
drawables.push_back(&shape1);
drawables.push_back(&shape2);
drawables.push_back(&shape3);
drawables.push_back(&shape4);
drawables.push_back(&wave);
compositeDrawables.push_back(&videoEcho);
textureWrap = true;
screenDecay = 1.0;
videoEcho.orientation = FlipX;
videoEcho.zoom = 1.006752;
videoEcho.a = 0.5;
wave.mode = DoubleLine;
wave.additive = true;
wave.scale = 3.815202;
wave.smoothing = 0.9;
wave.modOpacityEnd = 1.1;
wave.modOpacityStart = 0.0;
wave.maximizeColors = true;
wave.modulateAlphaByVolume = true;
wave.r = 0.65;
wave.g = 0.65;
wave.b = 1;
wave.a = 0.1;
movement = 0;
t1 = (rand()%100)*0.01;
t2 = (rand()%100)*0.01;
t3 = (rand()%100)*0.01;
t4 = (rand()%100)*0.01;
shape1.sides =3;
shape1.x = 0.37;
shape1.y = 0.5;
shape1.radius = 6.811289;
shape1.ang = 3.644249;
shape1.a = 0.5;
shape1.a2 = 0.5;
shape1.border_r = 1;
shape1.border_g = 1;
shape1.border_b = 1;
shape1.border_a = 1;
shape2.sides =100;
shape2.additive = true;
shape2.textured = true;
shape2.radius = 0.897961;
shape2.ang = 3.644249;
shape2.a = 0.5;
shape2.a2 = 1;
shape3.sides =100;
shape3.additive = true;
shape3.textured = true;
shape3.radius = 0.513861;
shape3.ang = 4.209736;
shape3.a = 1;
shape3.a2 = 1;
shape4.sides =100;
shape4.additive = true;
shape4.textured = true;
shape4.ang = 0;
shape4.a = 1;
shape4.r = 0.6;
shape4.g = 0.8;
shape4.b = 1;
shape4.a2 = 1;
}
virtual void Render(const BeatDetect &music, const PipelineContext &context)
{
movement += 0.1*max(0,music.bass+music.bass_att-2) + 0.15*pow(music.bass,3) + 0.005;
float time = context.time;
shape1.ang = movement*(0.303 + 0.01*t1);
shape1.r = min(1,max(0,0+ 0.1*sin(time*0.417 + 1)));
shape1.g = min(1,max(0,0 + 0.1*sin(time*0.391 + 2)));
shape1.b = min(1,max(0,0 + 0.1*sin(time*0.432 + 4)));
shape1.r2 = min(1,max(0, 0.02*sin(time*0.657 + 3)));
shape1.g2 = min(1,max(0, 0.02*sin(time*0.737 + 5)));
shape1.b2 = min(1,max(0, 0.02*sin(time*0.884 + 6)));
shape1.additive = ((0.5+0.15*(music.bass+music.bass_att)) > 1.0) ? true : false;
shape2.x = 0.37 + 0.07*sin(movement*0.15+3);
shape2.y = 0.5 + 0.03*sin(movement*0.19+1);
shape2.tex_ang = movement*(0.01 + 0.0001*t2);
shape2.r = min(1,max(0, 1 + 0.01*sin(time*0.0417 + 1)));
shape2.g = min(1,max(0, 1 + 0.01*sin(time*0.391 + 2)));
shape2.b = min(1,max(0, 1 + 0.01*sin(time*0.432 + 4)));
shape2.r2 = min(1,max(0, 0.01*sin(time*0.457 + 3)));
shape2.g2 = min(1,max(0, 0.01*sin(time*0.0437 + 5)));
shape2.b2 = min(1,max(0, 0.01*sin(time*0.484 + 6)));
shape3.x = 0.67 + 0.05*sin(movement*0.017);
shape3.y = 0.43 + 0.09*sin(movement*0.013);
shape3.tex_ang = movement*(0.02 + 0.0001*t3);
shape3.radius = 0.222979 * (0.9 + 0.2*t4);
shape3.r = min(1,max(0,1+ 0.01*sin(time*0.417 + 1)));
shape3.g = min(1,max(0,1 + 0.01*sin(time*0.391 + 2)));
shape3.b = min(1,max(0,1 + 0.01*sin(time*0.432 + 4)));
shape3.r2 = min(1,max(0,0.01*sin(time*0.457 + 3)));
shape3.g2 = min(1,max(0,0.01*sin(time*0.437 + 5)));
shape3.b2 = min(1,max(0,0.01*sin(time*0.484 + 6)));
shape4.x = 0.5 + 0.08*sin(movement*0.25);
shape4.y = 0.5 + 0.1*sin(movement*0.5+2);
shape4.ang = time;
}
virtual PixelPoint PerPixel(PixelPoint p, const PerPixelContext context)
{
Transforms::Zoom(p,context,1.029902,1.00);
return p;
}
};
typedef NativePreset<RLGFractalDrop7c> RLGFractalDrop7Preset;
extern "C" RLGFractalDrop7Preset * create(const char * url) {
return new RLGFractalDrop7Preset(std::string(url));
}
extern "C" void destroy(RLGFractalDrop7Preset * preset) {
delete preset;
}

View File

@ -1,162 +0,0 @@
/*
* RovastarFractopiaFrantic.hpp
*
* Created on: Jun 18, 2008
* Author: pete
*/
#include "Pipeline.hpp"
#include "MilkdropCompatability.hpp"
#include "Transformation.hpp"
#include "MilkdropWaveform.hpp"
#include "Filters.hpp"
#include "NativePreset.hpp"
class RovastarDarkSecret : public Pipeline
{
public:
Shape shape1, shape2, shape3, shape4;
Border border;
Invert invert;
RovastarDarkSecret() : Pipeline()
{
screenDecay = 0.9;
textureWrap = true;
drawables.push_back(&border);
drawables.push_back(&shape1);
drawables.push_back(&shape2);
drawables.push_back(&shape3);
drawables.push_back(&shape4);
compositeDrawables.push_back(&invert);
border.outer_size = 0.015;
border.inner_size = 0.010;
border.outer_a = 1.0;
border.inner_a = 1.0;
shape1.sides = 4;
shape1.additive = true;
shape1.radius=1.621747;
shape1.textured = true;
shape1.tex_zoom=0.424973;
shape1.a = 1;
shape1.border_a = 0.0;
shape1.r = 1;
shape1.g = 0;
shape1.b = 0;
shape1.a2 = 0;
shape2.sides = 4;
shape2.additive = true;
shape2.radius=1.621747;
shape2.textured = true;
shape2.tex_zoom = 0.424973;
shape2.a = 1;
shape2.border_a = 0.0;
shape2.r = 1;
shape2.g = 0;
shape2.b = 1;
shape2.a2 = 0;
shape3.sides = 4;
shape3.additive = true;
shape3.radius=1.621747;
shape3.textured = true;
shape3.tex_zoom = 0.424973;
shape3.a = 1;
shape3.border_a = 0.0;
shape3.r = 0;
shape3.g = 1;
shape3.b = 1;
shape3.a2 = 0;
shape4.sides = 4;
shape4.additive = false;
shape4.radius=1.621747;
shape4.textured = true;
shape4.tex_zoom = 0.424973;
shape4.a = 1;
shape4.border_a = 0.0;
shape4.r = 1;
shape4.g = 1;
shape4.b = 1;
shape4.a2 = 0;
q8 = 0;
q7 = 0;
oldq7 = 0;
}
float q8, oldq8, q7, oldq7, q6;
float dx, dy;
virtual void Render(const BeatDetect &music, const PipelineContext &context)
{
float wave_r = 0.5+ 0.2*(music.bass-1);
float wave_g = 0.5+ 0.2*(music.mid-1.2);
float wave_b = 0.5+ 0.2*(music.treb-.5);
border.outer_r = 1-wave_r;
border.outer_g = 1-wave_g;
border.outer_b = 1-wave_b;
border.inner_r = 0.75 + 0.25*sin(context.time*0.4123);
border.inner_g = 0.25 + 0.25*cos(context.time*0.87);
border.inner_b = 0.5+0.5*sin(1.23*context.time);
float val = 1.2*music.bass+0.4*music.bass_att+0.1*music.treb+0.1*music.treb_att+0.1*music.mid+0.1*music.mid_att;
q8 = oldq8 +0.003*(((pow(val,6)/context.fps) + (pow(val,5)/context.fps) + (pow(val,4)/context.fps) + (pow(val,3)/context.fps) + (pow(val,2)/context.fps) +(val)/context.fps));
oldq8 = q8;
q7 =oldq7+ 0.001*(pow(val,7)/context.fps);
oldq7 = q7;
dy = 0.5 + 0.01*(sin(0.786*q7));
dx = 0.1*sin(1.143*q8);
q6 = 15+0.1*(((pow(val,6)/context.fps) + (pow(val,5)/context.fps) + (pow(val,4)/context.fps) + (pow(val,3)/context.fps) + (pow(val,2)/context.fps) +(val)/context.fps));
shape1.x = 0.5 + 0.1*sin(q7*0.986);
shape1.y = 0.5 + 0.1*sin(q7*0.846);
shape1.tex_ang = 3.1515 + 3.1415*sin(q7*0.4521) +0.05*sin(context.time);
shape2.x = 0.5 + 0.1*sin(q7*0.986);
shape2.y = 0.5 + 0.1*sin(q7*0.846);
shape2.tex_ang = 3.1515 + 3.1415*sin(q7*0.4521) +0.1*sin(context.time);
shape3.x = 0.5 + 0.1*sin(q7*0.986);
shape3.y = 0.5 + 0.1*sin(q7*0.846);
shape3.tex_ang = 3.1515 + 3.1415*sin(q7*0.4521) +0.15*sin(context.time);
shape4.x = 0.5 + 0.1*sin(q7*0.986);
shape4.y = 0.5 + 0.1*sin(q7*0.846);
shape4.tex_ang = 3.1515 + 3.1415*sin(q7*0.4521) +0.2*sin(context.time);;
}
virtual PixelPoint PerPixel(PixelPoint p, const PerPixelContext context)
{
float pdy=dy+0.008*cos((p.x-0.5 - 0.1*sin(q7))*(q6));
Transforms::Zoom(p,context,13.290894,1);
Transforms::Transform(p,context,dx,pdy);
return p;
}
};
typedef NativePreset<RovastarDarkSecret> RovastarDarkSecretPreset;
extern "C" RovastarDarkSecretPreset * create(const char * url) {
return new RovastarDarkSecretPreset(std::string(url));
}
extern "C" void destroy(RovastarDarkSecretPreset * preset) {
delete preset;
}

View File

@ -1,142 +0,0 @@
/*
* RovastarFractopiaFrantic.hpp
*
* Created on: Jun 18, 2008
* Author: pete
*/
#include <cmath>
#include "Pipeline.hpp"
#include "MilkdropCompatability.hpp"
#include "Transformation.hpp"
#include "MilkdropWaveform.hpp"
#include "NativePreset.hpp"
class RovastarDriftingChaos : public Pipeline
{
public:
Shape shape1, shape2, shape3;
MilkdropWaveform wave;
RovastarDriftingChaos() : Pipeline()
{
screenDecay = 1.0;
textureWrap = 0;
drawables.push_back(&shape1);
drawables.push_back(&shape2);
drawables.push_back(&shape3);
drawables.push_back(&wave);
shape1.sides = 3;
shape1.radius=0.550000;
shape1.a = 0.1;
shape1.a2 = 0.9;
shape1.border_r = 1.0;
shape1.border_g = 1.0;
shape1.border_b = 1.0;
shape1.border_a = 0.2;
shape2.sides = 32;
shape2.radius=0.40000;
shape2.a = 1.0;
shape2.a2 = 0.3;
shape2.border_r = 1.0;
shape2.border_g = 1.0;
shape2.border_b = 1.0;
shape2.border_a = 0.2;
shape3.sides = 4;
shape3.radius=0.40000;
shape3.a = 0.6;
shape3.a2 = 0.4;
shape3.border_r = 1.0;
shape3.border_g = 1.0;
shape3.border_b = 1.0;
shape3.border_a = 0.2;
}
float xamptarg, q8, oldq8, q7, xpos, ypos,xdir, xspeed, xamp, yamp, yamptarg,yspeed,ydir;
float dx, dy, angle;
virtual void Render(const BeatDetect &music, const PipelineContext &context)
{
float volume = 0.15*(music.bass+music.bass_att+music.treb+music.treb_att+music.mid+music.mid_att);
xamptarg = if_milk(equal(context.frame%15,0),min(0.5*volume*music.bass_att,0.5),xamptarg);
xamp = xamp + 0.5*(xamptarg-xamp);
xdir = if_milk(above(std::abs(xpos),xamp),-sign(xpos),if_milk(below(std::abs(xspeed),0.1),2*above(xpos,0)-1,xdir));
xspeed += xdir*xamp - xpos - xspeed*0.055*below(std::abs(xpos),xamp);
xpos = xpos + 0.001*xspeed;
dx = xpos*0.005;
yamptarg = if_milk(equal(context.frame%15,0),min(0.3*volume*music.treb_att,0.5),yamptarg);
yamp += 0.5*(yamptarg-yamp);
ydir = if_milk(above(std::abs(ypos),yamp),-sign(ypos),if_milk(below(std::abs(yspeed),0.1),2*above(ypos,0)-1,ydir));
yspeed += ydir*yamp - ypos - yspeed*0.055*below(std::abs(ypos),yamp);
ypos = ypos + 0.001*yspeed;
dy = ypos*0.005;
angle = 10*(dx-dy);
q8 =oldq8+ 0.0003*(powf(1+1.2*music.bass+0.4*music.bass_att+0.1*music.treb+0.1*music.treb_att+0.1*music.mid+0.1*music.mid_att,6)/context.fps);
oldq8 = q8;
q7 = 0.003*(powf(1+1.2*music.bass+0.4*music.bass_att+0.1*music.treb+0.1*music.treb_att+0.1*music.mid+0.1*music.mid_att,6)/context.fps);
shape1.ang = context.time*1.4;
shape1.x = 0.5 + 0.08*cos(context.time*1.3) + 0.03*cos(context.time*0.7);
shape1.y = 0.5 + 0.08*sin(context.time*1.4) + 0.03*sin(context.time*0.7);
shape1.r = 0.5 + 0.5*sin(q8*0.613 + 1);
shape1.g = 0.5 + 0.5*sin(q8*0.763 + 2);
shape1.b = 0.5 + 0.5*sin(q8*0.771 + 5);
shape1.r2 = 0.5 + 0.5*sin(q8*0.635 + 4);
shape1.g2 = 0.5 + 0.5*sin(q8*0.616+ 1);
shape1.b2 = 0.5 + 0.5*sin(q8*0.538 + 3);
shape2.ang = context.time*1.7;
shape2.x = 0.5 + 0.08*cos(context.time*1.1) + 0.03*cos(context.time*0.7);
shape2.y = 0.5 + 0.08*sin(context.time*1.1) + 0.03*sin(context.time*0.7);
shape2.r = 0.5 + 0.5*sin(q8*0.713 + 1);
shape2.g = 0.5 + 0.5*sin(q8*0.563 + 2);
shape2.b = 0.5 + 0.5*sin(q8*0.654 + 5);
shape2.r2 = 0.5 + 0.5*sin(q8*0.885 + 4);
shape2.g2 = 0.5 + 0.5*sin(q8*0.556+ 1);
shape2.b2 = 0.5 + 0.5*sin(q8*0.638 + 3);
shape3.ang = context.time*1.24;
shape3.x = 0.5 - 0.08*cos(context.time*1.07) + 0.03*cos(context.time*0.7);
shape3.y = 0.5 - 0.08*sin(context.time*1.33) + 0.03*sin(context.time*0.7);
shape3.g = 0.5 + 0.5*sin(q8*0.713 + 1);
shape3.b = 0.5 + 0.5*cos(q8*0.563 + 2);
shape3.r = 0.5 + 0.5*sin(q8*0.654 + 5);
shape3.r2 = 0.5 + 0.5*cos(q8*0.885 + 4);
shape3.g2 = 0.5 + 0.5*cos(q8*0.556+ 1);
shape3.b2 = 0.5 + 0.5*sin(q8*0.638 + 3);
}
virtual PixelPoint PerPixel(PixelPoint p, const PerPixelContext context)
{
Transforms::Zoom(p,context,1+0.05*context.rad,1);
Transforms::Transform(p,context,dx,dy);
Transforms::Rotate(p,context,angle,0.5,0.5);
return p;
}
};
typedef NativePreset<RovastarDriftingChaos> RovastarDriftingChaosPreset;
extern "C" RovastarDriftingChaosPreset * create(const char * url) {
return new RovastarDriftingChaosPreset(std::string(url));
}
extern "C" void destroy(RovastarDriftingChaosPreset * preset) {
delete preset;
}

View File

@ -1,85 +0,0 @@
/*
* RovastarFractalSpiral.hpp
*
* Created on: Jun 22, 2008
* Author: pete
*/
#include <cmath>
#include "Pipeline.hpp"
#include "Transformation.hpp"
#include "MilkdropCompatability.hpp"
#include "NativePreset.hpp"
class RovastarFractalSpiral : public Pipeline
{
public:
Border border;
float dx, dy, cx, cy, time;
RovastarFractalSpiral() : Pipeline()
{
drawables.push_back(&border);
textureWrap = true;
screenDecay = 1.0;
border.outer_size = 0.01;
border.outer_a = 1.0;
border.inner_size = 0.02;
border.inner_a = 1.0;
}
virtual void Render(const BeatDetect &music, const PipelineContext &context)
{
time = context.time;
border.outer_r = 0.3 - 0.3*(0.5*sin(time*0.701)+ 0.3*cos(time*0.438));
border.outer_g = 0.6- 0.4*sin(time*2.924);
border.outer_b = 0.35 - 0.3*cos(time*0.816);
cx = 0.5 - 0.1*sin(time*0.342);
cy = 0.5 + 0.1*sin(time*0.433);
border.inner_r = 0.5 + 0.5*sin(time*3.034);
border.inner_g = 0.5 + 0.5*sin(time*2.547);
border.inner_b = 0.5 + 0.5*sin(time*1.431);
dx = -0.008*sin(time*0.23);
dy = -0.008*sin(time*0.2);
}
virtual PixelPoint PerPixel(PixelPoint p, const PerPixelContext context)
{
float q1 = 8.05+(sin(p.x+0.137*time)-cos(p.y+0.213*time));
int val1 = std::abs(p.x*3-0.4*sin(q1));
int val2 = std::abs(p.y*3+0.4*sin(q1));
val1 = val1%2;
val2 = val2%2;
float box=(1-context.rad)+ 0.5 * val1 + 0.5*val2;
float zoom = if_milk(above(box,1),q1*.1,0.998531);
float rot = if_milk(above(box,1),1*sin(0.385*time),0.02);
Transforms::Zoom(p,context,zoom,1.01);
Transforms::Rotate(p,context,rot,cx,cy);
Transforms::Transform(p,context,dx,dy);
return p;
}
};
typedef NativePreset<RovastarFractalSpiral> RovastarFractalSpiralPreset;
extern "C" RovastarFractalSpiralPreset * create(const char * url) {
return new RovastarFractalSpiralPreset(std::string(url));
}
extern "C" void destroy(RovastarFractalSpiralPreset * preset) {
delete preset;
}

View File

@ -1,100 +0,0 @@
/*
* RovastarFractopiaFrantic.hpp
*
* Created on: Jun 18, 2008
* Author: pete
*/
#include "Pipeline.hpp"
#include "Transformation.hpp"
#include "NativePreset.hpp"
class RovastarFractopiaFrantic : public Pipeline
{
public:
Border border;
MotionVectors vectors;
float dx, dy;
float q4, q5, q6;
float movement;
RovastarFractopiaFrantic() : Pipeline()
{
drawables.push_back(&vectors);
drawables.push_back(&border);
screenDecay = 1.0;
vectors.x_num = 64;
vectors.y_num = 48;
vectors.r = 0.0;
vectors.g = 0.0;
vectors.b = 0.0;
vectors.a = 1.0;
vectors.x_offset = -0.002;
vectors.length = 2.0;
border.outer_size = 0.05;
border.outer_a = 1.0;
border.inner_size = 0.04;
border.inner_r = 0.0;
border.inner_g = 0.0;
border.inner_g = 0.0;
border.inner_a = 1.0;
q4 = 0.249+0.5*(rand()%100*0.01);
q5 = 0.249+0.5*(rand()%100*0.01);
q6 = 0.249+0.5*(rand()%100*0.01);
movement = 0.0;
}
virtual void Render(const BeatDetect &music, const PipelineContext &context)
{
movement += 0.5*(((music.bass+music.bass_att + 0.075*pow((music.bass+0.6*music.bass_att+0.2*music.treb_att),3)))/(float)context.fps);
if (movement > 10000.0)
movement = 0.0;
border.outer_r = q4+0.25*sin(movement*3.816);
border.outer_g = q4+0.25*sin(movement*0.744);
border.outer_b = q4+0.25*sin(movement*0.707);
if(music.bass+music.bass_att > 3.0) textureWrap = 1;
else textureWrap = 0;
vectors.y_offset = 0.03*sin(movement*0.34);
vectors.x_offset = 0.035*(sin(movement*0.217)+cos(movement*0.413)+sin(movement*0.311));
dx =0.01*sin(movement*5);
dy =0.0005*(music.bass+music.bass_att);
}
virtual PixelPoint PerPixel(PixelPoint p, const PerPixelContext context)
{
float myy = context.y-(0.250025);
float myx = context.x-0.5;
Transforms::Zoom(p,context,0.98,1.503744);
p.x = p.x - (dx + 2*(2*myx*myy));
p.y = p.y - (dy + 2*((myy*myy) - (myx*myx)));
return p;
}
};
typedef NativePreset<RovastarFractopiaFrantic> RovastarFractopiaFranticPreset;
extern "C" RovastarFractopiaFranticPreset * create(const char * url) {
return new RovastarFractopiaFranticPreset(std::string(url));
}
extern "C" void destroy(RovastarFractopiaFranticPreset * preset) {
delete preset;
}

View File

@ -9,15 +9,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(MSVC_EXTRA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/msvc")
include_directories("${MSVC_EXTRA_INCLUDE_DIR}")
add_library(dlfcn OBJECT
msvc/dlfcn.c
msvc/dlfcn.h
)
set_target_properties(dlfcn PROPERTIES
FOLDER libprojectM
)
# Additional preprocessor definitions for Windows builds
add_compile_definitions(
NOMINMAX
@ -40,7 +31,6 @@ set(EXPORTED_TARGETS
)
add_subdirectory(MilkdropPresetFactory)
add_subdirectory(NativePresetFactory)
add_subdirectory(Renderer)
set(PROJECTM_EXPORT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/include/libprojectM/projectM_export.h")
@ -100,7 +90,6 @@ target_include_directories(projectM_main
"${CMAKE_CURRENT_SOURCE_DIR}/Renderer"
"${CMAKE_CURRENT_SOURCE_DIR}/Renderer/hlslparser/src"
"${CMAKE_CURRENT_SOURCE_DIR}/MilkdropPresetFactory"
"${CMAKE_CURRENT_SOURCE_DIR}/NativePresetFactory"
"${MSVC_EXTRA_INCLUDE_DIR}"
)

View File

@ -1,30 +0,0 @@
if(NOT ENABLE_NATIVE_PRESETS)
return()
endif()
add_library(NativePresetFactory OBJECT
MilkdropCompatability.hpp
NativePreset.hpp
NativePresetFactory.cpp
NativePresetFactory.hpp
)
target_include_directories(NativePresetFactory
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/.."
PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}"
)
target_link_libraries(NativePresetFactory
PUBLIC
GLM::GLM
${PROJECTM_OPENGL_LIBRARIES}
${CMAKE_DL_LIBS}
)
set_target_properties(NativePresetFactory PROPERTIES
FOLDER libprojectM
)
set(EXPORTED_TARGETS ${EXPORTED_TARGETS} NativePresetFactory PARENT_SCOPE)

View File

@ -1,42 +0,0 @@
/*
* MilkdropCompatability.hpp
*
* Created on: Jun 18, 2008
* Author: pete
*/
#ifndef MILKDROPCOMPATABILITY_HPP_
#define MILKDROPCOMPATABILITY_HPP_
inline float sign(float a)
{
return a < 0.0 ? -1.0 : 1.0;
}
inline float above(float a, float b)
{
return a > b ? 1 : 0;
}
inline float equal(float a, float b)
{
return a == b ? 1 : 0;
}
inline float below(float a, float b)
{
return a < b ? 1 : 0;
}
inline float min(float a, float b)
{
return a < b ? a : b;
}
inline float max(float a, float b)
{
return a > b ? a : b;
}
inline float if_milk(float a, float b, float c)
{
return (a==1.0) ? b : c;
}
#endif /* MILKDROPCOMPATABILITY_HPP_ */

View File

@ -1,38 +0,0 @@
/*
* Preset.hpp
*
* Created on: Aug 5, 2008
* Author: carm
*/
#ifndef __NATIVE_PRESET_HPP_
#define __NATIVE_PRESET_HPP_
#include <string>
#include "BeatDetect.hpp"
#include "Pipeline.hpp"
#include "PipelineContext.hpp"
#include "Preset.hpp"
/// A templated preset class to build different various hard coded presets and
/// compile them into object files to be loaded into a playlist
template <class PipelineT>
class NativePreset : public Preset {
public:
inline NativePreset(const std::string & name=std::string(),
const std::string & author = std::string()) : Preset(name, author) {}
virtual ~NativePreset() {}
inline PipelineT & pipeline() { return _pipeline; }
inline virtual void Render(const BeatDetect &music, const PipelineContext &context) {
_pipeline.Render(music, context);
}
private:
PipelineT _pipeline;
};
#endif

View File

@ -1,119 +0,0 @@
//
// C++ Implementation: NativePresetFactory
//
// Description:
//
//
// Author: Carmelo Piccione <carmelo.piccione@gmail.com>, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//
extern "C" {
# include <dlfcn.h>
}
#include "NativePresetFactory.hpp"
typedef void Handle;
typedef void DestroyFunctor(Preset*);
typedef Preset * CreateFunctor(const char * url);
class LibraryPreset : public Preset {
public:
LibraryPreset(Preset * preset, DestroyFunctor * destroyFun) : Preset(preset->name(), preset->author()), _internalPreset(preset), _destroyFunctor(destroyFun) {}
inline Pipeline & pipeline() { return _internalPreset->pipeline(); }
inline virtual ~LibraryPreset() { _destroyFunctor(_internalPreset); }
inline void Render(const BeatDetect &music, const PipelineContext &context) {
return _internalPreset->Render(music, context);
}
private:
Preset * _internalPreset;
DestroyFunctor * _destroyFunctor;
};
class PresetLibrary {
public:
PresetLibrary(Handle * h, CreateFunctor * create, DestroyFunctor * destroy) :
_handle(h), _createFunctor(create), _destroyFunctor(destroy) {}
Handle * handle() { return _handle; }
CreateFunctor * createFunctor() { return _createFunctor; }
DestroyFunctor * destroyFunctor() { return _destroyFunctor; }
~PresetLibrary() {
dlclose(handle());
}
private:
Handle * _handle;
CreateFunctor * _createFunctor;
DestroyFunctor * _destroyFunctor;
};
NativePresetFactory::NativePresetFactory() {}
NativePresetFactory::~NativePresetFactory() {
for (PresetLibraryMap::iterator pos = _libraries.begin(); pos != _libraries.end(); ++pos) {
std::cerr << "deleting preset library" << std::endl;
delete(pos->second);
}
}
PresetLibrary * NativePresetFactory::loadLibrary(const std::string & url) {
if (_libraries.count(url))
return _libraries[url];
// load the preset library
void* handle = dlopen(url.c_str(), RTLD_LAZY);
if (!handle) {
std::cerr << "[NativePresetFactory] Cannot load library: " << dlerror() << '\n';
return 0;
}
// reset errors
dlerror();
// load the symbols
CreateFunctor * create = (CreateFunctor*) dlsym(handle, "create");
const char * dlsym_error = dlerror();
if (dlsym_error) {
std::cerr << "[NativePresetFactory] Cannot load symbol create: " << dlsym_error << '\n';
return 0;
}
DestroyFunctor * destroy = (DestroyFunctor*) dlsym(handle, "destroy");
dlsym_error = dlerror();
if (dlsym_error) {
std::cerr << "[NativePresetFactory] Cannot load symbol destroy: " << dlsym_error << '\n';
return 0;
}
std::cerr << "[NativePresetFactory] creating preset library from url " << url << std::endl;
PresetLibrary * library = new PresetLibrary(handle, create, destroy);
_libraries.insert(std::make_pair(url, library));
return library;
}
std::unique_ptr<Preset> NativePresetFactory::allocate
(const std::string & url, const std::string & name, const std::string & author) {
PresetLibrary * library;
if ((library = loadLibrary(url)) == 0)
return std::unique_ptr<Preset>();
return std::unique_ptr<Preset>(new LibraryPreset
(library->createFunctor()(url.c_str()), library->destroyFunctor()));
}

View File

@ -1,41 +0,0 @@
//
// C++ Interface: NativePresetFactory
//
// Description:
//
//
// Author: Carmelo Piccione <carmelo.piccione@gmail.com>, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef __NATIVE_PRESET_FACTORY_HPP
#define __NATIVE_PRESET_FACTORY_HPP
#include <memory>
#include "PresetFactory.hpp"
class PresetLibrary;
class NativePresetFactory : public PresetFactory {
public:
NativePresetFactory();
virtual ~NativePresetFactory();
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"; }
private:
PresetLibrary * loadLibrary(const std::string & url);
typedef std::map<std::string, PresetLibrary*> PresetLibraryMap;
PresetLibraryMap _libraries;
};
#endif

View File

@ -12,10 +12,6 @@
#include "PresetFactoryManager.hpp"
#include "MilkdropPresetFactory/MilkdropPresetFactory.hpp"
#ifdef ENABLE_NATIVE_PRESETS
#include "NativePresetFactory/NativePresetFactory.hpp"
#endif
#include "config.h"
#include <sstream>
@ -46,11 +42,6 @@ void PresetFactoryManager::initialize(int gx, int gy) {
factory = new MilkdropPresetFactory(_gx, _gy);
registerFactory(factory->supportedExtensions(), factory);
#ifdef ENABLE_NATIVE_PRESETS
factory = new NativePresetFactory();
registerFactory(factory->supportedExtensions(), factory);
#endif
}
// Current behavior if a conflict is occurs is to override the previous request

View File

@ -29,17 +29,8 @@
#include "PresetChooser.hpp"
#include "Renderer.hpp"
#include "TimeKeeper.hpp"
#include "fatal.h"
#include "projectM-opengl.h"
#ifdef _WIN32
#include "dirent.h"
#else
#include <dirent.h>
#endif
#include <iostream>
#include <map>
namespace {
constexpr int kMaxSwitchRetries = 10;

View File

@ -5,11 +5,9 @@ add_library(projectM_shared SHARED
$<TARGET_OBJECTS:projectM_main>
$<TARGET_OBJECTS:MilkdropPresetFactory>
$<$<TARGET_EXISTS:NativePresetFactory>:$<TARGET_OBJECTS:NativePresetFactory>>
$<TARGET_OBJECTS:Renderer>
$<TARGET_OBJECTS:hlslparser>
$<TARGET_OBJECTS:SOIL2>
$<$<PLATFORM_ID:Windows>:$<TARGET_OBJECTS:dlfcn>>
)
target_compile_definitions(projectM_shared
@ -32,7 +30,6 @@ target_include_directories(projectM_shared
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Renderer>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Renderer/hlslparser/src>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/MilkdropPresetFactory>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/NativePresetFactory>"
"$<BUILD_INTERFACE:${MSVC_EXTRA_INCLUDE_DIR}>"
"$<INSTALL_INTERFACE:${PROJECTM_INCLUDE_DIR}>"
)

View File

@ -5,11 +5,9 @@ add_library(projectM_static STATIC
$<TARGET_OBJECTS:projectM_main>
$<TARGET_OBJECTS:MilkdropPresetFactory>
$<$<TARGET_EXISTS:NativePresetFactory>:$<TARGET_OBJECTS:NativePresetFactory>>
$<TARGET_OBJECTS:Renderer>
$<TARGET_OBJECTS:hlslparser>
$<TARGET_OBJECTS:SOIL2>
$<$<PLATFORM_ID:Windows>:$<TARGET_OBJECTS:dlfcn>>
)
target_compile_definitions(projectM_static
@ -30,7 +28,6 @@ target_include_directories(projectM_static
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Renderer>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Renderer/hlslparser/src>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/MilkdropPresetFactory>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/NativePresetFactory>"
"$<BUILD_INTERFACE:${MSVC_EXTRA_INCLUDE_DIR}>"
"$<INSTALL_INTERFACE:${PROJECTM_INCLUDE_DIR}>"
)

View File

@ -1,489 +0,0 @@
/*
* dlfcn-win32
* Copyright (c) 2007 Ramiro Polla
* Copyright (c) 2015 Tiancheng "Timothy" Gu
*
* dlfcn-win32 is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* dlfcn-win32 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with dlfcn-win32; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
#define PSAPI_VERSION 1
#include <windows.h>
#include <psapi.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef SHARED
#define DLFCN_WIN32_EXPORTS
#endif
#include "dlfcn.h"
#if ((defined(_WIN32) || defined(WIN32)) && (defined(_MSC_VER)) )
#define snprintf sprintf_s
#endif
#ifdef UNICODE
#include <wchar.h>
#define CHAR wchar_t
#define UNICODE_L(s) L##s
#else
#define CHAR char
#define UNICODE_L(s) s
#endif
/* Note:
* MSDN says these functions are not thread-safe. We make no efforts to have
* any kind of thread safety.
*/
typedef struct global_object {
HMODULE hModule;
struct global_object *previous;
struct global_object *next;
} global_object;
static global_object first_object;
static global_object first_automatic_object;
static int auto_ref_count = 0;
/* These functions implement a double linked list for the global objects. */
static global_object *global_search( global_object *start, HMODULE hModule )
{
global_object *pobject;
if( hModule == NULL )
return NULL;
for( pobject = start; pobject; pobject = pobject->next )
if( pobject->hModule == hModule )
return pobject;
return NULL;
}
static void global_add( global_object *start, HMODULE hModule )
{
global_object *pobject;
global_object *nobject;
if( hModule == NULL )
return;
pobject = global_search( start, hModule );
/* Do not add object again if it's already on the list */
if( pobject )
return;
if( start == &first_automatic_object )
{
pobject = global_search( &first_object, hModule );
if( pobject )
return;
}
for( pobject = start; pobject->next; pobject = pobject->next );
nobject = (global_object*) malloc( sizeof( global_object ) );
/* Should this be enough to fail global_add, and therefore also fail
* dlopen?
*/
if( !nobject )
return;
pobject->next = nobject;
nobject->next = NULL;
nobject->previous = pobject;
nobject->hModule = hModule;
}
static void global_rem( global_object *start, HMODULE hModule )
{
global_object *pobject;
if( hModule == NULL )
return;
pobject = global_search( start, hModule );
if( !pobject )
return;
if( pobject->next )
pobject->next->previous = pobject->previous;
if( pobject->previous )
pobject->previous->next = pobject->next;
free( pobject );
}
/* POSIX says dlerror( ) doesn't have to be thread-safe, so we use one
* static buffer.
* MSDN says the buffer cannot be larger than 64K bytes, so we set it to
* the limit.
*/
static CHAR error_buffer[65535];
static CHAR *current_error;
static char dlerror_buffer[65536];
static int copy_string( CHAR *dest, int dest_size, const CHAR *src )
{
int i = 0;
/* gcc should optimize this out */
if( !src || !dest )
return 0;
for( i = 0 ; i < dest_size-1 ; i++ )
{
if( !src[i] )
break;
else
dest[i] = src[i];
}
dest[i] = '\0';
return i;
}
static void save_err_str( const CHAR *str )
{
DWORD dwMessageId;
DWORD pos;
dwMessageId = GetLastError( );
if( dwMessageId == 0 )
return;
/* Format error message to:
* "<argument to function that failed>": <Windows localized error message>
*/
pos = copy_string( error_buffer, sizeof(error_buffer), UNICODE_L("\"") );
pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, str );
pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, UNICODE_L("\": ") );
pos += FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
error_buffer+pos, sizeof(error_buffer)-pos, NULL );
if( pos > 1 )
{
/* POSIX says the string must not have trailing <newline> */
if( error_buffer[pos-2] == '\r' && error_buffer[pos-1] == '\n' )
error_buffer[pos-2] = '\0';
}
current_error = error_buffer;
}
static void save_err_ptr_str( const void *ptr )
{
CHAR ptr_buf[19]; /* 0x<pointer> up to 64 bits. */
#ifdef UNICODE
# if ((defined(_WIN32) || defined(WIN32)) && (defined(_MSC_VER)) )
swprintf_s( ptr_buf, 19, UNICODE_L("0x%p"), ptr );
# else
swprintf(ptr_buf, 19, UNICODE_L("0x%p"), ptr);
# endif
#else
snprintf( ptr_buf, 19, "0x%p", ptr );
#endif
save_err_str( ptr_buf );
}
void *dlopen( const char *file, int mode )
{
HMODULE hModule;
UINT uMode;
current_error = NULL;
/* Do not let Windows display the critical-error-handler message box */
uMode = SetErrorMode( SEM_FAILCRITICALERRORS );
if( file == 0 )
{
HMODULE hAddtnlMods[1024]; // Already loaded modules
HANDLE hCurrentProc = GetCurrentProcess( );
DWORD cbNeeded;
/* POSIX says that if the value of file is 0, a handle on a global
* symbol object must be provided. That object must be able to access
* all symbols from the original program file, and any objects loaded
* with the RTLD_GLOBAL flag.
* The return value from GetModuleHandle( ) allows us to retrieve
* symbols only from the original program file. For objects loaded with
* the RTLD_GLOBAL flag, we create our own list later on. For objects
* outside of the program file but already loaded (e.g. linked DLLs)
* they are added below.
*/
hModule = GetModuleHandle( NULL );
if( !hModule )
save_err_ptr_str( file );
/* GetModuleHandle( NULL ) only returns the current program file. So
* if we want to get ALL loaded module including those in linked DLLs,
* we have to use EnumProcessModules( ).
*/
if( EnumProcessModules( hCurrentProc, hAddtnlMods,
sizeof( hAddtnlMods ), &cbNeeded ) != 0 )
{
DWORD i;
for( i = 0; i < cbNeeded / sizeof( HMODULE ); i++ )
{
global_add( &first_automatic_object, hAddtnlMods[i] );
}
}
auto_ref_count++;
}
else
{
CHAR lpFileName[MAX_PATH];
int i;
/* MSDN says backslashes *must* be used instead of forward slashes. */
for( i = 0 ; i < sizeof(lpFileName) - 1 ; i ++ )
{
if( !file[i] )
break;
else if( file[i] == '/' )
lpFileName[i] = '\\';
else
lpFileName[i] = file[i];
}
lpFileName[i] = '\0';
/* POSIX says the search path is implementation-defined.
* LOAD_WITH_ALTERED_SEARCH_PATH is used to make it behave more closely
* to UNIX's search paths (start with system folders instead of current
* folder).
*/
hModule = LoadLibraryEx(lpFileName, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH );
/* If the object was loaded with RTLD_GLOBAL, add it to list of global
* objects, so that its symbols may be retrieved even if the handle for
* the original program file is passed. POSIX says that if the same
* file is specified in multiple invocations, and any of them are
* RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the
* symbols will remain global.
*/
if( !hModule )
save_err_str( lpFileName );
else if( (mode & RTLD_GLOBAL) )
global_add( &first_object, hModule );
}
/* Return to previous state of the error-mode bit flags. */
SetErrorMode( uMode );
return (void *) hModule;
}
static void free_auto( )
{
global_object *pobject = first_automatic_object.next;
if( pobject )
{
global_object *next;
for ( ; pobject; pobject = next )
{
next = pobject->next;
free( pobject );
}
first_automatic_object.next = NULL;
}
}
int dlclose( void *handle )
{
HMODULE hModule = (HMODULE) handle;
BOOL ret;
current_error = NULL;
ret = FreeLibrary( hModule );
/* If the object was loaded with RTLD_GLOBAL, remove it from list of global
* objects.
*/
if( ret )
{
HMODULE cur = GetModuleHandle( NULL );
global_rem( &first_object, hModule );
if( hModule == cur )
{
auto_ref_count--;
if( auto_ref_count < 0 )
auto_ref_count = 0;
if( !auto_ref_count )
free_auto( );
}
}
else
save_err_ptr_str( handle );
/* dlclose's return value in inverted in relation to FreeLibrary's. */
ret = !ret;
return (int) ret;
}
void *dlsym( void *handle, const char *name )
{
FARPROC symbol;
HMODULE hModule;
#ifdef UNICODE
wchar_t namew[MAX_PATH];
wmemset(namew, 0, MAX_PATH);
#endif
current_error = NULL;
symbol = GetProcAddress( (HMODULE) handle, name );
if( symbol != NULL )
goto end;
/* If the handle for the original program file is passed, also search
* in all globally loaded objects.
*/
hModule = GetModuleHandle( NULL );
if( hModule == handle )
{
global_object *pobject;
for( pobject = &first_object; pobject; pobject = pobject->next )
{
if( pobject->hModule )
{
symbol = GetProcAddress( pobject->hModule, name );
if( symbol != NULL )
goto end;
}
}
for( pobject = &first_automatic_object; pobject; pobject = pobject->next )
{
if( pobject->hModule )
{
symbol = GetProcAddress( pobject->hModule, name );
if( symbol != NULL )
goto end;
}
}
}
end:
if( symbol == NULL )
{
#ifdef UNICODE
size_t converted_chars;
size_t str_len = strlen(name) + 1;
#if ((defined(_WIN32) || defined(WIN32)) && (defined(_MSC_VER)) )
errno_t err = mbstowcs_s(&converted_chars, namew, str_len, name, str_len);
if (err != 0)
return NULL;
#else
mbstowcs(namew, name, str_len);
#endif
save_err_str( namew );
#else
save_err_str( name );
#endif
}
// warning C4054: 'type cast' : from function pointer 'FARPROC' to data pointer 'void *'
#ifdef _MSC_VER
#pragma warning( suppress: 4054 )
#endif
return (void*) symbol;
}
char *dlerror( void )
{
char *error_pointer = dlerror_buffer;
/* If this is the second consecutive call to dlerror, return NULL */
if (current_error == NULL)
{
return NULL;
}
#ifdef UNICODE
errno_t err = 0;
size_t converted_chars = 0;
size_t str_len = wcslen(current_error) + 1;
memset(error_pointer, 0, 65535);
# if ((defined(_WIN32) || defined(WIN32)) && (defined(_MSC_VER)) )
err = wcstombs_s(&converted_chars,
error_pointer, str_len * sizeof(char),
current_error, str_len * sizeof(wchar_t));
if (err != 0)
return NULL;
# else
wcstombs(error_pointer, current_error, str_len);
# endif
#else
memcpy(error_pointer, current_error, strlen(current_error) + 1);
#endif
/* POSIX says that invoking dlerror( ) a second time, immediately following
* a prior invocation, shall result in NULL being returned.
*/
current_error = NULL;
return error_pointer;
}
#ifdef SHARED
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
(void) hinstDLL;
/*
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
*
* When handling DLL_PROCESS_DETACH, a DLL should free resources such as heap
* memory only if the DLL is being unloaded dynamically (the lpReserved
* parameter is NULL).
*/
if( fdwReason == DLL_PROCESS_DETACH && !lpvReserved )
{
auto_ref_count = 0;
free_auto( );
}
return TRUE;
}
#endif

View File

@ -1,59 +0,0 @@
/*
* dlfcn-win32
* Copyright (c) 2007 Ramiro Polla
*
* dlfcn-win32 is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* dlfcn-win32 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with dlfcn-win32; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef DLFCN_H
#define DLFCN_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(DLFCN_WIN32_EXPORTS)
# define DLFCN_EXPORT __declspec(dllexport)
#else
# define DLFCN_EXPORT
#endif
/* POSIX says these are implementation-defined.
* To simplify use with Windows API, we treat them the same way.
*/
#define RTLD_LAZY 0
#define RTLD_NOW 0
#define RTLD_GLOBAL (1 << 1)
#define RTLD_LOCAL (1 << 2)
/* These two were added in The Open Group Base Specifications Issue 6.
* Note: All other RTLD_* flags in any dlfcn.h are not standard compliant.
*/
#define RTLD_DEFAULT 0
#define RTLD_NEXT 0
DLFCN_EXPORT void *dlopen ( const char *file, int mode );
DLFCN_EXPORT int dlclose(void *handle);
DLFCN_EXPORT void *dlsym(void *handle, const char *name);
DLFCN_EXPORT char *dlerror(void);
#ifdef __cplusplus
}
#endif
#endif /* DLFCN_H */