Ok, Im running into issues here.. Not too big, but enough to warrant concern on my part as I want to make this work properly. When I compile and run the following code, it autodetects the joysticks, displays the button info properly including a color change for button presses, but when it displays the axis information, its wrong.
The gamepad Im using is a Saitek 2900 wireless.. Works perfect.. Has 1 8way hat, 2 sticks and 14 buttons.. The 2 sticks each have an x & y axis along with a button.. When I run this, allegro tells me I have 3 sticks.. Heres what it displays:
Stick 0: stick
Num Axes: 0
Axis 0: x axis - 0
Axis 1: y axis - 0
Axis 2: z axis - 0 <<<<<<< This turns out to be Stick 1(right stick), its Y axis. 0 centered, -128 to 128.. HUH??????? Why isnt this on stick 1?
Stick 1: z-rotation
Num Axes: 1
Axis 0: -128 <<<<<<<<<< this is the right hand stick, its x axis.. -128 centered, 0 is to the left, 256 to the right
Stick 2: hat Switch
Everything works great except for the right stick has its Y axis listed under stick 0 with a different range of values than its x axis.. I know I could set it to use the left stick, but I wanted to use the right as well. Problem is, if it were just for me, I could code it right.. But if I want to release it, Im sure its going to read the sticks different..
So why does stick 1 have its Axes listed as 2 different sticks in allegro?????
For what its worth, its something in allegro doing this. Ive tested this using directinput and XNA and it reads the stick and axes properly, so does the windows control panel. Allegro is the only place it shows the right stick as a z rotation.
1 | #include <allegro.h> |
2 | |
3 | const int scrx = 800; |
4 | const int scry = 600; |
5 | BITMAP *buffer = NULL; // Declare a BITMAP called buffer. |
6 | |
7 | |
8 | // Init Everything |
9 | // |
10 | //************************************************************** |
11 | |
12 | int init(void) |
13 | { |
14 | // initialize allegro library |
15 | if (allegro_init()) |
16 | { |
17 | allegro_message("Cannot initalize Allegro.\n"); |
18 | return 1; |
19 | } |
20 | |
21 | // timer, keyboard and mouse! Oh My! |
22 | install_timer(); |
23 | install_keyboard(); |
24 | install_mouse(); |
25 | |
26 | // install joystick support |
27 | if (install_joystick(JOY_TYPE_AUTODETECT)) |
28 | { |
29 | allegro_message("Joystick Error: %s", allegro_error); |
30 | allegro_message("Error - Unable to initialize joystick routines..."); |
31 | return 1; //exit to DOS |
32 | } |
33 | |
34 | // install sound system |
35 | if(install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL)) |
36 | { |
37 | allegro_message("Sound Error: %s", allegro_error); |
38 | allegro_message("Error - Unable to initialize sound system..."); |
39 | return 1; //exit to DOS |
40 | } |
41 | |
42 | //set graphics mode, trying all acceptable depths |
43 | set_color_depth(32); |
44 | if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, scrx, scry, 0, 0)) |
45 | { |
46 | set_color_depth(24); |
47 | if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, scrx, scry, 0, 0)) |
48 | { |
49 | set_color_depth(16); |
50 | if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, scrx, scry, 0, 0)) |
51 | { |
52 | set_color_depth(15); |
53 | if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, scrx, scry, 0, 0)) |
54 | { |
55 | allegro_message("Video Error: %s.\n", allegro_error); |
56 | return 1; |
57 | } |
58 | } |
59 | } |
60 | } |
61 | |
62 | |
63 | buffer = create_bitmap(800, 600); //Create an empty bitmap. |
64 | |
65 | return 0; |
66 | } |
67 | |
68 | |
69 | |
70 | // mainLoop() routine |
71 | // |
72 | //************************************************************** |
73 | |
74 | void mainLoop() |
75 | { |
76 | poll_joystick(); |
77 | text_mode(makecol(0, 0, 255)); |
78 | |
79 | textprintf_ex(buffer, font, 10, 10, makecol(255,255,255), 0, "Number of Joysticks: %d", num_joysticks); |
80 | |
81 | if(num_joysticks > 0) |
82 | { |
83 | textprintf_ex(buffer, font, 10, 20, makecol(255,255,255), 0, "Number of sticks: %d", joy[0].num_sticks); |
84 | textprintf_ex(buffer, font, 10, 30, makecol(255,255,255), 0, "Number of buttons: %d", joy[0].num_buttons); |
85 | |
86 | |
87 | int y = 50; |
88 | for(int n=0; n < joy[0].num_sticks; n++) |
89 | { |
90 | textprintf_ex(buffer, font, 10, y, makecol(255,255,255), 0, "Stick %d: %s", n, joy[0].stick[n].name); |
91 | y += 10; |
92 | textprintf_ex(buffer, font, 10, y, makecol(255,255,255), 0, "Num Axes: %d", n, joy[0].stick[n].num_axis); |
93 | y += 20; |
94 | for (int ax = 0; ax < joy[0].stick[n].num_axis; ax++) |
95 | { |
96 | textprintf_ex(buffer, font, 10, y, makecol(255,255,255), 0, "Axis %d: %s - %d", ax, joy[0].stick[n].axis[ax].name, joy[0].stick[n].axis[ax].pos); |
97 | y += 10; |
98 | } |
99 | y += 30; |
100 | } |
101 | |
102 | textprintf_ex(buffer, font, 10, y, makecol(255,255,255), 0, "Buttons:"); |
103 | y += 20; |
104 | for( int n=0; n < joy[0].num_buttons; n++) |
105 | { |
106 | if( joy[0].button[n].b) |
107 | { |
108 | textprintf_ex(buffer, font, 10, y, makecol(255,0,0), 0, "Button %d: %s", n, joy[0].button[n].name); |
109 | } |
110 | else |
111 | { |
112 | textprintf_ex(buffer, font, 10, y, makecol(255,255,255), 0, "Button %d: %s", n, joy[0].button[n].name); |
113 | } |
114 | y += 10; |
115 | } |
116 | |
117 | |
118 | } |
119 | |
120 | } |
121 | |
122 | |
123 | |
124 | // Main() routine |
125 | // |
126 | //************************************************************** |
127 | |
128 | int main(int argc, char *argv[]) |
129 | { |
130 | init(); |
131 | |
132 | while (!keypressed()) |
133 | { |
134 | mainLoop(); |
135 | blit(buffer, screen, 0,0,0,0,800,600);//Draw the buffer to the screen |
136 | clear_bitmap(buffer); // Clear the contents of the buffer bitmap |
137 | } |
138 | |
139 | return 0; |
140 | //Allegro will automatically deinitalize itself on exit |
141 | } |
142 | END_OF_MAIN() |
I remember there was a thread about Allegro messing up the stick<->axis relation a while ago. I believe it was found to be a bug in the library, but I can't remember if anyone got to fix it.
When you're working with joysticks it's best not to assume anything and to always allow the user to configure their joystick to your game. There have been a number of games out there which I haven't been able to play with my joystick simply because it lacked decent joystick configuration routines.
The default joystick structure in DirectX doesn't separate sticks and axises like Allegro does. It basically has room for six standard axises, four hats, two slider axises, and 32 buttons, for each joystick. To detect more than that is seriously complicated and I doubt any of the Allegro devs would've done so.
But what Allegro does is unify all this data into sticks and axises per stick. I believe Allegro separates them as follows (though I haven't looked to confirm this):
Stick 0: 3 Standard Axises, First Slider
Stick 1: 3 Rotational Axises, Second Slider
Stick 2+: Hats 0+
(If there's no rotational or second slider, hats start on Stick 1.)
My MS Precision Pro joystick (1 twistable stick, 1 throttle, 1 hat, 9 buttons) comes up as:
Stick 0: X, Y and Throttle
Stick 1: Stick Twist
Stick 2: Hat
--- Kris Asick (Gemini)
--- http://www.pixelships.com
Ok, its just driving me nuts that one axis of stick 1 shows as stick 0's 3rd axis, while the other axis actually shows as stick 1.. guess I wont use the right stick.. just the left, hat and buttons maybe..
I would like to have it configurable so that if I have a config screen, I can tell the player to press their UP ont he gamepad and find a way to map that.. but Im not really quite sure how to go about that..
This is an old problem. I pointed it out a few times, but I don't think there are any active windows developers to fix it anymore.
If it's any consolation, the results you get are consistent for any dual-shock style gamepad running on Windows. You can hard-code the axes you have and it will work for many people.
On the other hand, a configuration screen will be universally useful, both for when people use a non-dual shock, aren't on Windows, or somebody fixes this bug. I keep meaning to code the GUI to do this but I haven't got around to it yet, sorry
Does either JOY_TYPE_DIRECTX or JOY_TYPE_WIN32 work better?
I will have to try both, I put it down for a while.. time to pick it up again.. Ill check on this and edit this post here shortly..
Same results either way I go. I know Ive played with SDL's joystick routines before and it detected alright.. I may have to hardcode it in somehow, its just gonna be odd.. =( Problem Im gonna have is my stick 2 X axis reads from 0 - 256, while the Y axis reads -128 to 128.. grrrrr....
I suppose stick 2 really isnt going to be that important tho...