1 /* $Id: joyc.c,v 1.2 2005-04-04 09:21:25 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 #pragma off (unreferenced)
17 static char rcsid[] = "$Id: joyc.c,v 1.2 2005-04-04 09:21:25 btb Exp $";
18 #pragma on (unreferenced)
36 // edi = pointer to buffer
37 // returns number of events
38 int joy_read_stick_asm( int read_masks, int * event_buffer, int timeout );
39 #pragma aux joy_read_stick_asm parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
41 int joy_read_stick_polled( int read_masks, int * event_buffer, int timeout );
42 #pragma aux joy_read_stick_polled parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
44 int joy_read_stick_bios( int read_masks, int * event_buffer, int timeout );
45 #pragma aux joy_read_stick_bios parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
48 char joy_installed = 0;
51 #define JOY_READ_BUTTONS ((~(inp(0x201) >> 4))&0xf)
53 #define JOY_READ_BUTTONS_ARCADE (~(inp(0x2A1)))
54 #define JOY_MAX_BUTTONS 28
56 #define JOY_MAX_BUTTONS 20
59 typedef struct Button_info {
68 typedef struct Joy_info {
74 Button_info buttons[JOY_MAX_BUTTONS];
82 void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max)
87 axis_min[i] = joystick.axis_min[i];
88 axis_center[i] = joystick.axis_center[i];
89 axis_max[i] = joystick.axis_max[i];
93 void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max)
98 joystick.axis_min[i] = axis_min[i];
99 joystick.axis_center[i] = axis_center[i];
100 joystick.axis_max[i] = axis_max[i];
105 ubyte joy_get_present_mask() {
106 return joystick.present_mask;
109 void joy_set_timer_rate(int max_value ) {
111 joystick.max_timer = max_value;
115 int joy_get_timer_rate() {
116 return joystick.max_timer;
123 if (!joy_installed) return;
126 for (i = 0; i < JOY_MAX_BUTTONS; i++)
128 joystick.buttons[i].ignore = 0;
129 joystick.buttons[i].state = 0;
130 joystick.buttons[i].timedown = 0;
131 joystick.buttons[i].downcount = 0;
132 joystick.buttons[i].upcount = 0;
138 #pragma off (check_stack)
140 extern int joy_read_buttons_bios();
142 void joy_handler(int ticks_this_time) {
148 Button_info * button;
150 joystick.max_timer = ticks_this_time;
152 if ( joystick.slow_read & JOY_BIOS_READINGS ) {
153 joystick.read_count++;
154 if ( joystick.read_count > 7 ) {
155 joystick.read_count = 0;
156 value = joy_read_buttons_bios();
157 joystick.last_value = value;
159 value = joystick.last_value;
162 value = JOY_READ_BUTTONS;
164 valuea = JOY_READ_BUTTONS_ARCADE;
168 for (i = 0; i < JOY_MAX_BUTTONS; i++)
170 button = &joystick.buttons[i];
171 if (!button->ignore) {
173 state = (value >> i) & 1;
176 state = (valuea >> (i-20)) & 1;
178 else if (i==(value+4))
183 if ( button->last_state == state ) {
184 if (state) button->timedown += ticks_this_time;
187 button->downcount += state;
190 button->upcount += button->state;
193 button->last_state = state;
199 void joy_handler_end() { // Dummy function to help calculate size of joystick handler function
202 #pragma off (check_stack)
204 ubyte joy_read_raw_buttons() {
205 if ( joystick.slow_read & JOY_BIOS_READINGS )
206 return joy_read_buttons_bios();
208 return JOY_READ_BUTTONS;
211 void joy_set_slow_reading(int flag)
213 joystick.slow_read |= flag;
217 ubyte joystick_read_raw_axis( ubyte mask, int * axis )
219 ubyte read_masks, org_masks;
220 int t, t1, t2, buffer[4*2+2];
221 int e, i, num_channels, c;
223 axis[0] = 0; axis[1] = 0;
224 axis[2] = 0; axis[3] = 0;
226 if (!joy_installed) return 0;
231 mask &= joystick.present_mask; // Don't read non-present channels
233 return 0; // Don't read if no stick connected.
236 if ( joystick.slow_read & JOY_SLOW_READINGS ) {
237 for (c=0; c<4; c++ ) {
238 if ( mask & (1 << c)) {
239 // Time out at (1/100th of a second)
241 if ( joystick.slow_read & JOY_POLLED_READINGS )
242 num_channels = joy_read_stick_polled( (1 << c), buffer, 65536 );
243 else if ( joystick.slow_read & JOY_BIOS_READINGS )
244 num_channels = joy_read_stick_bios( (1 << c), buffer, 65536 );
246 num_channels = joy_read_stick_asm( (1 << c), buffer, (1193180/100) );
248 if ( num_channels > 0 ) {
252 if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) ) {
258 t = t1 + joystick.max_timer - t2;
259 //mprintf( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t );
263 if ( e & 1 ) { axis[0] = t; read_masks |= 1; }
264 if ( e & 2 ) { axis[1] = t; read_masks |= 2; }
265 if ( e & 4 ) { axis[2] = t; read_masks |= 4; }
266 if ( e & 8 ) { axis[3] = t; read_masks |= 8; }
271 // Time out at (1/100th of a second)
272 if ( joystick.slow_read & JOY_POLLED_READINGS )
273 num_channels = joy_read_stick_polled( mask, buffer, 65536 );
274 else if ( joystick.slow_read & JOY_BIOS_READINGS )
275 num_channels = joy_read_stick_bios( (1 << c), buffer, 65536 );
277 num_channels = joy_read_stick_asm( mask, buffer, (1193180/100) );
278 //mprintf(( 0, "(%d)\n", num_channels ));
280 for (i=0; i<num_channels; i++ ) {
284 if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) ) {
290 t = t1 + joystick.max_timer - t2;
291 //mprintf(( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t ));
296 if ( e & 1 ) { axis[0] = t; read_masks |= 1; }
297 if ( e & 2 ) { axis[1] = t; read_masks |= 2; }
298 if ( e & 4 ) { axis[2] = t; read_masks |= 4; }
299 if ( e & 8 ) { axis[3] = t; read_masks |= 8; }
307 extern void timer_set_joyhandler( void (*joy_handler)() );
317 for (i = 0; i < JOY_MAX_BUTTONS; i++)
318 joystick.buttons[i].last_state = 0;
321 if ( !joy_installed ) {
324 joystick.max_timer = 65536;
325 joystick.slow_read = 0;
326 joystick.read_count = 0;
327 joystick.last_value = 0;
329 //--------------- lock everything for the virtal memory ----------------------------------
330 if (!dpmi_lock_region ((void near *)joy_handler, (char *)joy_handler_end - (char near *)joy_handler)) {
331 Error( "Can't lock joystick handler!\n" );
334 if (!dpmi_lock_region (&joystick, sizeof(Joy_info))) {
335 Error( "Can't lock joystick handler's data!\n" );
338 timer_set_joyhandler(joy_handler);
341 // Do initial cheapy calibration...
342 joystick.present_mask = JOY_ALL_AXIS; // Assume they're all present
343 joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, temp_axis );
345 if ( joystick.present_mask & 3 )
355 if (!joy_installed) return;
361 joystick.present_mask = JOY_ALL_AXIS; // Assume they're all present
362 joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_min );
363 if ( joystick.present_mask & 3 )
371 joystick.present_mask = JOY_ALL_AXIS; // Assume they're all present
372 joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_max );
373 if ( joystick.present_mask & 3 )
381 joystick.present_mask = JOY_ALL_AXIS; // Assume they're all present
382 joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_center );
383 if ( joystick.present_mask & 3 )
389 void joy_set_cen_fake(int channel)
393 int minx, maxx, cenx;
397 for (i=0; i<4; i++ ) {
398 if ( (joystick.present_mask & (1<<i)) && (i!=channel) ) {
400 minx += joystick.axis_min[i];
401 maxx += joystick.axis_max[i];
402 cenx += joystick.axis_center[i];
409 joystick.axis_min[channel] = minx;
410 joystick.axis_max[channel] = maxx;
411 joystick.axis_center[channel] = cenx;
414 int joy_get_scaled_reading( int raw, int axn )
418 // Make sure it's calibrated properly.
419 if ( joystick.axis_center[axn] - joystick.axis_min[axn] < 5 ) return 0;
420 if ( joystick.axis_max[axn] - joystick.axis_center[axn] < 5 ) return 0;
422 raw -= joystick.axis_center[axn];
425 d = joystick.axis_center[axn]-joystick.axis_min[axn];
427 d = joystick.axis_max[axn]-joystick.axis_center[axn];
435 if ( x < -128 ) x = -128;
436 if ( x > 127 ) x = 127;
441 void joy_get_pos( int *x, int *y )
446 if ((!joy_installed)||(!joy_present)) { *x=*y=0; return; }
448 flags=joystick_read_raw_axis( JOY_1_X_AXIS+JOY_1_Y_AXIS, axis );
450 if ( flags & JOY_1_X_AXIS )
451 *x = joy_get_scaled_reading( axis[0], 0 );
455 if ( flags & JOY_1_Y_AXIS )
456 *y = joy_get_scaled_reading( axis[1], 1 );
461 ubyte joy_read_stick( ubyte masks, int *axis )
466 if ((!joy_installed)||(!joy_present)) {
467 axis[0] = 0; axis[1] = 0;
468 axis[2] = 0; axis[3] = 0;
472 flags=joystick_read_raw_axis( masks, raw_axis );
474 if ( flags & JOY_1_X_AXIS )
475 axis[0] = joy_get_scaled_reading( raw_axis[0], 0 );
479 if ( flags & JOY_1_Y_AXIS )
480 axis[1] = joy_get_scaled_reading( raw_axis[1], 1 );
484 if ( flags & JOY_2_X_AXIS )
485 axis[2] = joy_get_scaled_reading( raw_axis[2], 2 );
489 if ( flags & JOY_2_Y_AXIS )
490 axis[3] = joy_get_scaled_reading( raw_axis[3], 3 );
500 if ((!joy_installed)||(!joy_present)) return 0;
502 return joy_read_raw_buttons();
505 void joy_get_btn_down_cnt( int *btn0, int *btn1 )
507 if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; }
510 *btn0 = joystick.buttons[0].downcount;
511 joystick.buttons[0].downcount = 0;
512 *btn1 = joystick.buttons[1].downcount;
513 joystick.buttons[1].downcount = 0;
517 int joy_get_button_state( int btn )
521 if ((!joy_installed)||(!joy_present)) return 0;
523 if (btn >= JOY_MAX_BUTTONS)
527 count = joystick.buttons[btn].state;
533 int joy_get_button_up_cnt( int btn )
537 if ((!joy_installed)||(!joy_present)) return 0;
539 if (btn >= JOY_MAX_BUTTONS)
543 count = joystick.buttons[btn].upcount;
544 joystick.buttons[btn].upcount = 0;
550 int joy_get_button_down_cnt( int btn )
554 if ((!joy_installed)||(!joy_present)) return 0;
555 if (btn >= JOY_MAX_BUTTONS)
559 count = joystick.buttons[btn].downcount;
560 joystick.buttons[btn].downcount = 0;
567 fix joy_get_button_down_time( int btn )
571 if ((!joy_installed)||(!joy_present)) return 0;
572 if (btn >= JOY_MAX_BUTTONS)
576 count = joystick.buttons[btn].timedown;
577 joystick.buttons[btn].timedown = 0;
580 return fixmuldiv(count, 65536, 1193180 );
583 void joy_get_btn_up_cnt( int *btn0, int *btn1 )
585 if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; }
588 *btn0 = joystick.buttons[0].upcount;
589 joystick.buttons[0].upcount = 0;
590 *btn1 = joystick.buttons[1].upcount;
591 joystick.buttons[1].upcount = 0;
595 void joy_set_btn_values( int btn, int state, fix timedown, int downcount, int upcount )
598 joystick.buttons[btn].ignore = 1;
599 joystick.buttons[btn].state = state;
600 joystick.buttons[btn].timedown = fixmuldiv( timedown, 1193180, 65536 );
601 joystick.buttons[btn].downcount = downcount;
602 joystick.buttons[btn].upcount = upcount;
608 if ( joystick.slow_read & JOY_BIOS_READINGS )
609 joystick.last_value = joy_read_buttons_bios();