2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
15 #pragma off (unreferenced)
16 static char rcsid[] = "$Id: mouse.c,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $";
17 #pragma on (unreferenced)
32 #define ME_CURSOR_MOVED (1<<0)
33 #define ME_LB_P (1<<1)
34 #define ME_LB_R (1<<2)
35 #define ME_RB_P (1<<3)
36 #define ME_RB_R (1<<4)
37 #define ME_MB_P (1<<5)
38 #define ME_MB_R (1<<6)
39 #define ME_OB_P (1<<7)
40 #define ME_OB_R (1<<8)
42 #define ME_Y_C (1<<10)
43 #define ME_Z_C (1<<11)
44 #define ME_P_C (1<<12)
45 #define ME_B_C (1<<13)
46 #define ME_H_C (1<<14)
47 #define ME_O_C (1<<15)
49 #define MOUSE_MAX_BUTTONS 11
51 typedef struct event_info {
59 ushort device_dependant;
62 typedef struct mouse_info {
66 ubyte pressed[MOUSE_MAX_BUTTONS];
67 fix time_went_down[MOUSE_MAX_BUTTONS];
68 fix time_held_down[MOUSE_MAX_BUTTONS];
69 uint num_downs[MOUSE_MAX_BUTTONS];
70 uint num_ups[MOUSE_MAX_BUTTONS];
75 typedef struct cyberman_info {
82 ubyte pitch_descriptor;
83 ubyte roll_descriptor;
88 static mouse_info Mouse;
90 static int Mouse_installed = 0;
92 #pragma off (check_stack)
93 void _loadds far mouse_handler (int m_ax, int mbx, int mcx, int mdx, int msi, int mdi)
95 #pragma aux mouse_handler parm [EAX] [EBX] [ECX] [EDX] [ESI] [EDI]
97 Mouse.ctime = timer_get_fixed_secondsX();
99 if (m_ax & ME_LB_P) { // left button pressed
100 if (!Mouse.pressed[MB_LEFT]) {
101 Mouse.pressed[MB_LEFT] = 1;
102 Mouse.time_went_down[MB_LEFT] = Mouse.ctime;
104 Mouse.num_downs[MB_LEFT]++;
105 } else if (m_ax & ME_LB_R ) { // left button released
106 if (Mouse.pressed[MB_LEFT]) {
107 Mouse.pressed[MB_LEFT] = 0;
108 Mouse.time_held_down[MB_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_LEFT];
110 Mouse.num_ups[MB_LEFT]++;
113 if (m_ax & ME_RB_P ) { // right button pressed
114 if (!Mouse.pressed[MB_RIGHT]) {
115 Mouse.pressed[MB_RIGHT] = 1;
116 Mouse.time_went_down[MB_RIGHT] = Mouse.ctime;
118 Mouse.num_downs[MB_RIGHT]++;
119 } else if (m_ax & ME_RB_R ) {// right button released
120 if (Mouse.pressed[MB_RIGHT]) {
121 Mouse.pressed[MB_RIGHT] = 0;
122 Mouse.time_held_down[MB_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_RIGHT];
124 Mouse.num_ups[MB_RIGHT]++;
127 if (m_ax & ME_MB_P ) { // middle button pressed
128 if (!Mouse.pressed[MB_MIDDLE]) {
129 Mouse.pressed[MB_MIDDLE] = 1;
130 Mouse.time_went_down[MB_MIDDLE] = Mouse.ctime;
132 Mouse.num_downs[MB_MIDDLE]++;
133 } else if (m_ax & ME_MB_R ) { // middle button released
134 if (Mouse.pressed[MB_MIDDLE]) {
135 Mouse.pressed[MB_MIDDLE] = 0;
136 Mouse.time_held_down[MB_MIDDLE] += Mouse.ctime-Mouse.time_went_down[MB_MIDDLE];
138 Mouse.num_ups[MB_MIDDLE]++;
141 if (Mouse.cyberman && (m_ax & (ME_Z_C|ME_P_C|ME_B_C|ME_H_C))) {
142 Mouse.x_info = (event_info *)((msi & 0xFFFF) << 4);
144 if (m_ax & ME_Z_C ) { // z axis changed
145 if (Mouse.pressed[MB_Z_UP]) {
147 Mouse.pressed[MB_Z_UP] = 0;
148 Mouse.time_held_down[MB_Z_UP] += Mouse.ctime-Mouse.time_went_down[MB_Z_UP];
149 Mouse.num_ups[MB_Z_UP]++;
150 } else if ( Mouse.x_info->z>0 ) {
152 Mouse.pressed[MB_Z_UP] = 1;
153 Mouse.time_went_down[MB_Z_UP]=Mouse.ctime;
154 Mouse.num_downs[MB_Z_UP]++;
156 if (Mouse.pressed[MB_Z_DOWN]) {
158 Mouse.pressed[MB_Z_DOWN] = 0;
159 Mouse.time_held_down[MB_Z_DOWN] += Mouse.ctime-Mouse.time_went_down[MB_Z_DOWN];
160 Mouse.num_ups[MB_Z_DOWN]++;
161 } else if ( Mouse.x_info->z<0 ) {
163 Mouse.pressed[MB_Z_DOWN] = 1;
164 Mouse.time_went_down[MB_Z_DOWN]=Mouse.ctime;
165 Mouse.num_downs[MB_Z_DOWN]++;
168 if (m_ax & ME_P_C ) { // pitch changed
169 if (Mouse.pressed[MB_PITCH_BACKWARD]) {
170 // pitch backward released
171 Mouse.pressed[MB_PITCH_BACKWARD] = 0;
172 Mouse.time_held_down[MB_PITCH_BACKWARD] += Mouse.ctime-Mouse.time_went_down[MB_PITCH_BACKWARD];
173 Mouse.num_ups[MB_PITCH_BACKWARD]++;
174 } else if ( Mouse.x_info->pitch>0 ) {
175 // pitch backward pressed
176 Mouse.pressed[MB_PITCH_BACKWARD] = 1;
177 Mouse.time_went_down[MB_PITCH_BACKWARD]=Mouse.ctime;
178 Mouse.num_downs[MB_PITCH_BACKWARD]++;
180 if (Mouse.pressed[MB_PITCH_FORWARD]) {
181 // pitch forward released
182 Mouse.pressed[MB_PITCH_FORWARD] = 0;
183 Mouse.time_held_down[MB_PITCH_FORWARD] += Mouse.ctime-Mouse.time_went_down[MB_PITCH_FORWARD];
184 Mouse.num_ups[MB_PITCH_FORWARD]++;
185 } else if ( Mouse.x_info->pitch<0 ) {
186 // pitch forward pressed
187 Mouse.pressed[MB_PITCH_FORWARD] = 1;
188 Mouse.time_went_down[MB_PITCH_FORWARD]=Mouse.ctime;
189 Mouse.num_downs[MB_PITCH_FORWARD]++;
193 if (m_ax & ME_B_C ) { // bank changed
194 if (Mouse.pressed[MB_BANK_LEFT]) {
195 // bank left released
196 Mouse.pressed[MB_BANK_LEFT] = 0;
197 Mouse.time_held_down[MB_BANK_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_BANK_LEFT];
198 Mouse.num_ups[MB_BANK_LEFT]++;
199 } else if ( Mouse.x_info->bank>0 ) {
201 Mouse.pressed[MB_BANK_LEFT] = 1;
202 Mouse.time_went_down[MB_BANK_LEFT]=Mouse.ctime;
203 Mouse.num_downs[MB_BANK_LEFT]++;
205 if (Mouse.pressed[MB_BANK_RIGHT]) {
206 // bank right released
207 Mouse.pressed[MB_BANK_RIGHT] = 0;
208 Mouse.time_held_down[MB_BANK_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_BANK_RIGHT];
209 Mouse.num_ups[MB_BANK_RIGHT]++;
210 } else if ( Mouse.x_info->bank<0 ) {
211 // bank right pressed
212 Mouse.pressed[MB_BANK_RIGHT] = 1;
213 Mouse.time_went_down[MB_BANK_RIGHT]=Mouse.ctime;
214 Mouse.num_downs[MB_BANK_RIGHT]++;
218 if (m_ax & ME_H_C ) { // heading changed
219 if (Mouse.pressed[MB_HEAD_LEFT]) {
220 // head left released
221 Mouse.pressed[MB_HEAD_LEFT] = 0;
222 Mouse.time_held_down[MB_HEAD_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_HEAD_LEFT];
223 Mouse.num_ups[MB_HEAD_LEFT]++;
224 } else if ( Mouse.x_info->heading>0 ) {
226 Mouse.pressed[MB_HEAD_LEFT] = 1;
227 Mouse.time_went_down[MB_HEAD_LEFT]=Mouse.ctime;
228 Mouse.num_downs[MB_HEAD_LEFT]++;
230 if (Mouse.pressed[MB_HEAD_RIGHT]) {
231 // head right released
232 Mouse.pressed[MB_HEAD_RIGHT] = 0;
233 Mouse.time_held_down[MB_HEAD_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_HEAD_RIGHT];
234 Mouse.num_ups[MB_HEAD_RIGHT]++;
235 } else if ( Mouse.x_info->heading<0 ) {
236 // head right pressed
237 Mouse.pressed[MB_HEAD_RIGHT] = 1;
238 Mouse.time_went_down[MB_HEAD_RIGHT]=Mouse.ctime;
239 Mouse.num_downs[MB_HEAD_RIGHT]++;
249 void mouse_handler_end (void) // dummy functions
252 #pragma on (check_stack)
254 //--------------------------------------------------------
255 // returns 0 if no mouse
256 // else number of buttons
257 int mouse_init(int enable_cyberman)
262 union REGS inregs, outregs;
263 ubyte *Mouse_dos_mem;
266 return Mouse.num_buttons;
268 if (_dos_getvect(0x33) == NULL) {
269 // No mouse driver loaded
273 // Reset the mouse driver
274 memset( &inregs, 0, sizeof(inregs) );
276 int386(0x33, &inregs, &outregs);
277 if (outregs.w.ax != 0xffff)
280 Mouse.num_buttons = outregs.w.bx;
283 // Enable mouse driver
284 memset( &inregs, 0, sizeof(inregs) );
285 inregs.w.ax = 0x0020;
286 int386(0x33, &inregs, &outregs);
287 if (outregs.w.ax != 0xffff )
290 if ( enable_cyberman ) {
291 Mouse_dos_mem = dpmi_get_temp_low_buffer( 64 );
292 if (Mouse_dos_mem==NULL) {
293 printf( "Unable to allocate DOS buffer in mouse.c\n" );
295 // Check for Cyberman...
296 memset( &rr, 0, sizeof(dpmi_real_regs) );
297 rr.es = DPMI_real_segment(Mouse_dos_mem);
298 rr.edx = DPMI_real_offset(Mouse_dos_mem);
300 dpmi_real_int386x( 0x33, &rr );
302 // SWIFT functions supported
303 ci = (cyberman_info *)Mouse_dos_mem;
304 if (ci->device_type==1) { // Cyberman
306 //printf( "Cyberman mouse detected\n" );
307 Mouse.num_buttons = 11;
313 if (!dpmi_lock_region(&Mouse,sizeof(mouse_info))) {
314 Error( "Unable to lock mouse data region" );
316 if (!dpmi_lock_region((void near *)mouse_handler,(char *)mouse_handler_end - (char near *)mouse_handler)) {
317 Error( "Unable to lock mouse handler" );
320 // Install mouse handler
321 memset( &inregs, 0, sizeof(inregs));
322 memset( &sregs, 0, sizeof(sregs));
324 inregs.w.cx = ME_LB_P|ME_LB_R|ME_RB_P|ME_RB_R|ME_MB_P|ME_MB_R; // watch all 3 button ups/downs
326 inregs.w.cx |= ME_Z_C| ME_P_C| ME_B_C| ME_H_C; // if using a cyberman, also watch z, pitch, bank, heading.
327 inregs.x.edx = FP_OFF(mouse_handler);
328 sregs.es = FP_SEG(mouse_handler);
329 int386x(0x33, &inregs, &outregs, &sregs);
333 atexit( mouse_close );
337 return Mouse.num_buttons;
345 union REGS inregs, outregs;
347 if (Mouse_installed) {
349 // clear mouse handler by setting flags to 0.
350 memset( &inregs, 0, sizeof(inregs));
351 memset( &sregs, 0, sizeof(sregs));
353 inregs.w.cx = 0; // disable event handler by setting to zero.
356 int386x(0x33, &inregs, &outregs, &sregs);
361 void mouse_set_limits( int x1, int y1, int x2, int y2 )
363 union REGS inregs, outregs;
365 if (!Mouse_installed) return;
367 memset( &inregs, 0, sizeof(inregs));
368 inregs.w.ax = 0x7; // Set Horizontal Limits for Pointer
371 int386(0x33, &inregs, &outregs);
373 memset( &inregs, 0, sizeof(inregs));
374 inregs.w.ax = 0x8; // Set Vertical Limits for Pointer
377 int386(0x33, &inregs, &outregs);
380 void mouse_get_pos( int *x, int *y)
382 union REGS inregs, outregs;
384 if (!Mouse_installed) {
388 memset( &inregs, 0, sizeof(inregs));
389 inregs.w.ax = 0x3; // Get Mouse Position and Button Status
390 int386(0x33, &inregs, &outregs);
391 *x = (short)outregs.w.cx;
392 *y = (short)outregs.w.dx;
395 void mouse_get_delta( int *dx, int *dy )
397 union REGS inregs, outregs;
399 if (!Mouse_installed) {
404 memset( &inregs, 0, sizeof(inregs));
405 inregs.w.ax = 0xb; // Read Mouse motion counters
406 int386(0x33, &inregs, &outregs);
407 *dx = (short)outregs.w.cx;
408 *dy = (short)outregs.w.dx;
417 if (!Mouse_installed)
420 for (i=0; i<MOUSE_MAX_BUTTONS; i++ ) {
421 if (Mouse.pressed[i])
428 void mouse_set_pos( int x, int y)
430 union REGS inregs, outregs;
432 if (!Mouse_installed)
435 memset( &inregs, 0, sizeof(inregs));
436 inregs.w.ax = 0x4; // Set Mouse Pointer Position
439 int386(0x33, &inregs, &outregs);
448 if (!Mouse_installed)
453 //Clear the mouse data
454 CurTime =timer_get_fixed_secondsX();
455 for (i=0; i<MOUSE_MAX_BUTTONS; i++ ) {
456 Mouse.pressed[i] = 0;
457 Mouse.time_went_down[i] = CurTime;
458 Mouse.time_held_down[i] = 0;
459 Mouse.num_downs[i]=0;
466 // Returns how many times this button has went down since last call.
467 int mouse_button_down_count(int button)
471 if (!Mouse_installed)
476 count = Mouse.num_downs[button];
477 Mouse.num_downs[button]=0;
484 // Returns 1 if this button is currently down
485 int mouse_button_state(int button)
489 if (!Mouse_installed)
494 state = Mouse.pressed[button];
503 // Returns how long this button has been down since last call.
504 fix mouse_button_down_time(int button)
508 if (!Mouse_installed)
513 if ( !Mouse.pressed[button] ) {
514 time_down = Mouse.time_held_down[button];
515 Mouse.time_held_down[button] = 0;
517 time = timer_get_fixed_secondsX();
518 time_down = time - Mouse.time_went_down[button];
519 Mouse.time_went_down[button] = time;
527 void mouse_get_cyberman_pos( int *x, int *y )
531 ubyte *Mouse_dos_mem;
533 if ( (!Mouse_installed) || (!Mouse.cyberman) ) {
538 Mouse_dos_mem = dpmi_get_temp_low_buffer( 64 );
540 if ( !Mouse_dos_mem ) {
546 memset( &rr, 0, sizeof(dpmi_real_regs) );
547 rr.es = DPMI_real_segment(Mouse_dos_mem);
548 rr.edx = DPMI_real_offset(Mouse_dos_mem);
550 dpmi_real_int386x( 0x33, &rr );
552 ei = (event_info *)Mouse_dos_mem;
554 *x = (((ei->x+8128)*256)/(8064+8128+1)) - 127;
555 *y = (((ei->y+8128)*256)/(8064+8128+1)) - 127;