|
Mouse Addon causing program crash |
Doctor Cop
Member #16,833
April 2018
|
Hello friends, how are you all? I am trying to figure out the mouse click event for every button in my program, I tried debugging but even after lots of tries I couldn't find the problem. Here's my code for Buttons: 1#pragma once
2
3#include <stdio.h>
4#include <allegro5/allegro.h>
5#include <allegro5/allegro_primitives.h>
6#include <allegro5/allegro_font.h>
7#include <allegro5/allegro_ttf.h>
8#include "base.h"
9
10
11ALLEGRO_FONT* font;
12
13typedef struct
14{
15 Model M;
16 int radius;
17 char* text;
18 ALLEGRO_FONT* font;
19 int text_align;
20} Button;
21
22typedef struct
23{
24 Model M;
25 int radius;
26 char* text;
27 ALLEGRO_BITMAP* image;
28 int flip;
29} ImageButton;
30
31
32void view_button(Button* btn)
33{
34 // Button background
35 if (btn->M.clicked == CLICKED)
36 al_draw_filled_rounded_rectangle(btn->M.x, btn->M.y, btn->M.x + btn->M.width, btn->M.y+btn->M.height, btn->radius, btn->radius, btn->M.C.primary_variant_color);
37 else
38 al_draw_filled_rounded_rectangle(btn->M.x, btn->M.y, btn->M.x + btn->M.width, btn->M.y+btn->M.height, btn->radius, btn->radius, btn->M.C.primary_color);
39 // Button border
40 al_draw_rounded_rectangle(btn->M.x, btn->M.y, btn->M.x + btn->M.width, btn->M.y+btn->M.height, btn->radius, btn->radius, btn->M.C.border_color, btn->M.border);
41 // Button text
42 al_draw_text(btn->font, btn->M.C.on_primary_color, btn->M.x + btn->M.padding, btn->M.y + btn->M.padding, btn->text_align, btn->text);
43}
44
45void view_image_button(ImageButton* btn)
46{
47 // Button background
48 al_draw_filled_rounded_rectangle(btn->M.x, btn->M.y, btn->M.x + btn->M.width, btn->M.y+btn->M.height, btn->radius, btn->radius, btn->M.C.primary_color);
49 // Button border
50 al_draw_rounded_rectangle(btn->M.x, btn->M.y, btn->M.x + btn->M.width, btn->M.y+btn->M.height, btn->radius, btn->radius, btn->M.C.border_color, btn->M.border);
51 // Button image
52 al_draw_bitmap(btn->image, btn->M.x, btn->M.y, btn->flip);
53}
54
55void controller_click_down(Model* btn, ALLEGRO_MOUSE_STATE* state)
56{
57 printf("Mouse x = %d \nMouse y = %d", state->x, state->y);
58 if (state != NULL)
59 if (state->buttons & 1)
60 if (state->x > btn->x &&
61 state->y > btn->y &&
62 state->x < btn->x + btn->width &&
63 state->y < btn->y + btn->height) {
64 btn->clicked = PRESSED;
65 printf("controller_click_down\n");
66 }
67}
68void controller_click_up(Model* btn, ALLEGRO_MOUSE_STATE* state)
69{
70 if (state != NULL)
71 if (state->buttons & 1)
72 if (state->x > btn->x &&
73 state->y > btn->y &&
74 state->x < btn->x + btn->width &&
75 state->y < btn->y + btn->height) {
76 btn->clicked = CLICKED;
77 printf("controller_click_up\n");
78 }
79}
80
81/*void controller_image_button(ImageButton* btn)
82{
83 ALLEGRO_MOUSE_STATE state;
84 al_get_mouse_state(&state);
85 if (state.buttons & 1)
86 if (state.x > btn->M.x &&
87 state.y > btn->M.y &&
88 state.x < btn->M.x + btn->M.width &&
89 state.y < btn->M.y + btn->M.height)
90 btn->clicked = true;
91}*/
92
93void init_buttons(Model* parent, Button* btns, int length, ALLEGRO_FONT* font)
94{
95 materialize();
96
97 Model BUTTON;
98 int positionin = parent->x + parent->padding;
99 int b_width = 20;
100 int endin = parent->y + parent->padding;
101 int b_height = 20;
102 char temp_text[] = "a";
103 printf("parent pointer size : %d", sizeof(Model*));
104
105 for (int i=0; i<length; i++)
106 {
107 BUTTON.id = i;
108 BUTTON.C = MATERIAL;
109 BUTTON.x = positionin;
110 BUTTON.y = endin;
111 BUTTON.width = b_width;
112 BUTTON.height = b_height;
113 BUTTON.offset_x = b_width;
114 BUTTON.offset_y = b_height;
115 BUTTON.padding = 6;
116 BUTTON.border = 2;
117 BUTTON.visibility = VISIBLE;
118 BUTTON.clicked = UNSET;
119
120 btns[i].M = BUTTON;
121 btns[i].radius = 2;
122 temp_text[0] = 'a'+i;
123 btns[i].text = malloc(2);
124 strcpy(btns[i].text, temp_text);
125 btns[i].text_align = ALLEGRO_ALIGN_LEFT;
126 btns[i].font = font;
127
128 if ((b_width)*2 + positionin + parent->padding <= parent->width+parent->x) {
129 positionin += b_width + parent->padding;
130 } else {
131 endin += b_height + parent->padding;
132 positionin = parent->x + parent->padding;
133 }
134 }
135}
136
137void init_image_buttons(Model* parent, ImageButton* btns, int length)
138{
139 font = al_create_builtin_font();
140 materialize();
141
142 Model BUTTON;
143 int positionin = parent->x + parent->padding;
144 int b_width = 20;
145 int endin = parent->y + parent->padding;
146 int b_height = 20;
147 char filename[] = "../images/Sprites/flatLight/flatLight00.png";
148 printf("parent pointer size : %d", sizeof(Model*));
149
150 for (int i=0; i<length; i++)
151 {
152 BUTTON.id = i;
153 BUTTON.C = MATERIAL;
154 BUTTON.x = positionin;
155 BUTTON.y = endin;
156 BUTTON.width = b_width;
157 BUTTON.height = b_height;
158 BUTTON.offset_x = b_width;
159 BUTTON.offset_y = b_height;
160 BUTTON.padding = 6;
161 BUTTON.border = 2;
162 BUTTON.visibility = VISIBLE;
163 BUTTON.clicked = UNSET;
164
165 btns[i].M = BUTTON;
166 btns[i].radius = 2;
167 filename[38] = '0'+i;
168 printf("Load image %s\n", filename);
169 btns[i].image = al_load_bitmap(filename);
170 btns[i].flip = ALLEGRO_FLIP_HORIZONTAL;
171
172 if ((b_width)*2 + positionin + parent->padding <= parent->width+parent->x) {
173 positionin += b_width + parent->padding;
174 } else {
175 endin += b_height + parent->padding;
176 positionin = parent->x + parent->padding;
177 }
178 }
179}
I have attached the complete code.
|
Arthur Kalliokoski
Second in Command
February 2005
|
I compiled it by hand with gcc -g main.c -o t -lallegro -lallegro_primitives -lallegro_font -lallegro_image -lallegro_ttf They all watch too much MSNBC... they get ideas. |
Peter Hull
Member #1,136
March 2001
|
Good to hear from you Doctor! Have a look at this, main.c, line 87 (approx) // close the display else if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE || event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break;
Checking for keycode being 'escape' but you didn't check first if that event was a key event. The event structure is a union and all the different possibilities are laid over each other and you need to check the event.type to figure out which one is valid. (ALLEGRO_EVENT) $0 = { type = 20 any = { type = 20 source = 0x0000000100199890 timestamp = 2.275083 } ...skip a bit... keyboard = { type = 20 source = 0x0000000100199890 timestamp = 2.275083 display = 0x0000000100675dd0 keycode = 59 unichar = 165 modifiers = 0 repeat = false } mouse = { type = 20 source = 0x0000000100199890 timestamp = 2.275083 display = 0x0000000100675dd0 x = 59 y = 165 z = 0 w = 0 dx = -1 dy = 0 dz = 0 dw = 0 button = 0 pressure = 0 } So, when you move the mouse to x=59, the app will try to exit. Now, in the last part of main: al_destroy_font(font); al_destroy_display(disp); al_destroy_timer(timer); al_destroy_event_queue(queue); al_destroy_bitmap(icon); al_destroy_font(font); return 0; You've got al_destroy_font twice and that is what causes the crash (segfault) That's as far as I got, there may be more. What I did: Hope that helps!
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Excellent debugging Peter. You get a gold sticker. {"name":"kawaii_face_gold_star_sticker-r6754b0139f8949e9ae01004fc4af8279_v9w09_8byvr_512.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/9\/49a213c9deaa84857576b6998f75c947.jpg","w":512,"h":512,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/9\/49a213c9deaa84857576b6998f75c947"} 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 |
Doctor Cop
Member #16,833
April 2018
|
Hi Peter, thanks for the detailed solution. One more thing, can you tell me if using a single event queue is enough for everything or I should use different queues for different things such as drawing UI and App logic? @Arthur Kalliokoski, I see you linked -lallegro -lallegro_primitives -lallegro_font -lallegro_image -lallegro_ttf in the compilation phase, I just link the monolith, does it make any difference by linking all the shared lib files separately? Arthur Kalliokoski said: Upon exit it'd crash because you had two lines of It's a side-effect of cargo cult programming that I developed a habit of at my previous workplace, I'm trying to leave this bad habit but it still affects me one way or other. I'm trying to improve by making templates off of my previous projects so that I do not write Frankenstein code anymore. I have attached the png file now. Edit: IDK why it fixed it or what was causing the problem. If anybody can tell me, I would appreciate that.
|
Arthur Kalliokoski
Second in Command
February 2005
|
Doctor Cop said: I just link the monolith, does it make any difference by linking all the shared lib files separately? I suppose not. I mostly didn't do it because the makefile wouldn't work as is (didn't have the correct directory structure) so I either had to futz with makedir or build it by hand. And it turned out I didn't have a monolith lib built, and didn't want to fiddle around with cmake and stuff trying to build it. I'd suggest if you do this sort of thing again, make a parent directory and copy your program with sub directories into it, along with any needed data and compress the parent directory. Then uncompress it somewhere else and try to build it with a simple make command or whatever. Don't go too far with this however, having build libraries such as monolith would be more the testers responsibility. They all watch too much MSNBC... they get ideas. |
Peter Hull
Member #1,136
March 2001
|
Doctor Cop said: One more thing, can you tell me if using a single event queue is enough for everything I don't believe I've ever used more that one queue. Not sure what that would be useful for, maybe if you were doing multi-threaded apps? Quote: I was wondering why my buttons weren't "clicking". In controller_click_up you've got if (state != NULL) if (state->buttons & 1) I think state->buttons is always zero for the button you've just released in a mouse up event, therefore the following code never runs. One more thing, it's normal to put the bulk of the code in .c files and just have the declarations in .h files (in C++, exceptions for very short functions which can be inlined)
|
Doctor Cop
Member #16,833
April 2018
|
@Peter, I'm trying to keep the number of files as less as possible, as I don't write lengthy functions for anything and I keep my header files small and always create a new file if the functionality can be extended to other files. It just feels convenient and keeps me sane during debugging. But I agree that I should probably change my habits. Thanks for the solution, but I still don't get what's the point of getting the mouse and keyboard state when there are events for them, like I can just directly pass the event.mouse in function and it works, just have to change from state.buttons to event.button .
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Event queues are immensely useful in multi-threaded applications. Each thread gets its own synchronized access to the queue handled by a mutex. That's how my library does it anyway. Rant: What's more, the InputGroup class can hold combinations of keys and button states. It makes configuring your program immensely easy because you have a map of keys to actions you can change anytime. 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 |
Doctor Cop
Member #16,833
April 2018
|
Hi Edgar, Actually I have tried to compile your library many times before, but failed. The last time I tried to compile Eagle the CMake version needed an update and after that my compiler didn't compile Eagle because it's Mingw32 and Eagle needs Mingw64, so I downloaded Mingw64, but guess what, Allegro 5 library wasn't setup in my new compiler and I couldn't recall how I managed to install Allegro in my Mingw32 in the first place. If you could provide binaries then I would be really grateful. I have looked into the source code of Eagle library and have learned a lot of things from it, It's amazing and not complicated as code of other GUI libraries I have looked into. I hope I will succeed in compiling the Eagle library this time.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
You should have said something to me, I would have helped you immediately. I can make some binaries for you, if you like, or help you get it to compile. Either is fine. Are you still on Discord? I am # 2 6 0 1 , I will send you a link to my eagle discord channel, where we can discuss your problems. The cmake version is probably too high for normal use. I always use the latest cmake, so it never bothers 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 |
Doctor Cop
Member #16,833
April 2018
|
Edgar, a part of me really wants to compile the Eagle project, but I really need those binaries. If you make them available as github packages then it'll be so convenient. I urge you to release the binaries as packages when every you compile a new major version. I'll make life of us noobs very easier.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Let me put together a clean release. I want to brush up the docs and make sure they're ready before I release anything. As an aside, I have no idea what version to call it. I've been working on it so long, it's got to be close to version 1. Or maybe I should adopt the YY-MM dating that is popular these days. 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 |
Doctor Cop
Member #16,833
April 2018
|
Edgar, the YY-MM format can be confusing as it happened in the case of Angular, but you do you, just that the version numbers don't be years apart.
|
|