Elegant way to loop combos via call?

GPC2 script programming for Titan Two. Code examples, questions, requests.

Elegant way to loop combos via call?

Postby Yuri-chan » Thu Jul 02, 2020 2:24 pm

Hi! I'd like to simply loop a combo n times from within a combo, to clean up my messy spaghetti code :)

Code: Select all
combo doTenPresses {
    uint8 presses;
 
    for(presses=0; presses<10; presses++)
    {
        call(doSinglePress);
    }
}


This setup only gives me an error " Illegal operation 'call' ".
If I put the call outside the for loop, it doesn't give me errors.

I wonder what's the problem, maybe someone here can chime in and help? It would be highly appreciated!
User avatar
Yuri-chan
Staff Sergeant
Staff Sergeant
 
Posts: 10
Joined: Sun Jun 28, 2020 3:57 pm

Re: Elegant way to loop combos via call?

Postby J2Kbr » Thu Jul 02, 2020 2:40 pm

Here is a example on how you can implement this:
Code: Select all
int counter;
 
main {
    if(event_active(BUTTON_16)) {
        if(!doTenPresses) {
            counter = 0;
            combo_run(doTenPresses);
        }
    }
}
 
combo doTenPresses {
    set_val(BUTTON_15, 100);
    wait(100);
    set_val(BUTTON_15, 0);
    wait(100);
 
    // At the very end of the combo block
    if(++counter < 10) {
        doTenPresses[1] = 0;
    }
    wait(0);
}
 
ConsoleTuner Support Team
User avatar
J2Kbr
General of the Army
General of the Army
 
Posts: 20323
Joined: Tue Mar 18, 2014 1:39 pm

Re: Elegant way to loop combos via call?

Postby Yuri-chan » Thu Jul 02, 2020 3:09 pm

Thanks for the fast reply!

So, looking at your example it seems it only works from the main loop, not from another combo, right?

The thing is, I have several combos calling other combos to have a cleaner code and better overview when I want to change a single thing that has to be repeated over and over, so I need to run this off of another combo.
I used call so far because it directly chains the next combo without releasing any buttons, and also waits for the last combo to finish, so everything stays in sync. Since call and also wait don't seem to work from a for-loop, I'm pretty much stuck, since I cannot just replace the calls with combo_run, as combo_run doesn't seem to wait until the combo is finished.

So my setup, without going too much into unnecessary detail, is:
Code: Select all
main {
    if (event_active(SWITCH_X)) combo_run(doThings);; // initiate combo
}
 
combo doThings() {
    call doTenPresses();
    call doOtherStuff();
 
    call doTenPresses();
    call doTenPresses();
    call doTenPresses();
    call doTenPresses();
    call doTenPresses();
    call doTenPresses();
    call doTenPresses();
    call doOtherStuff();
 
}
 
combo doTenPresses {
    call(doSinglePress);
    call(doSinglePress);
    call(doSinglePress);
    call(doSinglePress);
    call(doSinglePress);
    call(doSinglePress);
    call(doSinglePress);
    call(doSinglePress);
    call(doSinglePress);
    call(doSinglePress);
}

And I would like to clean all this up so I don't have all these duplicates in there. The timing of a single combo, for example doTenPresses is also slightly different every time as I use a randomizer in it too.

Sorry to bother you but I just started out with the Titan Two, and while I'm not new to programming, some of these restrictions are holding me back at the moment.
User avatar
Yuri-chan
Staff Sergeant
Staff Sergeant
 
Posts: 10
Joined: Sun Jun 28, 2020 3:57 pm

Re: Elegant way to loop combos via call?

Postby Scachi » Thu Jul 02, 2020 5:43 pm

Usa wrote:Thanks for the fast reply!

So, looking at your example it seems it only works from the main loop, not from another combo, right?

Seems to work fine from within combos:
Code: Select all
#define SWITCH_X BUTTON_16
int counter;
 
main {
    if (event_active(SWITCH_X)) combo_run(doThings);; // initiate combo
}
 
combo doThings {
    printf("0");
    call(doTenPresses);
    call(doOtherStuff);
    printf("1");
    call(doTenPresses);
    printf("2");
    call(doTenPresses);
    printf("3");
    call(doTenPresses);
    printf("4");
    call(doTenPresses);
    printf("5");
    call(doTenPresses);
    printf("6");
    call(doTenPresses);
    printf("7");
    call(doTenPresses);
    printf("8");
    call(doOtherStuff);
}
 
combo doTenPresses {
    call(doSinglePress);
    // At the very end of the combo block
    //if(++counter < 10) combo_restart(doTenPresses);
    if(++counter < 10) doTenPresses[1]=0;
    wait(0);
    counter = 0;
}
 
