|
get all pressed keys? (part two) |
Shadowblitz16
Member #16,818
March 2018
|
sorry for the new post but my old one was locked for some reason. is there a way to read keyboard up and down events and mouse up and down events outside of main without needing to pass a handle to the display? I want to make a simple 6 functions without needing to update them in main.. is there a easy way to do this? EDIT: I think this might be able to be done with threads but I am afraid to use them due to mutex locks. |
Elias
Member #358
May 2000
|
You could use global variables. Something like: 1int key_down[ALLEGRO_KEY_MAX];
2bool key_held[ALLEGRO_KEY_MAX];
3int key_up[ALLEGRO_KEY_MAX];
4
5void after_game_tick) {
6 for (int i = 0; i < ALLEGRO_KEY_MAX; i++) {
7 key_down[i] = 0;
8 key_up[i] = 0;
9 }
10}
11
12void on_event_key_down(int key) {
13 key_down[key]++;
14 key_held[key] = true;
15}
16
17void on_event_key_up(int key) {
18 key_up[key]++;
19 key_held[key] = false;
20}
21
22bool is_keyboard_key_down(int key) { return key_down[key] > 0; }
23bool is_keyboard_key_held(int key) { return key_held[key]; }
24bool is_keyboard_key_up(int key) { return key_up[key] > 0; }
Call the two event functions when you receive a key up/down event in main. Call the after_game_tick function when you're done handling game input to reset the down/up counters. Exactly the same will work for mouse. -- |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Your old topic wasn't locked. You just can't double post. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
torhu
Member #2,727
September 2002
|
Edgar Reynaldo said: Your old topic wasn't locked. You just can't double post. Could mention the trick to get around that: Edit the post, preferreably putting "APPEND:" or similiar before the additions, then click on Send to top |
Edgar Reynaldo
Major Reynaldo
May 2007
|
, why? You just did it for me. :/ My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
torhu
Member #2,727
September 2002
|
I meant that I could :p |
Shadowblitz16
Member #16,818
March 2018
|
@Elias @Edgar Reynaldo and @torhu sorry I didn't realize that. |
bamccaig
Member #7,536
July 2006
|
No, but the "Send to Top" button does (if it has been more than an hour since your last update). -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Elias
Member #358
May 2000
|
The way I do it is I have an init() function and tick() function for the game and do everything there (and the actual main loop inside of main() does nothing but handling the Allegro events). -- |
Shadowblitz16
Member #16,818
March 2018
|
@bamccaig awesome i will keep that in mind. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
For now, you have to have a window to get input. Because that's where Windows sends you the input. There's no way around it. Please explain what you are trying to do. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Rodolfo Lam
Member #16,045
August 2015
|
It seems that the OP is having a case of the “XY Problem”. He is asking about an attempted solution rather than his actual problem. In other words, he is trying to solve a problem X. He really thinks solution Y will work. Now, instead of asking about X, he is asking about Y. Can you start from 0 and tell us what you want to do? I saw a red flag when you mentioned threads. Most code doesn’t need threads at all. You also said modules. Are you trying to abstract Allegro into different components or something like that? The more information and code you provide, the more likely someone here will give you a solution.
|
Audric
Member #907
January 2001
|
Examples are often made as single file / function, but I understand the issue is about organizing the code in different modules (C files). The main event loop, wherever it is, could include this part : (Adapted from Edgar's earlier example) 1 do
2 {
3 ALLEGRO_EVENT e;
4 al_wait_for_event(q , &e);
5 (...)
6 if (e.type == ALLEGRO_EVENT_KEY_DOWN) //
7 { //
8 input_notify(&e); //
9 } // This part communicates with input.c
10 if (e.type == ALLEGRO_EVENT_KEY_UP) //
11 { //
12 input_notify(&e); //
13 } //
14 (...)
15 } while (!al_is_event_queue_empty(q));
input.c: 1// 'private'
2int mykeys[ALLEGRO_KEY_MAX];
3
4void input_init()
5{
6 // clear mykeys[] using memset or whatever
7}
8
9void input_notify(ALLEGRO_EVENT *evt) // < this
10{
11 // examine the event and update the keyboard state
12 if (e.type == ALLEGRO_EVENT_KEY_DOWN)
13 {
14 mykeys[e.keyboard.keycode] = 1;
15 }
16 if (e.type == ALLEGRO_EVENT_KEY_UP)
17 {
18 mykeys[e.keyboard.keycode] = 0;
19 }
20}
21
22int input_is_key_down(ALLEGRO_KEY k)
23{
24 // examine the keyboard state, return 0 or 1
25 return mykeys[e.keyboard.keycode];
26}
input.h: // the declaration of all the above methods // mykeys is *not* declared here, because other modules don't need to know about it
|
Shadowblitz16
Member #16,818
March 2018
|
so I wrote this yesterday. however I can't test it since it's in a dll project and I can't figure out how to link it into my executable 1//app.h
2#pragma once
3#include <allegro5\allegro.h>
4#include <algorithm>
5#include <vector>
6namespace
7{
8 int _w = 0;
9 int _h = 0;
10 int _fps = 60;
11 const char* _text = "untitled";
12 bool _visible = false;
13 ALLEGRO_DISPLAY* _display = nullptr;
14 ALLEGRO_EVENT_QUEUE* _queue = nullptr;
15 ALLEGRO_TIMER* _timer = nullptr;
16
17}
18namespace pure {
19namespace app {
20
21 Event init;
22 Event tick;
23 Event draw;
24 Event free;
25
26 int getW()
27 {
28 return _w;
29 }
30 int getH()
31 {
32 return _h;
33 }
34 int getFPS()
35 {
36 return _fps;
37 }
38
39 void run(int w=256, int h=240, const char* text = "untitled", int fps=60)
40 {
41 al_init();
42
43 _w = w;
44 _h = h;
45 _fps = fps;
46 _text = text;
47
48 init.invoke();
49
50 bool running = true;
51 while (running)
52 {
53 if (_visible) al_flip_display();
54
55 ALLEGRO_EVENT event;
56 al_wait_for_event(_queue, &event);
57
58 switch (event.type)
59 {
60 case ALLEGRO_EVENT_DISPLAY_CLOSE:
61 running = false;
62 break;
63 case ALLEGRO_EVENT_TIMER:
64 tick.invoke();
65 draw.invoke();
66 break;
67 }
68 }
69 free.invoke();
70 }
71
72 void show()
73 {
74 _display = al_create_display(_w, _h);
75 _queue = al_create_event_queue();
76 _timer = al_create_timer(1.0f / _fps);
77
78 al_set_window_title(_display, _text);
79
80 al_register_event_source(_queue, al_get_display_event_source(_display));
81 al_register_event_source(_queue, al_get_timer_event_source(_timer));
82
83 _visible = true;
84 }
85
86 struct Event
87 {
88 private:
89 std::vector<void(*)()> functions;
90
91 public:
92 void invoke()
93 {
94 for (int i = 0; i < functions.size(); i++)
95 {
96 if (functions[i] != nullptr) functions[i]();
97 else functions.erase(std::remove(functions.begin(), functions.end(), functions[i]), functions.end());
98 }
99 }
100 void operator +=(void(*function)())
101 {
102 functions.push_back(function);
103 }
104 void operator -=(void(*function)())
105 {
106 functions.erase(std::remove(functions.begin(), functions.end(), function), functions.end());
107 }
108 };
109}}
1///inp.h
2#pragma once
3#include <allegro5\allegro.h>
4#include "app.h"
5namespace
6{
7 bool initalized = false;
8
9 //keyboard
10 int curr_keys[ALLEGRO_KEY_MAX];
11 int prev_keys[ALLEGRO_KEY_MAX];
12
13 //mouse
14 int curr_curs[16];
15 int prev_curs[16];
16
17 void tick()
18 {
19 if (!initalized) return;
20
21 ALLEGRO_KEYBOARD_STATE k_state;
22 al_get_keyboard_state(&k_state);
23 for (int i = 0; i < ALLEGRO_KEY_MAX; i++)
24 {
25 prev_keys[i] = curr_keys[i];
26 curr_keys[i] = al_key_down(&k_state, i);
27 }
28
29 ALLEGRO_MOUSE_STATE m_state;
30 al_get_mouse_state(&m_state);
31 for (int i = 0; i < ALLEGRO_KEY_MAX; i++)
32 {
33 prev_curs[i] = curr_curs[i];
34 curr_curs[i] = al_mouse_button_down(&m_state, i);
35 }
36 }
37}
38
39namespace pure {
40namespace inp {
41
42 void init()
43 {
44 al_install_keyboard();
45 al_install_mouse();
46
47 //pure::app::tick is a Event which is struct around a vector of function pointers
48 pure::app::tick += tick;
49 initalized = true;
50 }
51
52 bool is_key_down(int key)
53 {
54 return !prev_keys && curr_keys;
55 }
56 bool is_key_held(int key)
57 {
58 return prev_keys && curr_keys;
59 }
60 bool is_key_up (int key)
61 {
62 return prev_keys && !curr_keys;
63 }
64
65 bool is_mouse_down(int key)
66 {
67 return !prev_curs && curr_curs;
68 }
69 bool is_mouse_held(int key)
70 {
71 return prev_curs && curr_curs;
72 }
73 bool is_mouse_up (int key)
74 {
75 return prev_curs && !curr_curs;
76 }
77}}
|
MikiZX
Member #17,092
June 2019
|
I cannot test this either though one thing seems to be wrong - namely, second source file, at line 31: for (int i = 0; i < ALLEGRO_KEY_MAX; i++) I believe you should change ALLEGRO_KEY_MAX to a variable that your would set in your program's initialization part using the function call that Edgar suggested here: https://www.allegro.cc/forums/thread/617983 |
Edgar Reynaldo
Major Reynaldo
May 2007
|
MikiZX, nope. ALLEGRO_KEY_MAX is a constant that doesn't change. It's perfectly safe to use. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
MikiZX
Member #17,092
June 2019
|
There are two 'for' loops in Shadowblitz's source, one after the other. The first one is for the keys while the second one is for the mouse buttons. It seems the second loop is the one that accesses an array of 16 elements using an index well out of bounds - sorry, I should have explained it better in my previous post. |
torhu
Member #2,727
September 2002
|
Shadowblitz16 said: so I wrote this yesterday. however I can't test it since it's in a dll project and I can't figure out how to link it into my executable You need to split it into header files and implementation (*.cpp) files. Function definitions go in the implementation files. Class/struct declarations, function prototypes, symbolic constants, typedefs, etc. go in the headers. Then you just add these files to your game project, which should be configured to build an executable. You don't need to create DLL's unless you have a specific reason to want that level of separation. Also, you don't really need multiple levels of namespaces in a small project, it's just more to type. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Oh, MikiZX, you're right, sorry I can't read. No, you definitely don't want to check ALLEGRO_KEY_MAX mouse buttons. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
bamccaig
Member #7,536
July 2006
|
torhu said: You need to split it into header files and implementation (*.cpp) files. Function definitions go in the implementation files. Class/struct declarations, function prototypes, symbolic constants, typedefs, etc. go in the headers. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Doctor Cop
Member #16,833
April 2018
|
This is something good, I would like to bookmark it. And... I just did.
|
|