Whenever I try to run a program that uses allegro's mouse functions, it crashes with an access violation. Always. I won't bother posting code, because it just always happens with whatever it is. It happened with my own programs using the mouse, so I figured I was just doing something wrong. So I broke out my copy of Game Programming All in One which has a CD with example programs on it, and compiled a program out of that book that uses the mouse.
Same thing happened, access violation Anyone know what could be going on?
Does the example program crash as well (exmouse)? What version of Allegro are you running? I'm also assuming this is in Windows.
Shared dll, compiling with dev-c++ mingw32, and what happens is the program crashes with an access fault on exit. And the mouse doesn't display. I just tested it a little more and it appears it only happens when show_mouse is used with the buffer as the parameter. Nothing else crashes besides the program on exit.
Did you try the exmouse.exe example program? If that works without failure then the access violation is with whatever you're compiling. If not, then it could potentially be a problem with your system or (unlikely) Allegro. If you're using an ancient version of Allegro, that would be bad. What version are you using (eg: 4.2.1, etc)? What flavor of Windows are you running under?
Allegro version 4.2.0, windows xp, and unfortunately I haven't heard of this exmouse test program. Does it come with allegro? Perhaps I don't have it because I downloaded the devpak...
Hm. I'm not sure if the devpak builds the example programs. If it did, it would be in the allegro directory structure under examples. Here's the code and you can just compile it yourself and see if it works. After that test we can better figure out what the real problem is.
1 | /* |
2 | * Example program for the Allegro library, by Shawn Hargreaves. |
3 | * |
4 | * This program demonstrates how to get mouse input. The |
5 | * first part of the test retrieves the raw mouse input data |
6 | * and displays it on the screen without using any mouse |
7 | * cursor. When you press a key the standard arrow-like mouse |
8 | * cursor appears. You are not restricted to this shape, |
9 | * and a second keypress modifies the cursor to be several |
10 | * concentric colored circles. They are not joined together, |
11 | * so you can still see bits of what's behind when you move the |
12 | * cursor over the printed text message. |
13 | */ |
14 | |
15 | |
16 | #include <stdio.h> |
17 | |
18 | #include <allegro.h> |
19 | |
20 | |
21 | |
22 | int main(void) |
23 | { |
24 | int mickeyx = 0; |
25 | int mickeyy = 0; |
26 | BITMAP *custom_cursor; |
27 | int c = 0; |
28 | |
29 | if (allegro_init() != 0) |
30 | return 1; |
31 | install_keyboard(); |
32 | install_timer(); |
33 | |
34 | if (set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0) != 0) { |
35 | if (set_gfx_mode(GFX_SAFE, 320, 200, 0, 0) != 0) { |
36 | set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); |
37 | allegro_message("Unable to set any graphic mode\n%s\n", allegro_error); |
38 | return 1; |
39 | } |
40 | } |
41 | |
42 | set_palette(desktop_palette); |
43 | clear_to_color(screen, makecol(255, 255, 255)); |
44 | |
45 | /* Detect mouse presence */ |
46 | if (install_mouse() < 0) { |
47 | textout_centre_ex(screen, font, "No mouse detected, but you need one!", |
48 | SCREEN_W/2, SCREEN_H/2, makecol(0, 0, 0), |
49 | makecol(255, 255, 255)); |
50 | readkey(); |
51 | return 0; |
52 | } |
53 | |
54 | textprintf_centre_ex(screen, font, SCREEN_W/2, 8, makecol(0, 0, 0), |
55 | makecol(255, 255, 255), |
56 | "Driver: %s", mouse_driver->name); |
57 | |
58 | do { |
59 | /* On most platforms (eg. DOS) things will still work correctly |
60 | * without this call, but it is a good idea to include it in any |
61 | * programs that you want to be portable, because on some platforms |
62 | * you may not be able to get any mouse input without it. |
63 | */ |
64 | poll_mouse(); |
65 | |
66 | acquire_screen(); |
67 | |
68 | /* the mouse position is stored in the variables mouse_x and mouse_y */ |
69 | textprintf_ex(screen, font, 16, 48, makecol(0, 0, 0), |
70 | makecol(255, 255, 255), "mouse_x = %-5d", mouse_x); |
71 | textprintf_ex(screen, font, 16, 64, makecol(0, 0, 0), |
72 | makecol(255, 255, 255), "mouse_y = %-5d", mouse_y); |
73 | |
74 | /* or you can use this function to measure the speed of movement. |
75 | * Note that we only call it every fourth time round the loop: |
76 | * there's no need for that other than to slow the numbers down |
77 | * a bit so that you will have time to read them... |
78 | */ |
79 | c++; |
80 | if ((c & 3) == 0) |
81 | get_mouse_mickeys(&mickeyx, &mickeyy); |
82 | |
83 | textprintf_ex(screen, font, 16, 88, makecol(0, 0, 0), |
84 | makecol(255, 255, 255), "mickey_x = %-7d", mickeyx); |
85 | textprintf_ex(screen, font, 16, 104, makecol(0, 0, 0), |
86 | makecol(255, 255, 255), "mickey_y = %-7d", mickeyy); |
87 | |
88 | /* the mouse button state is stored in the variable mouse_b */ |
89 | if (mouse_b & 1) |
90 | textout_ex(screen, font, "left button is pressed ", 16, 128, |
91 | makecol(0, 0, 0), makecol(255, 255, 255)); |
92 | else |
93 | textout_ex(screen, font, "left button not pressed", 16, 128, |
94 | makecol(0, 0, 0), makecol(255, 255, 255)); |
95 | |
96 | if (mouse_b & 2) |
97 | textout_ex(screen, font, "right button is pressed ", 16, 144, |
98 | makecol(0, 0, 0), makecol(255, 255, 255)); |
99 | else |
100 | textout_ex(screen, font, "right button not pressed", 16, 144, |
101 | makecol(0, 0, 0), makecol(255, 255, 255)); |
102 | |
103 | if (mouse_b & 4) |
104 | textout_ex(screen, font, "middle button is pressed ", 16, 160, |
105 | makecol(0, 0, 0), makecol(255, 255, 255)); |
106 | else |
107 | textout_ex(screen, font, "middle button not pressed", 16, 160, |
108 | makecol(0, 0, 0), makecol(255, 255, 255)); |
109 | |
110 | /* the wheel position is stored in the variable mouse_z */ |
111 | textprintf_ex(screen, font, 16, 184, makecol(0, 0, 0), |
112 | makecol(255, 255, 255), "mouse_z = %-5d", mouse_z); |
113 | |
114 | release_screen(); |
115 | |
116 | vsync(); |
117 | |
118 | } while (!keypressed()); |
119 | |
120 | clear_keybuf(); |
121 | |
122 | /* To display a mouse pointer, call show_mouse(). There are several |
123 | * things you should be aware of before you do this, though. For one, |
124 | * it won't work unless you call install_timer() first. For another, |
125 | * you must never draw anything onto the screen while the mouse |
126 | * pointer is visible. So before you draw anything, be sure to turn |
127 | * the mouse off with show_mouse(NULL), and turn it back on again when |
128 | * you are done. |
129 | */ |
130 | clear_to_color(screen, makecol(255, 255, 255)); |
131 | textout_centre_ex(screen, font, "Press a key to change cursor", |
132 | SCREEN_W/2, SCREEN_H/2, makecol(0, 0, 0), |
133 | makecol(255, 255, 255)); |
134 | show_mouse(screen); |
135 | readkey(); |
136 | show_mouse(NULL); |
137 | |
138 | /* create a custom mouse cursor bitmap... */ |
139 | custom_cursor = create_bitmap(32, 32); |
140 | clear_to_color(custom_cursor, bitmap_mask_color(screen)); |
141 | for (c=0; c<8; c++) |
142 | circle(custom_cursor, 16, 16, c*2, palette_color[c]); |
143 | |
144 | /* select the custom cursor and set the focus point to the middle of it */ |
145 | set_mouse_sprite(custom_cursor); |
146 | set_mouse_sprite_focus(16, 16); |
147 | |
148 | clear_to_color(screen, makecol(255, 255, 255)); |
149 | textout_centre_ex(screen, font, "Press a key to quit", SCREEN_W/2, |
150 | SCREEN_H/2, makecol(0, 0, 0), makecol(255, 255, 255)); |
151 | show_mouse(screen); |
152 | readkey(); |
153 | show_mouse(NULL); |
154 | |
155 | destroy_bitmap(custom_cursor); |
156 | |
157 | return 0; |
158 | } |
159 | |
160 | END_OF_MAIN() |
Hm, the exmouse program works. And the error only seems to occur when I draw to the buffer. Perhaps I shall post the code tomorrow. I can't right now because it's a long day at work tomorrow, and it's late and I need sleep, hehe. It's spread over 14 files so it'd take awhile to get up here. I'll post it tomorrow though Thanks for the help, I appreciate it.
Don't mention it. Your code will definitely help debug. What I think is that you're either blitting to an improperly created/loaded bitmap (are you checking for NULL return on create_bitmap and load_bitmap?) or you're trying to draw on an already destroy()'ed bitmap.
Post the code and you'll get some more help. Good luck.
Sounds like you're using show_mouse on a non-screen buffer (which there's not real point to, BTW, you'll never see it until you blit the buffer wasting resources in the mean-time (ie. draw_sprite the mouse_sprite to the buffer manually before showing the buffer)), then destroying the buffer while the mouse is still trying to draw to it.
Well, it's fixed now. Not how I was hoping for but it is :p
1) After what Kitty Cat said, I drew to the screen instead of the buffer and that part worked.
2) Other things weren't working because I had show_mouse, scare_mouse, and set_mouse_sprite all in different functions in different files, and apparently allegro didn't like that very much.
So I broke out my copy of Game Programming All in One...
I stopped reading right there and skipped down to the reply box. Don't use examples from that book and expect them to work. The problem you're having is this:
1. Make the mouse draw to your back buffer.
2. When you're done with your program, you destroy the buffer.
3. Mouse still wants to draw to the buffer which is now already gone.
4. Kaboom!
Possible solutions:
1. Use hardware cursors.
2. Make the mouse draw to the screen instead of back buffer.
3. Make the mouse stop drawing to your back buffer before destroying it.
4. Draw the cursor yourself with draw_sprite.