home *** CD-ROM | disk | FTP | other *** search
- joystkmd.se Middle Level Joystick Routines for JSTKRD2.C
- Preliminary Structured English
-
- MODULES:
- Low Level /* joystklo.se */
-
- 1: detect : presence through bios or port
- 2: get_valid_axes : return mask of valid axes
- 3: get_active_axes : return mask of active axes
- 4: set_active_axes : set mask of active axes
- 5 button_state ; current button state
- 6: button_change : returns bitmask of button changes
- 7: axis_position : gets position of given axis
-
- Middle Level /* this module */
-
- 8: initialize : detect & inititalize joystick globals
- 9: axis_position_change : returns changes in active axes
- 10: real_coords_to_rel : translates axis pos relative to center
- 11: get_center_coords : gets center position of joystick
- 12: set_center_coords : grabs current position as new center
- 13: get_min_coords ; gets minimum position of joystick
- 14: set_min_coords ; grabs current position as new minimum
- 15: get_max_coords ; gets maximum position of joystick
- 16: set_max_coords ; grabs current position as new maximum
- 17: get_tolerance : get tolerance of change to ignore
- 18: set_tolerance : set tolerance of change to ignore
-
- High Level /* do it yo-sef */
-
- 19: create : grab interrupt 1Ch & set up queue
- 20: destroy : release interrupt 1Ch & queue
- 21: get_joystick_event : get event from queue
- 22: push_joystick_event : push event into queue
- 23: interrupt_handler : timer interrupt 1Ch polling routine
-
- PURPOSE:
- To create an event compatible set of routines to read input from
- the game port. (particularly geared to joysticks).
- Based on the file c_joy.c written by Gary Blaine,
- CIS 72707,1736 March 4, 1990 which is available in the
- Borland C Programming Forum on Compuserve in the file JOY.ARC.
- Use assembly for time-critical operations.
-
- GLOBAL DEFINES:
- ; return values for button_change and button state
-
- JA1_BUTTON_DOWN 16 ; joystick A, button 1, down
- JA1_BUTTON_UP 1 ; joystick A, button 1, up
- JA2_BUTTON_DOWN 32 ; joystick A, button 2, down
- JA2_BUTTON_UP 2 ; joystick A, button 2, up
-
- JB1_BUTTON_DOWN 64 ; joystick B, button 1, down
- JB1_BUTTON_UP 4 ; joystick B, button 1, up
- JB2_BUTTON_DOWN 128 ; joystick B, button 2, down
- JB2_BUTTON_UP 8 ; joystick B, button 2, up
-
- J_ANY_BUTTON_DOWN 0xf0 ; any button down: either stick
-
- J_A_BUTTON_DOWN 0x30 ; any button down: joystick A
- J_B_BUTTON_DOWN 0xC0 ; any button down: joystick B
-
- J_BUTTON_1_DOWN 0x50 ; button 1 down: either joystick
- J_BUTTON_2_DOWN 0xA0 ; button 2 down: either joystick
-
- ; values for axis_position, axis_position_change & set_active_axes
-
- JAX_AXIS 1 ; x axis mask for joystick A
- JAY_AXIS 2 ; y axis mask for joystick A
- JBX_AXIS 4 ; x axis mask for joystick B
- JBY_AXIS 8 ; y axis mask for joystick B
-
- ; values for functions with the stick parameter
-
- JOYSTICK_A 3 ; axis mask for joystick A
- JOYSTICK_B 0x0C ; axis mask for joystick B
-
- struct StickValues {
- int jax ; ; joystick A x-coordinate value
- int jay ; ; joystick A y-coordinate value
- int jbx ; ; joystick B x-coordinate value
- int jby ; ; joystick B y-coordinate value
- } ;
- struct JoystickPosition {
- int jx ; ; joystick x-coordinate value
- int jy ; ; joystick y-coordinate value
- } ;
- struct Tolerance {
- int axl ; ; joystick A x-low breakpoint
- int axm ; ; joystick A x-mid breakpoint
- int axh ; ; joystick A x-hi breakpoint
- int ayl ; ; joystick A y-low breakpoint
- int aym ; ; joystick A y-mid breakpoint
- int ayh ; ; joystick A y-hi breakpoint
- int bxl ; ; joystick B x-low breakpoint
- int bxm ; ; joystick B x-mid breakpoint
- int bxh ; ; joystick B x-hi breakpoint
- int byl ; ; joystick B y-low breakpoint
- int bym ; ; joystick B y-mid breakpoint
- int byh ; ; joystick B y-hi breakpoint
- char t1 ; ; low graded tolerance
- char t2 ; ; mid graded tolerance
- char t3 ; ; hi graded tolerance
- } ;
-
- GLOBAL VARIABLES:
-
- G_Stick_Centers: coords of joystick centers
- G_Stick_Minimums: minimum joystick coordinates
- G_Stick_Maximums: maximum joystick coordinates
- G_Stick_Last_Pos: joystick coordinates last read
- G_Stick_Tolerance: ignore change value byte
- G_Stick_Breaks: breakpoints for joystick tolerance
-
- /* not currently used--- */
- G_Stick_Reset_Flag: reset in progress flag for clock interrupts
-
- /*---------------------------------------------------------------------*/
- initialize ( void(*NotifyUserFunc)(int) )
- : detect & inititalize joystick globals
- parameters: NotifyUserFunc
- ; User Notification function which displays the given prompt (int)
- variables: retval
- globals: G_Stick_Centers, G_Stick_Minimums, G_Stick_Maximums,
- G_Stick_Last_Pos, G_Stick_Tolerance
- BEGIN
- clear G_Stick_Active_Axes
- retval = detect() ; inst check & set up valid and active axes
- if ( (retval & (JAX_AXIS | JAY_AXIS)) == (JAX_AXIS | JAY_AXIS) )
- G_Stick_Active_Axes = (JAX_AXIS | JAY_AXIS) ;
- if ( (retval & (JBX_AXIS | JBY_AXIS)) == (JBX_AXIS | JBY_AXIS) )
- G_Stick_Active_Axes = G_Stick_Active_Axes | (JBX_AXIS | JBY_AXIS) ;
- if G_Stick_Active_Axes == 0
- call NotifyUserFunc with message 0
- return 0
- call NotifyUserFunc with message 1 (press escape to quit)
- if user_quit = call init_sub ( 2, J_ANY_BUTTON_DOWN, &G_Stick_Centers )
- return fail
- if user_quit = call init_sub ( 3, J_BUTTON_1_DOWN, &G_Stick_Minimums )
- return fail
- if user_quit = call init_sub ( 4, J_BUTTON_2_DOWN, &G_Stick_Maximums )
- return fail
- clear G_Stick_Last_Pos
- if ( G_Stick_Maximums.jax != 0 )
- Jstk = G_Stick_Maximums.jax + G_Stick_Maximums.jay
- G_Stick_Tolerance = G_Stick_Maximums.jax divided by 64
- else if ( G_Stick_Maximums.jbx != 0 )
- Jstk = G_Stick_Maximums.jbx + G_Stick_Maximums.jby
- G_Stick_Tolerance = G_Stick_Maximums.jbx divided by 64
- set_tolerance G_Stick_Tolerance
- return success
- END
-
- init_sub ( int msg, button, struct StickValues *what )
- parameters: msg ; User Notification message
- button ; button to signal position
- what ; what global variables to set
- variables: retval
- BEGIN
- call NotifyUserFunc( msg )
- initialize retval to NULL
- do
- if key waiting in keyboard buffer
- retval = getkey()
- if (retval == 27)
- call NotifyUserFunc with message -1 (user terminate)
- call NotifyUserFunc with message -2 (warning)
- return fail
- retval = button_change()
- while ( retval & stop_button == 0 )
- what->jax = axis_position( JAX_AXIS )
- what->jay = axis_position( JAY_AXIS )
- what->jbx = axis_position( JBX_AXIS )
- what->jby = axis_position( JBY_AXIS )
- return success
- END
-
- NotifyUserFunc ; Program-specific user display prompts
- ; Supplied as a parameter to initialize ()
- parameters: msg
- BEGIN
- display message...
- switch (msg)
- case -2: "warning: joystick installation incomplete"
- case -1: "joystick installation terminated by user"
- case 0: "no joystick detected"
- case 1: "press escape to quit"
- case 2: "center joystick and press button"
- case 3: "move joystick to top-left and press button 1"
- case 4: "move joystick to lower-right and press button 2"
- case -3: return
- default : return
- END
-
- /*---------------------------------------------------------------------*/
- axis_position_change ( int stick, struct JoystickPosition *stickpos )
- : returns changes in active axes
- parameters: stick, stickpos
- variables: x_pos, y_pos
- globals: G_Stick_Last_Pos, G_Stick_Tolerance
- BEGIN
- if stick is JOYSTICK_A or JOYSTICK_B
- BEGIN
- if stick AND get_active_Axes == stick
- BEGIN
- if stick == JOYSTICK_A
- BEGIN
- x_pos = JstGetPosition( JAX_AXIS )
- if x_pos < G_Stick_Breaks.axl ; set x tolerance
- xtol = G_Stick_Breaks.t1
- else if x_pos < G_Stick_Breaks.axm
- xtol = G_Stick_Breaks.t2
- else if x_pos < G_Stick_Breaks.axh
- xtol = G_Stick_Breaks.t3
- y_pos = JstGetPosition( JAY_AXIS )
- if y_pos < G_Stick_Breaks.ayl ; set y tolerance
- ytol = G_Stick_Breaks.t1
- else if y_pos < G_Stick_Breaks.aym
- ytol = G_Stick_Breaks.t2
- else if y_pos < G_Stick_Breaks.ayh
- ytol = G_Stick_Breaks.t3
- ; check for pos change
- if ( x_pos < G_Stick_Last_Pos.jax - xtol or
- x_pos > G_Stick_Last_Pos.jax + xtol or
- y_pos < G_Stick_Last_Pos.jay - ytol or
- y_pos > G_Stick_Last_Pos.jay + ytol )
- BEGIN
- G_Stick_Last_Pos.jax = x_pos
- G_Stick_Last_Pos.jay = y_pos
- stickpos->jx = x_pos
- stickpos->jy = y_pos
- return change: 1
- END
- END
- else if stick == JOYSTICK_B
- BEGIN
- x_pos = JstGetPosition( JBX_AXIS )
- if x_pos < G_Stick_Breaks.bxl ; set x tolerance
- xtol = G_Stick_Breaks.t1
- else if x_pos < G_Stick_Breaks.bxm
- xtol = G_Stick_Breaks.t2
- else if x_pos < G_Stick_Breaks.bxh
- xtol = G_Stick_Breaks.t3
- y_pos = JstGetPosition( JBY_AXIS )
- if y_pos < G_Stick_Breaks.byl ; set y tolerance
- ytol = G_Stick_Breaks.t1
- else if y_pos < G_Stick_Breaks.bym
- ytol = G_Stick_Breaks.t2
- else if y_pos < G_Stick_Breaks.byh
- ytol = G_Stick_Breaks.t3
- ; check for pos change
- if ( x_pos < G_Stick_Last_Pos.jbx - xtol or
- x_pos > G_Stick_Last_Pos.jbx + xtol or
- y_pos < G_Stick_Last_Pos.jby - ytol or
- y_pos > G_Stick_Last_Pos.jby + ytol )
- BEGIN
- G_Stick_Last_Pos.jbx = x_pos
- G_Stick_Last_Pos.jby = y_pos
- stickpos->jx = x_pos
- stickpos->jy = y_pos
- return change: 1
- END
- END
- END
- END
- return error/no change: 0
- END
- /*---------------------------------------------------------------------*/
- real_coords_to_rel ( int stick, struct JoystickPosition *stickpos )
- : translates axis pos relative to center
- parameters: stickpos
- variables: x_pos, y_pos
- globals: G_Stick_Centers
- BEGIN
- if stick == JOYSTICK_A
- BEGIN
- stickpos->jx = stickpos->jx - G_Stick_Centers.jax
- if stickpos->jx > 0
- stickpos->jx = stickpos->jx >> 1
- stickpos->jy = - (stickpos->jy - G_Stick_Centers.jay)
- if stickpos->jy < 0
- stickpos->jy = stickpos->jy / 2
- END
- else if stick == JOYSTICK_B
- BEGIN
- stickpos->jx = stickpos->jx - G_Stick_Centers.jbx
- if stickpos->jx > 0
- stickpos->jx = stickpos->jx >> 1
- stickpos->jy = - (stickpos->jy - G_Stick_Centers.jby)
- if stickpos->jy < 0
- stickpos->jy = stickpos->jy / 2
- END
- END
- /*---------------------------------------------------------------------*/
- get_min_coords(stick, ptrJoyPos ) ; gets center position for joystick
- BEGIN
- if stick == JOYSTICK_A
- ptrJoyPos->jx = G_Stick_Centers.jax
- ptrJoyPos->jy = G_Stick_Centers.jay
- if stick == JOYSTICK_B
- ptrJoyPos->jx = G_Stick_Centers.jbx
- ptrJoyPos->jy = G_Stick_Centers.jby
- END
- /*---------------------------------------------------------------------*/
- get_min_coords(stick, ptrJoyPos ) ; gets minimum position for joystick
- BEGIN
- if stick == JOYSTICK_A
- ptrJoyPos->jx = G_Stick_Minimums.jax
- ptrJoyPos->jy = G_Stick_Minimums.jay
- if stick == JOYSTICK_B
- ptrJoyPos->jx = G_Stick_Minimums.jbx
- ptrJoyPos->jy = G_Stick_Minimums.jby
- END
- /*---------------------------------------------------------------------*/
- get_max_coords(stick, ptrJoyPos ) : gets maximum position for joystick
- BEGIN
- if stick == JOYSTICK_A
- ptrJoyPos->jx = G_Stick_Maximums.jax
- ptrJoyPos->jy = G_Stick_Maximums.jay
- if stick == JOYSTICK_B
- ptrJoyPos->jx = G_Stick_Maximums.jbx
- ptrJoyPos->jy = G_Stick_Maximums.jby
- END
- /*---------------------------------------------------------------------*/
- set_center_coords( stick ) : grabs current position as new center
- BEGIN
- return (call grab_coords( stick, 1 ))
- END
- /*---------------------------------------------------------------------*/
- set_min_coords( stick ) ; grabs current position as new minimum
- BEGIN
- return (call grab_coords( stick, 2 ))
- END
- /*---------------------------------------------------------------------*/
- set_max_coords( stick ) ; grabs current position as new maximum
- BEGIN
- return (call grab_coords( stick, 3 ))
- END
- /*---------------------------------------------------------------------*/
- grab_coords ( int function )
- ; internal subroutine for re_center, set_min_coords, set_max_coords
- parameter: stick
- variables: ptrStickValues
- globals: G_Stick_Centers, G_Stick_Minimums, G_Stick_Maximums
- BEGIN
- if stick is JOYSTICK_A or JOYSTICK_B
- BEGIN
- if stick AND get_active_Axes == stick
- BEGIN
- if function == 1
- ptrStickValues = address of G_Stick_Centers
- if function == 2
- ptrStickValues = address of G_Stick_Minimums
- if function == 3
- ptrStickValues = address of G_Stick_Maximums
- if stick == JOYSTICK_A
- ptrStickValues->jax = axis_position( JAX_AXIS )
- ptrStickValues->jay = axis_position( JAY_AXIS )
- if stick == JOYSTICK_B
- ptrStickValues->jbx = axis_position( JBX_AXIS )
- ptrStickValues->jby = axis_position( JBY_AXIS )
- call set_tolerance ( G_Stick_Tolerance )
- return success
- END
- END
- return error
- END
- /*---------------------------------------------------------------------*/
- get_tolerance : get tolerance of change to ignore
- globals: G_Stick_Tolerance
- BEGIN
- return G_Stick_Tolerance
- END
- /*---------------------------------------------------------------------*/
- set_tolerance (int tolerance) : set tolerance of change to ignore
- parameters: tolerance
- globals: G_Stick_Tolerance
- BEGIN
- G_Stick_Tolerance = tolerance ;
- if ( tolerance > 7 )
- {
- G_Stick_Breaks.axl = G_Stick_Centers.jax >> 2 ;
- G_Stick_Breaks.axm = G_Stick_Centers.jax >> 1 ;
- G_Stick_Breaks.axh = G_Stick_Maximums.jax >> 1 ;
- G_Stick_Breaks.ayl = G_Stick_Centers.jay >> 2 ;
- G_Stick_Breaks.aym = G_Stick_Centers.jay >> 1 ;
- G_Stick_Breaks.ayh = G_Stick_Maximums.jay >> 1 ;
- G_Stick_Breaks.bxl = G_Stick_Centers.jbx >> 2 ;
- G_Stick_Breaks.bxm = G_Stick_Centers.jbx >> 1 ;
- G_Stick_Breaks.bxh = G_Stick_Maximums.jbx >> 1 ;
- G_Stick_Breaks.byl = G_Stick_Centers.jby >> 2 ;
- G_Stick_Breaks.bym = G_Stick_Centers.jby >> 1 ;
- G_Stick_Breaks.byh = G_Stick_Maximums.jby >> 1 ;
- G_Stick_Breaks.t1 = (tolerance >> 2) - 1 ;
- G_Stick_Breaks.t2 = tolerance >> 2 ;
- G_Stick_Breaks.t3 = tolerance >> 1 ;
- }
- else
- {
- G_Stick_Breaks.axl = G_Stick_Breaks.axm = G_Stick_Breaks.axh = 0 ;
- G_Stick_Breaks.ayl = G_Stick_Breaks.aym = G_Stick_Breaks.ayh = 0 ;
- G_Stick_Breaks.bxl = G_Stick_Breaks.bxm = G_Stick_Breaks.bxh = 0 ;
- G_Stick_Breaks.byl = G_Stick_Breaks.bym = G_Stick_Breaks.byh = 0 ;
- G_Stick_Breaks.t1 = tolerance ;
- G_Stick_Breaks.t2 = tolerance ;
- G_Stick_Breaks.t3 = tolerance ;
- }
- END
-
- /*-- end joystkmd.se ------------------*/
-