Multi_prop.h, I feel I am getting closer to something usable but

It DID work for me or I would not have posted it. Specially not after my miserable first attempt at posting a non-working version of it.

I did make a Github account. I have branches from profezzorn, you NoSloppy (that’s where I found your blaster_BC_buttons.h - last week), ryryog25 & more.

I tried to add as draft a previous version of multi_prop.h but when I look for it to update, I couln’t find it ? I think I need a Github tutorial. Do you know of a good Youtube video ?

It didn’t fall from anywhere or go in the washing machine or dish-washer neither.

I must apologize again for wasting your time for a dumb finger-trouble mistake.

I also apologize if I seem frustrated, because I know I am. It is not at anyone of you, you have all been more than helpful and I thank you for it, but it is at me.

I will take a break now, and hopefully I find the working version tomorrow.

Good to know, my first guess was “Sound Blaster” but I know that couldn’t be it.

Imagine you would try to explain it to your grand-parents. Or to my parents who are almost 80. (They both can use a computer to check their emails or browse the internet, and they both “think” they know “a lot” about their computer compared to some of their friends who can only use a land line to make a phone call!)

So same question: what “kind of type” of EFFECT “can be requested” ?

Meaning that because it’s in SB_Effect, it expects EFFECT_X, Like EFFECT_BLAST or something that’s an effect.
I can’t really comment further because the posted multi_props.h file is not available to examine.

Ok, it uses magic to do magic, magically!

Seriously though, I’m not sure what you’re asking for makes sense. I would have to use imprecise language, approximate what is actually happening and unless you have some basic level of understanding of programming, you still wouldn’t be able to use that information for anything.

Let’s try to make it as simple as I think it makes sense to make it:

The point of SB_Effect is generally to play sounds. It is a function. It is called when things happen. One of the arguments to the function is called “effect” which specifies what happened. There are several SB_Effect functions, and each is responsible for playing some effects. Most SB_Effect() functions start with a switch statement based on the “effect”, with cases for each of the events that they care about. Each case leads to a bit of code that plays a sound.

Is this still too complicated?

Edit: file deleted, see further down for the latest one.
This is my previous working (compiling) version (revision 30) but “buttons mapping is not yet fully handled”. I will retrace my steps of yesterday and hopefully I find my working revision 31. I just tested the above and it does compile.

Unless I missed one, this is done.

No it is much better, at least a lot “less obscure”.

I will keep on working at it until I get it right.

I finally found my version31 which I thought was working but I guess I must have tested version30 instead. I don’t know for now, how to handle the buttons mapping that is what is causing the problem. Last night I had nothing working because I had also messed-up my config which was causing all sorts of error messages.

So if I understand the (re-)mapping correctly: only the blaster needs the mapping & re-mapping functions & this needs to happen before event2.

I am guessing that the mapping to blaster will also affect the behavior of my “dual botton extra long push” which expects “power+aux for 4 sec” but instead it will receive “fire+mode_select for 4sec”.

I starting writing this message this morning. Just saying in case the above doesn’t match the bellow.

I think I figured out the “mapping” and where to put it (yes it compiles) here is version 32:
Eddit: file deleted, new one further down.

So guess I need to put the sound effects somewhere else, where they will only be played once ? Correct ?

I think what you want is to:

  1. Add a new event in common/saber_base.h
  2. have switchMode call SaberBase::DoEvent using the new event as the argument.
  3. Have SB_Event do nothing unless it’s the right event.

What you want is similar to EFFECT_MODE, but since that event is already used by the blaster prop AND you are also using the blaster prop, I think you need a new one…

1 Like

I am guessing you mean a new EFFECT in the #define DEFINE_ALL_EFFECTS() \ “list”
So I added: (EDIT: I removed it because I would rather not modify Proffie OS for now)

    /* Multi prop effects */                  \
    DEFINE_EFFECT(BLASTERMODE)                \
    DEFINE_EFFECT(SABERMODE)                  \
    DEFINE_EFFECT(DETMODE)                    \
    DEFINE_EFFECT(JETMODE)                    \
    DEFINE_EFFECT(DROIDMODE)                  \

