**2018-09-09 UPDATED THE APIGeneral.agc file as follows to fix some bugs, add a TColor type and to implement constants for the full range of known key codes:**
// ***********************************************************************
// CONSTANT REFERENCES
// ***********************************************************************
#constant TRUE 1
#constant FALSE 0
#constant TRANSPARENCY_MODE_OFF 0
#constant TRANSPARENCY_MODE_ALPHA 1
#constant TRANSPARENCY_MODE_ADDITIVE 2
#constant KEY_LEFT 37
#constant KEY_A 65
#constant KEY_RIGHT 39
#constant KEY_D 68
#constant KEY_UP 38
#constant KEY_W 87
#constant KEY_DOWN 40
#constant KEY_S 83
#constant KEY_T 84
#constant KEY_E 69
#constant KEY_SPACE 32
#constant KEY_N 78
#constant KEY_ESC 27
#constant KEY_Z 90
#constant KEY_X 88
#constant KEY_C 67
#constant KEY_SHIFT 16
#constant KEY_ENTER 13
#constant KEY_1 49
#constant KEY_2 50
#constant KEY_3 51
#constant KEY_4 52
#constant KEY_5 53
#constant KEY_6 54
#constant KEY_F1 112
#constant KEY_F2 113
#constant KEY_F3 114
#constant KEY_F4 115
#constant KEY_BACK 8
#constant KEY_TAB 9
#constant KEY_CONTROL 17
#constant KEY_PAGEUP 33
#constant KEY_PAGEDOWN 34
#constant KEY_END 35
#constant KEY_HOME 36
#constant KEY_INSERT 45
#constant KEY_DELETE 46
#constant KEY_0 48
#constant KEY_7 55
#constant KEY_8 56
#constant KEY_9 57
#constant KEY_B 66
#constant KEY_F 70
#constant KEY_G 71
#constant KEY_H 72
#constant KEY_I 73
#constant KEY_J 74
#constant KEY_K 75
#constant KEY_L 76
#constant KEY_M 77
#constant KEY_O 79
#constant KEY_P 80
#constant KEY_Q 81
#constant KEY_R 82
#constant KEY_U 85
#constant KEY_V 86
#constant KEY_Y 89
#constant KEY_F5 116
#constant KEY_F6 117
#constant KEY_F7 118
#constant KEY_F8 119
#constant KEY_SEMI 186
#constant KEY_EQUAL 187
#constant KEY_COMMA 188
#constant KEY_HYPHEN 189
#constant KEY_PERIOD 190
#constant KEY_FSLASH 191
#constant KEY_SQUOTE 192
#constant KEY_LBRACK 219
#constant KEY_BSLASH 220
#constant KEY_RBRACK 221
#constant KEY_POUND 222
#constant KEY_TICK 223
// ***********************************************************************
// TYPES
// ***********************************************************************
type TVector2D
x as float
y as float
endtype
type TColor
r as float
g as float
b as float
a as float
endtype
// ***********************************************************************
// GENERAL FUNCTIONS
// ***********************************************************************
function InitDisplay(title as string, width as integer, height as integer, maxFrameRate as float, allowResize as integer, fullscreen as integer)
SetWindowTitle(title)
SetWindowSize(width, height, fullscreen)
SetWindowAllowResize(allowResize)
SetVirtualResolution(width, height)
SetOrientationAllowed(1, 1, 1, 1)
SetScissor(0,0,0,0)
UseNewDefaultFonts(1)
SetVSync(1)
if maxFrameRate > 0 then SetSyncRate(maxFrameRate, 0)
sync()
sync()
sleep(500)
endfunction
function MinF(value1 as float, value2 as float)
result as float
if value1 < value2
result = value1
else
result = value2
endif
endfunction result
function Min(value1 as integer, value2 as integer)
result as integer
if value1 < value2
result = value1
else
result = value2
endif
endfunction result
function MaxF(value1 as float, value2 as float)
result as float
if value1 > value2
result = value1
else
result = value2
endif
endfunction result
function Max(value1 as integer, value2 as integer)
result as integer
if value1 > value2
result = value1
else
result = value2
endif
endfunction result
function SgnF(value as float)
result as float
if value < 0
result = -1
elseif value > 0
result = 1
endif
endfunction result
function Sgn(value as integer)
result as integer
if value < 0
result = -1
elseif value > 0
result = 1
endif
endfunction result
function GetFormatedInteger(value as integer, totalLength as integer)
formatted as String
formatted = right("0000000000" + str(value), totalLength)
endfunction formatted
function SetColorType(color ref as TColor, r as float, g as float, b as float, a as float)
color.r = r
color.g = g
color.b = b
color.a = a
endfunction
// ***********************************************************************
// 2D VECTOR FUNCTIONS
// ***********************************************************************
function Vector2DGetRatios(v2d ref as TVector2D)
sgnX as integer
sgnY as integer
if v2d.x < 0
sgnX = -1
elseif v2d.x > 1
sgnX = 1
endif
if v2d.y < 0
sgnY = -1
elseif v2d.y > 1
sgnY = 1
endif
if v2d.x = 0
v2d.y = sgnY
exitfunction
endif
if v2d.y = 0
v2d.x = sgnX
exitfunction
endif
if abs(v2d.x) > abs(v2d.y)
v2d.y = v2d.y / abs(v2d.x)
v2d.x = sgnX
v2d.x = v2d.x
v2d.y = v2d.y
elseif abs(v2d.x) < abs(v2d.y)
v2d.x = v2d.x / abs(v2d.y)
v2d.y = sgnY
v2d.x = v2d.x
v2d.y = v2d.y
else
v2d.x = sgnX
v2d.y = sgnY
v2d.x = v2d.x
v2d.y = v2d.y
endif
endfunction
function Vector2DNormalize(v2d ref as TVector2D)
length as float
length = sqrt((v2d.x * v2d.x) + (v2d.y * v2d.y))
v2d.x = v2d.x / length
v2d.y = v2d.y / length
endfunction
// ***********************************************************************
// ANGLE FUNCTIONS
// ***********************************************************************
function AngleGetDistanceToAngle(fromAngle as float, toAngle as float)
distance as float
if fromAngle < 0 then inc fromAngle, 360
if toAngle < 0 then inc toAngle, 360
distance = toAngle - fromAngle
endfunction distance
function AngleGetShortestDistanceToAngle(fromAngle as float, toAngle as float)
distance as float
reverseDistance as float
shortest as float
distance = AngleGetDistanceToAngle(fromAngle, toAngle)
if distance < 0
reverseDistance = distance + 360
else
reverseDistance = distance - 360
endif
if abs(distance) <= abs(reverseDistance)
shortest = distance
else
shortest = reverseDistance
endif
endfunction shortest
function AngleIsWithin(testAngle as float, AngleToCompareTo as float, degrees as float)
result as integer
if abs(AngleGetShortestDistanceToAngle(testAngle, AngleToCompareTo)) <= degrees then result = 1
endfunction result
function AngleIsBetween(testAngle as float, Angle1 as float, Angle2 as float)
result as integer
if testAngle < 0 then inc testAngle, 360
testAngle = mod(testAngle, 360)
if Angle1 < 0 then inc Angle1, 360
Angle1 = mod(Angle1, 360)
if Angle2 < 0 then inc Angle2, 360
Angle2 = mod(Angle2, 360)
if Angle1 < Angle2
result = (Angle1 <= testAngle and testAngle <= Angle2)
else
result = (Angle1 <= testAngle or testAngle <= Angle2)
endif
endfunction result
function AngleAddWithLimits(angle as float, valueToAdd as float, angleMin as float, angleMax as float)
result as integer
newa as float
a1 as float
a2 as float
newa = angle
a1 = angleMin
a2 = angleMax
if newa < 0 then inc newa, 360
if a1 < 0
inc a1, 360
inc a2, 360
elseif a2 < 0
inc a1, 360
inc a2, 360
endif
inc newa, valueToAdd
if newa < a1
newa = angleMin
elseif newa > a2
newa = angleMax
endif
if newa >= 360
dec newa, 360
elseif newa < 0
inc newa, 360
endif
endfunction newa
// ***********************************************************************
// SPRITE FUNCTIONS
// ***********************************************************************
function SetSpriteFaceSprite(sprite as integer, SpriteToFace as integer)
SetSpriteAngle(sprite, ATan2(GetSpriteYByOffset(SpriteToFace)-GetSpriteYByOffset(sprite), GetSpriteXByOffset(SpriteToFace)-GetSpriteXByOffset(sprite)))
endfunction
function SetSpriteFacePosition(sprite as integer, targetX as float, targetY as float)
SetSpriteAngle(sprite, ATan2(targetY-GetSpriteYByOffset(sprite), targetX-GetSpriteXByOffset(sprite)))
endfunction
function SetSpriteFaceMouse(sprite as integer)
SetSpriteAngle(sprite, ATan2(GetRawMouseY()-GetSpriteYByOffset(sprite), GetRawMouseX()-GetSpriteXByOffset(sprite)))
endfunction

