Jump to content

Controls and bitwise


ItHadToComeToThis
 Share

You are about to reply to a thread that has been inactive for 207 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I really should be more informed on bitwise but here we are.

When it comes to controls, we can press, hold and release.

Is there a way to do a different action depending on whether you press, hold or release, on the same key?

I don't mean in order, I mean if I chose to hold the key rather than press it, it would do a different action than if I was to just press it.

I have tried such things and many bitwise variations of if((~press&FORWARD)&(hold&FORWARD), playing around with the & | && ~ ! etc etc but I can't seem to figure out what the right way to write it is.

I am trying to see just how many actions I can get out of the limited controls LL allows us to take in a script.

If I can do the following.....

Hold PAGE DOWN and press WASDEC for six actions

and

Hold PAGE DOWN and hold WASDEC for six different actions

That would be neat.

To further this, would it be possible to add to this, hold PAGE DOWN and release WASDEC for six further actions that aren't pressing or holding, or am I asking for too much here?

I don't particularly want to use timers if I can help it.

Edited by ItHadToComeToThis
Link to comment
Share on other sites

To differentiate between "press" (quick) and "hold" (long), you need to track time manually using llGetTime or similar.

For example, llResetTime if (level & edge & CONTROL_whatever), then llGetTime if (level & CONTROL_whatever) until the "hold" action should trigger.

If the key is released early (level & ~edge & CONTROL_whatever), do the "press" action.

Edited by Wulfie Reanimator
  • Like 3
Link to comment
Share on other sites

13 minutes ago, Wulfie Reanimator said:

you need to track time manually using llGetTime or similar.

Actually, you could probably track the number of control events. for simplicity assuming just Control_FWD is being tracked, (and just an off the cuff untested example:)

integer gCount_FWD = 0;

control(key ID, integer level, integer edge)
{   if( (level&CONTROL_FWD) && (edge&CONTROL_FWD) ) // equivalently, level&edge&control_fwd?
    {   gCount_FWD = 0; // button was just pressed, 
    }else if( (level&CONTROL_FWD) && (~edge&CONTROL_FWD) )
    {   ++gCount_FWD; // button is held, increment count.
    }else if( (~level&CONTROL_FWD) && (edge&CONTROL_FWD) )
    {   // button was released.
        if(gCount_FWD > 45) // IIRC there are about 45 events per second?
        {   do_long_hold_action();
        }else
        {   do_short_hold_action();
        }
    }
}

 

  • Like 3
Link to comment
Share on other sites

37 minutes ago, Quistess Alpha said:

Actually, you could probably track the number of control events.

I suppose, but I don't think the rate of control events is as consistent as time-tracking.

It's probably much harder to remember what the number of events represents in time. How long is 123 events?

Scripts also tend to "run faster" based on inputs. (It's a bane for combat devs, since it affects rez-speed.) I dunno how the rate of control events would be affected if you were making intermittent/rapid inputs.

Edited by Wulfie Reanimator
  • Thanks 1
Link to comment
Share on other sites

49 minutes ago, Wulfie Reanimator said:

I don't think the rate of control events is as consistent as time-tracking.

probably not, and certainly not for timescales longer than a few seconds, but for a cut-off point between roughly 0.2~0.7 seconds, might depends more on your connection latency than the specific method used. Whether to use one or the other would be up to a bit of testing, and whether the timing of multiple inputs is important (hold down c, wait a moment then press another control being different than pressing both c and the other control at the same time)  I forgot you can just record the start time of an input without resetting the script's clock. I probably would use time rather than # of events for legibility if nothing else. llResetTime() on attach and changed_teleport if float precision becomes an issue.

Link to comment
Share on other sites

2 hours ago, Wulfie Reanimator said:

To differentiate between "press" (quick) and "hold" (long), you need to track time manually using llGetTime or similar.

For example, llResetTime if (level & edge & CONTROL_whatever), then llGetTime if (level & CONTROL_whatever) until the "hold" action should trigger.

If the key is released early, do the "press" action.

Okay firstly I played around with your method. And this is VERY rough around the edges and needs to be VASTLY improved. I will try to improve this a little more when I wake up and im not so tired, though if you can offer any thoughts I would gladly listen.

 

@Quistess Alpha I am going to play around with your method tomorrow when I wake up and compare the two.

 

I should point out the double tap section is from another script I wrote a long time ago, I haven't merged the ideas yet, just pasted it in to show the full set of controls I have so far.

 

This is what I have so far from @Wulfie Reanimator idea.

integer type;
integer timeNow;
float timeHold;
integer holdBool=0;
integer timeCheck(){
    if((llGetUnixTime()-timeNow)>1){
        timeNow=llGetUnixTime();
        type=0;
        return 1;
    }
    return 0;
}

default{
    state_entry(){
        llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS);
        timeNow=llGetUnixTime();
    }
    run_time_permissions(integer x){
        if(x&PERMISSION_TAKE_CONTROLS){
            llTakeControls(CONTROL_FWD|CONTROL_BACK|CONTROL_RIGHT|CONTROL_LEFT|CONTROL_ROT_RIGHT|CONTROL_ROT_LEFT|CONTROL_UP|CONTROL_DOWN|CONTROL_LBUTTON|CONTROL_ML_LBUTTON,TRUE,TRUE);
        }
    }
    control(key id, integer level, integer edge){
        integer start=level&edge;   //Press
        integer end=~level&edge;    //Unpress
        integer held=level&~edge;   //Held
        //integer untouched=~(level|edge);
        
        //==========Control Set 1 - While holding C or PAGE DOWN==========
        if(held&CONTROL_DOWN){
            //Holding the keys down
            if(held&CONTROL_FWD||held&CONTROL_BACK||held&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)||held&(CONTROL_LEFT|CONTROL_ROT_LEFT)||held&CONTROL_UP){
                if(!holdBool){
                    timeHold=llGetTime();
                    holdBool=1;
                }
                if(llGetTime()-timeHold>=0.25){
                    if(held&CONTROL_FWD){
                        llOwnerSay("PG_DOWN Hold Action 1");
                    }else if(held&CONTROL_BACK){
                        llOwnerSay("PG_DOWN Hold Action 2");
                    }else if(held&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)){
                        llOwnerSay("PG_DOWN Hold Action 3");
                    }else if(held&(CONTROL_LEFT|CONTROL_ROT_LEFT)){
                        llOwnerSay("PG_DOWN Hold Action 4");
                    }else if(held&CONTROL_UP){
                        llOwnerSay("HPG_DOWN old Action 5");
                    }
                }
            }
            //Or tapping (pressing) the keys
            if(end&CONTROL_FWD||end&CONTROL_BACK||end&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)||end&(CONTROL_LEFT|CONTROL_ROT_LEFT)||end&CONTROL_UP){
                if(llGetTime()-timeHold<0.25){
                    if(end&CONTROL_FWD){
                        llOwnerSay("PG_DOWN Press Action 1");
                    }else if(end&CONTROL_BACK){
                        llOwnerSay("PG_DOWN Press Action 2");
                    }else if(end&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)){
                        llOwnerSay("PG_DOWN Press Action 3");
                    }else if(end&(CONTROL_LEFT|CONTROL_ROT_LEFT)){
                        llOwnerSay("PG_DOWN Press Action 4");
                    }else if(end&CONTROL_UP){
                        llOwnerSay("PG_DOWN Press Action 5");
                    }
                }
                holdBool=0;
            }
        }else{
            //==========Control Set 2 - While holding left mouse button==========
            if(held&CONTROL_LBUTTON){
                //Holding the keys down
                if(held&CONTROL_FWD||held&CONTROL_BACK||held&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)||held&(CONTROL_LEFT|CONTROL_ROT_LEFT)||held&CONTROL_UP){
                    if(!holdBool){
                        timeHold=llGetTime();
                        holdBool=1;
                    }
                    if(llGetTime()-timeHold>=0.25){
                        if(held&CONTROL_FWD){
                            llOwnerSay("LEFT_MOUSE Hold Action 1");
                        }else if(held&CONTROL_BACK){
                            llOwnerSay("LEFT_MOUSE Hold Action 2");
                        }else if(held&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)){
                            llOwnerSay("LEFT_MOUSE Hold Action 3");
                        }else if(held&(CONTROL_LEFT|CONTROL_ROT_LEFT)){
                            llOwnerSay("LEFT_MOUSE Hold Action 4");
                        }else if(held&CONTROL_UP){
                            llOwnerSay("LEFT_MOUSE Hold Action 5");
                        }
                    }
                }
                //Or tapping (pressing) the keys
                if(end&CONTROL_FWD||end&CONTROL_BACK||end&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)||end&(CONTROL_LEFT|CONTROL_ROT_LEFT)||end&CONTROL_UP){
                    if(llGetTime()-timeHold<0.25){
                        if(end&CONTROL_FWD){
                            llOwnerSay("LEFT_MOUSE Press Action 1");
                        }else if(end&CONTROL_BACK){
                            llOwnerSay("LEFT_MOUSE Press Action 2");
                        }else if(end&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)){
                            llOwnerSay("LEFT_MOUSE Press Action 3");
                        }else if(end&(CONTROL_LEFT|CONTROL_ROT_LEFT)){
                            llOwnerSay("LEFT_MOUSE Press Action 4");
                        }else if(end&CONTROL_UP){
                            llOwnerSay("LEFT_MOUSE Press Action 5");
                        }
                    }
                    holdBool=0;
                }
            }else{
                //==========Control Set 3 - While holding E or PAGE UP==========
                if(held&CONTROL_UP){
                    //Holding the keys down
                    if(held&CONTROL_FWD||held&CONTROL_BACK||held&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)||held&(CONTROL_LEFT|CONTROL_ROT_LEFT)||held&CONTROL_UP){
                        if(!holdBool){
                            timeHold=llGetTime();
                            holdBool=1;
                        }
                        if(llGetTime()-timeHold>=0.25){
                            if(held&CONTROL_FWD){
                                llOwnerSay("PAGE UP Hold Action 1");
                            }else if(held&CONTROL_BACK){
                                llOwnerSay("PAGE UP Hold Action 2");
                            }else if(held&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)){
                                llOwnerSay("PAGE UP Hold Action 3");
                            }else if(held&(CONTROL_LEFT|CONTROL_ROT_LEFT)){
                                llOwnerSay("PAGE UP Hold Action 4");
                            }else if(held&CONTROL_UP){
                                llOwnerSay("PAGE UP Hold Action 5");
                            }
                        }
                    }
                    //Or tapping (pressing) the keys
                    if(end&CONTROL_FWD||end&CONTROL_BACK||end&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)||end&(CONTROL_LEFT|CONTROL_ROT_LEFT)||end&CONTROL_UP){
                        if(llGetTime()-timeHold<0.25){
                            if(end&CONTROL_FWD){
                                llOwnerSay("PAGE UP Press Action 1");
                            }else if(end&CONTROL_BACK){
                                llOwnerSay("PAGE UP Press Action 2");
                            }else if(end&(CONTROL_RIGHT|CONTROL_ROT_RIGHT)){
                                llOwnerSay("PAGE UP Press Action 3");
                            }else if(end&(CONTROL_LEFT|CONTROL_ROT_LEFT)){
                                llOwnerSay("PAGE UP Press Action 4");
                            }else if(end&CONTROL_UP){
                                llOwnerSay("PAGE UP Press Action 5");
                            }
                        }
                        holdBool=0;
                    }
                }
            }
        }
        //==========Control Set 4 - Double Tap==========
        if(timeCheck()|start){
            type+=start;
            //Fwd
            if((start&CONTROL_FWD)&&type==2){
                llOwnerSay("Double Tap 1");
            }
            //Back
            if((start&CONTROL_BACK)&&type==4){
                llOwnerSay("Double Tap 2");
            }
            //Left
            if((start&(CONTROL_LEFT|CONTROL_ROT_LEFT))&&type==512){
                llOwnerSay("Double Tap 3");
            }
            //Right
            if((start&(CONTROL_RIGHT|CONTROL_ROT_RIGHT))&&type==1024){
                llOwnerSay("Double Tap 4");
            }
            //E or PAGE UP
            if((start&CONTROL_UP)&&type==32){
                llOwnerSay("Double Tap 5");
            }
            //C or PAGE DOWN
            if((start&CONTROL_DOWN)&&type==64){
                llOwnerSay("Double Tap 6");
            }
        }
        //Reset holdBool
        if(end&CONTROL_DOWN||end&CONTROL_LBUTTON||end&CONTROL_UP){
            holdBool=0;
        }
    }
}

 

Link to comment
Share on other sites

to make things a little more efficient we can use XOR (^) to filter controls. Example:

if (held & CONTROL_DOWN)
{
   if (held ^ CONTROL_DOWN) 
   {
      // here held != 0 when other controls are also held
      // which additionally means that CONTROL_DOWN on its own will not execute here

      if (!heldBool)
      {
         ...
      }

      if (held & ...

    }
}

another little efficiency by removing arithmetic

timeHold = llGetTime() + 0.25;

if (llGetTime() >= timeHold)  ... Hold Action

if (llGetTime() < timeHold)  ... Press Action

 

 

Edited by elleevelyn
delete a further example as not true
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 207 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...