I was just wondering if there anyway for the config to call upon blade styles from the sd card in the fonts folders to save space (and allow the config to have more then 7 to 10 fonts active at a time) without using Edit Mode?
tl; dr; no, sort of, no, maybe
confused yet?
the short answer is that no, thatās not possible.
The longer answer is that it might be possible, but itās either limited or hard.
The limited version is to prepare a bunch of styles with parameters, these parameters can then be altered with editor mode, or the proffieos workbench. This can create thousands of different combinations without using up more flash memory.
The UNLIMITED version, is to compile the entire blade style into a dynamically loaded machine code object. It is far more complicated, and is unlikely to happen. Besides, it would mean loading the code into RAM, and there might not be enough RAM to do that.
So far, the strategy has always been two-fold:
- Invent new ways to save memory. This has limited impact, but helps. Of course, every time I save a kilobyte or two, someone comes up with a more complicated blade style. One step forward, two steps backā¦
- Work on building proffieboards with more memory.
Unfortunately (2) has been severely hampered by the chip shortage, or it would have already happened⦠![]()
More relevant information if you donāt already know it:
Iād recommend using the library to generate all of your styles, I can typically fit 20+ āoptionā styles on a saber and then with the āoptionā capabilities turn that into thousands of unique presets as Fredrik noted.
If youāre mixing older or non-optimized styles with newer ones youāre probably wasting a lot of memory as well. If you generate all of your styles in the library their syntax will typically save additional memory versus mixing all different syntaxes and versions together.
You also should make sure you have all of the memory saving defines enabled as 7 to 10 seems really low unless you have multiple blades with really complex styles.
You can post your CONFIG_TOP section if you want us to check your defines for you ![]()
#ifdef CONFIG_TOP
#include "proffieboard_v2_config.h"
#define NUM_BLADES 1
#define NUM_BUTTONS 1
#define VOLUME 1800
const unsigned int maxLedsPerStrip = 144;
#define CLASH_THRESHOLD_G 2.5
#define ENABLE_AUDIO
#define ENABLE_MOTION
#define ENABLE_WS2811
#define ENABLE_SD
#define ENABLE_SERIAL
#define ENABLE_AUTO_SWING_BLAST
#define COLOR_CHANGE_DIRECT
#define DISABLE_DIAGNOSTIC_COMMANDS
#define BC_TWIST_OFF
#define BC_TWIST_ON
#define BC_STAB_ON
#define BC_THRUST_ON
#define FEMALE_TALKIE_VOICE
#define VOLUME_MENU_CYCLE
#define IDLE_OFF_TIME 60 * 5 * 1000
#define SPEAK_BLADE_ID
#endif
i have 2 fonts from Grayscalefonts and there are alot of // that when i try to remove i get errors and iām guessing that just thoses to fonts are taking up a lot of space but i also really like theses bladestyles too much to not have them
StylePtr<Layers<
StyleFire<BrownNoiseFlicker<RotateColorsX<Variation,Red>,RandomPerLEDFlicker<RotateColorsX<Variation,Rgb16<11805,0,1587>>,RotateColorsX<Variation,Rgb<60,0,0>>>,300>,RotateColorsX<Variation,Rgb<80,0,0>>,0,6,FireConfig<10,1000,2>,FireConfig<10,1000,2>,FireConfig<10,1000,2>,FireConfig<10,1000,2>>,
//Unstable red/pink
TransitionEffectL<TrConcat<TrFade<200>,AlphaL<RotateColorsX<Variation,DeepPink>,SwingSpeed<400>>,TrDelay<30000>,AlphaL<RotateColorsX<Variation,DeepPink>,SwingSpeed<400>>,TrFade<800>>,EFFECT_FORCE>,
//Force effect, temporarily allows color change based on swing speed
AlphaL<AudioFlickerL<RotateColorsX<Variation,DeepPink>>,SwingSpeed<400>>,
//Swing effect, audioflicker, Deep Pink connects the tip and emitter when swinging
LockupTrL<Layers<
AlphaL<AudioFlickerL<Rgb<255,225,0>>,Bump<Scale<BladeAngle<>,Scale<BladeAngle<0,16000>,Int<4000>,Int<26000>>,Int<6000>>,Scale<SwingSpeed<100>,Int<14000>,Int<18000>>>>,
AlphaL<NavajoWhite,Bump<Scale<BladeAngle<>,Scale<BladeAngle<0,16000>,Int<4000>,Int<26000>>,Int<6000>>,Int<10000>>>>,TrConcat<TrInstant,White,TrFade<400>>,TrConcat<TrInstant,AlphaL<White,Int<0>>,TrWaveX<TransitionEffect<NavajoWhite,Rgb<255,225,0>,TrInstant,TrFade<200>,EFFECT_LOCKUP_BEGIN>,Int<300>,Int<100>,Int<400>,Scale<BladeAngle<>,Scale<BladeAngle<0,16000>,Int<4000>,Int<26000>>,Int<6000>>>>,SaberBase::LOCKUP_NORMAL>,
//Responsive lockup
ResponsiveLightningBlockL<Strobe<White,AudioFlicker<White,Blue>,50,1>,TrConcat<TrInstant,AlphaL<White,Bump<Int<12000>,Int<18000>>>,TrFade<200>>,TrConcat<TrInstant,HumpFlickerL<AlphaL<White,Int<16000>>,30>,TrSmoothFade<600>>>,
//Responsive lightning block
AlphaL<RotateColorsX<Variation,DeepPink>,SmoothStep<Scale<SlowNoise<Int<2500>>,Int<1500>,Int<4500>>,Int<-6000>>>,
//Sparking emitter flare
ResponsiveStabL<Orange>,
//Responsive stab
EffectSequence<EFFECT_BLAST,TransitionEffectL<TrConcat<TrInstant,AlphaL<White,BlastF<200,200>>,TrFade<300>>,EFFECT_BLAST>,ResponsiveBlastL<White,Int<400>,Scale<SwingSpeed<200>,Int<100>,Int<400>>,Int<400>>,ResponsiveBlastWaveL<White,Scale<SwingSpeed<400>,Int<500>,Int<200>>,Scale<SwingSpeed<400>,Int<100>,Int<400>>>,ResponsiveBlastFadeL<White,Scale<SwingSpeed<400>,Int<6000>,Int<12000>>,Scale<SwingSpeed<400>,Int<400>,Int<100>>>,ResponsiveBlastL<White,Scale<SwingSpeed<400>,Int<400>,Int<100>>,Scale<SwingSpeed<400>,Int<200>,Int<100>>,Scale<SwingSpeed<400>,Int<400>,Int<200>>>>,
//Multi-blast, blaster reflect cycles through different responsive effects
ResponsiveClashL<TransitionEffect<Rgb<255,240,80>,LemonChiffon,TrInstant,TrFade<100>,EFFECT_CLASH>,TrInstant,TrFade<400>,Scale<BladeAngle<0,16000>,Int<4000>,Int<26000>>,Int<6000>,Int<20000>>,
//Responsive clash
TransitionEffectL<TrConcat<TrInstant,Stripes<3000,-3500,RotateColorsX<Variation,Rgb<255,150,150>>,RandomPerLEDFlicker<RotateColorsX<Variation,Rgb<60,0,0>>,Black>,BrownNoiseFlicker<RotateColorsX<Variation,DeepPink>,RotateColorsX<Variation,Rgb<60,0,0>>,200>,RandomPerLEDFlicker<RotateColorsX<Variation,Rgb<128,0,0>>,RotateColorsX<Variation,Rgb<60,0,0>>>>,TrFade<1200>>,EFFECT_IGNITION>,
//Unstable ignition effect
AlphaL<RotateColorsX<Variation,DeepPink>,SmoothStep<Scale<SlowNoise<Int<2500>>,Int<28000>,Int<33000>>,Int<10000>>>,
//Sparking tip flare
LockupTrL<AlphaL<BrownNoiseFlickerL<White,Int<300>>,SmoothStep<Int<30000>,Int<5000>>>,TrWipeIn<400>,TrFade<300>,SaberBase::LOCKUP_DRAG>,
//Drag
LockupTrL<AlphaL<Mix<TwistAngle<>,Rgb<255,200,0>,DarkOrange>,SmoothStep<Int<28000>,Int<5000>>>,TrWipeIn<600>,TrFade<300>,SaberBase::LOCKUP_MELT>,
//Responsive melt
EffectSequence<EFFECT_POWERSAVE,AlphaL<Black,Int<8192>>,AlphaL<Black,Int<16384>>,AlphaL<Black,Int<24576>>,AlphaL<Black,Int<0>>>,
//Power save, if using fett263's prop file hold Aux and click PWR while ON (pointing up) to dim blade in 25% increments.
InOutTrL<TrWipeSparkTip<White,100>,TrColorCycle<1065>>,
//Spark tip ignition, cycle down retraction
//TransitionEffectL<TrConcat<TrDelay<1500>,Black,TrFade<1000>,AlphaL<Mix<BatteryLevel,Red,Green>,Bump<Int<0>,Int<6000>>>,TrFade<3000>>,EFFECT_BOOT>,
//TransitionEffectL<TrConcat<TrInstant,AlphaL<Mix<BatteryLevel,Red,Green>,Bump<Int<0>,Int<6000>>>,TrFade<3000>>,EFFECT_NEWFONT>,
//Optional/alternate passive battery monitor, on boot (1st line) or font change (2nd line) you will get a visual indicator at the emitter of your current battery level. This also works without a blade if you have a lit emitter or blade plug. Green is Full, Red is Low (the color will blend from Green to Red as the battery is depleted), the indicator will fade out after 3000 ms and not display again until powered down and back up or fonts change.
TransitionEffectL<TrConcat<TrInstant,AlphaL<Mix<BatteryLevel,Red,Green>,Bump<BatteryLevel,Int<10000>>>,TrDelay<2000>,AlphaL<Mix<BatteryLevel,Red,Green>,Bump<BatteryLevel,Int<10000>>>,TrFade<1000>>,EFFECT_BATTERY_LEVEL>,
//On demand battery level, if using fett263's prop file Hold AUX and click PWR while OFF, the battery level is represented by the location on the blade; tip = full, hilt = low and color; green = full, yellow = half, red = low
TransitionEffectL<TrConcat<TrInstant,AlphaL<Mix<Sin<Scale<Trigger<EFFECT_RETRACTION,Int<3000>,Int<1000>,Int<500>>,Int<70>,Int<550>>>,RotateColorsX<Variation,DeepPink>,RotateColorsX<Variation,Rgb16<65535,0,2716>>>,Bump<Scale<Trigger<EFFECT_PREON,Int<3000>,Int<1000>,Int<500>>,Int<41000>,Int<32768>>>>,TrDelay<3000>>,EFFECT_PREON>,
TransitionEffectL<TrConcat<TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,DeepPink>,Bump<Int<0>,Int<4000>>>,TrFade<520>>,TrWaveX<RotateColorsX<Variation,DeepPink>,Int<520>,Int<550>,Int<520>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Bump<Int<0>,Int<4000>>>,TrFade<420>>,TrWaveX<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Int<420>,Int<450>,Int<420>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,DeepPink>,Bump<Int<0>,Int<4000>>>,TrFade<340>>,TrWaveX<RotateColorsX<Variation,DeepPink>,Int<340>,Int<430>,Int<340>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Bump<Int<0>,Int<4000>>>,TrFade<300>>,TrWaveX<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Int<300>,Int<400>,Int<300>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,DeepPink>,Bump<Int<0>,Int<4000>>>,TrFade<240>>,TrWaveX<RotateColorsX<Variation,DeepPink>,Int<240>,Int<380>,Int<240>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Bump<Int<0>,Int<4000>>>,TrFade<210>>,TrWaveX<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Int<210>,Int<360>,Int<210>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,DeepPink>,Bump<Int<0>,Int<4000>>>,TrFade<190>>,TrWaveX<RotateColorsX<Variation,DeepPink>,Int<190>,Int<340>,Int<190>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Bump<Int<0>,Int<4000>>>,TrFade<170>>,TrWaveX<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Int<170>,Int<320>,Int<170>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,DeepPink>,Bump<Int<0>,Int<4000>>>,TrFade<160>>,TrWaveX<RotateColorsX<Variation,DeepPink>,Int<160>,Int<300>,Int<160>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Bump<Int<0>,Int<4000>>>,TrFade<150>>,TrWaveX<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Int<150>,Int<250>,Int<150>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,DeepPink>,Bump<Int<0>,Int<4000>>>,TrFade<130>>,TrWaveX<RotateColorsX<Variation,DeepPink>,Int<130>,Int<150>,Int<130>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Bump<Int<0>,Int<4000>>>,TrFade<100>>,TrWaveX<RotateColorsX<Variation,Rgb16<65535,0,2716>>,Int<100>,Int<100>,Int<100>,Int<0>>>,AlphaL<Black,Int<0>>,TrJoin<TrConcat<TrInstant,AlphaL<RotateColorsX<Variation,DeepPink>,Bump<Int<0>,Int<4000>>>,TrFade<70>>,TrWaveX<RotateColorsX<Variation,DeepPink>,Int<70>,Int<500>,Int<70>,Int<0>>>,Black,TrInstant>,EFFECT_PREON>
//Preon effect, HUGE thanks to /u/NoSloppy for this!
>>()
StylePtr<Layers<
StripesX<Int<3500>,Int<1200>,Mix<Sin<Int<20>>,RotateColorsX<Variation,Rgb<95,0,210>>,RotateColorsX<Variation,Rgb<75,0,165>>>,Mix<Sin<Int<23>>,RotateColorsX<Variation,Rgb<52,0,125>>,RotateColorsX<Variation,Rgb<84,0,210>>>,Mix<Sin<Int<16>>,RotateColorsX<Variation,Rgb<115,15,220>>,RotateColorsX<Variation,Rgb<95,0,210>>>,Mix<Sin<Int<18>>,RotateColorsX<Variation,Rgb<26,0,42>>,RotateColorsX<Variation,Rgb<60,0,132>>>>,
//Bright purple absorb effect
//StripesX<Int<3500>,Int<1200>,Mix<Sin<Int<20>>,RotateColorsX<Variation,Rgb<95,0,210>>,RotateColorsX<Variation,Rgb<75,0,165>>>,Mix<Sin<Int<23>>,RotateColorsX<Variation,Rgb<52,0,125>>,RotateColorsX<Variation,Rgb<84,0,210>>>,Mix<Sin<Int<16>>,RotateColorsX<Variation,Rgb<115,0,220>>,RotateColorsX<Variation,Rgb<95,0,210>>>,Mix<Sin<Int<18>>,RotateColorsX<Variation,Rgb<26,0,42>>,RotateColorsX<Variation,Rgb<60,0,132>>>>,
//Alternate darker purple absorb effect, color change friendly (for reds and such)
AlphaL<BrownNoiseFlicker<RotateColorsX<Variation,Rgb<95,0,210>>,Black,300>,SwingSpeed<400>>,
//Unstable swing
AlphaL<Stripes<1000,2000,RandomPerLEDFlicker<RotateColorsX<Variation,Rgb<95,0,210>>,Black>,Black,RotateColorsX<Variation,Rgb<95,0,210>>,Black>,SwingSpeed<500>>,
//Ripple down swing
AlphaL<RotateColorsX<Variation,Rgb<160,60,255>>,Scale<IsLessThan<SwingSpeed<600>,Int<13600>>,Scale<SwingSpeed<600>,Int<-19300>,Int<32768>>,Int<0>>>,
//Bright hard swings
LockupTrL<Layers<
AlphaL<AudioFlickerL<Azure>,Bump<Scale<BladeAngle<>,Scale<BladeAngle<0,16000>,Int<4000>,Int<26000>>,Int<6000>>,Scale<SwingSpeed<100>,Int<14000>,Int<18000>>>>,
AlphaL<White,Bump<Scale<BladeAngle<>,Scale<BladeAngle<0,16000>,Int<4000>,Int<26000>>,Int<6000>>,Int<10000>>>>,TrConcat<TrInstant,White,TrFade<400>>,TrConcat<TrInstant,AlphaL<White,Int<0>>,TrWaveX<White,Int<300>,Int<100>,Int<400>,Scale<BladeAngle<>,Scale<BladeAngle<0,16000>,Int<4000>,Int<26000>>,Int<6000>>>,StripesX<Int<3500>,Int<1200>,Mix<Sin<Int<20>>,RotateColorsX<Variation,Rgb<95,0,210>>,RotateColorsX<Variation,Rgb<75,0,165>>>,Mix<Sin<Int<23>>,RotateColorsX<Variation,Rgb<52,0,125>>,RotateColorsX<Variation,Rgb<84,0,210>>>,Mix<Sin<Int<16>>,RotateColorsX<Variation,Rgb<115,15,220>>,RotateColorsX<Variation,Rgb<95,0,210>>>,Mix<Sin<Int<18>>,RotateColorsX<Variation,Rgb<26,0,42>>,RotateColorsX<Variation,Rgb<60,0,132>>>>,TrFade<1225>,RotateColorsX<Variation,Rgb<160,60,255>>,TrFade<250>>,SaberBase::LOCKUP_NORMAL>,
//Responsive lockup with reset
ResponsiveLightningBlockL<Strobe<White,AudioFlicker<White,Blue>,50,1>,TrConcat<TrInstant,AlphaL<White,Bump<Int<12000>,Int<18000>>>,TrFade<200>>,TrConcat<TrInstant,HumpFlickerL<AlphaL<White,Int<16000>>,30>,TrSmoothFade<600>>>,
//Responsive lightning block
AlphaL<RotateColorsX<Variation,Rgb<160,60,255>>,SmoothStep<Scale<SlowNoise<Int<1750>>,Int<1500>,Int<4500>>,Int<-6000>>>,
//Sparking emitter flare
//AlphaL<RotateColorsX<Variation,Rgb16<45025,0,65535>>,SmoothStep<Scale<SlowNoise<Int<1750>>,Int<1500>,Int<4500>>,Int<-6000>>>,
//Alternate darker sparking emitter flare, color change friendly (for reds and such)
ResponsiveStabL<Red>,
//Responsive stab
EffectSequence<EFFECT_BLAST,ResponsiveBlastL<White,Int<400>,Scale<SwingSpeed<200>,Int<100>,Int<400>>,Int<400>>,LocalizedClashL<White,80,30,EFFECT_BLAST>,ResponsiveBlastWaveL<White,Scale<SwingSpeed<400>,Int<500>,Int<200>>,Scale<SwingSpeed<400>,Int<100>,Int<400>>>,BlastL<White,200,200>,ResponsiveBlastFadeL<White,Scale<SwingSpeed<400>,Int<6000>,Int<12000>>,Scale<SwingSpeed<400>,Int<400>,Int<100>>>,ResponsiveBlastL<White,Scale<SwingSpeed<400>,Int<400>,Int<100>>,Scale<SwingSpeed<400>,Int<200>,Int<100>>,Scale<SwingSpeed<400>,Int<400>,Int<200>>>>,
//Multi-blast, blaster reflect cycles through different responsive effects
ResponsiveClashL<TransitionEffect<Azure,White,TrInstant,TrFade<100>,EFFECT_CLASH>,TrInstant,TrFade<400>,Scale<BladeAngle<0,16000>,Int<4000>,Int<26000>>,Int<6000>,Int<20000>>,
//Responsive clash
TransitionEffectL<TrConcat<TrInstant,Stripes<3000,-3500,RotateColorsX<Variation,Rgb<160,60,255>>,RandomPerLEDFlicker<Rgb<60,60,60>,Black>,BrownNoiseFlicker<RotateColorsX<Variation,Rgb<175,80,255>>,Rgb<30,30,30>,200>,RandomPerLEDFlicker<Rgb<80,80,80>,Rgb<30,30,30>>>,TrFade<1650>>,EFFECT_IGNITION>,
//Bright unstable ignition
TransitionEffectL<TrConcat<TrInstant,HumpFlickerL<RotateColorsX<Variation,Rgb<160,60,255>>,40>,TrFade<1200>>,EFFECT_RETRACTION>,
//Bright HumpFlicker retraction
LockupTrL<AlphaL<BrownNoiseFlickerL<White,Int<300>>,SmoothStep<Int<30000>,Int<5000>>>,TrWipeIn<400>,TrFade<300>,SaberBase::LOCKUP_DRAG>,
//Drag
LockupTrL<AlphaL<Mix<TwistAngle<>,Red,Orange>,SmoothStep<Int<28000>,Int<5000>>>,TrWipeIn<600>,TrFade<300>,SaberBase::LOCKUP_MELT>,
//Responsive melt
EffectSequence<EFFECT_POWERSAVE,AlphaL<Black,Int<8192>>,AlphaL<Black,Int<16384>>,AlphaL<Black,Int<24576>>,AlphaL<Black,Int<0>>>,
//Power save, if using fett263's prop file hold Aux and click PWR while ON (pointing up) to dim blade in 25% increments.
InOutTrL<TrWipeInSparkTip<White,200>,TrWipeInSparkTip<White,1125>>,
//Spark tip in ignition and retraction
//InOutTrL<TrWipeSparkTip<White,200>,TrWipeInSparkTip<White,1125>>,
//Alternate spark tip ignition and retraction
//TransitionEffectL<TrConcat<TrDelay<1500>,Black,TrFade<1000>,AlphaL<Mix<BatteryLevel,Red,Green>,Bump<Int<0>,Int<6000>>>,TrFade<3000>>,EFFECT_BOOT>,
//TransitionEffectL<TrConcat<TrInstant,AlphaL<Mix<BatteryLevel,Red,Green>,Bump<Int<0>,Int<6000>>>,TrFade<3000>>,EFFECT_NEWFONT>,
//Optional/alternate passive battery monitor, on boot (1st line) or font change (2nd line) you will get a visual indicator at the emitter of your current battery level. This also works without a blade if you have a lit emitter or blade plug. Green is Full, Red is Low (the color will blend from Green to Red as the battery is depleted), the indicator will fade out after 3000 ms and not display again until powered down and back up or fonts change.
TransitionEffectL<TrConcat<TrInstant,AlphaL<Mix<BatteryLevel,Red,Green>,Bump<BatteryLevel,Int<10000>>>,TrDelay<2000>,AlphaL<Mix<BatteryLevel,Red,Green>,Bump<BatteryLevel,Int<10000>>>,TrFade<1000>>,EFFECT_BATTERY_LEVEL>,
//On demand battery level, if using fett263's prop file Hold AUX and click PWR while OFF, the battery level is represented by the location on the blade; tip = full, hilt = low and color; green = full, yellow = half, red = low
TransitionEffectL<TrConcat<TrInstant,HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,40>,TrWipe<150>,HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,40>,TrBoing<350,2>>,EFFECT_PREON>,
TransitionEffectL<TrConcat<TrInstant,AlphaL<HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,30>,Bump<Int<0>,Int<5000>>>,TrFade<625>,AlphaL<HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,30>,Bump<Int<0>,Int<9000>>>,TrFade<625>,AlphaL<HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,40>,Bump<Int<0>,Int<13000>>>,TrFade<500>,AlphaL<HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,69>,Bump<Int<0>,Int<18000>>>,TrFade<750>,AlphaL<HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,69>,Bump<Int<0>,Int<23000>>>,TrFade<750>,AlphaL<HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,30>,Bump<Int<0>,Int<7000>>>,TrFade<500>,AlphaL<HumpFlickerL<RotateColorsX<Variation,Rgb<95,0,210>>,50>,Bump<Int<0>,Int<19000>>>,TrBoing<1950,9>>,EFFECT_PREON>,
TransitionEffectL<TrConcat<TrInstant,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<500>,Int<200>,Int<400>,Int<32768>>>,TrDelay<1250>,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<300>,Int<300>,Int<300>,Int<32768>>>,TrDelay<1000>,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<300>,Int<315>,Int<215>,Int<32768>>>,TrDelay<1000>,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<115>,Int<375>,Int<115>,Int<32768>>>,TrDelay<1250>,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<300>,Int<300>,Int<300>,Int<32768>>>,TrDelay<1500>,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<100>,Int<400>,Int<100>,Int<32768>>>,TrDelay<1750>,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<300>,Int<300>,Int<300>,Int<32768>>>,TrDelay<2000>,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<300>,Int<315>,Int<215>,Int<32768>>>,TrDelay<450>,TransitionLoopL<TrWaveX<RotateColorsX<Variation,Rgb<95,0,210>>,Int<100>,Int<400>,Int<100>,Int<32768>>>,TrDelay<1450>,AlphaL<RotateColorsX<Variation,Rgb<95,0,210>>,Bump<Int<0>,Int<6000>>>,TrBoing<1450,5>>,EFFECT_PREON>,
TransitionEffectL<TrConcat<TrDelay<4350>,AlphaL<Mix<Trigger<EFFECT_PREON,Int<3000>,Int<5000>,Int<3000>>,BrownNoiseFlicker<Black,RotateColorsX<Variation,Rgb16<33124,0,65535>>,100>,RandomPerLEDFlicker<RotateColorsX<Variation,Rgb16<56306,0,65535>>,RotateColorsX<Variation,Rgb16<21919,0,22863>>>,BrownNoiseFlicker<Mix<NoisySoundLevel,RotateColorsX<Variation,Rgb16<33124,0,65535>>,RotateColorsX<Int<2750>,RotateColorsX<Variation,Rgb16<33124,0,65535>>>>,RotateColorsX<Variation,Rgb16<42753,14386,65535>>,50>>,SmoothStep<Scale<NoisySoundLevel,Int<-5000>,Int<42500>>,Int<-4000>>>,TrDelay<7750>>,EFFECT_PREON>
//Life force drain preon
>>()
And youāre on OS6? If, yes add this define it will save you some additional memory off the bat.
#define DISABLE_BASIC_PARSER_STYLES
Unfortunately greyscale styles take up a lot of memory in my experience, theyāre also an older syntax and not really optimized. The sections with // arenāt used by the compiler so they donāt affect memory at all, removing or leaving is no different in terms of space on the board.
If youāre concerned about fitting more on your board I would recommend finding optimized equivalents in the library and building out āoptionā styles. As noted above, if you are looking to save memory and fit more on the board I do not recommend mixing older syntax and non-optimized styles with the library styles as this will use up additional memory. If you generate new styles on the library you should fit a noticeable amount more than using the greyscale styles.
If youāre using BCās prop youāll have to enable WebUSB and use ProffieOS Workbench to edit and use the option capabilities or you can switch to my prop and utilize Edit Modeās features to add more presets.
@Speakeasy You kind of need to look at Greyscale ( @KidsTryThisAtHome 's ) styles as āgourmetā customized blade styles.
They are constructed to work specifically with the font, and have timings and colors/effects specific to the sounds therein.
Yes, super cool. Yes, super memory hungry.
The general usage is to have them almost by themselves as styles on the saber at one time, where as more memory friendly/editable styles can work across a multitude of fonts in a more universal way.
So, go gourmet and pay the high falutin price, or take it down a notch and fit more styles.
@NoSloppy @Fett263 @profezzorn you guys are amazing and super helpful, Iāll try a couple of theses and see what happens but thank you guys so much for the help
Didnāt you build a seismic charge bladestyle that took up like 50% memory?
I think there was a version that used MultiTransitionEffect unnecessarily at first, then it slimmed down when the style was optimized a bit. Iām probably thinking of the blade style for my Portal font though.
It really seems like having custom animation Preons is what takes up the space.
Seismic Charge preon would be a perfect example.
A really long TrConcat seems to be memory hungry.
I think Chained Events in OS7 might be the key to optimization there? Weāll see.
Hi all,
I read a lot of issues lately about shrinking styles, styles taking up to much space so I was thinking about this issue actually.
I went to work to create a Proof of Concept for this issue. Based on this PoC, I was able to bring down the size of my own saber setup from 55% to 38%.
We all know the current config files compile the styles into the firmware.
sd_style.h lets you put a style definition in a plain text file on your SD card (e.g. fonts/myfont/blade.style or in the root of the cd styles/mystyle.style) and reference it from your config like this:
StyleFromSD("fonts/myfont/blade.style")
or
StyleFromSD("styles/blade.style")
In my case:
{"Cal Kestis;common", "common/tracks/mars.wav",
StyleFromSD("styles/test_simple.style"),
StylePtr<White>(),
"calkestis"},
The firmware reads and parses that file at runtime, no recompile needed. To change your blade style, you just edit the .style file on the SD card and reboot the saber.
The .style file uses the exact same syntax as a normal ProffieOS style. Layers<...>, AudioFlicker<...>, LockupTrL<...>, etc.
So you can paste any existing style directly into it.
Iām still working on the full parser at the moment, but I was feeling excited it worked and wanted to let you guys know.
For anyone interested: theunschut/ProffieOS at feature/StyleFromSD.
Interesting since thatās how CFX is handled. Iām open to seeing how this works given I barely ever exceed even 9gb on my cards and the room is there. *So long as SD Card corruption doesnāt become a thing letās see where this goes.
@profezzorn Thoughts?
I have a theory about the āadditional riskā for SD corruption, and the way this works should not impact it any more than it already does.
Everytime another font is selected, or at boot, the style is read from the SD and kept in memory. So reading multiple times of the SD card for the sound files would be a much higher risk on the corruption.
I donāt think that reading from SD-card causes corruption, it is the writing that could cause it. Or the early āejectingā (pulling it out/disconnecting the power) while writing to an SD-card, that causes the corruption.
Which might be a (theoretical for now) concern if say someone posts the bladestyle to the SD and then itās edited using the buttons, EditMode, what have you, and thus written to the SD. Itās definitely worth another look but IIRC @profezzorn covered the bigger concerns in the second reply.
Waits on the prototyping of the V4 board to commenceā¦
If I can have as many blade styles as I want on my SD card, I would never use edit mode (and I have never used it anyway), so no corruption on my side, but I see your point. I guess you need to choose your āpoisonā, use edit mode or store your blade styles on the SD? I am definitely going for storing rather than editing.
Very cool.
Some comments:
- You donāt have to re-implement all the style classes. In most cases you can write a template that wraps the existing template and makes it into a node instead.
- Iāll be really curious to see supporting all styles will fit in memory or not.
- I suspect it will also be a bit slower, but Iām not sure how much. Make sure to check the frame rate.
- I think it would be better to put the styles into presets.ini, as ProffieOS already reads presets from there. We just replace ābuiltinā with something else and update the style parser to handle style code.
The next iteration of proffiebords is likely to be much faster hand have much more memory, so (2) and (3) wonāt be a concern eventually.
Cool, Iāll keep that in mind and refactor when I have the chance. I was already feeling itchy about redesigning the full style classes, but I couldnāt get it to work just yet so I went this way for the PoC.
As for v2 and v3, If this works well with the full lib, people can see for themselves if the RAM is enough.
The āoldā way is still supported, so a hybrid option could work. If you have a very large style, just compile it. As long as it fits in memory, this will clear up space on the board.
As for the frame rate: when I was thinking about this, I was thinking that the framerate or speed of the style would be the same? It would take a bit more time (I suppose) to read and parse the style. But when in memory it would be the same as before, as everything is already loaded? Thatās also why I went for a separate file per font/blade style to minimise the data read and kept in RAM
The templated code contains a fair number of optimizations that wonāt work for dynamically loaded code, and on top of that, a call to a virtual function generally takes a little bit longer than a function call where the compiler knows exactly whatās going to be called. (It will often inline the code, which removes the cost of the call entirely.)
A blade with a 100 leds, running at 60 fps, and a style made up of 50 individual styles will need to do about 300k calls per second. At that point, every extra cycle you add costs 0.375% of the total available cpu. I have a saber with 529 leds, for that one to be fast enough, I need to use fairly simple styles, and also increase the optimization, āsmallest codeā just isnāt fast enough.
Frame rate might not end up being a problem, but itās definitely something to keep an eye on. (You can use the ātopā command in the serial monitor to check on this stuff.)
Keeping things in a separate file is not likely to reduce the amount of read operations needed. (Opening a file takes time too.) However, itās probably helpful for organizational purposes.
Clarification; for point (2) above, I meant flash memory, not RAM. Having all style templates available will use up a chunk of flash memory. RAM might also be a problem, since dynamically loaded styles will most likely use more RAM than compiled-in styles. However, dynamically loaded styles will be made up of many small allocations, while compiled-in styles generally use one large allocation. The smaller allocations might be able to use the available ram more efficiently, even if it uses more memory in total.
I have to admit, Iām a bit stuck on the implementation. I do have a software background, but Iām a Back-end developer, not embedded.
Iāve been reading the ProffieOS code and with the help of AI trying to get it right. Most of the features (styles/functions) are build and parsed.
A few issues I have:
-
One style has a fast ignition when compiled, but this ignition is really slow when read from SD. All other style settings work like the compiled version (like the off, and blade flickering).
-
Another style (one from greyscale) is already ignited (not the sound, but the color) when this font is selected. Other greyscale fonts Iām using donāt have this. Just that specific one.
-
Some effects from styles seem to be missing, but that could be because I still have some functions left to parse. I do have a list somewhere.
Iām left a bit overwhelmed by the compile time styles together with my parser.
Especially because I really want to reuse existing code instead of building a ācopyā of all style classes.
I do feel like a good foundation has been set and my Proof of Concept was a success IMO. To finish this PoC it probably needs some help of someone who understands the existing code better than I do.
I still want to keep trying to make it right, but I would not say no to anyone who want to help and give it a go. Message me if you want to contribute to my GitHub repo. I can add you as a contributor.
I donāt know what is causing your issues, and I think you should probably try to clean up the code a bit before I dig in and try to help debug. It kind of sounds like there might be uninitialized variables somewhere though.
One thing that could be an issue is the return value of the run() functions. Those return values are used to determine when the blade can be turned off, and your styles donāt have them. (Which means the blade will always be powered.)
Reusing existing code should be kind of simple I think
For instance, your RtAlphaL is nearly there, just turn it into a template by replacing Base with a templated type, and you should have a class that can be used to turn any style that takes a color and a function into an RtColorNode. Not sure if itās possible to make a truly generic template, but one template per unique input signature should work reasonably well.