I am sure most of you do the same thing I do when developing continually writing little bits of code to provide functionality that is very useful and often needed yet is not included in the built-in API. Unfortunately, I often end up writing these same things again and again. So I decided to make a proper project of it creating an Extended API I can use in all projects going forward. It'd be awesome if it is was built in but this is the next best thing... include files.

Ultimately, I will have 3 include files... APIGeneral.agc, API2D.agc and API3D.agc which each holding the type of stuff their name implies. For now I am putting everything into APIGeneral.agc because there is not a lot to this yet and it is more convenient to mess with one external file inclusion instead of multiple at this point.

So far I have implemented the following...

**** CONSTANT DECLARATIONS ****
TRUE

FALSE

TRANSPARENCY_MODE_OFF

TRANSPARENCY_MODE_ALPHA

TRANSPARENCY_MODE_ADDITIVE

KEY_LEFT

KEY_A

KEY_RIGHT

KEY_D

KEY_UP

KEY_W

KEY_DOWN

KEY_S

KEY_T

KEY_E

KEY_SPACE

KEY_N

KEY_ESC

KEY_Z

KEY_X

KEY_C

KEY_SHIFT

KEY_ENTER

KEY_1

KEY_2

KEY_3

KEY_4

KEY_5

KEY_6

KEY_F1

