check_active() with keyboards?
36 posts
• Page 3 of 4 • 1, 2, 3, 4
Re: check_active() with keyboards?
antithesis wrote:Nice work Buffy!
Very nice indeed. I really liked the solution of having a gph file for configuration, so only the keys/inputs of interest are tracked for events detection.
ConsoleTuner Support Team
-
J2Kbr - General of the Army
- Posts: 20323
- Joined: Tue Mar 18, 2014 1:39 pm
Re: check_active() with keyboards?
J2Kbr wrote:antithesis wrote:Nice work Buffy!
Very nice indeed. I really liked the solution of having a gph file for configuration, so only the keys/inputs of interest are tracked for events detection.
I opened a ticket for it, but one thing that would be nice would be if we could use sizeof with arrays. It could simply some code and require less work by the user to setup the extra buttons:
- Code: Select all
uint8 extra_keys_status[sizeof(EXTRA_KEY_VAR)] = { 0 };
-
Buffy - Lieutenant
- Posts: 422
- Joined: Wed Jul 20, 2016 5:23 am
Re: check_active() with keyboards?
I just saw on GitHub.
https://github.com/J2Kbr/GtunerIV/issues/225
I believe we can have that. Thank you.
https://github.com/J2Kbr/GtunerIV/issues/225
I believe we can have that. Thank you.
ConsoleTuner Support Team
-
J2Kbr - General of the Army
- Posts: 20323
- Joined: Tue Mar 18, 2014 1:39 pm
Re: check_active() with keyboards?
J2Kbr wrote:I just saw on GitHub.
https://github.com/J2Kbr/GtunerIV/issues/225
I believe we can have that. Thank you.
It'd be even better if structs were to be added too
-
Buffy - Lieutenant
- Posts: 422
- Joined: Wed Jul 20, 2016 5:23 am
Re: check_active() with keyboards?
the sizeof() on array declaration is now implemented and will be available with Gtuner IV 1.00RC-60.
The support for structs is on the plans, this implementation will be more complex, but will be done.
The support for structs is on the plans, this implementation will be more complex, but will be done.
ConsoleTuner Support Team
-
J2Kbr - General of the Army
- Posts: 20323
- Joined: Tue Mar 18, 2014 1:39 pm
Re: check_active() with keyboards?
Just posting this to show what I'm working on. This is a fork of Buffy and J2Kbr's amazing work, in an attempt to add in some extra features, shortcuts. This code is fully functional, requires a configuration header though.
Configuration Only (No code)
Core Code (Working as intended.)
There's a bunch of defines I use as shortcuts for frequently used nested statements.
A couple new fire-once events have been added.
If you're looking at the code for mouse_check it might seem fairly useless. I wrote it purely to help me keep track of user idling in combination with the built in key_check.
Warning to potential newcomers about the code below.
The code below is in an unfinished state and I would advise against using it. This is the same code as the above with some attempts at optimizing it.
Optimization was obtained by adding in a timer in the form of _extra_buttons_time_since_last_update.
This is a very minor sacrifice of responsiveness for improving device performance.
For most general use cases this works, however for some of the time related key events it's been causing me issues.
Configuration Only (No code)
- Code: Select all
/* *********************************************************** *
* Example KB&M Script for Titan Two
*
* Created by Buffy - 5/10/2018
*
* *********************************************************** */
#ifndef _EXTRA_CONFIG_
#define _EXTRA_CONFIG_
#define EXTRA_MOUSE_INPUT 192
#include <keyboard.gph>
#include <mouse.gph>
// your config here
#define NUM_OF_EXTRA_KEYS 3
#define EXTRA_KEY_VAR extra_keys_to_monitor
const uint8 EXTRA_KEY_VAR[NUM_OF_EXTRA_KEYS] = {
KEY_TAB,
KEY_I,
MBUTTON_1 | EXTRA_MOUSE_INPUT,
};
#endif
Core Code (Working as intended.)
There's a bunch of defines I use as shortcuts for frequently used nested statements.
A couple new fire-once events have been added.
- key_event_hold_active - Check if the monitored key has been active for the specified time.
- key_event_hold_release - Check if the monitored key was active for or greater than the specified time - before release.
- key_event_hold_release_under - Check if the monitored key was active for or less than the specified time - before release.
- mouse_check - Return active mouse input.
- key_status_override - Manually set the currently stored key state.
If you're looking at the code for mouse_check it might seem fairly useless. I wrote it purely to help me keep track of user idling in combination with the built in key_check.
- Code: Select all
#ifndef EXTRA_KEY_GPC_
#define EXTRA_KEY_GPC_
#include <keyboard.gph>
#include <mouse.gph>
#ifndef EXTRA_KEY_VAR
#define EXTRA_KEY_VAR _key_list
#define NUM_OF_EXTRA_KEYS 1
uint8 EXTRA_KEY_VAR[1] = { 0 };
#endif
#ifndef NUM_OF_EXTRA_KEYS
#define NUM_OF_EXTRA_KEYS 1
#endif
#ifndef EXTRA_MOUSE_INPUT
#define EXTRA_MOUSE_INPUT 192
#endif
#define _KEY_NOT_FOUND_IN_ARRAY 255
#define _KEY_STATUS_RELEASED 1
#define _KEY_STATUS_JUST_RELEASED 3
#define _KEY_STATUS_PRESSED 4
#define _KEY_STATUS_JUST_PRESSED 12
#define _KEY_STATUS_JUST_PRESSED_WAIT_WHILE_ACTIVE 24
uint8 _key_status[NUM_OF_EXTRA_KEYS] = { 0 };
uint32 _key_press_timestamp[NUM_OF_EXTRA_KEYS] = { 0 };
uint32 _key_rel_timestamp[NUM_OF_EXTRA_KEYS] = { 0 };
// Updates the release & active time values of every monitored key.
main {
uint8 _key_idx;
for(_key_idx = 0; _key_idx < NUM_OF_EXTRA_KEYS; _key_idx++) {
if(is_extra_button_active(EXTRA_KEY_VAR[_key_idx])) {
if (_key_status[_key_idx] & _KEY_STATUS_RELEASED) {
_key_status[_key_idx] = _KEY_STATUS_JUST_PRESSED;
_key_press_timestamp[_key_idx] = system_time();
}
else if (_key_status[_key_idx] == _KEY_STATUS_JUST_PRESSED){
_key_status[_key_idx] = _KEY_STATUS_PRESSED;
}
}
else {
if ((_key_status[_key_idx] & _KEY_STATUS_PRESSED) ||
(_key_status[_key_idx] & _KEY_STATUS_JUST_PRESSED_WAIT_WHILE_ACTIVE)) {
_key_status[_key_idx] = _KEY_STATUS_JUST_RELEASED;
_key_rel_timestamp[_key_idx] = system_time();
}
else {
_key_status[_key_idx] = _KEY_STATUS_RELEASED;
}
}
}
_key_idx = 0;
}
bool is_extra_button_active(uint8 button) {
return (key_status(button)) || ((button >= EXTRA_MOUSE_INPUT) && mouse_status(button - EXTRA_MOUSE_INPUT));
}
// Returns the array index associated with the button identifier.
uint8 key_index(uint8 key) {
uint8 i;
for(i = 0; i < NUM_OF_EXTRA_KEYS; i++) {
if(EXTRA_KEY_VAR[i] == key) {
return i;
}
}
printf("Error: Key not found in EXTRA_KEY_VAR array. Key: 0x%x (uint8 %u)", key, key);
return _KEY_NOT_FOUND_IN_ARRAY;
}
void key_status_override(uint8 key, uint8 status, uint32 time) {
uint8 i = key_index(key);
_key_status[i] = status;
switch (status) {
case _KEY_STATUS_PRESSED:
case _KEY_STATUS_JUST_PRESSED:
_key_press_timestamp[i] = time;
break;
case _KEY_STATUS_RELEASED:
case _KEY_STATUS_JUST_RELEASED:
_key_rel_timestamp[i] = time;
break;
}
}
// EVENT: Check if the monitored key changed its state from release to active.
bool key_event_active(uint8 key) {
return (_key_status[key_index(key)] == _KEY_STATUS_JUST_PRESSED);
}
// EVENT: Check if the monitored key changed its state from active to release.
bool key_event_release(uint8 key) {
return (_key_status[key_index(key)] == _KEY_STATUS_JUST_RELEASED);
}
// EVENT: Check if the monitored key has been active for the specified time.
bool key_event_hold_active(uint8 key, uint32 ms) {
uint8 i = key_index(key);
if (_key_status[i] == _KEY_STATUS_JUST_PRESSED) {
_key_status[i] = _KEY_STATUS_JUST_PRESSED_WAIT_WHILE_ACTIVE;
}
if ((_key_status[i] == _KEY_STATUS_JUST_PRESSED_WAIT_WHILE_ACTIVE) && (key_time_active(key) >= ms)) {
_key_status[i] = _KEY_STATUS_PRESSED;
return TRUE;
}
////printf("%d && %u", _key_status[i], key_time_active(key));
return FALSE;
}
// EVENT: Check if the monitored key was active for or greater than the specified time - before release.
bool key_event_hold_release(uint8 key, uint32 ms) {
return (_key_status[key_index(key)] == _KEY_STATUS_JUST_RELEASED && key_time_active(key) >= ms);
}
// EVENT: Check if the monitored key was active for or less than the specified time - before release.
bool key_event_hold_release_under(uint8 key, uint32 ms) {
return (_key_status[key_index(key)] == _KEY_STATUS_JUST_RELEASED && key_time_active(key) <= ms);
}
// The time that has passed since entered in active state.
uint32 key_time_active(uint8 key) {
uint8 i = key_index(key);
if(is_extra_button_active(key)) {
return (system_time() - _key_press_timestamp[i]);
///printf("IF: r = %u", r);
}
return 0;
}
// The time that has passed since entered in release state.
uint32 key_time_release(uint8 key) {
uint8 i = key_index(key);
if(is_extra_button_active(key)) {
return 0;
}
return 0;
}
bool key_check_active(uint8 key, uint32 ms) {
return (is_extra_button_active(key) && key_time_active(key) >= ms);
}
bool key_check_release(uint8 key, uint32 ms) {
return (!is_extra_button_active(key) && key_time_release(key) >= ms);
}
// Returns true if the key is actively being held down.
#define key_is_active(key) key_status(key)
// Returns true if the key is currently in a release state.
#define key_is_release(key) !key_is_active(key)
#define mouse_is_active(mouse) mouse_status(mouse)
#define mouse_is_release(mouse) !mouse_is_active(mouse)
#define mouse_event_active(mouse) key_event_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_event_release(mouse) key_event_release((mouse | EXTRA_MOUSE_INPUT))
#define mouse_time_active(mouse) key_time_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_time_release(mouse) key_time_release((mouse | EXTRA_MOUSE_INPUT))
#define mouse_check_active(mouse) key_check_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_check_release(mouse) key_check_release((mouse | EXTRA_MOUSE_INPUT))
// Return active mouse input. NOTE: Returns 0 if none BUT also 0 if MOUSE_X
// because MOUSE_X is indexed as 0. Shouldn't be a problem as long as you
// do not check exclusively for MOUSE_X input.
uint8 mouse_check(bool include_xy_movement) {
uint8 start_index = 2;
if (include_xy_movement) {
start_index = 0;
}
// Check mouse input indexes 2 through 19
uint8 i;
for (i = start_index; i < 20; i++) {
if (mouse_status(i)) {
return i;
}
}
return 0;
}
// key_is_active macros.
#define key_is_active_combo_run(b, c) if (key_is_active(b)) { combo_run(c); }
#define key_is_active_combo_stop(b, c) if (key_is_active(b)) { combo_stop(c); }
#define key_is_active_combo_pause(b, c) if (key_is_active(b)) { combo_pause(c); }
#define key_is_active_combo_restart(b, c) if (key_is_active(b)) { combo_restart(c); }
#define key_is_active_combo_toggle(b, c) if (key_is_active(b)) { c = !c; }
#define key_is_active_macro_run(b, c) if (key_is_active(b)) { macro_run(m); }
#define key_is_active_macro_stop(b, c) if (key_is_active(b)) { macro_stop(m); }
#define key_is_active_macro_toggle(b, c) if (key_is_active(b)) { m = !m; }
#define key_is_active_set_val(b, i, v) if (key_is_active(b)) { set_val(i, v); }
// key_status macros.
#define key_status_combo_run(b, c) if (key_status(b)) { combo_run(c); }
#define key_status_combo_stop(b, c) if (key_status(b)) { combo_stop(c); }
#define key_status_combo_pause(b, c) if (key_status(b)) { combo_pause(c); }
#define key_status_combo_restart(b, c) if (key_status(b)) { combo_restart(c); }
#define key_status_combo_toggle(b, c) if (key_status(b)) { c = !c; }
#define key_status_macro_run(b, c) if (key_status(b)) { macro_run(m); }
#define key_status_macro_stop(b, c) if (key_status(b)) { macro_stop(m); }
#define key_status_macro_toggle(b, c) if (key_status(b)) { m = !m; }
#define key_status_set_val(b, i, v) if (key_status(b)) { set_val(i, v); }
// key_event_active macros.
#define key_event_active_combo_run(b, c) if (key_event_active(b)) { combo_run(c); }
#define key_event_active_combo_stop(b, c) if (key_event_active(b)) { combo_stop(c); }
#define key_event_active_combo_pause(b, c) if (key_event_active(b)) { combo_pause(c); }
#define key_event_active_combo_restart(b, c) if (key_event_active(b)) { combo_restart(c); }
#define key_event_active_combo_toggle(b, c) if (key_event_active(b)) { c = !c; }
#define key_event_active_macro_run(b, c) if (key_event_active(b)) { macro_run(m); }
#define key_event_active_macro_stop(b, c) if (key_event_active(b)) { macro_stop(m); }
#define key_event_active_macro_toggle(b, c) if (key_event_active(b)) { m = !m; }
#define key_event_active_set_val(b, i, v) if (key_event_active(b)) { set_val(i, v); }
// key_event_release macros.
#define key_event_release_combo_run(b, c) if (key_event_release(b)) { combo_run(c); }
#define key_event_release_combo_stop(b, c) if (key_event_release(b)) { combo_stop(c); }
#define key_event_release_combo_pause(b, c) if (key_event_release(b)) { combo_pause(c); }
#define key_event_release_combo_restart(b, c) if (key_event_release(b)) { combo_restart(c); }
#define key_event_release_combo_toggle(b, c) if (key_event_release(b)) { c = !c; }
#define key_event_release_macro_run(b, c) if (key_event_release(b)) { macro_run(m); }
#define key_event_release_macro_stop(b, c) if (key_event_release(b)) { macro_stop(m); }
#define key_event_release_macro_toggle(b, c) if (key_event_release(b)) { m = !m; }
#define key_event_release_set_val(b, i, v) if (key_event_release(b)) { set_val(i, v); }
// key_check_active macros.
#define key_check_active_combo_run(b, ms, c) if (key_check_active(b, ms)) { combo_run(c); }
#define key_check_active_combo_stop(b, ms, c) if (key_check_active(b, ms)) { combo_stop(c); }
#define key_check_active_combo_pause(b, ms, c) if (key_check_active(b, ms)) { combo_pause(c); }
#define key_check_active_combo_restart(b, ms, c) if (key_check_active(b, ms)) { combo_restart(c); }
#define key_check_active_combo_toggle(b, ms, c) if (key_check_active(b, ms)) { c = !c; }
#define key_check_active_macro_run(b, ms, c) if (key_check_active(b, ms)) { macro_run(m); }
#define key_check_active_macro_stop(b, ms, c) if (key_check_active(b, ms)) { macro_stop(m); }
#define key_check_active_macro_toggle(b, ms, c) if (key_check_active(b, ms)) { m = !m; }
#define key_check_active_set_val(b, ms, i, v) if (key_check_active(b, ms)) { set_val(i, v); }
#endif /* EXTRA_KEY_GPC_ */
Warning to potential newcomers about the code below.
The code below is in an unfinished state and I would advise against using it. This is the same code as the above with some attempts at optimizing it.
Optimization was obtained by adding in a timer in the form of _extra_buttons_time_since_last_update.
This is a very minor sacrifice of responsiveness for improving device performance.
For most general use cases this works, however for some of the time related key events it's been causing me issues.
- Code: Select all
#ifndef EXTRA_KEY_GPC_
#define EXTRA_KEY_GPC_
#include <keyboard.gph>
#include <mouse.gph>
#ifndef EXTRA_KEY_VAR
#define EXTRA_KEY_VAR _key_list
#define NUM_OF_EXTRA_KEYS 1
uint8 EXTRA_KEY_VAR[1] = { 0 };
#endif
#ifndef NUM_OF_EXTRA_KEYS
#define NUM_OF_EXTRA_KEYS 1
#endif
#ifndef EXTRA_MOUSE_INPUT
#define EXTRA_MOUSE_INPUT 192
#endif
#define _KEY_NOT_FOUND_IN_ARRAY 255
#define _KEY_STATUS_RELEASED 0
#define _KEY_STATUS_JUST_RELEASED 3
#define _KEY_STATUS_PRESSED 6
#define _KEY_STATUS_JUST_PRESSED 9
#define _KEY_STATUS_JUST_PRESSED_WAIT_WHILE_ACTIVE 12
// This setting controls the rate at which keys are updated.
// A lower setting will increase responsiveness and CPU usage.
#define _KEY_UPDATE_DELAY 100
uint8 _key_status[NUM_OF_EXTRA_KEYS] = { 0 };
uint32 _key_press_timestamp[NUM_OF_EXTRA_KEYS] = { 0 };
uint32 _key_rel_timestamp[NUM_OF_EXTRA_KEYS] = { 0 };
uint32 _extra_buttons_time_since_last_update = 0;
// Initialize the arrays to set their default values.
// This will prevent issues when scripts first launch using this header.
init {
uint8 _key_idx_init;
for(_key_idx_init = 0; _key_idx_init < NUM_OF_EXTRA_KEYS; _key_idx_init++) {
_key_status[_key_idx_init] = _KEY_STATUS_RELEASED;
_key_press_timestamp[_key_idx_init] = 0;
_key_rel_timestamp[_key_idx_init] = 0;
}
}
// Updates the release & active time values of every monitored key.
main {
_extra_buttons_time_since_last_update += elapsed_time();
if (_extra_buttons_time_since_last_update > 75) {
_extra_buttons_time_since_last_update = 0;
uint8 _key_idx;
for(_key_idx = 0; _key_idx < NUM_OF_EXTRA_KEYS; _key_idx++) {
if(is_extra_button_active(EXTRA_KEY_VAR[_key_idx])) {
if (_key_status[_key_idx] & _KEY_STATUS_RELEASED) {
_key_status[_key_idx] = _KEY_STATUS_JUST_PRESSED;
_key_press_timestamp[_key_idx] = system_time();
}
else if (_key_status[_key_idx] == _KEY_STATUS_JUST_PRESSED) {
_key_status[_key_idx] = _KEY_STATUS_PRESSED;
}
}
else {
if ((_key_status[_key_idx] & _KEY_STATUS_PRESSED) ||
(_key_status[_key_idx] & _KEY_STATUS_JUST_PRESSED_WAIT_WHILE_ACTIVE))
{
_key_status[_key_idx] = _KEY_STATUS_JUST_RELEASED;
_key_rel_timestamp[_key_idx] = system_time();
}
else {
_key_status[_key_idx] = _KEY_STATUS_RELEASED;
}
}
}
_key_idx = 0;
}
}
// Combines key_status and mouse_status in one.
bool is_extra_button_active(uint8 button) {
return (key_status(button)) || ((button >= EXTRA_MOUSE_INPUT) && mouse_status(button - EXTRA_MOUSE_INPUT));
}
// Returns the array index associated with the button identifier.
uint8 key_index(uint8 key) {
uint8 i;
for(i = 0; i < NUM_OF_EXTRA_KEYS; i++) {
if(EXTRA_KEY_VAR[i] == key) {
return i;
}
}
printf("Error: Key not found in EXTRA_KEY_VAR array. Key: 0x%x (uint8 %u)", key, key);
return _KEY_NOT_FOUND_IN_ARRAY;
}
void key_status_override(uint8 key, uint8 status, uint32 time) {
uint8 i = key_index(key);
_key_status[i] = status;
switch (status) {
case _KEY_STATUS_PRESSED:
case _KEY_STATUS_JUST_PRESSED:
_key_press_timestamp[i] = time;
break;
case _KEY_STATUS_RELEASED:
case _KEY_STATUS_JUST_RELEASED:
_key_rel_timestamp[i] = time;
break;
}
}
// EVENT: Check if the monitored key changed its state from release to active.
bool key_event_active(uint8 key) {
if (_extra_buttons_time_since_last_update) return FALSE;
return (is_extra_button_active(key) && _key_status[key_index(key)] == _KEY_STATUS_JUST_PRESSED);
}
// EVENT: Check if the monitored key changed its state from active to release.
bool key_event_release(uint8 key) {
if (_extra_buttons_time_since_last_update) return FALSE;
return (!is_extra_button_active(key) && _key_status[key_index(key)] == _KEY_STATUS_JUST_RELEASED);
}
// EVENT: Check if the monitored key has been active for the specified time.
bool key_event_hold_active(uint8 key, uint32 ms) {
uint8 i = key_index(key);
if (_key_status[i] == _KEY_STATUS_JUST_PRESSED) {
_key_status[i] = _KEY_STATUS_JUST_PRESSED_WAIT_WHILE_ACTIVE;
}
if ((_key_status[i] == _KEY_STATUS_JUST_PRESSED_WAIT_WHILE_ACTIVE) && (key_time_active(key) >= ms)) {
_key_status[i] = _KEY_STATUS_PRESSED;
return TRUE;
}
////printf("%d && %u", _key_status[i], key_time_active(key));
return FALSE;
}
// EVENT: Check if the monitored key was active for or greater than the specified time - before release.
bool key_event_hold_release(uint8 key, uint32 ms) {
if (_extra_buttons_time_since_last_update) return FALSE;
return (!is_extra_button_active(key) && _key_status[key_index(key)] == _KEY_STATUS_JUST_RELEASED && key_time_active(key) >= ms);
}
// EVENT: Check if the monitored key was active for or less than the specified time - before release.
bool key_event_hold_release_under(uint8 key, uint32 ms) {
if (_extra_buttons_time_since_last_update) return FALSE;
return (!is_extra_button_active(key) && _key_status[key_index(key)] == _KEY_STATUS_JUST_RELEASED && key_time_active(key) <= ms);
}
// The time that has passed since entered in active state.
uint32 key_time_active(uint8 key) {
uint8 i = key_index(key);
if(is_extra_button_active(key) && (_key_press_timestamp[i]) > _key_rel_timestamp[i]) {
////printf("key_time_active = %u", (system_time() - _key_press_timestamp[i]));
return (system_time() - _key_press_timestamp[i]);
}
return 0;
}
// The time that has passed since entered in release state.
uint32 key_time_release(uint8 key) {
uint8 i = key_index(key);
if(is_extra_button_active(key)) {
return 0;
}
return 0;
}
bool key_check_active(uint8 key, uint32 ms) {
return (is_extra_button_active(key) && key_time_active(key) >= ms);
}
bool key_check_release(uint8 key, uint32 ms) {
return (!is_extra_button_active(key) && key_time_release(key) >= ms);
}
// Returns true if the key is actively being held down.
#define key_is_active(key) key_status(key)
// Returns true if the key is currently in a release state.
#define key_is_release(key) !key_is_active(key)
#define mouse_is_active(mouse) mouse_status(mouse)
#define mouse_is_release(mouse) !mouse_is_active(mouse)
#define mouse_event_active(mouse) key_event_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_event_release(mouse) key_event_release((mouse | EXTRA_MOUSE_INPUT))
#define mouse_time_active(mouse) key_time_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_time_release(mouse) key_time_release((mouse | EXTRA_MOUSE_INPUT))
#define mouse_check_active(mouse) key_check_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_check_release(mouse) key_check_release((mouse | EXTRA_MOUSE_INPUT))
// Return active mouse input. NOTE: Returns 0 if none BUT also 0 if MOUSE_X
// because MOUSE_X is indexed as 0. Shouldn't be a problem as long as you
// do not check exclusively for MOUSE_X input.
uint8 mouse_check(bool include_xy_movement) {
uint8 start_index = 2;
if (include_xy_movement) {
start_index = 0;
}
// Check mouse input indexes 2 through 19
uint8 i;
for (i = start_index; i < 20; i++) {
if (mouse_status(i)) {
return i;
}
}
return 0;
}
// key_is_active macros.
#define key_is_active_combo_run(b, c) if (key_is_active(b)) { combo_run(c); }
#define key_is_active_combo_stop(b, c) if (key_is_active(b)) { combo_stop(c); }
#define key_is_active_combo_pause(b, c) if (key_is_active(b)) { combo_pause(c); }
#define key_is_active_combo_restart(b, c) if (key_is_active(b)) { combo_restart(c); }
#define key_is_active_combo_toggle(b, c) if (key_is_active(b)) { c = !c; }
#define key_is_active_macro_run(b, c) if (key_is_active(b)) { macro_run(m); }
#define key_is_active_macro_stop(b, c) if (key_is_active(b)) { macro_stop(m); }
#define key_is_active_macro_toggle(b, c) if (key_is_active(b)) { m = !m; }
#define key_is_active_set_val(b, i, v) if (key_is_active(b)) { set_val(i, v); }
// key_status macros.
#define key_status_combo_run(b, c) if (key_status(b)) { combo_run(c); }
#define key_status_combo_stop(b, c) if (key_status(b)) { combo_stop(c); }
#define key_status_combo_pause(b, c) if (key_status(b)) { combo_pause(c); }
#define key_status_combo_restart(b, c) if (key_status(b)) { combo_restart(c); }
#define key_status_combo_toggle(b, c) if (key_status(b)) { c = !c; }
#define key_status_macro_run(b, c) if (key_status(b)) { macro_run(m); }
#define key_status_macro_stop(b, c) if (key_status(b)) { macro_stop(m); }
#define key_status_macro_toggle(b, c) if (key_status(b)) { m = !m; }
#define key_status_set_val(b, i, v) if (key_status(b)) { set_val(i, v); }
// key_event_active macros.
#define key_event_active_combo_run(b, c) if (key_event_active(b)) { combo_run(c); }
#define key_event_active_combo_stop(b, c) if (key_event_active(b)) { combo_stop(c); }
#define key_event_active_combo_pause(b, c) if (key_event_active(b)) { combo_pause(c); }
#define key_event_active_combo_restart(b, c) if (key_event_active(b)) { combo_restart(c); }
#define key_event_active_combo_toggle(b, c) if (key_event_active(b)) { c = !c; }
#define key_event_active_macro_run(b, c) if (key_event_active(b)) { macro_run(m); }
#define key_event_active_macro_stop(b, c) if (key_event_active(b)) { macro_stop(m); }
#define key_event_active_macro_toggle(b, c) if (key_event_active(b)) { m = !m; }
#define key_event_active_set_val(b, i, v) if (key_event_active(b)) { set_val(i, v); }
// key_event_release macros.
#define key_event_release_combo_run(b, c) if (key_event_release(b)) { combo_run(c); }
#define key_event_release_combo_stop(b, c) if (key_event_release(b)) { combo_stop(c); }
#define key_event_release_combo_pause(b, c) if (key_event_release(b)) { combo_pause(c); }
#define key_event_release_combo_restart(b, c) if (key_event_release(b)) { combo_restart(c); }
#define key_event_release_combo_toggle(b, c) if (key_event_release(b)) { c = !c; }
#define key_event_release_macro_run(b, c) if (key_event_release(b)) { macro_run(m); }
#define key_event_release_macro_stop(b, c) if (key_event_release(b)) { macro_stop(m); }
#define key_event_release_macro_toggle(b, c) if (key_event_release(b)) { m = !m; }
#define key_event_release_set_val(b, i, v) if (key_event_release(b)) { set_val(i, v); }
// key_check_active macros.
#define key_check_active_combo_run(b, ms, c) if (key_check_active(b, ms)) { combo_run(c); }
#define key_check_active_combo_stop(b, ms, c) if (key_check_active(b, ms)) { combo_stop(c); }
#define key_check_active_combo_pause(b, ms, c) if (key_check_active(b, ms)) { combo_pause(c); }
#define key_check_active_combo_restart(b, ms, c) if (key_check_active(b, ms)) { combo_restart(c); }
#define key_check_active_combo_toggle(b, ms, c) if (key_check_active(b, ms)) { c = !c; }
#define key_check_active_macro_run(b, ms, c) if (key_check_active(b, ms)) { macro_run(m); }
#define key_check_active_macro_stop(b, ms, c) if (key_check_active(b, ms)) { macro_stop(m); }
#define key_check_active_macro_toggle(b, ms, c) if (key_check_active(b, ms)) { m = !m; }
#define key_check_active_set_val(b, ms, i, v) if (key_check_active(b, ms)) { set_val(i, v); }
#endif /* EXTRA_KEY_GPC_ */
My github account: [link]
-
PoshLemur - Sergeant Major
- Posts: 75
- Joined: Thu Mar 08, 2018 9:26 am
Re: check_active() with keyboards?
Thank you PoshLemur for sharing your GPC header file with us. Hopefully soon you can publish it on Gtuner IV, as you did with limits and safeprint.
ConsoleTuner Support Team
-
J2Kbr - General of the Army
- Posts: 20323
- Joined: Tue Mar 18, 2014 1:39 pm
Re: check_active() with keyboards?
Since then, I've added some optimizations to my code; even with 15 keys being recorded performance was still pretty good. I've also changed it so the user doesn't have to use as much code to set the extra keys up, with the use of sizeof in the header.
I've attached the files below
I've attached the files below
- Attachments
-
- extra_buttons.zip
- (1.34 KiB) Downloaded 71 times
-
Buffy - Lieutenant
- Posts: 422
- Joined: Wed Jul 20, 2016 5:23 am
Re: check_active() with keyboards?
Excellent. I was working on it "5 minutes with rubber", and in result I have more then I will ever needed at all.
-
sky418 - Command Sergeant Major
- Posts: 124
- Joined: Fri Nov 25, 2016 4:28 am
Re: check_active() with keyboards?
Here's my newest fully functional version based off of Buffy's newest version (as of 19-7-18)
It's been further optimized. I have a very complex KBM script that used to run at 160-200% CPU.
With Buffy's updated version it still ran at 18-30% a huge improvement. This version is now running around 2%.
Hey Buffy, your newest version seems to have a bug when monitoring for KEY_LEFTCONTROL. Basically moving the mouse causes it to register as having been pressed. I'm assuming any key with a high identifier number would have also caused this. The problem is located in is_extra_button_active(). This wasn't an issue in your older version so I reverted the code.
NEW VERSION 19-7-2018
Zip attached at bottom for easy download.
Everything works (as far as I can tell, report bugs please.)
Big shout out to Buffy who wrote the vast majority of this code and has done some amazing work.
Example usage in a script:
Configuration file: (extra-buttons-config.gph)
REMEMBER TO INCLUDE IT BEFORE THE MAIN HEADER FILE.
Main header file: (extra-buttons.gph)
Additional macros file: (extra-buttons-macros.gph)
It's been further optimized. I have a very complex KBM script that used to run at 160-200% CPU.
With Buffy's updated version it still ran at 18-30% a huge improvement. This version is now running around 2%.
Hey Buffy, your newest version seems to have a bug when monitoring for KEY_LEFTCONTROL. Basically moving the mouse causes it to register as having been pressed. I'm assuming any key with a high identifier number would have also caused this. The problem is located in is_extra_button_active(). This wasn't an issue in your older version so I reverted the code.
NEW VERSION 19-7-2018
Zip attached at bottom for easy download.
Everything works (as far as I can tell, report bugs please.)
Big shout out to Buffy who wrote the vast majority of this code and has done some amazing work.
Example usage in a script:
- Code: Select all
#include "extra-buttons-config.gph"
#include "extra-buttons.gph"
#include "extra-buttons-macros.gph"
main {
if (key_event_active(KEY_W)) {
printf("You pressed the W key!");
}
}
Configuration file: (extra-buttons-config.gph)
REMEMBER TO INCLUDE IT BEFORE THE MAIN HEADER FILE.
- Code: Select all
#ifndef EXTRA_BUTTONS_CONFIG_GPH_
#define EXTRA_BUTTONS_CONFIG_GPH_
#define EXTRA_MOUSE_INPUT 192
#include <keyboard.gph>
#include <mouse.gph>
// Your config here
#define EXTRA_KEY_VAR extra_keys_to_monitor
const uint8 EXTRA_KEY_VAR[NUM_OF_EXTRA_KEYS] = {
KEY_TAB,
KEY_I,
MBUTTON_1 | EXTRA_MOUSE_INPUT,
};
#endif /* EXTRA_BUTTONS_CONFIG_GPH_ */
Main header file: (extra-buttons.gph)
- Code: Select all
#ifndef EXTRA_BUTTONS_GPH_
#define EXTRA_BUTTONS_GPH_
#include <keyboard.gph>
#include <mouse.gph>
#ifndef EXTRA_KEY_VAR
#define EXTRA_KEY_VAR extra_keys_list
uint8 EXTRA_KEY_VAR[1] = { 0 };
#endif
#define _NUM_OF_EXTRA_KEYS sizeof(EXTRA_KEY_VAR)
#ifndef EXTRA_MOUSE_INPUT
#define EXTRA_MOUSE_INPUT 192
#endif
#define _EXRTA_MOUSE_INPUT_IMASK 31
#define _EXTRA_KEY_NOT_FOUND_IN_ARRAY 255
#define _EXTRA_KEY_STATUS_RELEASED 1
#define _EXTRA_KEY_STATUS_JUST_RELEASED 3
#define _EXTRA_KEY_STATUS_PRESSED 4
#define _EXTRA_KEY_STATUS_JUST_PRESSED 12
uint8 extra_keys_status[_NUM_OF_EXTRA_KEYS] = { 0 };
uint32 extra_keys_status_press_time[_NUM_OF_EXTRA_KEYS] = { 0 };
uint32 extra_keys_status_rel_time[_NUM_OF_EXTRA_KEYS] = { 0 };
uint32 _extra_buttons_time_since_last_update = 0;
main {
uint8 _extra_key_i;
_extra_buttons_time_since_last_update += elapsed_time();
if (_extra_buttons_time_since_last_update > 5) {
_extra_buttons_time_since_last_update = 0;
for(_extra_key_i = 0; _extra_key_i < _NUM_OF_EXTRA_KEYS; _extra_key_i++) {
if(is_extra_button_active(EXTRA_KEY_VAR[_extra_key_i])) {
if(extra_keys_status[_extra_key_i] & _EXTRA_KEY_STATUS_RELEASED) {
extra_keys_status[_extra_key_i] = _EXTRA_KEY_STATUS_JUST_PRESSED;
extra_keys_status_press_time[_extra_key_i] = system_time();
}
else extra_keys_status[_extra_key_i] = _EXTRA_KEY_STATUS_PRESSED;
}
else {
if(extra_keys_status[_extra_key_i] & _EXTRA_KEY_STATUS_PRESSED) {
extra_keys_status[_extra_key_i] = _EXTRA_KEY_STATUS_JUST_RELEASED;
extra_keys_status_rel_time[_extra_key_i] = system_time();
}
else extra_keys_status[_extra_key_i] = _EXTRA_KEY_STATUS_RELEASED;
}
}
}
}
bool is_extra_buttons_on_cooldown() {
return (_extra_buttons_time_since_last_update < 5);
}
bool is_extra_button_active(uint8 button) {
//return (key_status(button)) || ((button >= EXTRA_MOUSE_INPUT) && mouse_status(button & _EXRTA_MOUSE_INPUT_IMASK)); // BREAKS WHEN USING CERTAIN KEYS WITH HIGH IDENTIFIER NUMBERS.
return (key_status(button)) || ((button >= EXTRA_MOUSE_INPUT) && mouse_status(button - EXTRA_MOUSE_INPUT));
}
uint8 get_key_index(uint8 key) {
uint8 _extra_key_i;
for(_extra_key_i = 0; _extra_key_i < _NUM_OF_EXTRA_KEYS; _extra_key_i++) {
if(EXTRA_KEY_VAR[_extra_key_i] == key) return _extra_key_i;
}
printf("Error: Key not found in EXTRA_KEY_VAR array. Key: 0x%x (uint8 %u)", key, key);
return _EXTRA_KEY_NOT_FOUND_IN_ARRAY;
}
// EVENT: Check if the monitored key changed its state from release to active.
bool key_event_active(uint8 key) {
if (is_extra_buttons_on_cooldown()) { return FALSE; }
return (is_extra_button_active(key)) && (extra_keys_status[get_key_index(key)] == _EXTRA_KEY_STATUS_JUST_PRESSED);
}
// EVENT: Check if the monitored key changed its state from active to release.
bool key_event_release(uint8 key) {
if (is_extra_buttons_on_cooldown()) { return FALSE; }
return (!is_extra_button_active(key)) && (extra_keys_status[get_key_index(key)] == _EXTRA_KEY_STATUS_JUST_RELEASED);
}
// EVENT: Check if the monitored key was active for or greater than the specified time - before release.
bool key_event_hold_release(uint8 key, uint32 ms) {
if (is_extra_buttons_on_cooldown()) { return FALSE; }
return (extra_keys_status[get_key_index(key)] == _EXTRA_KEY_STATUS_JUST_RELEASED && key_time_active(key) >= ms);
}
// EVENT: Check if the monitored key has been active for the specified time.
bool key_event_hold_active(uint8 key, uint32 ms) {
if (is_extra_buttons_on_cooldown()) { return FALSE; }
// This works because of the 5ms interval. Will break if value is changed.
if (is_extra_button_active(key) && (key_time_active(key) >= (ms - 5) && (key_time_active(key) <= (ms)))) {
return TRUE;
}
////printf("%d && %u", extra_keys_status[i], key_time_active(key));
return FALSE;
}
// EVENT: Check if the monitored key was active for or less than the specified time - before release.
bool key_event_hold_release_under(uint8 key, uint32 ms) {
if (is_extra_buttons_on_cooldown()) { return FALSE; }
return (extra_keys_status[get_key_index(key)] == _EXTRA_KEY_STATUS_JUST_RELEASED && key_time_active(key) <= ms);
}
// The return value does not necessary means the I/O is currently active.
uint32 key_time_active(uint8 key) {
if(is_extra_button_active(key))
return (system_time() - extra_keys_status_press_time[get_key_index(key)]);
//else
return (extra_keys_status_rel_time[get_key_index(key)] - extra_keys_status_press_time[get_key_index(key)]);
}
// The return value does not necessary means the I/O is currently release.
uint32 key_time_release(uint8 key) {
if(is_extra_button_active(key))
return (extra_keys_status_press_time[get_key_index(key)] - extra_keys_status_rel_time[get_key_index(key)]);
//else
return (system_time() - extra_keys_status_rel_time[get_key_index(key)]);
}
bool key_check_active(uint8 key, uint32 ms) {
return (is_extra_button_active(key) && key_time_active(key) >= ms);
}
bool key_check_release(uint8 key, uint32 ms) {
return (!is_extra_button_active(key) && key_time_release(key) >= ms);
}
// Return active mouse input. NOTE: Returns 0 if none BUT also 0 if MOUSE_X
// because MOUSE_X is indexed as 0. Shouldn't be a problem as long as you
// do not check exclusively for MOUSE_X input.
uint8 mouse_check(bool include_xy_movement) {
uint8 start_index = 2;
if (include_xy_movement) {
start_index = 0;
}
// Check mouse input indexes 2 through 19
uint8 i;
for (i = start_index; i < 20; i++) {
if (mouse_status(i)) {
return i;
}
}
return 0;
}
#define key_is_active(key) key_status(key)
#define key_is_release(key) !key_is_active(key)
#define mouse_is_active(mouse) mouse_status(mouse)
#define mouse_is_release(mouse) !mouse_is_active(mouse)
#define mouse_event_active(mouse) key_event_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_event_release(mouse) key_event_release((mouse | EXTRA_MOUSE_INPUT))
#define mouse_time_active(mouse) key_time_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_time_release(mouse) key_time_release((mouse | EXTRA_MOUSE_INPUT))
#define mouse_check_active(mouse) key_check_active((mouse | EXTRA_MOUSE_INPUT))
#define mouse_check_release(mouse) key_check_release((mouse | EXTRA_MOUSE_INPUT))
#endif /* EXTRA_BUTTONS_GPH_ */
Additional macros file: (extra-buttons-macros.gph)
- Code: Select all
#ifndef EXTRA_BUTTONS_MACROS_GPH_
#define EXTRA_BUTTONS_MACROS_GPH_
// key_is_active macros.
#define key_is_active_combo_run(b, c) if (key_is_active(b)) { combo_run(c); }
#define key_is_active_combo_stop(b, c) if (key_is_active(b)) { combo_stop(c); }
#define key_is_active_combo_pause(b, c) if (key_is_active(b)) { combo_pause(c); }
#define key_is_active_combo_restart(b, c) if (key_is_active(b)) { combo_restart(c); }
#define key_is_active_combo_toggle(b, c) if (key_is_active(b)) { c = !c; }
#define key_is_active_macro_run(b, c) if (key_is_active(b)) { macro_run(m); }
#define key_is_active_macro_stop(b, c) if (key_is_active(b)) { macro_stop(m); }
#define key_is_active_macro_toggle(b, c) if (key_is_active(b)) { m = !m; }
#define key_is_active_set_val(b, i, v) if (key_is_active(b)) { set_val(i, v); }
// key_status macros.
#define key_status_combo_run(b, c) if (key_status(b)) { combo_run(c); }
#define key_status_combo_stop(b, c) if (key_status(b)) { combo_stop(c); }
#define key_status_combo_pause(b, c) if (key_status(b)) { combo_pause(c); }
#define key_status_combo_restart(b, c) if (key_status(b)) { combo_restart(c); }
#define key_status_combo_toggle(b, c) if (key_status(b)) { c = !c; }
#define key_status_macro_run(b, c) if (key_status(b)) { macro_run(m); }
#define key_status_macro_stop(b, c) if (key_status(b)) { macro_stop(m); }
#define key_status_macro_toggle(b, c) if (key_status(b)) { m = !m; }
#define key_status_set_val(b, i, v) if (key_status(b)) { set_val(i, v); }
// key_event_active macros.
#define key_event_active_combo_run(b, c) if (key_event_active(b)) { combo_run(c); }
#define key_event_active_combo_stop(b, c) if (key_event_active(b)) { combo_stop(c); }
#define key_event_active_combo_pause(b, c) if (key_event_active(b)) { combo_pause(c); }
#define key_event_active_combo_restart(b, c) if (key_event_active(b)) { combo_restart(c); }
#define key_event_active_combo_toggle(b, c) if (key_event_active(b)) { c = !c; }
#define key_event_active_macro_run(b, c) if (key_event_active(b)) { macro_run(m); }
#define key_event_active_macro_stop(b, c) if (key_event_active(b)) { macro_stop(m); }
#define key_event_active_macro_toggle(b, c) if (key_event_active(b)) { m = !m; }
#define key_event_active_set_val(b, i, v) if (key_event_active(b)) { set_val(i, v); }
// key_event_release macros.
#define key_event_release_combo_run(b, c) if (key_event_release(b)) { combo_run(c); }
#define key_event_release_combo_stop(b, c) if (key_event_release(b)) { combo_stop(c); }
#define key_event_release_combo_pause(b, c) if (key_event_release(b)) { combo_pause(c); }
#define key_event_release_combo_restart(b, c) if (key_event_release(b)) { combo_restart(c); }
#define key_event_release_combo_toggle(b, c) if (key_event_release(b)) { c = !c; }
#define key_event_release_macro_run(b, c) if (key_event_release(b)) { macro_run(m); }
#define key_event_release_macro_stop(b, c) if (key_event_release(b)) { macro_stop(m); }
#define key_event_release_macro_toggle(b, c) if (key_event_release(b)) { m = !m; }
#define key_event_release_set_val(b, i, v) if (key_event_release(b)) { set_val(i, v); }
// key_check_active macros.
#define key_check_active_combo_run(b, ms, c) if (key_check_active(b, ms)) { combo_run(c); }
#define key_check_active_combo_stop(b, ms, c) if (key_check_active(b, ms)) { combo_stop(c); }
#define key_check_active_combo_pause(b, ms, c) if (key_check_active(b, ms)) { combo_pause(c); }
#define key_check_active_combo_restart(b, ms, c) if (key_check_active(b, ms)) { combo_restart(c); }
#define key_check_active_combo_toggle(b, ms, c) if (key_check_active(b, ms)) { c = !c; }
#define key_check_active_macro_run(b, ms, c) if (key_check_active(b, ms)) { macro_run(m); }
#define key_check_active_macro_stop(b, ms, c) if (key_check_active(b, ms)) { macro_stop(m); }
#define key_check_active_macro_toggle(b, ms, c) if (key_check_active(b, ms)) { m = !m; }
#define key_check_active_set_val(b, ms, i, v) if (key_check_active(b, ms)) { set_val(i, v); }
#endif /* EXTRA_BUTTONS_MACROS_GPH_ */
- Attachments
-
- extra-buttons-7-19-18.rar
- (2.25 KiB) Downloaded 79 times
My github account: [link]
-
PoshLemur - Sergeant Major
- Posts: 75
- Joined: Thu Mar 08, 2018 9:26 am
36 posts
• Page 3 of 4 • 1, 2, 3, 4
Return to GPC2 Script Programming
Who is online
Users browsing this forum: No registered users and 86 guests