JSFX Dojo

It’s how values are returned from functions. It allows us to use arbitrary blocks of code in variable initialisation too that aren’t just C-style ternary statements ( a = 42 > 41 ? 1 : 2; ) :

a = 42 > 41 ? ( b = 2; b+= 1; b == 3 ? 94 );

In C++ we’d have to use an “Immediately Invoked Function Expression (IIFE)”, i.e. a lambda that is called immediately like this equally useless one here:

auto a = []() { if (42 > 41) { auto b = 2; b += 1; return b == 3 ? 94 : 0; }(); // note the () at the end.

Taking a little break and detour tonight after some time with the book after work. I should probably start a new thread on this, but I seem to remember Justin mentioning programming in BASIC as a kid. I would say that must have had some lasting influence. I know that BASIC isn’t ‘relevant’ these days, but damn if it doesn’t look like a fun environment to learn programming in. Seems like it could still have some relevance in education (and self-education), where the genuine goal is learning programming, not a specific language, not catering to industry, not selling a university course, etc. I mean, thumb through this if you have a minute. That makes Python books look disgusting to me. Freebasic Beginners Guide - Browse Files at SourceForge.net ch 1-7.pdf

 ( a = 42 > 41 ? 1 : 2; ) :

It’s been a good minute since I touched jsfx, but you are reminding me now. I do remember thinking that syntax was strange when I started with jsfx.

BASIC was good fun, the language isn’t important though, what was important was the immediacy of it since computers came with it staring users in the face when they switched it on. If optionally typed Python had been available it would have been a much better choice for the better features.

Have you taken a good look at Python learning resources for beginners though? That to me is major for beginners. More important than the language itself, I would say.

The beginner books I have looked over have been 99% cutesy, not really teaching solid programming. I suppose sure, something like that could draw beginners in. But then what for getting down to learning solid programming in Python?

I watched a presentation a couple of years back where the guy said if he ran a course for beginners the first lesson(ish) wouldn’t have any code in it at all. To emphasise that it’s all about solving problems.

Once syntax etc isn’t tripping you up you find what libraries you can use for whatever task you are interested in and wind up on Stack Overflow or some forum or other over and over again as you ask yourself/them more specific questions. Literally, until you have solved enough little (or major) problems that you need to search less.

All of the supposedly irrelevant noodling in the tutorials you are working through are exposing you to all sorts of code, file ops, creating structs/data objects, calling conventions etc that you need for creating and interacting with more interesting stuff. But as I said you can dive straight(er) into ReaScript or something for more instant satisfaction and less formality.

Read other people’s code, although that one’s a sort point since sometimes you are much better off not trying to do that with some code! :slight_smile:

Set some interesting task, like creating a ReaScript that shows a window that has a simple display of tracks and eq settings or something. What you’ll learn just from the wrong turns is priceless. With ReaScript you have interesting data to work with instead of cin.

Or in C++ do some kind of file scanner thing to identify large files or something. Any actual task using interesting data you don’t have to create from scratch.

The “How do I…?/Why do we…?” questions we ask ourselves then become very specific and answerable.

Snookoda, I think you’re mistaking what I’m saying about Python learning resources and bringing up about BASIC as being relevant to my own learning of c++. I have watched numerous people (coworkers and family) eat the Python propaganda as their first language and come up very short because the learning resources flat sucked. I watched one coworker do this for a couple of years and recently heard that she is stilling doing it after a few years, still getting nowhere really. It isn’t the language, it’s the learning resources. I’m proposing here that an antiquated language (BASIC) could possibly be a better solution, because a learning resource for it covers solid programming topics, not object oriented programming by chapter 2. And not a ton of crap to install, update, and break as with Python. Just a compiler. Not a ton of cutesy books and video courses to wade through that don’t really go anywhere. And if you do write an interesting program and want to share it, the recipients don’t have to install various packages (some of which might break or break other things) to run your program.

Oh right, yeah I was mistaken there.

Re Python or Lua, somebody could write a script starter program that has every library you’d want in a simple distribution either statically compiled or bundled with so/dlls. Then just create a zip file when you want to share.

ZeroBraneStudio’s distribution does something like that. Written entirely in Lua (with a small C starter stub) and with no external dependencies.

Nice one Snooks
I got the vscode extension working

Sweet, I installed this vim plugin so EEL2 looks and acts a bit nicer now too. Can you see places where they are assuming window size, for example the block at line 36 where there are margins with sizes in pixels? In the JSFX “General Dynamics”, you can see that in the @gfx section there is a line something like:

small_window = gfx_w < 200 || gfx_h < 200;

So that the tiny window logic can be applied selectively.

I could make a repo with ridiculously well commented commits documenting the refactoring and making the GUI responsive if you think that’s better.

For this one I think making the x-axis numbering disappear below a certain width while removing the vertical margins and same with y-axis with plugin height would be good. And sorting out the jumpy horizontal sizing. Oh, and the font.

If you’re motivated to explore and experiment then it would be better you riding that wave yourself with some nudges here and there if you need them.

LOL It might be mate
I’m so new to EEL, it might be above my paygrade
If I can see how to change a plugin to be embedded,
I can experiment on some simpler ones

Sorry to drag the chain here Snooks
I’ve been reading the EEL2 reference so I understand the syntax fully
(a bit JS-esque to me with the ternary operator)
and looking through the smallest examples of jsfx coding

I haven’t actually found a tiny example of an embedded plugin yet
A simple before and after example would be a big help

Like take one of Loser’s mute or volume examples that’s a few lines of code,
give it a simple gui,
and then embed it

Maybe there’s a tutorial somewhere I missed

Actually that might be a good fit for this notepad I’m tweaking

I’ve been experimenting and reading from this resource I found:
https://www.reaper.fm/sdk/js/gfx.php

So I have the background colour I like now,
and a range of text colours (orange/red/green/white)

I’d like to set up a settings button ala zenoMOD’s VU Meter to switch between the text colours
or alternatively a slider or knob

If you can point me in that direction it’d be helpful

Otherwise I can just have different named notepads with separate font colours
but it’s a bit redundant like that

I really don’t mind any of it at all, I’ll do the repo thing with the Multifreaq and just post it here in a thread. Then you can have a browse through the commits to see what I changed and why (from the commit messages). It should be a good exercise for me as well since it’s been ages since I’ve done any EEL2.

Re the button, no worries. Does it bring up a menu or other popup thing?

No, it’s just a button with text on it that changes as you cycle through the different VU themes
A menu version would also do the job

ZenMod’s VU Meter uses slider1 to cycle through the ‘styles’

slider1: 1<0,9,1{Classic,Knight,Purple,Mint,Pastel,Warm,Ivory,Trooper,Ultimate,Mooncake}> -UI Style
//========================================== STYLES =================================================/

  style = slider1;

  style == 0 ? ( gfx_clear = 30 + 60 * 256 + 110 * 65536; );

  style == 1 ? ( gfx_clear = 18 + 18 * 256 + 18 * 65536; );

  style == 2 ? ( gfx_clear = 16 + 10 * 256 + 26 * 65536; );

  style == 3 ? ( gfx_clear = 52 + 89 * 256 + 86 * 65536; );

  style == 4 ? ( gfx_clear = 245 + 169 * 256 + 171 * 65536; );

  style == 5 ? ( gfx_clear = 26 + 25 * 256 + 21 * 65536; );

  style == 6 ? ( gfx_clear = 204 + 199 * 256 + 180 * 65536; );

  style == 7 ? ( gfx_clear = 163 + 162 * 256 + 158 * 65536; );

  style == 8 ? ( gfx_clear = 46 + 46 * 256 + 46 * 65536; );

  style == 9 ? ( gfx_clear = 30 + 31 * 256 + 35 * 65536; );

  w1 = $pi * 16.5 / 180;

  w2 = $pi * 45 / 180;

  xw = max(1,floor((gfx_w-30) / 2));

  yw = floor(xw / 1.5);

  r1 = floor(yw * 0.85);

  chan = 0;

  while (chan <= 1) (

      xd = 10 + chan*(xw+10);

      mode === 1 ? xd += floor(xw/2);

      yd = 10;

      xa = floor(xd + xw / 2);

      ya = floor(yd + yw * 1.1);

    //************************************* meter background styles **************************************

      // background style 0: classic

      style == 0 ? ( gfx_r=1; gfx_g=1; gfx_b=0.7;  gfx_rect(xd,yd,xw,yw);  );

      // background style 1: dark knight

      style == 1 ? ( gfx_r=gfx_g=0.18431 ;gfx_b = 0.2;  gfx_rect(xd,yd,xw,yw);   );

      // background style 2: purple

      style == 2 ? ( gfx_r=0.14110; gfx_g=0.09020; gfx_b=0.21961;  gfx_rect(xd,yd,xw,yw);  );

      // background style 3: mint

      style == 3 ? ( gfx_r=0.65490; gfx_g=0.94902; gfx_b=0.92157;  gfx_rect(xd,yd,xw,yw);  );

      // background style 4: pastel

      style == 4 ? ( gfx_r=0;gfx_g=1;gfx_b=.9;  gfx_rect(xd,yd,xw,yw);

      !gfx_ext_flags ? (gfx_r=0.65; gfx_g=0.37; gfx_b=0.6;  gfx_rect(xd,yd+yw;,xw-(xw/1.35),yw*yw ) );

                     gfx_r=0.85490; gfx_g=0.85490; gfx_b=0.96078;  gfx_rect(xd,yd,xw,yw); gfx_a=0.79; );

      // background style 5: warm

      style == 5 ? ( gfx_r=1; gfx_g=0.76471; gfx_b=0.32549; gfx_a=1;  gfx_rect(xd,yd,xw,yw);

                     gfx_r=0.87451; gfx_g=0.49412; gfx_b=0.08235; gfx_a=.10; gfx_rect(xd,yd,xw,yw/yd*1.6);

                     gfx_r=0.87451; gfx_g=0.49412; gfx_b=0.08235; gfx_a=.13; gfx_rect(xd,yd,xw,yw/yd*1.5);

                     gfx_r=0.87451; gfx_g=0.49412; gfx_b=0.08235; gfx_a=.15; gfx_rect(xd,yd,xw,yw/yd*1.4);

                     gfx_r=1; gfx_g=0.88235; gfx_b=0.53725; gfx_a=.1/2; gfx_rect(xd,ya*.76,xw,yw/yd*1.7);

                     gfx_r=1; gfx_g=0.88235; gfx_b=0.53725; gfx_a=.10; gfx_circle(xa,ya*1.15,r1*0.87,1,1);

                     gfx_r=1; gfx_g=0.88235; gfx_b=0.53725; gfx_a=.13; gfx_circle(xa,ya*1.20,r1*0.87,1,1);

                     gfx_r=1; gfx_g=0.88235; gfx_b=0.53725; gfx_a=.15; gfx_circle(xa,ya*1.25,r1*0.87,1,1);

                     gfx_r=1; gfx_g=0.88235; gfx_b=0.53725; gfx_a=.18; gfx_circle(xa,ya*1.30,r1*0.87,1,1);

                     gfx_r=1; gfx_g=0.88235; gfx_b=0.53725; gfx_a=.25; gfx_circle(xa,ya*1.27,r1*0.77,1,1);

                     gfx_r=0.10196; gfx_g=0.09804; gfx_b=0.08235; gfx_a=1;  gfx_rect(xd,ya*0.91,xw,yw*2); );

      // background style 6: ivory

      style == 6 ? ( gfx_r=0.86667; gfx_g=0.85490; gfx_b=0.78039;  gfx_rect(xd,yd,xw,yw); );

      // background style 7: trooper

      style == 7 ? ( gfx_r=gfx_g=gfx_b=0.0; gfx_a=1;  gfx_rect(xd,yd,xw,yw);

                     gfx_r=0.14902; gfx_g=0.15294; gfx_b=0.16078; gfx_a=.1; gfx_rect(xd,yd,xw,yw/yd*1.6);

                     gfx_r=0.14902; gfx_g=0.15294; gfx_b=0.16078; gfx_a=.2; gfx_rect(xd,yd,xw,yw/yd*1.5);

                     gfx_r=0.14902; gfx_g=0.15294; gfx_b=0.16078; gfx_a=.3; gfx_rect(xd,yd,xw,yw/yd*1.4);

                     gfx_r=0.14902; gfx_g=0.15294; gfx_b=0.16078; gfx_a=.1; gfx_rect(xd,ya*.76,xw,yw/yd*1.7);

                     gfx_r=0.14902; gfx_g=0.15294; gfx_b=0.16078; gfx_a=.10; gfx_circle(xa,ya*1.10,r1*0.87,1,1);

                     gfx_r=0.14902; gfx_g=0.15294; gfx_b=0.16078; gfx_a=.12; gfx_circle(xa,ya*1.15,r1*0.87,1,1);

                     gfx_r=0.14902; gfx_g=0.15294; gfx_b=0.16078; gfx_a=.14; gfx_circle(xa,ya*1.20,r1*0.87,1,1);

                     gfx_r=0.14902; gfx_g=0.15294; gfx_b=0.16078; gfx_a=.15; gfx_circle(xa,ya*1.29,r1*0.87,1,1);

                     gfx_r=0.63922; gfx_g=0.63529; gfx_b=0.61961; gfx_a=1;  gfx_rect(xd,ya*0.91,xw,yw*2); );

      // background style 8: ultimate

      style == 8 ? ( gfx_r=0.55294; gfx_g=0.55294; gfx_b=0.55294;  gfx_rect(xd,yd,xw,yw);

                     gfx_r=0.42745; gfx_g=0.42745; gfx_b=0.42745;  gfx_a=.65;

                     gfx_rect(xd+1,yd,xw-1,yw-1,0); gfx_a=1; );

      // background style 9: mooncake

      style == 9 ? ( gfx_r=0.03922; gfx_g=0.04314; gfx_b=0.04314;  gfx_rect(xd,yd,xw,yw); );

zenomod_VU Meter (ZenoMOD).jsfx (48.1 KB)

What I’ve got so far that’s relevant:


@init

gfx_ext_retina = ext_noinit = 1;

gfx_clear = 0*141414;              //! Black background

// gfx_clear = 0x222222;           //! Dark Grey background

// gfx_clear = 0xFFFFFF;           //! White background

and…


@gfx 20 1

// replace gfx_set(0) (just below @gfx) with gfx_set(r, g, b).

// Note that r, g, and b are values between 0.0 and 1.0 (not 0 and 255),

// so e.g. this would set the color to orange:

// gfx_set(1.0, 0.5, 0.0);

//! Colour of font, 1 is white, 0 is black, RGB is 3 comma-separated numbers

// gfx_set(0);                  //! Black  

gfx_set(1);                  //! White  (the default if missing)

// gfx_set(0.7, 0.7, 0.7);      //! Grey

// gfx_set(1.0, 0.5, 0.0);      //! Orange

// gfx_set(1.0, 0.0, 0.0);     //! Red

// gfx_set(0, 1, 0);            //! Green

// gfx_set(0.13, 0.56, 0.87);           //! Blue

gfx_setfont (1, "Arial" , 17 , 'b'  * gfx_ext_retina);

// gfx_setfont(1, "Arial", 13 * gfx_ext_retina);

Sorry, they got empty spaces inserted in them via the code brackets here

I remember that, there are hidden parameters with names that begin with a minus - so that they are stored with the project. Copy that slider but take the minus out so that it’s visible to play with it.

The most direct way would be wrap any gfx_clear or gfx_drawxxx commands in a conditional. Probably put a style = slider1; in the @slider section, to avoid having to remember what slider does what when you see slider17 pop up in code somewhere.

If you get that working without the button, just using the visible slider, then it’s just a case of getting a right click menu or button to select the theme instead.

@slider
  style = slider1;

@gfx 400 200
  style == 0 ? (
    gfx_clear = 0xffffff; // better dealing in hex with one number colours stuff since each pair of `ff`s is r, g, b
    gfx_set(0, 0, 0, 0);
  ) : ( // <-- remember this is how elses are done
    style == 1 ? (
      // change colours
    ) : (
      style == 2 ? (
        //change colours
      );
   );
);

That plugin doesn’t use elses at all for selecting the graphics, which is frowned upon. There are different ways of doing things too, but just going through the style number and setting colours is the most straightforward.

I’d prefer storing the colours in the giant JSFX memory array and setting them directly, but there’s a bit more boilerplate and arrays are a different topic!

It turns out there’s a lot to tidy up in Multifreaq, I’ve made a couple of changes already, all getting logged via git. It’s going to be a bit shorter by the time I’ve finished. I notice that the freq and amp scales aren’t very accurate either.

1 Like