KEY_F2

KEY_F3

KEY_F4

**** TYPES ****
TVector2D

**** GENERAL FUNCTIONS ****
InitDisplay(title as string, width as integer, height as integer, maxFrameRate as float, allowResize as integer, fullscreen as integer)

MinF(value1 as float, value2 as float)

Min(value1 as integer, value2 as integer)

MaxF(value1 as float, value2 as float)

Max(value1 as integer, value2 as integer)

SgnF(value as float)

Sgn(value as integer)

GetFormatedInteger(value as integer, totalLength as integer)

**** 2D VECTOR FUNCTIONS ****
Vector2DGetRatios(v2d ref as TVector2D)

Vector2DNormalize(v2d ref as TVector2D)

**** ANGLE FUNCTIONS ****
AngleGetDistanceToAngle(fromAngle as float, toAngle as float)

AngleGetShortestDistanceToAngle(fromAngle as float, toAngle as float)

AngleIsWithin(testAngle as float, AngleToCompareTo as float, degrees as float)

AngleIsBetween(testAngle as float, Angle1 as float, Angle2 as float)

AngleAddWithLimits(angle as float, valueToAdd as float, angleMin as float, angleMax as float)

**** SPRITE FUNCTIONS ****
SetSpriteFaceSprite(sprite as integer, SpriteToFace as integer)

SetSpriteFacePosition(sprite as integer, targetX as float, targetY as float)

SetSpriteFaceMouse(sprite as integer)

And I created a little demo illustrating most of these functions...

The top 5 lines on the screen are Angle tests where A0 to A2 are angle values.

The blue sprite rotates to face the yellow sprite by using the SetSpriteFaceSprite function.

The green sprite rotates to face the yellow sprite by using the SetSpriteFacePosition passing in the position of the yellow sprite.

The red sprite rotates to face the mouse pointer (that is not visible) by using the SetSpriteFaceMouse function.

I've also added this to the CodeBase

**here**.

And the project for this demo is attached to this post.

Anyway, just thought this might be useful to some of you.