combo doSinglePress {
    set_val(SWITCH_X,100); wait(100);
    set_val(SWITCH_X,0); wait(100);
    wait(100);
}
 
combo doOtherStuff {
    wait(100);
}
User avatar
Scachi
Brigadier General
Brigadier General
 
Posts: 3044
Joined: Wed May 11, 2016 6:25 am
Location: Germany

Re: Elegant way to loop combos via call?

Postby DontAtMe » Thu Jul 02, 2020 6:04 pm

I would like to clean all this up so I don't have all these duplicates in there


Code: Select all
#define CONCAT(prefix) _CONCAT(prefix,__LINE__)
#define _CONCAT(A,B) _CONCAT_(A,B)
#define _CONCAT_(A,B)A##B
#define wait_until(CONDITON, ELSE, COMBO_NAME)  if(!(CONDITON)){uint8 CONCAT(a)=COMBO_NAME[1];combo_restart(COMBO_NAME),COMBO_NAME[1]=CONCAT(a)-1;}else(ELSE);wait(0);
 
int total_loops;
int current_loop;
 
main {
  if(event_active(BUTTON_14)) combo_run(doThings); // initiate combo
 
  //set_val(20, current_loop);
}
 
combo doThings {
 
  combo_run(doSinglePress);
  total_loops = 10;
  wait_until(current_loop == total_loops, current_loop = -1, doThings)
 
  call(doOtherStuff);
 
  combo_run(doSinglePress);
  total_loops = 70;
  wait_until(current_loop == total_loops, current_loop = -1, doThings)
 
  call(doOtherStuff);
 
}
 
combo doSinglePress {
  set_val(BUTTON_16, 100);
  wait(100);
  set_val(BUTTON_16, 0);
  wait(100);
  current_loop += elapsed_time();
}
 
combo doOtherStuff {
  wait(500);
  printf("Done other stuff");
}


Time for some preprocessor fun :a1chill_angry1:
User avatar
DontAtMe
Captain
Captain
 
Posts: 502
Joined: Tue Oct 02, 2018 4:49 am

Re: Elegant way to loop combos via call?

Postby Yuri-chan » Fri Jul 03, 2020 2:24 am

Thanks for the helpful replies, Scachi and DontAtMe, I can really learn from these examples!
I think I just need to wrap my head around those, as I'm used to work differently with procedures.

I still find it kinda strange and restricting to not be able to call from an if statement or for loop,
but I can see how these workarounds do basically the same stuff, just differently.

Thanks again, you helped me out quite a bit :)
User avatar
Yuri-chan
Staff Sergeant
Staff Sergeant
 
Posts: 10
Joined: Sun Jun 28, 2020 3:57 pm

Re: Elegant way to loop combos via call?

Postby Buffy » Fri Jul 03, 2020 7:49 pm

You can use call in an if statement inside a combo.

For example, if you don't want it to tap the button if the button is already being held down on the controller itself:

Code: Select all
  
 
int num_times_to_press;
int curr_times_pressed;
 
main {
  if(event_active(BUTTON_14)) combo_run(doThings); // initiate combo
}
 
combo doThings {
    num_times_to_press = 10;
    if(is_release(BUTTON_15)) call(doPresses);
 
    call(doOtherStuff);
 
    num_times_to_press = 1;
    if(is_release(BUTTON_15))  call(doPresses);
    num_times_to_press = 70;
    if(is_release(BUTTON_15))  call(doPresses);
 
    call(doOtherStuff);
}
 
combo doPresses {
    set_val(BUTTON_15, 100);
    wait(100);
    set_val(BUTTON_15, 0);
    wait(100);
    if(curr_times_pressed = (curr_times_pressed + 1) % num_times_to_press) combo_restart(doPresses);
    wait(0);
}
 
combo doOtherStuff {
    wait(500);
    printf("Done other stuff");
}
 
ConsoleTuner Support Team || Discord || Custom Scripts
User avatar
Buffy
Lieutenant
Lieutenant
 
Posts: 422
Joined: Wed Jul 20, 2016 5:23 am

Re: Elegant way to loop combos via call?

Postby Scachi » Fri Jul 03, 2020 8:04 pm

oh wow, I didn't know that. doesn't seems to work when using { }
User avatar
Scachi
Brigadier General
Brigadier General
 
Posts: 3044
Joined: Wed May 11, 2016 6:25 am
Location: Germany


Return to GPC2 Script Programming

Who is online

Users browsing this forum: midg3t2 and 200 guests