mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-03-30 19:23:45 +00:00
267 lines
8.9 KiB
C++
267 lines
8.9 KiB
C++
#include "PerFrameContext.hpp"
|
|
|
|
#include "MilkdropPresetExceptions.hpp"
|
|
|
|
#ifdef MILKDROP_PRESET_DEBUG
|
|
#include <iostream>
|
|
#endif
|
|
|
|
#define REG_VAR(var) \
|
|
var = projectm_eval_context_register_variable(perFrameCodeContext, #var);
|
|
|
|
namespace libprojectM {
|
|
namespace MilkdropPreset {
|
|
|
|
PerFrameContext::PerFrameContext(projectm_eval_mem_buffer gmegabuf, PRJM_EVAL_F (*globalRegisters)[100])
|
|
: perFrameCodeContext(projectm_eval_context_create(gmegabuf, globalRegisters))
|
|
{
|
|
}
|
|
|
|
PerFrameContext::~PerFrameContext()
|
|
{
|
|
if (perFrameCodeHandle != nullptr)
|
|
{
|
|
projectm_eval_code_destroy(perFrameCodeHandle);
|
|
}
|
|
|
|
if (perFrameCodeContext != nullptr)
|
|
{
|
|
projectm_eval_context_destroy(perFrameCodeContext);
|
|
}
|
|
}
|
|
|
|
void PerFrameContext::RegisterBuiltinVariables()
|
|
{
|
|
projectm_eval_context_reset_variables(perFrameCodeContext);
|
|
|
|
REG_VAR(zoom);
|
|
REG_VAR(zoomexp);
|
|
REG_VAR(rot);
|
|
REG_VAR(warp);
|
|
REG_VAR(cx);
|
|
REG_VAR(cy);
|
|
REG_VAR(dx);
|
|
REG_VAR(dy);
|
|
REG_VAR(sx);
|
|
REG_VAR(sy);
|
|
REG_VAR(time);
|
|
REG_VAR(fps);
|
|
REG_VAR(bass);
|
|
REG_VAR(mid);
|
|
REG_VAR(treb);
|
|
REG_VAR(bass_att);
|
|
REG_VAR(mid_att);
|
|
REG_VAR(treb_att);
|
|
REG_VAR(frame);
|
|
REG_VAR(decay);
|
|
REG_VAR(wave_a);
|
|
REG_VAR(wave_r);
|
|
REG_VAR(wave_g);
|
|
REG_VAR(wave_b);
|
|
REG_VAR(wave_x);
|
|
REG_VAR(wave_y);
|
|
REG_VAR(wave_mystery);
|
|
REG_VAR(wave_mode);
|
|
for (int q = 0; q < QVarCount; q++)
|
|
{
|
|
std::string qvar = "q" + std::to_string(q + 1);
|
|
q_vars[q] = projectm_eval_context_register_variable(perFrameCodeContext, qvar.c_str());
|
|
}
|
|
REG_VAR(progress);
|
|
REG_VAR(ob_size);
|
|
REG_VAR(ob_r);
|
|
REG_VAR(ob_g);
|
|
REG_VAR(ob_b);
|
|
REG_VAR(ob_a);
|
|
REG_VAR(ib_size);
|
|
REG_VAR(ib_r);
|
|
REG_VAR(ib_g);
|
|
REG_VAR(ib_b);
|
|
REG_VAR(ib_a);
|
|
REG_VAR(mv_x);
|
|
REG_VAR(mv_y);
|
|
REG_VAR(mv_dx);
|
|
REG_VAR(mv_dy);
|
|
REG_VAR(mv_l);
|
|
REG_VAR(mv_r);
|
|
REG_VAR(mv_g);
|
|
REG_VAR(mv_b);
|
|
REG_VAR(mv_a);
|
|
REG_VAR(echo_zoom);
|
|
REG_VAR(echo_alpha);
|
|
REG_VAR(echo_orient);
|
|
REG_VAR(wave_usedots);
|
|
REG_VAR(wave_thick);
|
|
REG_VAR(wave_additive);
|
|
REG_VAR(wave_brighten);
|
|
REG_VAR(darken_center);
|
|
REG_VAR(gamma);
|
|
REG_VAR(wrap);
|
|
REG_VAR(invert);
|
|
REG_VAR(brighten);
|
|
REG_VAR(darken);
|
|
REG_VAR(solarize);
|
|
REG_VAR(meshx);
|
|
REG_VAR(meshy);
|
|
REG_VAR(pixelsx);
|
|
REG_VAR(pixelsy);
|
|
REG_VAR(aspectx);
|
|
REG_VAR(aspecty);
|
|
REG_VAR(blur1_min);
|
|
REG_VAR(blur2_min);
|
|
REG_VAR(blur3_min);
|
|
REG_VAR(blur1_max);
|
|
REG_VAR(blur2_max);
|
|
REG_VAR(blur3_max);
|
|
REG_VAR(blur1_edge_darken);
|
|
}
|
|
|
|
void PerFrameContext::EvaluateInitCode(PresetState& state)
|
|
{
|
|
if (state.perFrameInitCode.empty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto* initCode = projectm_eval_code_compile(perFrameCodeContext, state.perFrameInitCode.c_str());
|
|
if (initCode == nullptr)
|
|
{
|
|
#ifdef MILKDROP_PRESET_DEBUG
|
|
int line;
|
|
int col;
|
|
auto* errmsg = projectm_eval_get_error(perFrameCodeContext, &line, &col);
|
|
if (errmsg)
|
|
{
|
|
std::cerr << "[Preset] Could not compile per-frame INIT code: " << errmsg << "(L" << line << " C" << col << ")" << std::endl;
|
|
}
|
|
#endif
|
|
throw MilkdropCompileException("Could not compile per-frame init code");
|
|
}
|
|
|
|
projectm_eval_code_execute(initCode);
|
|
projectm_eval_code_destroy(initCode);
|
|
|
|
for (int q = 0; q < QVarCount; q++)
|
|
{
|
|
q_values_after_init_code[q] = *q_vars[q];
|
|
state.frameQVariables[q] = *q_vars[q];
|
|
}
|
|
}
|
|
|
|
void PerFrameContext::LoadStateVariables(PresetState& state)
|
|
{
|
|
*zoom = static_cast<PRJM_EVAL_F>(state.zoom);
|
|
*zoomexp = static_cast<PRJM_EVAL_F>(state.zoomExponent);
|
|
*rot = static_cast<PRJM_EVAL_F>(state.rot);
|
|
*warp = static_cast<PRJM_EVAL_F>(state.warpAmount);
|
|
*cx = static_cast<PRJM_EVAL_F>(state.rotCX);
|
|
*cy = static_cast<PRJM_EVAL_F>(state.rotCY);
|
|
*dx = static_cast<PRJM_EVAL_F>(state.xPush);
|
|
*dy = static_cast<PRJM_EVAL_F>(state.yPush);
|
|
*sx = static_cast<PRJM_EVAL_F>(state.stretchX);
|
|
*sy = static_cast<PRJM_EVAL_F>(state.stretchY);
|
|
*time = static_cast<PRJM_EVAL_F>(state.renderContext.time);
|
|
*fps = static_cast<PRJM_EVAL_F>(state.renderContext.fps);
|
|
*bass = static_cast<PRJM_EVAL_F>(state.audioData.bass);
|
|
*mid = static_cast<PRJM_EVAL_F>(state.audioData.mid);
|
|
*treb = static_cast<PRJM_EVAL_F>(state.audioData.treb);
|
|
*bass_att = static_cast<PRJM_EVAL_F>(state.audioData.bassAtt);
|
|
*mid_att = static_cast<PRJM_EVAL_F>(state.audioData.midAtt);
|
|
*treb_att = static_cast<PRJM_EVAL_F>(state.audioData.trebAtt);
|
|
*frame = static_cast<PRJM_EVAL_F>(state.renderContext.frame);
|
|
for (int q = 0; q < QVarCount; q++)
|
|
{
|
|
*q_vars[q] = q_values_after_init_code[q];
|
|
}
|
|
*progress = static_cast<PRJM_EVAL_F>(state.renderContext.progress);
|
|
*decay = static_cast<PRJM_EVAL_F>(state.decay);
|
|
*wave_a = static_cast<PRJM_EVAL_F>(state.waveAlpha);
|
|
*wave_r = static_cast<PRJM_EVAL_F>(state.waveR);
|
|
*wave_g = static_cast<PRJM_EVAL_F>(state.waveG);
|
|
*wave_b = static_cast<PRJM_EVAL_F>(state.waveB);
|
|
*wave_x = static_cast<PRJM_EVAL_F>(state.waveX);
|
|
*wave_y = static_cast<PRJM_EVAL_F>(state.waveY);
|
|
*wave_mystery = static_cast<PRJM_EVAL_F>(state.waveParam);
|
|
*wave_mode = static_cast<PRJM_EVAL_F>(state.waveMode);
|
|
*ob_size = static_cast<PRJM_EVAL_F>(state.outerBorderSize);
|
|
*ob_r = static_cast<PRJM_EVAL_F>(state.outerBorderR);
|
|
*ob_g = static_cast<PRJM_EVAL_F>(state.outerBorderG);
|
|
*ob_b = static_cast<PRJM_EVAL_F>(state.outerBorderB);
|
|
*ob_a = static_cast<PRJM_EVAL_F>(state.outerBorderA);
|
|
*ib_size = static_cast<PRJM_EVAL_F>(state.innerBorderSize);
|
|
*ib_r = static_cast<PRJM_EVAL_F>(state.innerBorderR);
|
|
*ib_g = static_cast<PRJM_EVAL_F>(state.innerBorderG);
|
|
*ib_b = static_cast<PRJM_EVAL_F>(state.innerBorderB);
|
|
*ib_a = static_cast<PRJM_EVAL_F>(state.innerBorderA);
|
|
*mv_x = static_cast<PRJM_EVAL_F>(state.mvX);
|
|
*mv_y = static_cast<PRJM_EVAL_F>(state.mvY);
|
|
*mv_dx = static_cast<PRJM_EVAL_F>(state.mvDX);
|
|
*mv_dy = static_cast<PRJM_EVAL_F>(state.mvDY);
|
|
*mv_l = static_cast<PRJM_EVAL_F>(state.mvL);
|
|
*mv_r = static_cast<PRJM_EVAL_F>(state.mvR);
|
|
*mv_g = static_cast<PRJM_EVAL_F>(state.mvG);
|
|
*mv_b = static_cast<PRJM_EVAL_F>(state.mvB);
|
|
*mv_a = static_cast<PRJM_EVAL_F>(state.mvA);
|
|
*echo_zoom = static_cast<PRJM_EVAL_F>(state.videoEchoZoom);
|
|
*echo_alpha = static_cast<PRJM_EVAL_F>(state.videoEchoAlpha);
|
|
*echo_orient = static_cast<PRJM_EVAL_F>(state.videoEchoOrientation);
|
|
*wave_usedots = static_cast<PRJM_EVAL_F>(state.waveDots);
|
|
*wave_thick = static_cast<PRJM_EVAL_F>(state.waveThick);
|
|
*wave_additive = static_cast<PRJM_EVAL_F>(state.additiveWaves);
|
|
*wave_brighten = static_cast<PRJM_EVAL_F>(state.maximizeWaveColor);
|
|
*darken_center = static_cast<PRJM_EVAL_F>(state.darkenCenter);
|
|
*gamma = static_cast<PRJM_EVAL_F>(state.gammaAdj);
|
|
*wrap = static_cast<PRJM_EVAL_F>(state.texWrap);
|
|
*invert = static_cast<PRJM_EVAL_F>(state.invert);
|
|
*brighten = static_cast<PRJM_EVAL_F>(state.brighten);
|
|
*darken = static_cast<PRJM_EVAL_F>(state.darken);
|
|
*solarize = static_cast<PRJM_EVAL_F>(state.solarize);
|
|
*meshx = static_cast<PRJM_EVAL_F>(state.renderContext.perPixelMeshX);
|
|
*meshy = static_cast<PRJM_EVAL_F>(state.renderContext.perPixelMeshY);
|
|
*pixelsx = static_cast<PRJM_EVAL_F>(state.renderContext.viewportSizeX);
|
|
*pixelsy = static_cast<PRJM_EVAL_F>(state.renderContext.viewportSizeY);
|
|
*aspectx = static_cast<PRJM_EVAL_F>(state.renderContext.invAspectX);
|
|
*aspecty = static_cast<PRJM_EVAL_F>(state.renderContext.invAspectY);
|
|
*blur1_min = static_cast<PRJM_EVAL_F>(state.blur1Min);
|
|
*blur2_min = static_cast<PRJM_EVAL_F>(state.blur2Min);
|
|
*blur3_min = static_cast<PRJM_EVAL_F>(state.blur3Min);
|
|
*blur1_max = static_cast<PRJM_EVAL_F>(state.blur1Max);
|
|
*blur2_max = static_cast<PRJM_EVAL_F>(state.blur2Max);
|
|
*blur3_max = static_cast<PRJM_EVAL_F>(state.blur3Max);
|
|
*blur1_edge_darken = static_cast<PRJM_EVAL_F>(state.blur1EdgeDarken);
|
|
}
|
|
|
|
void PerFrameContext::CompilePerFrameCode(const std::string& perFrameCode)
|
|
{
|
|
if (perFrameCode.empty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
perFrameCodeHandle = projectm_eval_code_compile(perFrameCodeContext, perFrameCode.c_str());
|
|
if (perFrameCodeHandle == nullptr)
|
|
{
|
|
#ifdef MILKDROP_PRESET_DEBUG
|
|
int line;
|
|
int col;
|
|
auto* errmsg = projectm_eval_get_error(perFrameCodeContext, &line, &col);
|
|
if (errmsg)
|
|
{
|
|
std::cerr << "[Preset] Could not compile per-frame code: " << errmsg << "(L" << line << " C" << col << ")" << std::endl;
|
|
}
|
|
#endif
|
|
throw MilkdropCompileException("Could not compile per-frame code");
|
|
}
|
|
}
|
|
|
|
void PerFrameContext::ExecutePerFrameCode()
|
|
{
|
|
if (perFrameCodeHandle != nullptr)
|
|
{
|
|
projectm_eval_code_execute(perFrameCodeHandle);
|
|
}
|
|
}
|
|
|
|
} // namespace MilkdropPreset
|
|
} // namespace libprojectM
|