I made this to learn a bit about trigonometry and am hoping to share this so that someone else might find interest in trig. The FreeBasic manual was very helpful to me. Code criticism is welcome.
edit -
- frame rate controller that accounts for skipped frames
- custom line & arc color fading functions
- fast cos, sin, & atan2 functions
- screen scaling
Code: Select all
' ... top down tank controls ...
'
' this demonstration shows player movement relative to the
' mouse position.
'
' _right_mouse_button_ to enable tank movement
'
' _wasd_ or _arrows_ move player
' _shift_ fast speed
' _control_ slow speed
' _escape_ or _q_ to exit
#define rgb_r( c ) ( culng( c ) shr 16 and 255 )
#define rgb_g( c ) ( culng( c ) shr 8 and 255 )
#define rgb_b( c ) ( culng( c ) and 255 )
#define c_black rgb( 0, 0, 0 )
#define c_fuchsia rgb( 255, 0, 255 )
#define c_player rgb( 159, 63, 63 )
#define c_tile rgb( 7, 7, 7 )
#define c_path_dark rgb( 15, 15, 7 )
#define c_path_light rgb( 127, 63, 31 )
#define c_strafe_border rgb( 63, 0, 0 )
#define negative_pi -3.141593
#define negative_pi_half -1.570796
#define radian 0.01745329
#define cos_45_over_pi 0.2250791
#define fast_atan2_const 0.2808722
#define four_over_pi_squared 0.4052847
#define cos_45 0.7071068
'#define sin_45 0.7071068
#define four_over_pi 1.273239
#define pi_half 1.570796
#define pi 3.141593
#define tau 6.283185
#define pathway_dist 37
#define pathway_dist_diag ( pathway_dist * cos_45 )
#define fb_windowed &h00 ' screencontrol flags
#define fb_fullscreen &h01
#define fb_GDI "GDI"
#define fb_DirectX "DirectX"
#define source_w 640
#define source_h 360
#define sixteen_bit_max 65536
#include "fbgfx.bi"
type t_image_old_header field = 1
bpp as ushort
w as ushort
h as ushort
end type
type t_image field = 1
union
old as t_image_old_header
old_type as ulong
end union
bpp as long
w as ulong
h as ulong
p as ulong
r( 1 to 12 ) as ubyte
end type
type t_display
sw as long ' source width
sh as long ' source height
sp as t_image ptr
m as long ' resolution multiplier
ss as integer ' scale step
sf as integer ' screen flag
dr( 0 to 1 ) as integer
rl( 1 to 6, 0 to 1 ) as integer
w as long
h as long
dp as long
bpp as long
p as long
r as long
dn as string
end type
type t_player
tv as single ' temporary
tvd as single
x as single ' screen coordinates
y as single
v as single ' movement speed
vd as single ' movement speed for diagonal
ms as single ' maximum tank strafe circle angle change speed
end type
type t_mouse
tx as long ' temporary
ty as long
tb as long
x as long ' screen coordinates
y as long
b as long ' button state
r as long ' getmouse() result
end type
type t_player_to_mouse
tx as single ' temporary
ty as single
tz as single
ta as single
dx as single ' deltas
dy as single
z as single ' distance
a as single ' angle of player to mouse in radians
end type
type t_frame_rate_control
kmj_fps_l as long ' fps limit # keyboard mouse joystick = kmj
kmj_fr as double ' frame resolution
kmj_ft_p as double ' frame timer previous
kmj_ct_d as double ' cycle timer difference
kmj_ct_p as double 'cycle timer previous
kmj_ct as double ' cycle timer
kmj_fps as long ' frame counter sum
kmj_fc as long ' frame counter
gfx_fps_l as long ' fps limit
gfx_fr as double ' frame resolution
gfx_ft_p as double ' frame timer previous
gfx_ct_d as double ' cycle timer difference
gfx_ct_p as double 'cycle timer previous
gfx_ct as double ' cycle timer
gfx_fps as long ' frame counter sum
gfx_fc as long ' frame counter
st_d as long ' sleep time difference
st_p as long ' sleep time previous
st as long ' sleep time
fs as ubyte ' frames skipped
render as boolean
end type
dim shared d as t_display
dim shared p as t_player
dim shared m as t_mouse
dim shared pm as t_player_to_mouse
dim shared frc as t_frame_rate_control
declare sub init_display( _
byval _m as byte = -1, _
byval _f as long = -1, _
byval _dn as string = "" )
declare sub destroy_display()
declare sub clear_buffer_display()
declare sub scale_step_display()
declare sub flip_display()
declare sub init_frame_rate_control( _
byval _gfx_l as long, _
byval _kmj_l as long )
declare sub init_player( _
byval _x as single, _
byval _y as single, _
byval _v as single, _
byval _ms as single )
declare sub init_mouse()
declare sub init_player_to_mouse()
declare function set_timer alias "timeBeginPeriod" ( _
as ulong = 1 ) _
as long
declare function release_timer alias "timeEndPeriod" ( _
as ulong = 1 ) _
as long
declare sub start_frame_rate_control()
declare sub regulate_frame_rate_control()
declare sub release_frame_rate_control()
declare sub simulate_lag()
declare sub update_mouse()
declare sub calc_player_to_mouse()
declare sub move_player()
declare sub draw_player_movement_pathways()
declare sub draw_player_movement_pathways_fade()
declare sub draw_player_strafe_delta_border()
declare sub draw_tiles()
declare sub draw_player()
declare sub draw_line( _
byval _x1 as long, _
byval _y1 as long, _
byval _x2 as long, _
byval _y2 as long, _
byval _c as long )
declare sub draw_circle( _
byval _x as long, _
byval _y as long, _
byval _r as long, _
byval _c as long )
declare sub draw_line_fade( _
byval _x1 as long, _
byval _y1 as long, _
byval _x2 as long, _
byval _y2 as long, _
byval _c1 as long, _
byval _c2 as long )
declare sub draw_arc_fade( _
byval _x as long, _
byval _y as long, _
byval _r as long, _
byval _a1 as single, _
byval _a2 as single, _
byval _c1 as long, _
byval _c2 as long )
declare sub pset_large( _
byval _x as long, _
byval _y as long, _
byval _c as long )
declare function fast_sin( _
byval _n as single ) _
as single
declare function fast_cos( _
byval _n as single ) _
as single
declare function fast_atan2( _
byval _y as single, _
byval _x as single )_
as single
' ____________
'__________________________________________________________________________________________/ main \
'
'init_display( 3, fb_fullscreen, "DirectX" ) ' pass 3x scale 1920x1080, fullscreen, DirectX
init_display()
init_frame_rate_control( 24, 1000 )
init_player( ( source_w / 2 ), ( source_h / 2 ), 3, 16 )
init_mouse()
init_player_to_mouse()
start_frame_rate_control()
do
update_mouse()
calc_player_to_mouse()
if ( frc.render = true ) then
move_player()
calc_player_to_mouse() ' call again to sync drawn pathways
screenlock()
clear_buffer_display()
draw_tiles()
draw_player_strafe_delta_border()
'draw_player_movement_pathways()
draw_player_movement_pathways_fade()
draw_player()
draw string d.sp, ( 9, 1 ), "keyboard/mouse fps " & frc.kmj_fps & "/" & frc.kmj_fps_l
draw string d.sp, ( 9, 10 ), " screen fps " & frc.gfx_fps & "/" & frc.gfx_fps_l
draw string d.sp, ( 9, 19 ), "default sleep time " & frc.st_d
draw string d.sp, ( 9, 28 ), "current sleep time " & frc.st
draw string d.sp, ( 9, 37 ), " frames skipped " & frc.fs
draw string d.sp, ( 9, 50 ), d.w & "," & d.h & "," & d.dp & "bpp," & d.r & "hz " & d.dn
draw string d.sp, ( ( d.sw / 2 ) - 143, d.sh - 9 ), "hold left mouse button to lag frames"
flip_display()
screenunlock()
frc.render = false
frc.fs = 0
end if
regulate_frame_rate_control()
if ( m.b and 1 ) then simulate_lag()
loop until ( multikey( fb.sc_escape ) or multikey( fb.sc_q ) )
release_frame_rate_control()
destroy_display()
' ____________________
'__________________________________________________________________________________/ init_display \
'
sub init_display( _
byval _m as byte = -1, _
byval _f as long = -1, _
byval _dn as string = "" )
dim as byte _i
d.sw = source_w
d.sh = source_h
for _i = 1 to 6
d.rl( _i, 0 ) = d.sw * _i
d.rl( _i, 1 ) = d.sh * _i
next _i
screeninfo d.dr( 0 ), d.dr( 1 )
for _i = 6 to 1 step -1
if ( ( d.rl( _i, 0 ) < d.dr( 0 ) ) and ( d.rl( _i, 1 ) < d.dr( 1 ) ) ) then
d.w = d.rl( _i, 0 )
d.h = d.rl( _i, 1 )
d.m = _i
end if
next _i
d.rl( 1, 0 ) = d.sw
d.rl( 1, 1 ) = d.sh
d.m = 1
d.w = d.rl( d.m, 0 )
d.h = d.rl( d.m, 1 )
for _i = 2 to 6
d.rl( _i, 0 ) = d.sw * _i
d.rl( _i, 1 ) = d.sh * _i
if ( ( d.rl( _i, 0 ) < d.dr( 0 ) ) and ( d.rl( _i, 1 ) < d.dr( 1 ) ) ) then
d.w = d.rl( _i, 0 )
d.h = d.rl( _i, 1 )
d.m = _i
end if
next _i
if ( ( _m > 0 ) and ( _m < 7 ) ) then
d.m = _m
d.w = d.rl( d.m, 0 )
d.h = d.rl( d.m, 1 )
end if
if ( _f <> -1 ) then
d.sf = _f
else
d.sf = fb_windowed
end if
if ( _dn <> "" ) then
if ( _dn = fb_GDI ) then
d.dn = fb_GDI
else
if ( _dn = fb_DirectX ) then
d.dn = fb_DirectX
else
d.dn = fb_GDI ' default driver if misspelled
end if
end if
else
d.dn = fb_GDI ' default driver if none given
end if
/'
d.w = 640 d.w = 2560 available resolutions
d.h = 360 d.h = 1440
d.m = 1 d.m = 4
d.w = 1280 d.w = 3200
d.h = 720 d.h = 1800
d.m = 2 d.m = 5
d.w = 1920 d.w = 3840
d.h = 1080 d.h = 2160
d.m = 3 d.m = 6
'/
scale_step_display()
screencontrol( 103, d.dn )
screenres( d.w, d.h, 32, , d.sf )
dim as integer _w, _h, _dp, _bpp, _p, _r
screeninfo _w, _h, _dp, _bpp, _p, _r, d.dn
d.w = _w
d.h = _h
d.dp = _dp
d.bpp = _bpp
d.p = _p
d.r = _r
d.sp = imagecreate( d.sw, d.sh )
if ( d.sp = 0 ) then
end ' ######################################################################## need termination flag #
else
line d.sp, ( 0, 0 )-( d.w - 1, d.h - 1 ), rgb( 255, 0, 255 ), bf
end if
end sub
' _______________________
'_______________________________________________________________________________/ destroy_display \
'
sub destroy_display()
imagedestroy d.sp
screen 0
end sub
' ____________________________
'__________________________________________________________________________/ clear_buffer_display \
'
sub clear_buffer_display()
line d.sp, ( 0, 0 )-( d.w -1, d.h - 1 ), c_black, bf
end sub
' __________________________
'____________________________________________________________________________/ scale_step_display \
'
sub scale_step_display()
d.ss = ( 1 / d.m ) * sixteen_bit_max
end sub
' ____________________
'__________________________________________________________________________________/ flip_display \
'
sub flip_display()
static as t_image ptr _bp
static as ulong _scx, _scy
static as ulong _sxs = 0
static as ulong _sys = 0
static as ulong ptr _ssp, _stp, _sp
_bp = d.sp
_ssp = cptr( ulong ptr, _bp ) + 8
_stp = _ssp
_sp = screenptr()
if ( d.m = 1 ) then
put( 0, 0 ), _bp, pset
else
if ( d.m > 1 ) then
for _scy = 0 to ( d.h - 1 )
_stp = _ssp + ( ( _sys shr 16 ) * d.sw )
for _scx = 0 to ( d.w - 1 )
*_sp = _stp[ _sxs shr 16 ]
_sp += 1
_sxs += d.ss
next _scx
_sys += d.ss
_sxs = 0
next _scy
_ssp = cptr( ulong ptr, _bp ) + 8
_sys = 0
else
line( 0, 0 )-( d.w - 1, d.h - 1 ), c_fuchsia, bf
end if
end if
end sub
' _______________________________
'_______________________________________________________________________/ init_frame_rate_control \
'
sub init_frame_rate_control( _
byval _gfx_l as long, _
byval _kmj_l as long )
frc.kmj_fps_l = _kmj_l
frc.gfx_fps_l = _gfx_l
frc.kmj_fr = 1 / frc.kmj_fps_l
frc.gfx_fr = 1 / frc.gfx_fps_l
frc.kmj_fps = _kmj_l
frc.gfx_fps = _gfx_l
frc.kmj_fps = 0
frc.gfx_fps = 0
frc.st_d = 1000 / frc.kmj_fps_l
frc.st_p = frc.st_d
frc.fs = 0
frc.render = false
#ifdef __FB_WIN32__
set_timer()
#endif
end sub
' ___________________
'___________________________________________________________________________________/ init_player \
'
sub init_player( _
byval _x as single, _
byval _y as single, _
byval _v as single, _
byval _ms as single )
p.x = _x
p.y = _y
p.v = _v
p.ms = _ms
p.vd = cos_45 * p.v
p.tv = p.v
p.tvd = p.vd
end sub
' __________________
'____________________________________________________________________________________/ init_mouse \
'
sub init_mouse()
m.r = getmouse ( m.tx, m.ty, , m.tb )
if ( d.m = 1 ) then
else
m.tx = m.tx / d.m
m.ty = m.ty / d.m
end if
end sub
' ____________________________
'__________________________________________________________________________/ init_player_to_mouse \
'
sub init_player_to_mouse()
calc_player_to_mouse()
if ( pm.z = 0 ) then
' prevent bug in backward tank movement when
' player coordinates equal mouse coordinates
pm.dx = 1
pm.dy = 0
pm.z = 1
pm.a = 0
end if
end sub
' ________________________________
'______________________________________________________________________/ start_frame_rate_control \
'
sub start_frame_rate_control()
frc.kmj_ct_p = timer
frc.gfx_ct_p = frc.kmj_ct_p
end sub
' ___________________________________
'___________________________________________________________________/ regulate_frame_rate_control \
'
sub regulate_frame_rate_control()
frc.kmj_fc += 1
frc.kmj_ct = timer
frc.gfx_ct_d = ((frc.kmj_ct)) - frc.gfx_ct_p
if ( frc.gfx_ct_d > frc.gfx_fr ) then
frc.gfx_ct_p += frc.gfx_fr
frc.gfx_ct_d = ((frc.kmj_ct)) - frc.gfx_ct_p
do while ( frc.gfx_ct_d > frc.gfx_fr )
frc.gfx_ct_p += frc.gfx_fr
frc.gfx_ct_d = ((frc.kmj_ct)) - frc.gfx_ct_p
frc.fs += 1
loop
frc.gfx_fc += 1
frc.render = true
end if
frc.kmj_ct_d = frc.kmj_ct - frc.kmj_ct_p
if ( frc.kmj_ct_d > 1 ) then
frc.kmj_ct_p += 1
frc.kmj_fps = frc.kmj_fc
frc.kmj_fc = 0
frc.gfx_fps = frc.gfx_fc
frc.gfx_fc = 0
end if
frc.st = frc.st_p + ( ( frc.kmj_fr - frc.kmj_ct + frc.kmj_ft_p ) * 1000 )
frc.kmj_ft_p = frc.kmj_ct
if ( frc.st < 1 ) then
frc.st = 1
else
if ( frc.st > frc.st_d ) then
frc.st = frc.st_d
end if
end if
sleep( frc.st, 1 )
frc.st_p = frc.st
end sub
' __________________________________
'_____________________________________________________________________/ release_frame_rate_control \
sub release_frame_rate_control()
#ifdef __FB_WIN32__
release_timer()
#endif
end sub
' ____________________
'__________________________________________________________________________________/ simulate_lag \
'
sub simulate_lag()
sleep( rnd * ( 3000 * frc.gfx_fr ) )
end sub
' ____________________
'__________________________________________________________________________________/ update_mouse \
'
sub update_mouse()
m.r = getmouse ( m.tx, m.ty, , m.tb )
if ( d.m = 1 ) then
else
m.tx = m.tx / d.m
m.ty = m.ty / d.m
end if
if ( m.r = 0 ) then
m.x = m.tx
m.y = m.ty
m.b = m.tb
else
' mouse off screen
end if
end sub
' ____________________________
'__________________________________________________________________________/ calc_player_to_mouse \
'
sub calc_player_to_mouse()
pm.dx = m.x - p.x
pm.dy = m.y - p.y
pm.z = sqr( ( pm.dx * pm.dx ) + ( pm.dy * pm.dy ) )
pm.a = fast_atan2( pm.dy, pm.dx )
if ( pm.z <> 0 ) then
' fixes bug in backward tank movement when
' player coordinates equal mouse coordinates
pm.tx = pm.dx
pm.ty = pm.dy
pm.tz = pm.z
pm.ta = pm.a
end if
end sub
' ___________________
'___________________________________________________________________________________/ move_player \
'
sub move_player()
if ( multikey( fb.sc_lshift ) or multikey( fb.sc_rshift ) ) then
if ( multikey( fb.sc_control ) ) then
p.tv = p.v / 2
p.tvd = p.vd / 2
else
p.tv = p.v * 2
p.tvd = p.vd * 2
end if
else
if ( multikey( fb.sc_control ) ) then
p.tv = p.v / 2
p.tvd = p.vd / 2
else
p.tv = p.v
p.tvd = p.vd
end if
end if
if ( frc.fs <> 0 ) then
' ### adjust for frame skip ####
p.tv = p.tv * ( frc.fs + 1 )
p.tvd = p.tvd * ( frc.fs + 1 )
end if
if ( m.b and 2 ) then
if ( multikey( fb.sc_a ) or multikey( fb.sc_left ) ) then
if ( multikey( fb.sc_d ) or multikey( fb.sc_right ) ) then
if ( multikey( fb.sc_w ) or multikey( fb.sc_up ) ) then
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
else
' ### tank forward ###
if ( p.tv > pm.z ) then
p.x = m.x
p.y = m.y
else
p.x = p.x + ( p.tv * pm.dx / pm.z )
p.y = p.y + ( p.tv * pm.dy / pm.z )
end if
end if
else
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
' ### tank backward ###
if ( pm.z <> 0 ) then
p.x = p.x - ( p.tv * pm.dx / pm.z )
p.y = p.y - ( p.tv * pm.dy / pm.z )
else
p.x = p.x - ( p.tv * pm.tx / pm.tz )
p.y = p.y - ( p.tv * pm.ty / pm.tz )
end if
else
end if
end if
else
if ( multikey( fb.sc_w ) or multikey( fb.sc_up ) ) then
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
else
' ### tank forward & left ###
if ( p.tvd > pm.z ) then
p.x = m.x
p.y = m.y
pm.ta += p.tv / p.ms
else
if ( pm.z <> 0 ) then
if ( pm.z < p.ms ) then
p.x = m.x - ( pm.z * fast_cos( pm.a + ( p.tvd / p.ms ) ) ) + ( p.tvd * pm.dx / p.ms )
p.y = m.y - ( pm.z * fast_sin( pm.a + ( p.tvd / p.ms ) ) ) + ( p.tvd * pm.dy / p.ms )
else
p.x = m.x - ( pm.z * fast_cos( pm.a + ( p.tvd / pm.z ) ) ) + ( p.tvd * pm.dx / pm.z )
p.y = m.y - ( pm.z * fast_sin( pm.a + ( p.tvd / pm.z ) ) ) + ( p.tvd * pm.dy / pm.z )
end if
else
end if
end if
end if
else
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
' ### tank backward & left ###
if ( pm.z <> 0 ) then
if ( pm.z < p.ms ) then
p.x = m.x - ( pm.z * fast_cos( pm.a + ( p.tvd / p.ms ) ) ) - ( p.tvd * pm.dx / p.ms )
p.y = m.y - ( pm.z * fast_sin( pm.a + ( p.tvd / p.ms ) ) ) - ( p.tvd * pm.dy / p.ms )
else
p.x = m.x - ( pm.z * fast_cos( pm.a + ( p.tvd / pm.z ) ) ) - ( p.tvd * pm.dx / pm.z )
p.y = m.y - ( pm.z * fast_sin( pm.a + ( p.tvd / pm.z ) ) ) - ( p.tvd * pm.dy / pm.z )
end if
else
pm.ta += p.tv / p.ms
p.x = m.x - ( p.tvd * fast_cos( pm.ta ) )
p.y = m.y - ( p.tvd * fast_sin( pm.ta ) )
end if
else
' ### tank left ###
if ( pm.z <> 0 ) then
if ( pm.z < p.ms ) then
p.x = m.x - ( pm.z * fast_cos( pm.a + ( p.tv / p.ms ) ) )
p.y = m.y - ( pm.z * fast_sin( pm.a + ( p.tv / p.ms ) ) )
else
p.x = m.x - ( pm.z * fast_cos( pm.a + ( p.tv / pm.z ) ) )
p.y = m.y - ( pm.z * fast_sin( pm.a + ( p.tv / pm.z ) ) )
end if
else
pm.ta += p.tv / p.ms
end if
end if
end if
end if
else
if ( multikey( fb.sc_d ) or multikey( fb.sc_right ) ) then
if ( multikey( fb.sc_w ) or multikey( fb.sc_up ) ) then
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
else
' ### tank forward & right ###
if ( p.tvd > pm.z ) then
p.x = m.x
p.y = m.y
pm.ta -= p.tv / p.ms
else
if ( pm.z <> 0 ) then
if ( pm.z < p.ms ) then
p.x = m.x - ( pm.z * fast_cos( pm.a - ( p.tvd / p.ms ) ) ) + ( p.tvd * pm.dx / p.ms )
p.y = m.y - ( pm.z * fast_sin( pm.a - ( p.tvd / p.ms ) ) ) + ( p.tvd * pm.dy / p.ms )
else
p.x = m.x - ( pm.z * fast_cos( pm.a - ( p.tvd / pm.z ) ) ) + ( p.tvd * pm.dx / pm.z )
p.y = m.y - ( pm.z * fast_sin( pm.a - ( p.tvd / pm.z ) ) ) + ( p.tvd * pm.dy / pm.z )
end if
else
end if
end if
end if
else
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
' ### tank backward & right ###
if ( pm.z <> 0 ) then
if ( pm.z < p.ms ) then
p.x = m.x - ( pm.z * fast_cos( pm.a - ( p.tvd / p.ms ) ) ) - ( p.tvd * pm.dx / p.ms )
p.y = m.y - ( pm.z * fast_sin( pm.a - ( p.tvd / p.ms ) ) ) - ( p.tvd * pm.dy / p.ms )
else
p.x = m.x - ( pm.z * fast_cos( pm.a - ( p.tvd / pm.z ) ) ) - ( p.tvd * pm.dx / pm.z )
p.y = m.y - ( pm.z * fast_sin( pm.a - ( p.tvd / pm.z ) ) ) - ( p.tvd * pm.dy / pm.z )
end if
else
pm.ta -= p.tv / p.ms
p.x = m.x - ( p.tvd * fast_cos( pm.ta ) )
p.y = m.y - ( p.tvd * fast_sin( pm.ta ) )
end if
else
' ### tank right ###
if ( pm.z <> 0 ) then
if ( pm.z < p.ms ) then
p.x = m.x - ( pm.z * fast_cos( pm.a - ( p.tv / p.ms ) ) )
p.y = m.y - ( pm.z * fast_sin( pm.a - ( p.tv / p.ms ) ) )
else
p.x = m.x - ( pm.z * fast_cos( pm.a - ( p.tv / pm.z ) ) )
p.y = m.y - ( pm.z * fast_sin( pm.a - ( p.tv / pm.z ) ) )
end if
else
pm.ta -= p.tv / p.ms
end if
end if
end if
else
if ( multikey( fb.sc_w ) or multikey( fb.sc_up ) ) then
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
else
' ### tank forward ###
if ( p.tv > pm.z ) then
p.x = m.x
p.y = m.y
else
p.x = p.x + ( p.tv * pm.dx / pm.z )
p.y = p.y + ( p.tv * pm.dy / pm.z )
end if
end if
else
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
' ### tank backward ###
if ( pm.z <> 0 ) then
p.x = p.x - ( p.tv * pm.dx / pm.z )
p.y = p.y - ( p.tv * pm.dy / pm.z )
else
p.x = m.x - ( p.tv * fast_cos( pm.ta ) )
p.y = m.y - ( p.tv * fast_sin( pm.ta ) )
end if
else
end if
end if
end if
end if
else
if ( multikey( fb.sc_a ) or multikey( fb.sc_left ) ) then
if ( multikey( fb.sc_d ) or multikey( fb.sc_right ) ) then
if ( multikey( fb.sc_w ) or multikey( fb.sc_up ) ) then
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
else
' ### move up ###
p.y -= p.tv
end if
else
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
' ### move down ###
p.y += p.tv
else
end if
end if
else
if ( multikey( fb.sc_w ) or multikey( fb.sc_up ) ) then
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
else
' ### move up & left ###
p.x -= p.tvd
p.y -= p.tvd
end if
else
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
' ### move down & left ###
p.x -= p.tvd
p.y += p.tvd
else
' ### move left ###
p.x -= p.tv
end if
end if
end if
else
if ( multikey( fb.sc_d ) or multikey( fb.sc_right ) ) then
if ( multikey( fb.sc_w ) or multikey( fb.sc_up ) ) then
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
else
' ### move up & right ###
p.x += p.tvd
p.y -= p.tvd
end if
else
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
' ### move down & right ###
p.x += p.tvd
p.y += p.tvd
else
' ### move right ###
p.x += p.tv
end if
end if
else
if ( multikey( fb.sc_w ) or multikey( fb.sc_up ) ) then
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
else
' ### move up ###
p.y -= p.tv
end if
else
if ( multikey( fb.sc_s ) or multikey( fb.sc_down ) ) then
' ### move down ###
p.y += p.tv
else
end if
end if
end if
end if
end if
' boundary box to keep player on screen
if ( p.x > ( d.sw - 4 ) ) then
p.x = d.sw - 4
else
if ( p.x < 3 ) then
p.x = 3
end if
end if
if ( p.y > ( d.sh - 4 ) ) then
p.y = d.sh - 4
else
if ( p.y < 3 ) then
p.y = 3
end if
end if
end sub
' _____________________________________
'_________________________________________________________________/ draw_player_movement_pathways \
'
sub draw_player_movement_pathways()
static as single _a1, _a2
static as single _m
static as long _b1, _b2
if ( m.b and 2 ) then
_b1 = fast_cos( pm.ta ) * ( d.w + d.h )
_b2 = fast_sin( pm.ta ) * ( d.w + d.h )
line d.sp, ( p.x, p.y )-( p.x - _b1, p.y - _b2 ), c_path_dark
_b1 = fast_cos( pm.ta + pi ) * ( d.w + d.h )
_b2 = fast_sin( pm.ta + pi ) * ( d.w + d.h )
line d.sp, ( p.x, p.y )-( p.x - _b1, p.y - _b2 ), c_path_dark
if ( pm.z <> 0 ) then
' only draw circle if radius is not zero
_b1 = fast_cos( pm.ta ) * pathway_dist
_b2 = fast_sin( pm.ta ) * pathway_dist
line d.sp, ( p.x, p.y )-( p.x - _b1, p.y - _b2 ), c_path_light
' backward movement pathway
if ( pathway_dist > pm.z ) then
' player movement speed is greater than the distance
' to the mouse coordinate
line d.sp, ( p.x, p.y )-( m.x, m.y ), c_path_light
else
' player movement speed is less than the distance
' to the mouse coordinate
line d.sp, ( p.x, p.y )-( p.x + _b1, p.y + _b2 ), c_path_light
end if
circle d.sp, ( m.x, m.y ), pm.z, c_path_dark
if ( pathway_dist > ( pi * pm.z ) ) then
' because player is closer to mouse coordinate than
' the pathway_dist, the arc pathways need to be
' shortened
circle d.sp, ( m.x, m.y ), pm.z, c_path_light
else
_a1 = pi - pm.ta - ( pathway_dist / pm.z )
_a2 = pi - pm.ta + ( pathway_dist / pm.z )
if ( _a1 < 0 ) then _a1 += tau
if ( _a2 > tau ) then _a2 -= tau
circle d.sp, ( m.x, m.y ), pm.z, c_path_light, _a1, _a2
end if
else
' because radius is zero do not draw forward pathway
_b1 = fast_cos( pm.ta ) * pathway_dist
_b2 = fast_sin( pm.ta ) * pathway_dist
line d.sp, ( p.x, p.y )-( p.x - _b1, p.y - _b2 ), c_path_light
' backward movement pathway
end if
else
line d.sp, ( p.x, 0 )-( p.x, d.h ), c_path_dark
line d.sp, ( 0, p.y )-( d.w, p.y ), c_path_dark
line d.sp, ( p.x, p.y - pathway_dist )-( p.x, p.y + pathway_dist ), c_path_light
line d.sp, ( p.x - pathway_dist, p.y )-( p.x + pathway_dist, p.y ), c_path_light
' cardinal movement pathway
_b1 = p.y - p.x
_b2 = _b1 + d.w
line d.sp, ( 0, _b1 )-( d.w, _b2 ), c_path_dark
line d.sp, ( p.x - pathway_dist_diag, p.y - pathway_dist_diag )-( p.x + pathway_dist_diag, p.y + pathway_dist_diag ), c_path_light
' diagonal movement pathway
_b1 = p.y + p.x
_b2 = _b1 - d.w
line d.sp, ( 0, _b1 )-( d.w, _b2 ), c_path_dark
line d.sp, ( p.x - pathway_dist_diag, p.y + pathway_dist_diag )-( p.x + pathway_dist_diag, p.y - pathway_dist_diag ), c_path_light
' diagonal movement pathway
end if
end sub
' __________________________________________
'____________________________________________________________/ draw_player_movement_pathways_fade \
'
sub draw_player_movement_pathways_fade()
static as single _a1, _a2
static as single _m
static as long _b1, _b2
if ( m.b and 2 ) then
_b1 = fast_cos( pm.ta ) * ( d.w + d.h )
_b2 = fast_sin( pm.ta ) * ( d.w + d.h )
line d.sp, ( p.x, p.y )-( p.x - _b1, p.y - _b2 ), c_path_dark
_b1 = fast_cos( pm.ta + pi ) * ( d.w + d.h )
_b2 = fast_sin( pm.ta + pi ) * ( d.w + d.h )
line d.sp, ( p.x, p.y )-( p.x - _b1, p.y - _b2 ), c_path_dark
if ( pm.z <> 0 ) then
' only draw circle if radius is not zero
_b1 = fast_cos( pm.a ) * pathway_dist
_b2 = fast_sin( pm.a ) * pathway_dist
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x - _b1 ), clng( p.y - _b2 ), c_path_light, c_path_dark )
' backward movement pathway
if ( pathway_dist > pm.z ) then
' player movement speed is greater than the distance
' to the mouse coordinate
draw_line_fade( clng( p.x ), clng( p.y ), m.x, m.y, c_path_light, c_path_dark )
else
' player movement speed is less than the distance
' to the mouse coordinate
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x + _b1 ), clng( p.y + _b2 ), c_path_light, c_path_dark )
end if
circle d.sp, ( m.x, m.y ), pm.z, c_path_dark
if ( pathway_dist > ( pi * pm.z ) ) then
' because player is closer to mouse coordinate than
' the pathway_dist, the arc pathways need to be
' shortened
_a1 = pm.a
_a2 = pm.a + pi
draw_arc_fade( m.x, m.y, clng( pm.z ), ( pm.a + pi ), _a1, c_path_light, c_path_dark )
draw_arc_fade( m.x, m.y, clng( pm.z ), ( pm.a - pi ), _a1, c_path_light, c_path_dark )
else
_a1 = pm.a - ( pathway_dist / pm.z ) + pi
_a2 = pm.a + ( pathway_dist / pm.z ) + pi
draw_arc_fade( m.x, m.y, clng( pm.z ), ( pm.a + pi ), _a1, c_path_light, c_path_dark )
draw_arc_fade( m.x, m.y, clng( pm.z ), ( pm.a + pi ), _a2, c_path_light, c_path_dark )
end if
else
' because radius is zero do not draw forward pathway
_b1 = fast_cos( pm.ta ) * pathway_dist
_b2 = fast_sin( pm.ta ) * pathway_dist
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x - _b1 ), clng( p.y - _b2 ), c_path_light, c_path_dark )
' backward movement pathway
end if
else
line d.sp, ( p.x, 0 )-( p.x, d.h ), c_path_dark
line d.sp, ( 0, p.y )-( d.w, p.y ), c_path_dark
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x ), clng( p.y - pathway_dist ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x ), clng( p.y + pathway_dist ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x - pathway_dist ), clng( p.y ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x + pathway_dist ), clng( p.y ), c_path_light, c_path_dark )
' cardinal movement pathway
_b1 = p.y - p.x
_b2 = _b1 + d.w
line d.sp, ( 0, _b1 )-( d.w, _b2 ), c_path_dark
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x - pathway_dist_diag ), clng( p.y - pathway_dist_diag ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x - pathway_dist_diag ), clng( p.y - pathway_dist_diag ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x + pathway_dist_diag ), clng( p.y + pathway_dist_diag ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x + pathway_dist_diag ), clng( p.y + pathway_dist_diag ), c_path_light, c_path_dark )
' diagonal movement pathway
_b1 = p.y + p.x
_b2 = _b1 - d.w
line d.sp, ( 0, _b1 )-( d.w, _b2 ), c_path_dark
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x + pathway_dist_diag ), clng( p.y - pathway_dist_diag ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x + pathway_dist_diag ), clng( p.y - pathway_dist_diag ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x - pathway_dist_diag ), clng( p.y + pathway_dist_diag ), c_path_light, c_path_dark )
draw_line_fade( clng( p.x ), clng( p.y ), clng( p.x - pathway_dist_diag ), clng( p.y + pathway_dist_diag ), c_path_light, c_path_dark )
' diagonal movement pathway
end if
end sub
' _______________________________________
'_______________________________________________________________/ draw_player_strafe_delta_border \
'
sub draw_player_strafe_delta_border()
if ( m.b and 2 ) then
circle d.sp, ( m.x, m.y ), p.ms, c_strafe_border
'draw_circle( m.x, m.y, clng( p.ms ), c_strafe_border )
end if
end sub
' __________________
'____________________________________________________________________________________/ draw_tiles \
'
sub draw_tiles()
dim as long _y, _x
for _y = 0 to ( d.h - 10 ) step 10
for _x = 0 to ( d.w - 10 ) step 10
line d.sp, ( _x + 1, _y + 1 )-( _x + 8, _y + 8 ), c_tile, bf
next _x
next _y
end sub
' ___________________
'___________________________________________________________________________________/ draw_player \
'
sub draw_player()
'line ( p.x - 3, p.y - 3 )-( p.x + 3, p.y + 3 ), c_player, bf
'circle ( p.x, p.y ), 3, rgb( 0, 0, 0 ) , , , , f
draw string d.sp, ( p.x - 4, p.y - 4 ), "@", rgb( 0, 0, 0 )
draw string d.sp, ( p.x - 2, p.y - 2 ), "@", rgb( 0, 0, 0 )
draw string d.sp, ( p.x - 4, p.y - 2 ), "@", rgb( 0, 0, 0 )
draw string d.sp, ( p.x - 2, p.y - 4 ), "@", rgb( 0, 0, 0 )
draw string d.sp, ( p.x - 3, p.y - 3 ), "@", c_player
end sub
' _________________
'_____________________________________________________________________________________/ draw_line \
'
sub draw_line( _
byval _x1 as long, _
byval _y1 as long, _
byval _x2 as long, _
byval _y2 as long, _
byval _c as long )
dim as long _dx, _dy
dim as long _d, _di1, _di2
dim as long _x, _xi1, _xi2
dim as long _y, _yi1, _yi2
dim as long _i, _n
_dx = abs( _x2 - _x1 )
_dy = abs( _y2 - _y1 )
if ( _dx >= _dy ) then
_n = _dx + 1
_d = ( _dy shl 1 ) - _dx
_di1 = _dy shl 1
_di2 = ( _dy - _dx ) shl 1
_xi1 = 1
_xi2 = 1
_yi1 = 0
_yi2 = 1
else
_n = _dy + 1
_d = ( _dx shl 1 ) - _dy
_di1 = _dx shl 1
_di2 = ( _dx - _dy ) shl 1
_xi1 = 0
_xi2 = 1
_yi1 = 1
_yi2 = 1
end if
if ( _x1 > _x2 ) then
_xi1 = - _xi1
_xi2 = - _xi2
end if
if ( _y1 > _y2 ) then
_yi1 = - _yi1
_yi2 = - _yi2
end if
_x = _x1
_y = _y1
for _i = 1 to _n
pset d.sp, ( _x, _y ), _c
'pset_large( _x, _y, _c )
if _d < 0 then
_d += _di1
_x += _xi1
_y += _yi1
else
_d += _di2
_x += _xi2
_y += _yi2
end if
next _i
end sub
' ___________________
'___________________________________________________________________________________/ draw_circle \
'
sub draw_circle( _
byval _x as long, _
byval _y as long, _
byval _r as long, _
byval _c as long )
dim as long _x1, _y1
dim as long _x2, _y2
dim as long _x3, _y3
dim as long _x4, _y4
dim as long _tx, _ty
dim as long _g, _di, _ri
_tx = 0
_ty = _r
_g = 3
_di = 10
_ri = 6
_g -= ( _r shl 1 )
_di -= ( _r shl 2 )
_x1 = _x
_y1 = _y + _r
_x2 = _x
_y2 = _y - _r
_x3 = _x + _r
_y3 = _y
_x4 = _x - _r
_y4 = _y
do while ( _tx <= _ty )
pset d.sp, ( _x1, _y1 ), _c
pset d.sp, ( _x1, _y2 ), _c
pset d.sp, ( _x2, _y1 ), _c
pset d.sp, ( _x2, _y2 ), _c
pset d.sp, ( _x3, _y3 ), _c
pset d.sp, ( _x3, _y4 ), _c
pset d.sp, ( _x4, _y3 ), _c
pset d.sp, ( _x4, _y4 ), _c
/'
pset_large( _x1, _y1, _c )
pset_large( _x1, _y2, _c )
pset_large( _x2, _y1, _c )
pset_large( _x2, _y2, _c )
pset_large( _x3, _y3, _c )
pset_large( _x3, _y4, _c )
pset_large( _x4, _y3, _c )
pset_large( _x4, _y4, _c )
'/
if ( _g >= 0 ) then
_g += _di
_di += 8
_ty -= 1
_y1 -= 1
_y2 += 1
_x3 -= 1
_x4 += 1
else
_g += _ri
_di += 4
end if
_ri += 4
_tx += 1
_x1 += 1
_x2 -= 1
_y3 += 1
_y4 -= 1
loop
end sub
' ______________________
'________________________________________________________________________________/ draw_line_fade \
'
sub draw_line_fade( _
byval _x1 as long, _
byval _y1 as long, _
byval _x2 as long, _
byval _y2 as long, _
byval _c1 as long, _
byval _c2 as long )
dim as single _d1 = _x2 - _x1
dim as single _d2 = _y2 - _y1
dim as single _m
dim as long _r1, _g1, _b1
dim as long _r2, _g2, _b2
dim as single _rd, _gd, _bd
dim as single _tr, _tg, _tb
dim as long _i
_r1 = rgb_r( _c1 )
_g1 = rgb_g( _c1 )
_b1 = rgb_b( _c1 )
_r2 = rgb_r( _c2 )
_g2 = rgb_g( _c2 )
_b2 = rgb_b( _c2 )
if ( abs( _d2 ) > abs( _d1 ) ) then
_m = _d1 / _d2
_rd = ( _r1 - _r2 ) / _d2
_gd = ( _g1 - _g2 ) / _d2
_bd = ( _b1 - _b2 ) / _d2
if ( _d2 < 0 ) then
for _i = 0 to _d2 step -1
_tr = ( _r1 - ( _i * _rd ) )
_tg = ( _g1 - ( _i * _gd ) )
_tb = ( _b1 - ( _i * _bd ) )
pset d.sp, ( ( _x1 + ( _i * _m ) ), ( _y1 + _i ) ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) )
'pset_large( clng( ( _x1 + ( _i * _m ) ) ), clng( ( _y1 + _i ) ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) ) )
next _i
else
for _i = 0 to _d2 step 1
_tr = ( _r1 - ( _i * _rd ) )
_tg = ( _g1 - ( _i * _gd ) )
_tb = ( _b1 - ( _i * _bd ) )
pset d.sp, ( ( _x1 + ( _i * _m ) ), ( _y1 + _i ) ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) )
'pset_large( clng( ( _x1 + ( _i * _m ) ) ), clng( ( _y1 + _i ) ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) ) )
next _i
end if
else
_m = _d2 / _d1
_rd = ( _r1 - _r2 ) / _d1
_gd = ( _g1 - _g2 ) / _d1
_bd = ( _b1 - _b2 ) / _d1
if ( _d1 < 0 ) then
for _i = 0 to _d1 step -1
_tr = ( _r1 - ( _i * _rd ) )
_tg = ( _g1 - ( _i * _gd ) )
_tb = ( _b1 - ( _i * _bd ) )
pset d.sp, ( ( _x1 + _i ), ( _y1 + ( _i * _m ) ) ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) )
'pset_large( clng( ( _x1 + _i ) ), clng( ( _y1 + ( _i * _m ) ) ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) ) )
next _i
else
for _i = 0 to _d1 step 1
_tr = ( _r1 - ( _i * _rd ) )
_tg = ( _g1 - ( _i * _gd ) )
_tb = ( _b1 - ( _i * _bd ) )
pset d.sp, ( ( _x1 + _i ), ( _y1 + ( _i * _m ) ) ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) )
'pset_large( clng( ( _x1 + _i ) ), clng( ( _y1 + ( _i * _m ) ) ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) ) )
next _i
end if
end if
end sub
' _____________________
'_________________________________________________________________________________/ draw_arc_fade \
'
sub draw_arc_fade( _
byval _x as long, _
byval _y as long, _
byval _r as long, _
byval _a1 as single, _
byval _a2 as single, _
byval _c1 as long, _
byval _c2 as long )
dim as ubyte _r1, _g1, _b1, _r2, _g2, _b2
dim as single _rd, _gd, _bd
dim as single _rs, _gs, _bs
dim as single _tr, _tg, _tb
dim as single _tx, _ty
dim as single _da, _as
dim as single _i
dim as long counter
_r1 = rgb_r( _c1 )
_g1 = rgb_g( _c1 )
_b1 = rgb_b( _c1 )
_r2 = rgb_r( _c2 )
_g2 = rgb_g( _c2 )
_b2 = rgb_b( _c2 )
_da = _a1 - _a2
_as = 1 / _r
_rd = _r1 - _r2
_gd = _g1 - _g2
_bd = _b1 - _b2
_rs = _rd / _da * _as
_gs = _gd / _da * _as
_bs = _bd / _da * _as
counter = 0
if ( _a1 < _a2 ) then
for _i = _a1 to _a2 step _as
'_tx = _x + ( fast_cos( _i ) * _r )
_tx = _x + ( fast_cos( _i ) * _r )
'_ty = _y + ( fast_sin( _i ) * _r )
_ty = _y + ( fast_sin( _i ) * _r )
_tr = _r1 + ( _rs * counter )
_tg = _g1 + ( _gs * counter )
_tb = _b1 + ( _bs * counter )
pset d.sp, ( _tx, _ty ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) )
'pset_large( clng( _tx ), clng( _ty ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) ) )
counter += 1
next _i
else
for _i = _a2 to _a1 step _as
' _tx = _x + ( fast_cos( _i ) * _r )
_tx = _x + ( fast_cos( _i ) * _r )
'_ty = _y + ( fast_sin( _i ) * _r )
_ty = _y + ( fast_sin( _i ) * _r )
_tr = _r2 + ( _rs * counter )
_tg = _g2 + ( _gs * counter )
_tb = _b2 + ( _bs * counter )
pset d.sp, ( _tx, _ty ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) )
'pset_large( clng( _tx ), clng( _ty ), rgb( cubyte( _tr ), cubyte( _tg ), cubyte( _tb ) ) )
counter += 1
next _i
end if
end sub
' __________________
'____________________________________________________________________________________/ pset_large \
'
sub pset_large( _
byval _x as long, _
byval _y as long, _
byval _c as long )
line d.sp, ( _x - 1, _y - 1 )-( _x + 1, _y + 1 ), _c, bf
end sub
' ________________
'______________________________________________________________________________________/ fast_sin \
'
function fast_sin( _
byval _n as single ) _
as single
if ( _n < negative_pi ) then
do
_n += tau
loop until ( _n >= negative_pi )
else
if ( _n > pi ) then
do
_n -= tau
loop until ( _n <= pi )
end if
end if
if ( _n < 0 ) then
_n = ( four_over_pi * _n ) + ( four_over_pi_squared * _n * _n )
if ( _n < 0 ) then
return( cos_45_over_pi * ( ( _n * -_n ) - _n ) + _n )
else
return( cos_45_over_pi * ( ( _n * _n ) - _n ) + _n )
end if
else
_n = ( four_over_pi * _n ) - ( four_over_pi_squared * _n * _n )
if ( _n < 0 ) then
return( cos_45_over_pi * ( ( _n * -_n ) - _n ) + _n )
else
return( cos_45_over_pi * ( ( _n * _n ) - _n ) + _n )
end if
end if
end function
' ________________
'______________________________________________________________________________________/ fast_cos \
'
function fast_cos( _
byval _n as single ) _
as single
_n += pi_half
if ( _n < negative_pi ) then
do
_n += tau
loop until ( _n >= negative_pi )
else
if ( _n > pi ) then
do
_n -= tau
loop until ( _n <= pi )
end if
end if
if ( _n < 0 ) then
_n = ( four_over_pi * _n ) + ( four_over_pi_squared * _n * _n )
if ( _n < 0 ) then
return( cos_45_over_pi * ( ( _n * -_n ) - _n ) + _n )
else
return( cos_45_over_pi * ( ( _n * _n ) - _n ) + _n )
end if
else
_n = ( four_over_pi * _n ) - ( four_over_pi_squared * _n * _n )
if ( _n < 0 ) then
return( cos_45_over_pi * ( ( _n * -_n ) - _n ) + _n )
else
return( cos_45_over_pi * ( ( _n * _n ) - _n ) + _n )
end if
end if
end function
function fast_atan2( _
byval _y as single, _
byval _x as single )_
as single
if( _x = 0 ) then
if( _y = 0 ) then
return( 0 )
else
if( _y > 0 ) then
return( pi_half )
else
return( negative_pi_half )
end if
end if
end if
dim as single _a
dim as single _z = _y / _x
if ( abs( _z ) < 1 ) then
_a = _z / ( 1 + fast_atan2_const * _z * _z )
if ( _x < 0 ) then
if ( _y < 0 ) then
return( _a - pi )
else
return( _a + pi )
end if
else
return( _a )
end if
else
_a = pi_half - ( _z / ( ( _z * _z ) + fast_atan2_const ) )
if ( _y < 0 ) then
return( _a - pi )
else
return( _a )
end if
end if
end function