At the bottom of the list.

Would this in multi_prop.h

EFFECT(blastermode); 
EFFECT(sabermode); 
EFFECT(detmode);
EFFECT(jetmode);

With (!hybrid_font.PlayPolyphonic(&SFX_blastermode)), !hybrid_font.PlayPolyphonic(&SFX_sabermode)), ... in the switch not work ? It does compile and I didn’t have to add anything to saber_base.h

Done, that was easy. :grin:

If I understand correctly, I need to create a new effect named “EFFECT_XYZ”, I’ll replace “XYZ” with a more appropriate name when I think of a good one, that work identicaly as EFFECT_MODE ?
What is wrong with EFFECT(blastermode); in multi_prop.h or with DEFINE_EFFECT(BLASTERMODE) \ in saber_base.h ?
The wav’s made by NoSloppy say “Blaster mode”, “Saber mode”, “Detonator mode”, … They do not say “Blaster” & then I need to add “mode” to it.

You can find all 5 sound files (created by NoSloppy) on my dropbox here:
https://www.dropbox.com/scl/fi/p2pj9os5v4seel0wmzwcz/Multi_prop_sounds_by_NoSloppy.zip?rlkey=hi6589mexymnx4jmxhtwqjfu0&st=3klofs5m&dl=0

Here is my latest multi_prop.h it compiles but since I have no way (yet) to test it, I should probably give it a rest and continue on soldering to finish my build.
multi_prop.h (17.0 KB)

Please if you have any more comments, I will work on them as soon as possible.

Cheers

Unfortunately, there is some confusing terminology in ProffieOS.
There is the effect enum, defined in common/saber_base.h using DEFINE_EFFECT(…).

Then there is the Effect class, which is is used to scan and keep track of files on the SD card. Using the EFFECT(something) define creates one of these, usually named SFX_something.

They are not interchangeable, and your SB_Effect function is likely to use both of them, so…

Nothing, but it doesn’t help with the effect enum.

  1. It doesn’t exist
  2. If it did exist, you probably shouldn’t use it, because then the prop that used that effect wouldn’t work well with multi_prop.h
  3. What you need isn’t really a “blaster mode”, more of a “prop mode”…

How can it use both if only one exists, I did not add anything in saber_base.h, I only have EFFECT_(something) in multi_prop.h and they are only used in the switch mode as !hybrid_font.PlayPolyphonic(&SFX_something) (<-- doesn’t this plays the sound ?) like this:

        case PropMode::BLASTER:
            if (!hybrid_font.PlayPolyphonic(&SFX_detmode)) { //auto beepers
                beeper.Beep(0.05, 2000);
                beeper.Silence(0.05);
                beeper.Beep(0.05, 2000);
                };
            currentMode = PropMode::DETONATOR;
            break;

