I'm new to AutoHotKey and am trying to create a script to let me use my Roku's Bluetooth remote with my PC. The issue with the remote is that all the keys are weird. What I would like is so that when I press x and y at the same time, all the necessary keys are remapped to the ones for the remote and vise-versa for the keyboard. Here is what I have right now (doesn't work):
state = keyboard
loop{
if (GetKeyState("x", "P") && GetKeyState("y", "P")){
if (state == "keyboard") {
state = roku
Sleep 30
}
else if (state == "roku") {
state = keyboard
Sleep 30
}
}
if (state == "roku"){
4::send h
u::send {up}
l::send {left}
r::send {right}
d::send {down}
e::send {esc}
6::send {backspace}
c::send r
8::send f
s::send {enter}
3::send c
a::send {space}
}
}
Does anyone know why this doesn't work?
~x & y::(HotkeysState:=!HotkeysState)
#If HotkeysState
4::SendInput h
u::SendInput {up}
l::SendInput {left}
r::SendInput {right}
d::SendInput {down}
e::SendInput {esc}
6::SendInput {backspace}
c::SendInput r
8::SendInput f
s::SendInput {enter}
3::SendInput c
a::SendInput {space}
#If
Related
I want to move an object in Haskell Gloss every frame a key is pressed, not just the one frame that the key is started being pressed. (Example: While 'w' key is pressed, accelerate object every frame)
Edit: I tried using the second parameter of EventKey but to no avail.
My code:
--TODO - Holding keys doesn't work yet
handleKeys :: Event -> AsteroidsGame -> AsteroidsGame
handleKeys (EventKey (Char char) _ _ _) game
| char == 'w' = move 0 1
| char == 'a' = move (-1) 0
| char == 's' = move 0 (-1)
| char == 'd' = move 1 0
where move x y = game {player = accelerateObject (player game) x y}
handleKeys _ game = game
accelerateObject :: Object -> Float -> Float -> Object
accelerateObject obj hor ver = obj {vel = (vx + hor, vy + ver)}
where (vx, vy) = vel obj
As OP correctly deduced, gloss gives you input events ("key was just pressed", "mouse was just moved"), rather than input state ("key is currently pressed", "mouse is at x,y"). There doesn't seem to be a built-in way to see input state on each frame, so we'll have to make our own workaround. Thankfully, this isn't too difficult!
For a simple working example, we'll make an incredibly fun "game" where you can watch a counter count upwards while the space bar is pressed. Riveting. This approach generalises to handling any key presses, so it'll be easy to extend to your case.
The first thing we need is our game state:
import qualified Data.Set as S
data World = World
{ keys :: S.Set Key
, counter :: Int }
We keep track of our specific game state (in this case just a counter), as well as state for our workaround (a set of pressed keys).
Handling input events just involves either adding a key to our set of currently pressed keys or removing it:
handleInput :: Event -> World -> World
handleInput (EventKey k Down _ _) world = world { keys = S.insert k (keys world)}
handleInput (EventKey k Up _ _) world = world { keys = S.delete k (keys world)}
handleInput _ world = world -- Ignore non-keypresses for simplicity
This can easily be extended to handle eg. mouse movement, by changing our World type to keep track of the last known coordinates of the cursor, and setting it in this function whenever we see an EventMotion event.
Our frame-to-frame world update function then uses the input state to update the specific game state:
update :: Float -> World -> World
update _ world
| S.member (SpecialKey KeySpace) (keys world) = world { counter = 1 + counter world }
| otherwise = world { counter = 0 }
If the spacebar is currently pressed (S.member (SpecialKey KeySpace) (keys world)), increment the counter - otherwise, reset it to 0. We don't care about how much time as elapsed between frames so we ignore the float argument.
Finally we can render our game and play it:
render :: World -> Picture
render = color white . text . show . counter
main :: IO ()
main = play display black 30 initWorld render handleInput update
where
display = InWindow "test" (800, 600) (0, 0)
initWorld = World S.empty 0
I am working on a promela model that is fairly simple. Using two different modules, it acts as a crosswalk/Traffic light. The first module is the traffic light that outputs the current signal (green, red, yellow, pending). This module also receives as an input a signal called "pedestrian" which acts as an indicator that there are pedestrians wanting to cross. The second module acts as the crosswalk. It receives output signals from the traffic light module (green, yellow, green). It outputs the pedestrian signal to the traffic light module. This module simply defines whether the pedestrian(s) is crossing, waiting or not present. My issue is that once the count value goes to 60, a timeout occurs. I believe the statement "SigG_out ! 1" is causing the error but I do not know why. I have attached the image of the trace I receive from the command line. I am completely new to Spin and Promela and so I am not sure how to use the information form the trace to find my issue in the code. Any help is greatly appreciated.
Here is the code for the complete model:
mtype = {red, green, yellow, pending, none, crossing, waiting};
mtype traffic_mode;
mtype crosswalk_mode;
int count;
chan pedestrian_chan = [0] of {byte};
chan sigR_chan = [0] of {byte};
chan sigG_chan = [0] of {byte};
chan sigY_chan = [0] of {byte};
ltl l1 {!<> (pedestrian_chan[0] == 1) && (traffic_mode == green || traffic_mode == yellow || traffic_mode == pending)}
ltl l2 {[]<> (pedestrian_chan[0] == 1) -> crosswalk_mode == crossing }
proctype traffic_controller(chan pedestrian_in, sigR_out, sigG_out, sigY_out)
{
do
::if
::(traffic_mode == red) ->
count = count + 1;
if
::(count >= 60) ->
sigG_out ! 1;
count = 0;
traffic_mode = green;
:: else -> skip;
fi
::(traffic_mode == green) ->
if
::(count < 60) ->
count = count + 1;
::(pedestrian_in == 1 & count < 60) ->
count = count + 1;
traffic_mode = pending;
::(pedestrian_in == 1 & count >= 60)
count = 0;
traffic_mode = yellow;
fi
::(traffic_mode == pending) ->
count = count + 1;
if
::(count >= 60) ->
sigY_out ! 1;
count = 0;
traffic_mode = yellow;
::else -> skip;
fi
::(traffic_mode == yellow) ->
count = count + 1;
if
::(count >= 5) ->
sigR_out ! 1;
count = 0;
traffic_mode = red;
:: else -> skip;
fi
fi
od
}
proctype crosswalk(chan sigR_in, sigG_in, sigY_in, pedestrian_out)
{
do
::if
::(crosswalk_mode == crossing) ->
if
::(sigG_in == 1) -> crosswalk_mode = none;
fi
::(crosswalk_mode == none) ->
if
:: (1 == 1) -> crosswalk_mode = none
:: (1 == 1) ->
pedestrian_out ! 1
crosswalk_mode = waiting
fi
::(crosswalk_mode == waiting) ->
if
::(sigR_in == 1) -> crosswalk_mode = crossing;
fi
fi
od
}
init
{
count = 0;
traffic_mode = red;
crosswalk_mode = crossing;
atomic
{
run traffic_controller(pedestrian_chan, sigR_chan, sigG_chan, sigY_chan);
run crosswalk(sigR_chan, sigG_chan, sigY_chan, pedestrian_chan);
}
}
You are using channels incorrectly, this line in particular I wouldn't even know how to interpret it:
:: (sigG_in == 1) ->
Your channels are synchronous, which means that whenever a process sends something on one side, another process must listen on the other end of the channel in order to deliver the message. Otherwise, the process blocks until when the situation changes. Your channels are synchronous because you declared them of size 0.
To read from a channel, you need to use the proper syntax:
int some_var;
...
some_channel?some_var;
// here some_var contains value received through some_channel
It seems to be a bit pointless to use three different channels to send different signals. What about using three different values?
mtype = { RED, GREEN, YELLOW };
chan c = [0] of { mtype };
...
c!RED
...
// (some other process)
...
mtype var;
c?var;
// here var contains RED
...
Vigenere is encrypting the message incorrectly for example if the key is "hello" and the message is hello, the encrypted text is now "eipsv" when it should be "hello".
I would really appreciate any tips on fixing this bug.
string message = GetString();
int m = strlen(message);
int i = 0;
if(isalpha(message[i]))
{
for(int j = 0; j < n; i++)
{
key[j] = tolower(key[j]) - 97;
j++;
for (i = 0; i < m; i++)
{
char c = message[i];
if (islower(c))
{
c = (((c - 'a' + key[j%n])%26) +'a');
j++;
printf("%c", c);
}
if (isupper (c))
{
c = (((c - 'A' + key[j%n])%26) +'A');
j++;
printf("%c", c);
}
else if (!isupper(c) && !islower(c))
{
printf("%c", c);
j++;
}
}
}
}
printf("\n");
}
Ok, a handful of changes:
Your first loop to convert the key to values of 0 - 25 should be in a separate loop from the encoding loop. Convert the key, and then move on to the encoding loop.
In the encoding loop, you will need two incrementers, "i" and "j", both of which need to be reinitialized to 0 in your FOR ( ...;...;... ) line. You can't reuse "j" from your key conversion loop because it is out of scope.
Remove j++ after your printf() line from your ELSE IF statement in encoding loop. You do not increment "j" if a letter isn't encoded.
By the way, once you update your program and run it through check50, you will find several error-check errors because you have some error conditions to check that I don't see in your current code. But, it should encode correctly with the above changes.
Using the keyword "hello" would encode your message "hello" as follows:
h -> (shift 7) -> o
e -> (shift 4) -> i
l -> (shift 11) -> w
l -> (shift 11) -> w
0 -> (shift 14) -> c
So, the result should be "oiwwc".
I've made a controls room for custom keymapping. I had an idea - if key is assigned to more than 1 control, then it shows up red. But it works only partially.
Spawn code:
with(instance_create(64,64,obj_button_key)) {
mytext="UP: ";
myKEY=global.keyUP;
mytype=1;
}
with(...
scr_keymap_conflict(argument0):
var ii;
ii = 0;
if (argument0 == global.keyUP) ii+=1;
if (argument0 == global.keyDOWN) ii+=1;
if (argument0 == global.keyLEFT) ii+=1;
if (argument0 == global.keyRIGHT) ii+=1;
if (argument0 == global.keySPRINT) ii+=1;
if (argument0 == global.keyCROUCH) ii+=1;
if (argument0 == global.keyGRENADE) ii+=1;
if (argument0 == global.keyACTION) ii+=1;
if (argument0 == global.keyCHAT) ii+=1;
if (argument0 == global.keyMELEE) ii+=1;
if (argument0 == global.keyDROP) ii+=1;
if (ii > 1) {
return true;
}
Draw:
if (active) {draw_set_color(c_yellow)}
else if (scr_keymap_conflict(myKEY)) {draw_set_color(c_red)}
else draw_set_color(c_gray);
...
It seems like there's a problem with scr_keymap_conflict(argument0) giving invalid info, so some buttons turn red, but some don't, an example, if there are two vk_space controls, then the first one will become red, but the second won't (I have a feeling that draw_set_color is overwriting separate objects at random moments). Anyway, global.key... hold ASCII real values (keyboard shortcuts). active and mytype are not important in this case. Anyone got any idea how to fix this?
Your script is only returning a value in case of ii being equal or more than 1. When GM ends a script without a return value (or simply calling "return") the value returned is just random, it might be "true" or "false", or "hello world" string.
(typically it is the previous function's result).
This is a first bug, but when you fix it you'll notice keys will never turn red.. This is because semantically you're checking if a key is binded to two "functions". NOT if two "functions" are binded to 2 keys.
You would need a different system for that, easiest thing I can think of is to use a controller (code below isn't tested, just to show the idea):
create event controlling object
keyUP = ds_list_create();
keyDown = ds_list_create();
keyLEFT = ds_list_create();
keyRIGHT = ds_list_create();
keySPRINT = ds_list_create();
keyCROUCH = ds_list_create();
keyGRENADE = ds_list_create();
keyACTION = ds_list_create();
keyCHAT = ds_list_create();
keyMELEE = ds_list_create();
keyDROP = ds_list_create();
step event controlling object
ds_list_clear(keyUP);
ds_list_clear(keyDOWN);
//... etc for all keys
with (objKeys) {
ds_list_add(myKEY, id);
}
spawn code of objKeys
with(instance_create(64,64,obj_button_key)) {
mytext="UP: ";
myKEY=objKeyController.keyUP;
//notice that it refers to the controller's list
mytype=1;
}
draw event
if (active) {draw_set_color(c_yellow)}
else if (ds_list_size(myKEY) > 1) {draw_set_color(c_red)}
else draw_set_color(c_gray);
...
The controller's step event can probably be removed if you add/remove the keys to/from the lists on assignment (user input). That way the lists don't have to rebuild each step.
Also an obvious improvement is to stash all those "keys" inside a map instead of simple variables.
This method has O(n) time instead of O(n^2) you would get when using a function instance_variable(obj,var)
I have found these two APIs at http://linux.die.net/man/3/xgetpointermapping. I think that they can be used to swap mouse buttons on linux or mac system. I used it in following way:
Display * curdisp; // Current display.
char curmap[MAX_NUM];// Current mapping.
int nmap; // number of mappings.
curdisp = XOpenDisplay(NULL);
nmap = XGetPointerMapping(curdisp, curmap, MAX_NUM);
if(!nmap)
return -1;
if(curmap[0] == '1' && curmap[2] == '3') {
curmap[0] = '3';
curmap[2] = '1';
} else {
curmap[0] = '1';
curmap[2] = '3';
}
//Set the mapping.
nmap = XSetPointerMapping(curdisp, curmap, nmap);
But the call XSetPointerMapping returns 0 and there is no effect on mouse button.
Can anyone give some example of swapping mouse button using XSetPointerMapping? or How to use it correctly? Will it work immediately?
The OS being used is Mac OS X 10.7.4.
The button numbers are stored as unsigned char but are not stored as characters.
Change '1' and '3' to 1 and 3.
Your code maps them to buttons 49 and 51 and does affect the buttons making button 1 and 3 unusable.