Original joystick only:
Code: Select all
type t_joystick
public:
as long id
as integer result, button
as single axis_x( any ), axis_y( any ), _ ' raw axis data
axis_a( any ) ' angle for axis
as long pointer_x, pointer_y, _
drag_sx, drag_sy, _ ' start position for drag
drag_dx, drag_dy, _ ' delta for drag
double_press_x, double_press_y
as long pointer_boundary_w, _
pointer_boundary_h, _
pointer_which_axis
as single sensitivity
as single deadzone
as long owner_drag, _
owner_double_press
as double time_double_press
declare constructor( _
byval p_axis as long = 3, _ ' set default number of axis to 4 in total
byval p_button as long = 31 ) ' set default number of buttons to 32 in total
declare destructor()
declare sub set_pointer_position( _
byval p_x as single = 0, _
byval p_y as single = 0 )
declare sub set_pointer_boundary( _
byval p_w as long = 0, _
byval p_h as long = 0 )
declare sub update_pointer_position()
declare sub get_state( _
byval p_timer as double = timer() )
declare sub close_state()
declare function joystick() _
as boolean
declare function press( _
byval p_button as long ) _
as boolean
declare function double_press( _
byval p_button as long ) _
as boolean
declare function release( _
byval p_button as long ) _
as boolean
declare function halt( _
byval p_button as long, _
byval p_time as double = 0.0 ) _
as boolean
declare function hold( _
byval p_button as long, _
byval p_time as double = 0.0 ) _
as boolean
declare function repeat( _
byval p_button as long, _
byval p_time as double = 0.0 ) _
as boolean
declare function drag( _
byval p_button as long ) _
as boolean
declare function drop( _
byval p_button as long ) _
as boolean
private:
as integer temp_button ' buffer for getjoystick()
as single temp_axis_x( any ), _
temp_axis_y( any )
as double local_timer
enum button_state
none = 0
press = 1
already_press = 2
release = 3
already_release = 4
double_press = 5
already_double_press = 6
void = 7
end enum
as byte state( any )
as double hold_start_time( any ), _
repeat_start_time( any ), _
double_press_start_time( any )
end type
constructor t_joystick( _
byval p_axis as long = 3, _ ' set default number of axis to 4 in total
byval p_button as long = 31 ) ' set default number of buttons to 32 in total
dim as byte _n
' retrieve the lowest numbered joystick attached to the computer
id = -1
for _n = 15 to 0 step( -1 )
result = getjoystick( _n )
if( result = 0 ) then
id = _n
end if
next _n
pointer_which_axis = 0
pointer_boundary_w = 0
pointer_boundary_h = 0
sensitivity = 10
deadzone = 0.001
owner_drag = -1
owner_double_press = -1
time_double_press = 0.2
redim axis_x( 0 to p_axis )
redim axis_y( 0 to p_axis )
redim axis_a( 0 to p_axis )
redim temp_axis_x( 0 to 3 )
redim temp_axis_y( 0 to 3 )
redim state( 0 to p_button )
redim hold_start_time( 0 to p_button )
redim repeat_start_time( 0 to p_button )
redim double_press_start_time( 0 to p_button )
end constructor
destructor t_joystick()
end destructor
sub t_joystick.set_pointer_position( _
byval p_x as single = 0, _
byval p_y as single = 0 )
pointer_x = p_x
pointer_y = p_y
end sub
sub t_joystick.set_pointer_boundary( _
byval p_w as long = 0, _
byval p_h as long = 0 )
pointer_boundary_w = p_w
pointer_boundary_h = p_h
end sub
sub t_joystick.update_pointer_position()
if( axis_x( pointer_which_axis ) <> 0 ) then
pointer_x += ( axis_x( pointer_which_axis ) * sensitivity )
pointer_x = iif( ( pointer_x ) < ( pointer_boundary_w ), _
( pointer_x ), ( pointer_boundary_w ) )
pointer_x = iif( ( pointer_x ) > ( 0 ), _
( pointer_x ), ( 0 ) )
end if
if( axis_y( pointer_which_axis ) <> 0 ) then
pointer_y += ( axis_y( pointer_which_axis ) * sensitivity )
pointer_y = iif( ( pointer_y ) < ( pointer_boundary_h ), _
( pointer_y ), ( pointer_boundary_h ) )
pointer_y = iif( ( pointer_y ) > ( 0 ), _
( pointer_y ), ( 0 ) )
end if
end sub
sub t_joystick.get_state( _
byval p_timer as double = timer() )
dim as long _i
local_timer = p_timer
result = getjoystick( id, button, temp_axis_x( 0 ), temp_axis_y( 0 ), _
temp_axis_x( 1 ), temp_axis_y( 1 ), _
temp_axis_x( 2 ), temp_axis_y( 2 ), _
temp_axis_x( 3 ), temp_axis_y( 3 ) )
if( result = 0 ) then
for _i = 0 to ubound( axis_a ) ' axis_x, axis_y, or axis_a all can be used here
if( ( ( temp_axis_x( _i ) * temp_axis_x( _i ) ) + ( temp_axis_y( _i ) * temp_axis_y( _i ) ) ) > deadzone ) then
axis_x( _i ) = temp_axis_x( _i )
axis_y( _i ) = temp_axis_y( _i )
else
axis_x( _i ) = 0
axis_y( _i ) = 0
end if
next _i
for _i = 0 to ubound( axis_a ) ' axis_x, axis_y, or axis_a all can be used here
'axis_a( _i ) = fast_atan2( axis_x( _i ), axis_y( _i ) )
axis_a( _i ) = atan2( axis_x( _i ), axis_y( _i ) )
next _i
_i = ubound( state )
do
if( button and ( 2 ^ _i ) ) then
if( state( _i ) = button_state.none ) then
if ( owner_drag = -1 ) then
owner_drag = _i
state( _i ) = button_state.press
hold_start_time( _i ) =local_timer
repeat_start_time( _i ) =local_timer
if( owner_double_press <> _i ) then
owner_double_press = _i
double_press_start_time( _i ) =local_timer
else
if( ( p_timer - double_press_start_time( _i ) ) < time_double_press ) then
double_press_x = pointer_x
double_press_y = pointer_y
state( _i ) = button_state.double_press
else
double_press_x = pointer_x
double_press_y = pointer_y
double_press_start_time( _i ) =local_timer
end if
end if
drag_dx = 0
drag_dy = 0
drag_sx = pointer_x
drag_sy = pointer_y
else
if( ( _i <> owner_drag ) ) then
' in drag state, this button press isn't the owner of the drag, so
' the button state gets set to void. the only way to clear the void
' state is to release. ending a drag will not clear another button's
' voided state.
'state( _i ) = button_state.void
state( _i ) = button_state.press
hold_start_time( _i ) =local_timer
repeat_start_time( _i ) =local_timer
if( owner_double_press <> _i ) then
owner_double_press = _i
double_press_start_time( _i ) =local_timer
else
if( ( p_timer - double_press_start_time( _i ) ) < time_double_press ) then
double_press_x = pointer_x
double_press_y = pointer_y
state( _i ) = button_state.double_press
else
double_press_x = pointer_x
double_press_y = pointer_y
double_press_start_time( _i ) =local_timer
end if
end if
end if
end if
else
if( owner_drag = _i ) then
drag_dx = pointer_x - drag_sx
drag_dy = pointer_y - drag_sy
end if
end if
else
if( state( _i ) = button_state.already_press ) then
state( _i ) = button_state.release
else
if( state( _i ) = button_state.already_release ) then
state( _i ) = button_state.none
if( owner_drag = _i ) then
owner_drag = -1
end if
else
if( state( _i ) = button_state.already_double_press ) then
state( _i ) = button_state.none
owner_drag = -1
owner_double_press = -1
else
if( state( _i ) = button_state.void ) then
state( _i ) = button_state.none
end if
end if
end if
end if
end if
_i -= 1
loop until( _i = -1 )
else
' result from getjoystick() is bad
end if
end sub
sub t_joystick.close_state()
dim as long _i
for _i = 0 to ubound( state )
if( state( _i ) = button_state.press ) then
state( _i ) = button_state.already_press
else
if( state( _i ) = button_state.release ) then
state( _i ) = button_state.already_release
else
if( state( _i ) = button_state.double_press ) then
state( _i ) = button_state.already_double_press
end if
end if
end if
next _i
end sub
function t_joystick.joystick() _
as boolean
dim as boolean _return
if( ( id < 0 ) or ( id > 15 ) ) then
_return = false
else
_return = true
end if
return _return
end function
function t_joystick.press( _
byval p_button as long ) _
as boolean
dim as boolean _return
if( state( p_button ) = button_state.press ) then
state( p_button ) = button_state.already_press
_return = true
else
_return = false
end if
return _return
end function
function t_joystick.double_press( _
byval p_button as long ) _
as boolean
dim as boolean _return
if( state( p_button ) = button_state.double_press ) then
state( p_button ) = button_state.already_double_press
_return = true
else
_return = false
end if
return _return
end function
function t_joystick.release( _
byval p_button as long ) _
as boolean
dim as boolean _return
if( state( p_button ) = button_state.release ) then
state( p_button ) = button_state.already_release
_return = true
else
_return = false
end if
return _return
end function
function t_joystick.halt( _
byval p_button as long, _
byval p_time as double = 0.0 ) _
as boolean
dim as boolean _return
if( ( state( p_button ) = button_state.press ) or _
( state( p_button ) = button_state.already_press ) ) then
if( p_time <> 0 ) then
if( ( local_timer - hold_start_time( p_button ) ) < p_time ) then
_return = true
else
_return = false
end if
else
_return = true
end if
else
_return = false
end if
return _return
end function
function t_joystick.hold( _
byval p_button as long, _
byval p_time as double = 0.0 ) _
as boolean
dim as boolean _return
if( ( state( p_button ) = button_state.press ) or _
( state( p_button ) = button_state.already_press ) ) then
if( p_time <> 0 ) then
if( ( local_timer - hold_start_time( p_button ) ) > p_time ) then
_return = true
else
_return = false
end if
else
_return = true
end if
else
_return = false
end if
return _return
end function
function t_joystick.repeat( _
byval p_button as long, _
byval p_time as double = 0.0 ) _
as boolean
dim as boolean _return
dim as double _time_difference
if( ( state( p_button ) = button_state.press ) or _
( state( p_button ) = button_state.already_press ) ) then
_time_difference = local_timer - repeat_start_time( p_button )
if( _time_difference > p_time ) then
repeat_start_time( p_button ) += _time_difference
_return = true
else
_return = false
end if
else
_return = false
end if
return _return
end function
function t_joystick.drag( _
byval p_button as long ) _
as boolean
return( hold( p_button ) and ( owner_drag = p_button ) )
end function
function t_joystick.drop( _
byval p_button as long ) _
as boolean
return( release( p_button ) and ( owner_drag = p_button ) )
end function
' ################################################################################ demo ####
type t_mouse
result as long
x as long
y as long
last_x as long
last_y as long
delta_x as long
delta_y as long
end type
type t_box
x as long
y as long
w as long
h as long
c as ulong
declare sub add_box( _
byval _x as long, _
byval _y as long )
declare sub draw_box( _
byval p_n as long )
end type
declare sub draw_pointer( _
byval p_x as single, _
byval p_y as single, _
byval p_r as long, _
byval p_c as ulong, _
byval p_b as boolean = false )
declare sub draw_joystick_stats( _
byref p_joystick as t_joystick )
dim as long screen_w = 1280
dim as long screen_h = 720
dim as double t1, timer_post
dim as long timer_post_avg = 1
dim box( 0 to 99 ) as t_box
dim as long number_of_boxes = 2
dim as long box_n
dim as long box_drag
dim as long temp
box_drag = -1
randomize()
for temp = 0 to number_of_boxes
box( temp ).add_box( ( ( rnd * 640 ) + 320 ), ( ( rnd * 360 ) + 180 ) )
next temp
dim as t_mouse m
dim as t_joystick j
screenres( screen_w, screen_h, 32 )
if( j.joystick() = true ) then
dim as boolean terminate = false
j.set_pointer_position( screen_w shr 1, screen_h shr 1 )
j.set_pointer_boundary( screen_w - 1, screen_h - 1 )
m.last_x = j.pointer_x
m.last_y = j.pointer_y
setmouse( j.pointer_x, j.pointer_y, 0 )
do while( not terminate )
t1 = timer()
j.get_state()
j.update_pointer_position()
m.result = getmouse( m.x, m.y )
if( m.result = 0 ) then
m.delta_x = m.x - m.last_x
m.delta_y = m.y - m.last_y
if( ( m.delta_x <> 0 ) or ( m.delta_y <> 0 ) ) then
m.last_x = m.x
m.last_y = m.y
j.set_pointer_position( m.x, m.y )
else
m.last_x = j.pointer_x
m.last_y = j.pointer_y
setmouse( j.pointer_x, j.pointer_y )
end if
end if
'if( j.joystick() = false ) then terminate = true
if( j.double_press( 2 ) ) then terminate = true
if( multikey( 1 ) ) then terminate = true
if( j.press( 0 ) ) then
for box_n = number_of_boxes to 0 step -1
if( ( j.pointer_x < ( box( box_n ).x + box( box_n ).w ) ) and _
( j.pointer_x > box( box_n ).x ) and _
( j.pointer_y < ( box( box_n ).y + box( box_n ).h ) ) and _
( j.pointer_y > box( box_n ).y ) ) then
box_drag = box_n
exit for
end if
next box_n
else
if( j.drop( 0 ) ) then
box_drag = -1
else
end if
end if
if( j.press( 1 ) ) then
number_of_boxes += 1
if( number_of_boxes > 99 ) then
number_of_boxes = 99
else
box( number_of_boxes ).add_box( j.pointer_x, j.pointer_y )
end if
end if
if( j.drag( 0 ) and ( box_drag <> -1 ) ) then
box( box_drag ).x += j.drag_dx
box( box_drag ).y += j.drag_dy
j.drag_sx += j.drag_dx
j.drag_sy += j.drag_dy
end if
screenlock()
cls
for box_n = 0 to number_of_boxes
box( box_n ).draw_box( box_n )
next box_n
draw_pointer( j.pointer_x, j.pointer_y, 5, rgb( 255, 255, 255 ), true )
draw_pointer( j.pointer_x + ( j.axis_x( 1 ) * 32 ), _
j.pointer_y + ( j.axis_y( 1 ) * 32 ), _
3, rgb( 255, 0, 0 ) )
draw_pointer( j.pointer_x + ( j.axis_x( 2 ) * 16 ), _
j.pointer_y + ( j.axis_y( 2 ) * 16 ), _
3, rgb( 0, 0, 255 ) )
draw_pointer( j.pointer_x + ( j.axis_x( 3 ) * 8 ), _
j.pointer_y + ( j.axis_y( 3 ) * 8 ), _
3, rgb( 0, 255, 0 ) )
draw_pointer( j.pointer_x, j.pointer_y, 3, rgb( 0, 0, 0 ) )
draw_joystick_stats( j )
draw string( 9, 701 ), " scene render time (ms) " & timer_post
draw string( 9, 710 ), "scene average time (ms) " & timer_post_avg
screenunlock()
j.close_state()
timer_post = ( timer() - t1 ) * 1000
timer_post_avg = ( timer_post_avg + timer_post ) / 2
sleep( 15 )
loop
else
draw string( 1, 1 ), "joystick required..."
sleep
end if
setmouse( ,, 1 )
sub t_box.add_box( _
byval _x as long, _
byval _y as long )
dim as long _temp
_temp = ( rnd * 50 ) + 75
x = _x - _temp
w = _temp + _temp
_temp = ( rnd * 50 ) + 75
y = _y - _temp
h = _temp + _temp
c = rgb( ( ( rnd * 191 ) + 64 ), ( ( rnd * 191 ) + 64 ), ( ( rnd * 191 ) + 64 ) )
end sub
sub t_box.draw_box( _
byval p_n as long )
line( x, y )-( x + w, y + h ), c, bf
line( x + 1, y + 1 )-( x + w - 1, y + h - 1 ), rgb( 0, 0, 0 ), b
draw string( x + 3, y + 3 ), str( "Box " & p_n ), rgb( 0, 0, 0 )
end sub
sub draw_pointer( _
byval p_x as single, _
byval p_y as single, _
byval p_r as long, _
byval p_c as ulong, _
byval p_b as boolean = false )
if( p_b = true ) then circle( p_x, p_y ), p_r + 1, rgb( 0, 0, 0 )
circle( p_x, p_y ), p_r, p_c,,,, f
end sub
sub draw_joystick_stats( _
byref p_joystick as t_joystick )
dim as long _i, _x, _y
_x = 9
_y = 1
draw string( _x, _y ), "getjoystick() data:", rgb( 255, 63, 63 ):_y += 9
with p_joystick
for _i = 0 to 3
_y += 9
draw string( _x, _y ), "axis " & _i & " ( " & .axis_x( _i ) & ", " & .axis_y( _i ) & " )"
next _i
_y += 9
for _i = 0 to 9
_y += 9
draw string( _x, _y ), "button 0" & _i & " " & cbool( .button and ( 1 shl _i ) )
next _i
for _i = 10 to 31
_y += 9
draw string( _x, _y ), "button " & _i & " " & cbool( .button and ( 1 shl _i ) )
next _i
_x = 1047
_y = 1
draw string( _x, _y ), " type t_joystick variables", rgb( 255, 63, 63 ): _y += 9
_y += 9
draw string( _x, _y ), " id " & .id: _y += 9
draw string( _x, _y ), " result " & .result: _y += 9
draw string( _x, _y ), " button " & .button: _y += 9
draw string( _x, _y ), " axis_a( 0 ) " & .axis_a( 0 ): _y += 9
draw string( _x, _y ), " axis_a( 1 ) " & .axis_a( 1 ): _y += 9
draw string( _x, _y ), " axis_a( 2 ) " & .axis_a( 2 ): _y += 9
draw string( _x, _y ), " axis_a( 3 ) " & .axis_a( 3 ): _y += 9
draw string( _x, _y ), " pointer_x " & .pointer_x: _y += 9
draw string( _x, _y ), " pointer_y " & .pointer_y: _y += 9
draw string( _x, _y ), " drag_sx " & .drag_sx: _y += 9
draw string( _x, _y ), " drag_sy " & .drag_sy: _y += 9
draw string( _x, _y ), " drag_dx " & .drag_dx: _y += 9
draw string( _x, _y ), " drag_dy " & .drag_dy: _y += 9
draw string( _x, _y ), " double_press_x " & .double_press_x: _y += 9
draw string( _x, _y ), " double_press_y " & .double_press_y: _y += 9
draw string( _x, _y ), "pointer_boundary_w " & .pointer_boundary_w: _y += 9
draw string( _x, _y ), "pointer_boundary_h " & .pointer_boundary_h: _y += 9
draw string( _x, _y ), "pointer_which_axis " & .pointer_which_axis: _y += 9
draw string( _x, _y ), " sensitivity " & .sensitivity: _y += 9
draw string( _x, _y ), " deadzone " & .deadzone: _y += 9
draw string( _x, _y ), " owner_drag " & .owner_drag: _y += 9
draw string( _x, _y ), "owner_double_press " & .owner_double_press: _y += 9
draw string( _x, _y ), " time_double_press " & .time_double_press: _y += 9
draw string( 485, 1 ), "( button 0 ) to drag boxes", rgb( 255, 127, 0 )
draw string( 485, 10 ), "( button 1 ) to add boxes", rgb( 255, 127, 0 )
draw string( 485, 19 ), "( button 2 ) double press to exit", rgb( 255, 127, 0 )
draw string( 485, 28 ), " ( escape ) to exit", rgb( 255, 127, 0 )
end with
end sub
Code: Select all
type t_fusion
as long j_id
as integer j_result, _
j_button
as single j_axis_x( any ), _
j_axis_y( any ), _
j_axis_a( any ), _
j_sensitivity, _
j_deadzone
as boolean j_axis_motion( any )
as integer m_result, _
m_button
as long m_x, _
m_y, _
m_w
as single m_axis_x, _
m_axis_y, _
m_axis_a, _
m_axis_w
as single p_x, _
p_y, _
p_a, _
p_drag_sx, _
p_drag_sy, _
p_drag_dx, _
p_drag_dy
as long p_boundary_x, _
p_boundary_y, _
p_boundary_w, _
p_boundary_h, _
p_j_which_axis, _
owner_drag, _
owner_double_press
as double j_time_double_press, _
m_time_double_press, _
k_time_double_press
as boolean use_joystick_axis( any )
as boolean use_joystick
as boolean use_mouse
as boolean use_keyboard
as long num_j_axis
as long num_j_buttons
as long num_m_buttons
as long num_k_keys
as long m_offset
as long k_offset
as long b( any )
as long k( any )
as double local_timer, _
local_timer_difference, _
hold_start_time( any ), _
repeat_start_time( any ), _
double_press_start_time( any )
enum button_state
none = 0
press = 1
already_press = 2
release = 3
already_release = 4
double_press = 5
already_double_press = 6
end enum
as byte state( any )
declare constructor()
declare destructor()
declare sub hide_mouse()
declare sub show_mouse()
declare sub set_pointer_position( _
byval v_x as single, _
byval v_y as single )
declare sub set_pointer_boundary( _
byval v_x as long, _
byval v_y as long, _
byval v_w as long, _
byval v_h as long )
declare sub update_pointer_position()
declare sub get_state( _
byval v_timer as double = timer() )
declare sub close_state()
declare sub correct_axis( _
byval v_which as long = -1 )
declare function joystick() _
as boolean
declare function press( _
byval v_button as long ) _
as boolean
declare function double_press( _
byval v_button as long ) _
as boolean
declare function release( _
byval v_button as long ) _
as boolean
declare function halt( _
byval v_button as long, _
byval v_time as double = 0.0 ) _
as boolean
declare function hold( _
byval v_button as long, _
byval v_time as double = 0.0 ) _
as boolean
declare function repeat( _
byval v_button as long, _
byval v_time as double = 0.0 ) _
as boolean
declare function drag( _
byval v_button as long ) _
as boolean
declare function drop( _
byval v_button as long ) _
as boolean
end type
constructor t_fusion()
dim as long _n
' Cycle backwards through all possible joystick identities
' and assign j_id to the lowest identity and assign true
' to use_joystick. If there aren't joystick identities
' found, then j_id is assigned to -1 and use_joystick
' is assigned false.
j_id = -1
use_joystick = false
for _n = 15 to 0 step( -1 )
j_result = getjoystick( _n )
if( j_result = 0 ) then
j_id = _n
use_joystick = true
end if
next _n
' Use getmouse() to find out if there is a mouse available.
' If there is a mouse true is assigned to use_mouse.
' Otherwise, use_mouse is assigned false.
use_mouse = false
m_result = getmouse( m_x, m_y )
if( m_result = 0 ) then use_mouse = true
' Set use_keyboard to true by default.
use_keyboard = true
' Default pointer position and assign which joystick axis
' is responsible for moving the pointer.
p_x = 0
p_y = 0
p_a = 0
p_boundary_x = 0
p_boundary_y = 0
p_boundary_w = 0
p_boundary_h = 0
p_j_which_axis = 0
' These two variables hold which button is currently in
' drag or double press mode. Assign them -1 here.
owner_drag = -1
owner_double_press = -1
' These next variables are multipliers for how much
' the correlating axis change the pointer position.
j_sensitivity = 250
' This deadzone value is a squared hypotenuse length
' to be checked against the joystick axis deltas. This
' is used to prevent micro deltas that can occur even
' when the joystick is at rest.
j_deadzone = 0.001
' Double press time is the time window that two presses
' much occur to activate double press. The value is in
' seconds, so a default of 0.2 = 200 milliseconds.
j_time_double_press = 0.2
m_time_double_press = 0.2
k_time_double_press = 0.2
' Tell our class how many buttons and how many axis so
' we can redim our appropriate variables.
num_j_axis = 4
num_j_buttons = 12
num_m_buttons = 3
num_k_keys = 128
' Joystick,mouse and key button states are stacked in that
' order. Because of this, the following offset variables
' provide the starting array position for each.
m_offset = num_j_buttons
k_offset = num_j_buttons + num_m_buttons
' Create an record of mouse buttons that stores the address
' of each within the state() array.
redim b( 0 to 2 )
b( 0 ) = m_offset
b( 1 ) = m_offset + 1
b( 2 ) = m_offset + 2
' Create an array that takes a keyboard scancode and returns
' it's address in the state() array.
redim k( 1 to 100 )
for _n = 1 to 100
k( _n ) = _n + k_offset
next _n
' Subtract 1 from our buttons and axis numbers because
' our array numbering starts at zero.
num_j_axis -= 1
num_j_buttons -= 1
num_m_buttons -= 1
num_k_keys -= 1
redim j_axis_x( 0 to num_j_axis )
redim j_axis_y( 0 to num_j_axis )
redim j_axis_a( 0 to num_j_axis )
redim j_axis_motion( 0 to num_j_axis )
redim use_joystick_axis( 0 to num_j_axis )
j_result = getjoystick( j_id, j_button, _
j_axis_x( 0 ), j_axis_y( 0 ), _
j_axis_x( 1 ), j_axis_y( 1 ), _
j_axis_x( 2 ), j_axis_y( 2 ), _
j_axis_x( 3 ), j_axis_y( 3 ) )
for _n = 0 to num_j_axis
if( j_axis_x( _n ) <> -1000 ) then
use_joystick_axis( _n ) = true
else
use_joystick_axis( _n ) = false
end if
next _n
redim hold_start_time( 0 to ( num_j_buttons + num_m_buttons + num_k_keys + 2 ) )
redim repeat_start_time( 0 to ( num_j_buttons + num_m_buttons + num_k_keys + 2 ) )
redim double_press_start_time( 0 to ( num_j_buttons + num_m_buttons + num_k_keys + 2 ) )
redim state( 0 to ( num_j_buttons + num_m_buttons + num_k_keys + 2 ) )
' This variable keeps track of how much time has passed since
' the previous close_state(). This variable is useful for
' time based physics.
local_timer_difference = 0
end constructor
destructor t_fusion()
end destructor
sub t_fusion.hide_mouse()
setmouse( ,, 0 )
end sub
sub t_fusion.show_mouse()
setmouse( ,, 1 )
end sub
sub t_fusion.set_pointer_position( _
byval v_x as single, _
byval v_y as single )
p_x = v_x
p_y = v_y
end sub
sub t_fusion.set_pointer_boundary( _
byval v_x as long, _
byval v_y as long, _
byval v_w as long, _
byval v_h as long )
p_boundary_x = v_x
p_boundary_y = v_y
p_boundary_w = v_w
p_boundary_h = v_h
end sub
sub t_fusion.update_pointer_position()
if( use_mouse = true ) then
if( m_result = 0 ) then
p_x = m_x + ( j_axis_x( p_j_which_axis ) * j_sensitivity * local_timer_difference )
p_y = m_y + ( j_axis_y( p_j_which_axis ) * j_sensitivity * local_timer_difference )
p_x = iif( ( p_x ) < ( p_boundary_w ), _
( p_x ), ( p_boundary_w ) )
p_x = iif( ( p_x ) > ( p_boundary_x ), _
( p_x ), ( p_boundary_x ) )
p_y = iif( ( p_y ) < ( p_boundary_h ), _
( p_y ), ( p_boundary_h ) )
p_y = iif( ( p_y ) > ( p_boundary_y ), _
( p_y ), ( p_boundary_y ) )
setmouse( p_x, p_y )
m_x = p_x
m_y = p_y
else
p_x += ( j_axis_x( p_j_which_axis ) * j_sensitivity * local_timer_difference )
p_y += ( j_axis_y( p_j_which_axis ) * j_sensitivity * local_timer_difference )
p_x = iif( ( p_x ) < ( p_boundary_w ), _
( p_x ), ( p_boundary_w ) )
p_x = iif( ( p_x ) > ( p_boundary_x ), _
( p_x ), ( p_boundary_x ) )
p_y = iif( ( p_y ) < ( p_boundary_h ), _
( p_y ), ( p_boundary_h ) )
p_y = iif( ( p_y ) > ( p_boundary_y ), _
( p_y ), ( p_boundary_y ) )
end if
else
if( use_joystick = true ) then
p_x += ( j_axis_x( p_j_which_axis ) * j_sensitivity * local_timer_difference )
p_y += ( j_axis_y( p_j_which_axis ) * j_sensitivity * local_timer_difference )
p_x = iif( ( p_x ) < ( p_boundary_w ), _
( p_x ), ( p_boundary_w ) )
p_x = iif( ( p_x ) > ( p_boundary_x ), _
( p_x ), ( p_boundary_x ) )
p_y = iif( ( p_y ) < ( p_boundary_h ), _
( p_y ), ( p_boundary_h ) )
p_y = iif( ( p_y ) > ( p_boundary_y ), _
( p_y ), ( p_boundary_y ) )
end if
end if
end sub
sub t_fusion.get_state( _
byval v_timer as double = timer() )
dim as long _i
local_timer_difference += ( v_timer - local_timer )
local_timer = v_timer
if( use_joystick = true ) then
dim as single temp_axis_x( 0 to 3 ), _
temp_axis_y( 0 to 3 )
j_result = getjoystick( j_id, j_button, _
temp_axis_x( 0 ), temp_axis_y( 0 ), _
temp_axis_x( 1 ), temp_axis_y( 1 ), _
temp_axis_x( 2 ), temp_axis_y( 2 ), _
temp_axis_x( 3 ), temp_axis_y( 3 ) )
if( j_result = 0 ) then
_i = num_j_axis
do
if( use_joystick_axis( _i ) = true ) then
if( j_deadzone < ( ( temp_axis_x( _i ) * temp_axis_x( _i ) ) + ( temp_axis_y( _i ) * temp_axis_y( _i ) ) ) ) then
j_axis_motion( _i ) = true
j_axis_x( _i ) = temp_axis_x( _i )
j_axis_y( _i ) = temp_axis_y( _i )
'j_axis_a( _i ) = fast_atan2( j_axis_y( _i ), j_axis_x( _i ) ) ' ###############################
j_axis_a( _i ) = atan2( j_axis_y( _i ), j_axis_x( _i ) ) ' #####################################
else
j_axis_motion( _i ) = false
j_axis_x( _i ) = 0
j_axis_y( _i ) = 0
end if
else
' not using this joystick axis
end if
_i -= 1
loop until( _i = -1 )
_i = num_j_buttons
do
if( j_button and ( 2 ^ _i ) ) then
if( state( _i ) = button_state.none ) then
if( owner_drag = -1 ) then
owner_drag = _i
state( _i ) = button_state.press
hold_start_time( _i ) = local_timer
repeat_start_time( _i ) = local_timer
if( owner_double_press <> _i ) then
owner_double_press = _i
double_press_start_time( _i ) = local_timer
else
if( ( local_timer - double_press_start_time( _i ) ) < j_time_double_press ) then
state( _i ) = button_state.double_press
else
double_press_start_time( _i ) = local_timer
end if
end if
p_drag_dx = 0
p_drag_dy = 0
p_drag_sx = p_x
p_drag_sy = p_y
else
if( ( _i <> owner_drag ) ) then
state( _i ) = button_state.press
hold_start_time( _i ) = local_timer
repeat_start_time( _i ) = local_timer
if( owner_double_press <> _i ) then
owner_double_press = _i
double_press_start_time( _i ) = local_timer
else
if( ( local_timer - double_press_start_time( _i ) ) < j_time_double_press ) then
state( _i ) = button_state.double_press
else
double_press_start_time( _i ) = local_timer
end if
end if
end if
end if
else
if( owner_drag = _i ) then
p_drag_dx = p_x - p_drag_sx
p_drag_dy = p_y - p_drag_sy
end if
end if
else
if( state( _i ) = button_state.already_press ) then
state( _i ) = button_state.release
else
if( state( _i ) = button_state.already_release ) then
state( _i ) = button_state.none
if( owner_drag = _i ) then
owner_drag = -1
end if
else
if( state( _i ) = button_state.already_double_press ) then
state( _i ) = button_state.release
end if
end if
end if
end if
_i -= 1
loop until( _i = -1 )
else
' j_result is bad
end if
end if
if( use_mouse = true ) then
dim as long temp_x, _
temp_y, _
temp_w, _
temp_b
m_result = getmouse( temp_x, temp_y, temp_w, temp_b )
if( m_result = 0 ) then
m_axis_x = temp_x - m_x
m_axis_y = temp_y - m_y
m_axis_w = temp_w - m_w
m_x = temp_x
m_y = temp_y
'm_w = temp_w
'm_axis_a = fast_atan2( m_axis_y, m_axis_x )
m_axis_a = atan2( m_axis_y, m_axis_x )
m_button = temp_b
_i = m_offset + num_m_buttons
do
if( m_button and ( 2 ^ ( _i - m_offset ) ) ) then
if( state( _i ) = button_state.none ) then
if( owner_drag = -1 ) then
owner_drag = _i
state( _i ) = button_state.press
hold_start_time( _i ) = local_timer
repeat_start_time( _i ) = local_timer
if( owner_double_press <> _i ) then
owner_double_press = _i
double_press_start_time( _i ) = local_timer
else
if( ( local_timer - double_press_start_time( _i ) ) < m_time_double_press ) then
state( _i ) = button_state.double_press
else
double_press_start_time( _i ) = local_timer
end if
end if
p_drag_dx = 0
p_drag_dy = 0
p_drag_sx = p_x
p_drag_sy = p_y
else
if( ( _i <> owner_drag ) ) then
state( _i ) = button_state.press
hold_start_time( _i ) = local_timer
repeat_start_time( _i ) = local_timer
if( owner_double_press <> _i ) then
owner_double_press = _i
double_press_start_time( _i ) = local_timer
else
if( ( local_timer - double_press_start_time( _i ) ) < m_time_double_press ) then
state( _i ) = button_state.double_press
else
double_press_start_time( _i ) = local_timer
end if
end if
end if
end if
else
if( owner_drag = _i ) then
p_drag_dx = p_x - p_drag_sx
p_drag_dy = p_y - p_drag_sy
end if
end if
else
if( state( _i ) = button_state.already_press ) then
state( _i ) = button_state.release
else
if( state( _i ) = button_state.already_release ) then
state( _i ) = button_state.none
if( owner_drag = _i ) then
owner_drag = -1
end if
else
if( state( _i ) = button_state.already_double_press ) then
state( _i ) = button_state.release
end if
end if
end if
end if
_i -= 1
loop until( _i = num_j_buttons )
else
' m_result is bad
m_axis_x = 0
m_axis_y = 0
m_axis_w = 0
end if
end if
if( use_keyboard = true ) then
_i = k_offset + num_k_keys
do
if( multikey( _i - k_offset ) ) then
if( state( _i ) = button_state.none ) then
state( _i ) = button_state.press
hold_start_time( _i ) = local_timer
repeat_start_time( _i ) = local_timer
if( owner_double_press <> _i ) then
owner_double_press = _i
double_press_start_time( _i ) = local_timer
else
if( ( local_timer - double_press_start_time( _i ) ) < k_time_double_press ) then
state( _i ) = button_state.double_press
else
double_press_start_time( _i ) = local_timer
end if
end if
end if
else
if( state( _i ) = button_state.already_press ) then
state( _i ) = button_state.release
else
if( state( _i ) = button_state.already_release ) then
state( _i ) = none
else
if( state( _i ) = button_state.already_double_press ) then
owner_double_press = -1
state( _i ) = button_state.release
end if
end if
end if
end if
_i -= 1
loop until( _i = ( m_offset + num_m_buttons ) )
end if
end sub
sub t_fusion.close_state()
dim as long _i
local_timer_difference = 0
for _i = 0 to ubound( state )
if( state( _i ) = button_state.press ) then
state( _i ) = button_state.already_press
else
if( state( _i ) = button_state.release ) then
state( _i ) = button_state.already_release
else
if( state( _i ) = button_state.double_press ) then
state( _i ) = button_state.already_double_press
end if
end if
end if
next _i
end sub
sub t_fusion.correct_axis( _
byval v_which as long = -1 )
dim as single _distance
if( v_which = -1 ) then
dim as long _i
for _i = 0 to num_j_axis
if( j_axis_x( _i ) <> -1000 ) then
_distance = ( j_axis_x( _i ) * j_axis_x( _i ) ) + ( j_axis_y( _i ) * j_axis_y( _i ) )
if( _distance > 1 ) then
j_axis_x( _i ) = cos( j_axis_a( _i ) )
j_axis_y( _i ) = sin( j_axis_a( _i ) )
end if
end if
next _i
else
if( j_axis_x( v_which ) <> -1000 ) then
_distance = ( j_axis_x( v_which ) * j_axis_x( v_which ) ) + ( j_axis_y( v_which ) * j_axis_y( v_which ) )
if( _distance > 1 ) then
j_axis_x( v_which ) = cos( j_axis_a( v_which ) )
j_axis_y( v_which ) = sin( j_axis_a( v_which ) )
end if
end if
end if
end sub
function t_fusion.joystick() _
as boolean
dim as boolean _return
if( ( j_id < 0 ) or ( j_id > 15 ) ) then
_return = false
else
_return = true
end if
return _return
end function
function t_fusion.press( _
byval v_button as long ) _
as boolean
dim as boolean _return
if( state( v_button ) = button_state.press ) then
state( v_button ) = button_state.already_press
_return = true
else
_return = false
end if
return _return
end function
function t_fusion.double_press( _
byval v_button as long ) _
as boolean
dim as boolean _return
if( state( v_button ) = button_state.double_press ) then
state( v_button ) = button_state.already_double_press
_return = true
else
_return = false
end if
return _return
end function
function t_fusion.release( _
byval v_button as long ) _
as boolean
dim as boolean _return
if( state( v_button ) = button_state.release ) then
state( v_button ) = button_state.already_release
_return = true
else
_return = false
end if
return _return
end function
function t_fusion.halt( _
byval v_button as long, _
byval v_time as double = 0.0 ) _
as boolean
dim as boolean _return
if( ( state( v_button ) = button_state.press ) or _
( state( v_button ) = button_state.already_press ) ) then
if( v_time <> 0 ) then
if( ( local_timer - hold_start_time( v_button ) ) < v_time ) then
_return = true
else
_return = false
end if
else
_return = true
end if
else
_return = false
end if
return _return
end function
function t_fusion.hold( _
byval v_button as long, _
byval v_time as double = 0.0 ) _
as boolean
dim as boolean _return
if( ( state( v_button ) = button_state.press ) or _
( state( v_button ) = button_state.double_press ) or _
( state( v_button ) = button_state.already_press ) or _
( state( v_button ) = button_state.already_double_press ) ) then
if( v_time <> 0 ) then
if( ( local_timer - hold_start_time( v_button ) ) > v_time ) then
_return = true
else
_return = false
end if
else
_return = true
end if
else
_return = false
end if
return _return
end function
function t_fusion.repeat( _
byval v_button as long, _
byval v_time as double = 0.0 ) _
as boolean
dim as boolean _return
if( ( state( v_button ) = button_state.press ) or _
( state( v_button ) = button_state.double_press ) ) then
_return = true
else
if( ( state( v_button ) = button_state.already_press ) or _
( state( v_button ) = button_state.already_double_press ) ) then
dim as double _time_difference
_time_difference = local_timer - repeat_start_time( v_button )
if( _time_difference > v_time ) then
repeat_start_time( v_button ) += _time_difference
_return = true
else
_return = false
end if
else
_return = false
end if
end if
return _return
end function
function t_fusion.drag( _
byval v_button as long ) _
as boolean
return( hold( v_button ) and ( owner_drag = v_button ) )
end function
function t_fusion.drop( _
byval v_button as long ) _
as boolean
return( release( v_button ) and ( owner_drag = v_button ) )
end function
' ########################################################################################################
type t_box
x as long
y as long
w as long
h as long
c as ulong
declare sub add_box( _
byval v_x as long, _
byval v_y as long )
declare sub draw_box( _
byval v_n as long )
end type
declare sub draw_pointer( _
byval v_x as single, _
byval v_y as single, _
byval v_r as long, _
byval v_c as ulong, _
byval v_b as boolean = false )
declare sub draw_joystick_stats( _
byref v_fusion as t_fusion )
dim as t_fusion fusion
'fusion.use_mouse = false
dim as long screen_w = 1280
dim as long screen_h = 720
dim as double t1, timer_post
dim as long timer_post_avg = 1
dim box( 0 to 99 ) as t_box
dim as long number_of_boxes = 2
dim as long box_n
dim as long box_drag
dim as long temp
box_drag = -1
randomize()
for temp = 0 to number_of_boxes
box( temp ).add_box( ( ( rnd * ( screen_w shr 1 ) ) + ( screen_w shr 2 ) ), ( ( rnd * ( screen_h shr 1 ) ) + ( screen_h shr 2 ) ) )
next temp
screenres( screen_w, screen_h, 32 )
fusion.hide_mouse()
if( fusion.use_joystick = true ) then
dim as boolean terminate = false
fusion.set_pointer_position( screen_w shr 1, screen_h shr 1 )
fusion.set_pointer_boundary( 0, 0, screen_w - 1, screen_h - 1 )
do while( not terminate )
t1 = timer()
fusion.get_state()
fusion.correct_axis()
fusion.update_pointer_position()
'if( fusion.double_press( 0 + fusion.m_offset ) ) then terminate = true
if( fusion.double_press( 2 ) ) then terminate = true
if( fusion.press( 1 + fusion.k_offset ) ) then terminate = true ' escape key
if( ( fusion.press( 0 ) or fusion.double_press( 0 ) ) or ( fusion.press( fusion.m_offset ) or fusion.double_press( fusion.m_offset ) ) ) then
for box_n = number_of_boxes to 0 step -1
if( ( fusion.p_x < ( box( box_n ).x + box( box_n ).w ) ) and _
( fusion.p_x > box( box_n ).x ) and _
( fusion.p_y < ( box( box_n ).y + box( box_n ).h ) ) and _
( fusion.p_y > box( box_n ).y ) ) then
box_drag = box_n
exit for
end if
next box_n
else
if( ( fusion.drop( 0 ) ) or ( fusion.drop( fusion.m_offset ) ) ) then
box_drag = -1
else
end if
end if
if( ( fusion.press( 1 ) ) or ( fusion.press( fusion.m_offset + 1 ) ) ) then
number_of_boxes += 1
if( number_of_boxes > 99 ) then
number_of_boxes = 99
else
box( number_of_boxes ).add_box( fusion.p_x, fusion.p_y )
end if
end if
if( ( fusion.drag( 0 ) ) or ( fusion.drag( fusion.m_offset ) ) ) then
if( box_drag <> -1 ) then
box( box_drag ).x += fusion.p_drag_dx
box( box_drag ).y += fusion.p_drag_dy
fusion.p_drag_sx += fusion.p_drag_dx
fusion.p_drag_sy += fusion.p_drag_dy
end if
end if
screenlock()
cls
for box_n = 0 to number_of_boxes
box( box_n ).draw_box( box_n )
next box_n
draw_pointer( fusion.p_x, fusion.p_y, 5, rgb( 255, 255, 255 ), true )
draw_pointer( fusion.p_x + ( fusion.j_axis_x( 1 ) * 24 ), _
fusion.p_y + ( fusion.j_axis_y( 1 ) * 24 ), _
3, rgb( 255, 0, 0 ) )
draw_pointer( fusion.p_x + ( fusion.j_axis_x( 2 ) * 16 ), _
fusion.p_y + ( fusion.j_axis_y( 2 ) * 16 ), _
3, rgb( 0, 0, 255 ) )
draw_pointer( fusion.p_x + ( fusion.j_axis_x( 3 ) * 8 ), _
fusion.p_y + ( fusion.j_axis_y( 3 ) * 8 ), _
3, rgb( 0, 255, 0 ) )
draw_pointer( fusion.p_x, fusion.p_y, 3, rgb( 0, 0, 0 ) )
draw_joystick_stats( fusion )
draw string( 9, 701 ), " scene render time (ms) " & timer_post
draw string( 9, 710 ), "scene average time (ms) " & timer_post_avg
screenunlock()
fusion.close_state()
timer_post = ( timer() - t1 ) * 1000
timer_post_avg = ( timer_post_avg + timer_post ) / 2
sleep( 15 )
loop
else
draw string( 1, 1 ), "joystick required..."
sleep
end if
fusion.show_mouse()
sub t_box.add_box( _
byval _x as long, _
byval _y as long )
dim as long _temp
_temp = ( rnd * 50 ) + 75
x = _x - _temp
w = _temp + _temp
_temp = ( rnd * 50 ) + 75
y = _y - _temp
h = _temp + _temp
c = rgb( ( ( rnd * 191 ) + 64 ), ( ( rnd * 191 ) + 64 ), ( ( rnd * 191 ) + 64 ) )
end sub
sub t_box.draw_box( _
byval p_n as long )
line( x, y )-( x + w, y + h ), c, bf
line( x + 1, y + 1 )-( x + w - 1, y + h - 1 ), rgb( 0, 0, 0 ), b
draw string( x + 3, y + 3 ), str( "Box " & p_n ), rgb( 0, 0, 0 )
end sub
sub draw_pointer( _
byval p_x as single, _
byval p_y as single, _
byval p_r as long, _
byval p_c as ulong, _
byval p_b as boolean = false )
if( p_b = true ) then circle( p_x, p_y ), p_r + 1, rgb( 0, 0, 0 )
circle( p_x, p_y ), p_r, p_c,,,, f
end sub
sub draw_joystick_stats( _
byref v_fusion as t_fusion )
dim as long _i, _x, _y
_x = 9
_y = 1
draw string( _x, _y ), "getjoystick() data:", rgb( 255, 63, 63 ):_y += 9
with v_fusion
for _i = 0 to 3
_y += 9
draw string( _x, _y ), "axis " & _i & " ( " & .j_axis_x( _i ) & ", " & .j_axis_y( _i ) & " )"
next _i
_y += 9
for _i = 0 to 9
_y += 9
draw string( _x, _y ), "button 0" & _i & " " & cbool( .j_button and ( 1 shl _i ) )
next _i
for _i = 10 to 31
_y += 9
draw string( _x, _y ), "button " & _i & " " & cbool( .j_button and ( 1 shl _i ) )
next _i
_x = 1049
_y = 1
draw string( _x, _y ), " joystick variables", rgb( 255, 63, 63 ): _y += 9
_y += 9
draw string( _x, _y ), " j_id " & .j_id: _y += 9
draw string( _x, _y ), " j_result " & .j_result: _y += 9
draw string( _x, _y ), " j_button " & .j_button: _y += 9
draw string( _x, _y ), "use_joystick_axis( 0 ) " & .use_joystick_axis( 0 ): _y += 9
draw string( _x, _y ), "use_joystick_axis( 1 ) " & .use_joystick_axis( 1 ): _y += 9
draw string( _x, _y ), "use_joystick_axis( 2 ) " & .use_joystick_axis( 2 ): _y += 9
draw string( _x, _y ), "use_joystick_axis( 3 ) " & .use_joystick_axis( 3 ): _y += 9
draw string( _x, _y ), " j_axis_a( 0 ) " & .j_axis_a( 0 ): _y += 9
draw string( _x, _y ), " j_axis_a( 1 ) " & .j_axis_a( 1 ): _y += 9
draw string( _x, _y ), " j_axis_a( 2 ) " & .j_axis_a( 2 ): _y += 9
draw string( _x, _y ), " j_axis_a( 3 ) " & .j_axis_a( 3 ): _y += 9
draw string( _x, _y ), " p_x " & .p_x: _y += 9
draw string( _x, _y ), " p_y " & .p_y: _y += 9
draw string( _x, _y ), " p_drag_sx " & .p_drag_sx: _y += 9
draw string( _x, _y ), " p_drag_sy " & .p_drag_sy: _y += 9
draw string( _x, _y ), " p_drag_dx " & .p_drag_dx: _y += 9
draw string( _x, _y ), " p_drag_dy " & .p_drag_dy: _y += 9
draw string( _x, _y ), " p_boundary_x " & .p_boundary_w: _y += 9
draw string( _x, _y ), " p_boundary_y " & .p_boundary_h: _y += 9
draw string( _x, _y ), " p_boundary_w " & .p_boundary_w: _y += 9
draw string( _x, _y ), " p_boundary_h " & .p_boundary_h: _y += 9
draw string( _x, _y ), " p_j_which_axis " & .p_j_which_axis: _y += 9
draw string( _x, _y ), " j_sensitivity " & .j_sensitivity: _y += 9
draw string( _x, _y ), " j_deadzone " & .j_deadzone: _y += 9
draw string( _x, _y ), " owner_drag " & .owner_drag: _y += 9
draw string( _x, _y ), " owner_double_press " & .owner_double_press: _y += 9
draw string( _x, _y ), " j_time_double_press " & .j_time_double_press: _y += 9
draw string( 485, 1 ), "( button 0 ) to drag boxes", rgb( 255, 127, 0 )
draw string( 485, 10 ), "( button 1 ) to add boxes", rgb( 255, 127, 0 )
draw string( 485, 19 ), "( button 2 ) double press to exit", rgb( 255, 127, 0 )
draw string( 485, 28 ), " ( escape ) to exit", rgb( 255, 127, 0 )
end with
end sub