And SB_Effect is empty as you suggested earlier:

    void SB_Effect(EffectType effect, float location) override {
        switch (currentMode) {
            case PropMode::SABER:
                Saber::SB_Effect(effect, location);
                break;
            case PropMode::BLASTER:
                Blaster::SB_Effect(effect, location);
                break;

So how could/would SB_Effect use both if:

  • only one exists
  • and it is not used by SB_Effect

Also

But it would exist if I add it. Which I choose not to for now, but if I do, I would remove the EFFECT_(something) from multi_prop.h and only use the DEFINE_EFFECT(SOMETHING) \ from saber_base.h

It would be added for multi_prop.h to use not for the other props.

You mean a “prop mode” “blaster” ? & why not a “prop mode blaster” ?

Personally, I prefer “blaster mode” to “prop mode blaster” or “prop mode” “blaster”. It rolls better off the Edit: thong tongue (I was informed it was miss-spelled) & sounds better too.

I need to know more of the why, because I am more confused now. It might be more obvious once I finish my build to test it on, but for now there is a big “fog of war” surrounding the sound effects.

I prefer not to touch saber_base.h because that is yours, now if you want me to add to saber_base.h for the purpose to add multi_prop.h to ProffieOS, that is fine by me. You can take multi_prop.h & make it yours, if you like it ? I have no problem with that. I don’t even mind doing whatever modifications you want me to do and push them on Github for your approval.

For now I just want something that works without touching your code, unless you give me the go-ahead because you are interested in it. And if it never makes the cut to be part of ProffieOS because you don’t like it, that is fine by me too. I completely understand that you don’t want a stranger to come and “mess with your stuff”, I am the same.

Fredrik can correct me if I’m wrong, but I believe the idea is to have a “prop mode” effect which is triggered generally to indicate a switch? And then logic would be implemented based off that premise? So it’s more of a general-purpose switch effect than it is specific to the blaster mode.

1 Like

Ah, that makes sense, I was unable to understand it like that, but will multi_prop not work as intended without it ?

For now I will be very happy if it works (and not just compile). It can always be improved later.

Unfortunately, making new props sometimes means making changes outside of the prop file. The effect enum is one place that often needs modifications when new functionality is added.

THe good news is that adding new entries to effect enum doesn’t have any CPU or memory overhead unless you actually use that entry.

You’re mixing up what the final output will be and the structure of the code.
I was talking about the name of the entry in the effect enum, which isn’t directly related to what the the contents of the sound file will be.

I highly encourage people to mess with ProffieOS, that’s what open-source is all about. :slight_smile: However, I have ideas about how things should work, and how it should be written, and for anybody who wants to have their code included with the base ProffieOS code, there is a code review process that can be very painful. The pain can be reduced significantly by talking through and reaching agreement on how things should be written, which is basically what we’re doing here…

Sure, but that isn’t the problem. The problem is that it will play the sound too much. You need to only play it when currentMode actually changes.

Please do.

No, DEFINE_EFFECT and EFFECT() does different things, one cannot be substituted for the other.

Hello @profezzorn, sorry for re-visiting my “old” threads but I would really love to understand all this stuff. When you said:

Does it mean:

  • Should I have both ? Which is what I believe is what you are implying but I do not understand why.
    or
  • Do I need to choose one or the other ? And if this is the case, I don’t know which is the “good one” or why ?

The way I understand the code, if I use SaberBase::DoEffect(xyz,0), it will play xyz.wav if I have DEFINE_EFFECT(XYZ) in saber_base.h (witch I do) and will also do other “things” if specifically programmed in saber_base.h to do so ?

I also created multipropdisplaycontroller.h (based on BlasterDisplayController) and added:

#ifdef PROPS_MULTI_PROP_H
#include "multipropdisplaycontroller.h" 
#endif

in ssd1306.h
multipropdisplaycontroller.h (15.9 KB)

So if I have xyz.bmp in “common” or “appropriate_font_folder”, xyz.bmp should display on OLED at the same time as xyz.wav is played for the duration of xyz.wav. Is this correct ?

Now why would I also need EFFECT(xyz); in my multi_prop.h ?

  • I either use hybrid_font.PlayPolyphonic(xyz) to play xyz.wav and that’s it.
    or
  • I use SaberBase::DoEffect(xyz,0) to play xyz.wav and more stuff, if programmed & maybe play xyz.bmp on OLED ?

I guess I am completely wrong on all of it but I would love to understand the “what it does”/“how it works” between the two, if you have the time to spare.

Thank you for reading so far.

They do DIFFERENT things.
Chosing one or the other is like choosing between apples and screwdrivers.

Let me explain a little about what they do:

DEFINE_EFFECT adds an enum value. An enum value is just assigning a name to a number, and that name only exists while compiling. If you add DEFINE_EFFECT(CHICKEN_DANCE), then it will create an enum value called EFFECT_CHECKEN_DANCE. This enum value will be associated with some number, it’s not particularly important what that number is though, all we care about is that it is different from all the other EFFECT_* enum values.

When you canll SaberBase::DoEffect(xyz,0); then xyz is one of these enum values. So the prop could call SaberBase::DoEffect(EFFECT_CHICKEN_DANCE, 0); to let all SaberBase instances know that it’s time to do the chicken dance. Note that this does not play a sound unless one of the SaberBase instances actually do so in SB_Effect().

Then there is the EFFECT() macro. It creates an instance of the Effect class. The purpose of the Effect class is to keep track of all the files on the SD card related to one specific effect. So, if we put EFFECT(chicken_dance); somewhere, it will create an object in that scope called SFX_chicken_dance. Normally, this is done at the global scope, which means that the lifetime of the object is permanent. When we scan a font directory, we offer each file to each effect, and if the name matches, then that Effect instance will remember the highest and lowest number of that file, and where it was, and other details like that. So if we have a chicken_dance.wav in our font directory, the SFX_chicken_dance object will (eventually) know that.

The missing piece that ties all of this together is the SB_Effect() function. It will receive the EFFECT_* enum value(s), and usually do something like hybrid_font.PlayPolyphonic(&SFX_chicken_dance); in response, and now sound will play when you call SaberBsae::DoEffect.

2 Likes

Thank you so much for this thorough explanation. I think I understand now.
This is all fascinating yet confusing (I am a lot less confused now then when I started - while revisiting my older posts, the answers you all gave me, make a lot more sense).

So in summary:

  • I need both (and I do)
  • I somehow/somewhere need to link them together via the SB_Effect() function.

This is not clear how/where I need to have that. Or is it just as simple as having SaberBase::DoEffect(EFFECT_XYZ, 0); in my switchModes function and that will trigger hybrid_font.PlayPolyphonic(&SFX_xyz); and thus I do not want to have:

SaberBase::DoEffect(EFFECT_XYZ, 0);
hybrid_font.PlayPolyphonic(&SFX_xyz);

in my switchModes function because that would play xyz.wav twice, which I don’t want so I need to remove any hybrid_font.PlayPolyphonic(&SFX_xyz); & only have SaberBase::DoEffect(EFFECT_XYZ, 0);

Obviously I still keep EFFECT(xyz); at global level in multi_prop.h & have DEFINE_EFFECT(XYZ) in saber_base.h

Did I understand it correctly, or do I still need to add some more code somewhere?

I thank for for your patience with me & dedication for the hobby. I hope I am not annoying you with all my questions.

This is an example of what you need to link an effect to a sound:

Don’t read the whole function, because some of it is a lot more complicated than what you need. Just the first three lines should be enough…

1 Like

Of course, I did read the whole section, sorry I couldn’t help it.
Here is what I came up with:

    void SB_Effect(EffectType effect, EffectLocation location) override {
        switch (effect) {
            case EFFECT_SABERMODE:     MultiPropHelpers::announcemode(&SFX_sabermode);       return;
            case EFFECT_BLASTERMODE:   MultiPropHelpers::announcemode(&SFX_blastermode);     return;
            case EFFECT_DETONATORMODE: MultiPropHelpers::announcemode(&SFX_detonatormode);   return;
            case EFFECT_JETPACKMODE:   MultiPropHelpers::announcemode(&SFX_jetpackmode);     return;
            case EFFECT_MORSECODEMODE: morsecodemode(); /* General invitation to transmit */ return;
        }
        switch (currentMode) {
            case Prop_Mode::SABER:         Saber::SB_Effect(effect, location); break;
            case Prop_Mode::BLASTER:     Blaster::SB_Effect(effect, location); break;
            case Prop_Mode::DETONATOR: Detonator::SB_Effect(effect, location); break;
            case Prop_Mode::JETPACK:     Jetpack::SB_Effect(effect, location); break;
            case Prop_Mode::MORSECODE: MorseCode::SB_Effect(effect, location); break;
       }
    }

Is this starting to look better, or am I still way-off ?

Please find my latest multi_prop.h with much reduced repetition.
multi_prop.h (20.2 KB)
Is it still too repetitive ? I tried to reduce the repetition further but it ended up using a lot more memory (3x as much - however, it was with plug-in 4.1.0 and I didn’t have the time to retry with 3.6.0, so I might “re-visit” that code later, once I know the rest is better)

It’s looking fairly reasonable I think.

1 Like