'\\ Unseen Game Deveopment Kit (GDK) - Version 1.8 - DEVELOPMENT VERSION - NOT FINISHED!!!
'// Updated 30/7/2019
'// Created By John Onyon a.k.a Unseen Machine
'// Optimistation by CodeGuy and DarthWho
'// ScanKeys% function by Cypherium
'// Image rotation function by Galleon
'// Rotated Rectangle Collision Detection By Richard Notley
'##########################################################################################################################
'// Typdef's
'##########################################################################################################################
BitMask
AS _MEM '// For pixel perfect collisions
'##########################################################################################################################
'// Collision detection
'##########################################################################################################################
SUB GDK_Rectangle_New
(RectRef
AS Rectangle
, x%
, y%
, Width%
, Height%
) RectRef.XY.X = x%
RectRef.XY.Y = y%
RectRef.WH.X = Width%
RectRef.WH.Y = Height%
SUB GDK_Rectangle_Autosize
(Sprite
AS Sprite
, Vector
AS Vector
, Rect
AS Rectangle
) Rect.XY.X = Vector.X - (Sprite.RotationX * Sprite.Scale)
Rect.XY.Y = Vector.Y - (Sprite.RotationY * Sprite.Scale)
Rect.WH.X
= (Sprite.
Width / Sprite.XFrameCount
) * Sprite.Scale
Rect.WH.Y = (Sprite.Height / Sprite.YFrameCount) * Sprite.Scale
Rect.Rotation = Vector.Rotation
Rect.RotationPoint.X = Sprite.RotationX * Sprite.Scale
Rect.RotationPoint.Y = Sprite.RotationY * Sprite.Scale
DIM pX
(3) AS SINGLE, pY
(3) AS SINGLE, W
AS LONG, H
AS LONG, I
AS LONG, X
AS LONG, Y
AS LONG, X2
AS LONG, Y2
AS LONG, PointX
AS LONG, PointY
AS LONG X = Vector.X
Y = Vector.Y
W
= (Sprite.
Width / Sprite.XFrameCount
) H = (Sprite.Height / Sprite.YFrameCount)
PointX = Sprite.RotationX
PointY = Sprite.RotationY
pX(0) = -PointX
pY(0) = -PointY
pX(1) = -PointX
pY(1) = -PointY + H - 1
pX(2) = -PointX + W - 1
pY(2) = -PointY + H - 1
pX(3) = -PointX + W - 1
pY(3) = -PointY 'Set dest screen points
SINr
= SIN(Vector.Rotation
) COSr
= COS(Vector.Rotation
) 'Precalculate SIN & COS of angle pX(I) = pX(I) * Sprite.Scale
pY(I) = pY(I) * Sprite.Scale 'Scale
X2 = pX(I) * COSr + SINr * pY(I)
pY(I) = pY(I) * COSr - pX(I) * SINr
pX(I) = X2 'Rotate Dest Points
pX(I) = pX(I) + X
pY(I) = pY(I) + Y 'Translate Dest Points
Rect.C1.X = pX(I)
Rect.C1.Y = pY(I)
Rect.C2.X = pX(I)
Rect.C2.Y = pY(I)
Rect.C3.X = pX(I)
Rect.C3.Y = pY(I)
Rect.C4.X = pX(I)
Rect.C4.Y = pY(I)
FUNCTION GDK_Rectangle_Intersect
(Rect1
AS Rectangle
, Rect2
AS Rectangle
) 'IF Rect1.Rotation = 0 AND Rect2.Rotation = 0 THEN '// No rotation do standard collision check'''
'
' IF Rect1.XY.X <= Rect2.XY.X + Rect2.WH.X THEN
' IF Rect1.XY.X + Rect1.WH.X >= Rect2.XY.X THEN
' IF Rect1.XY.Y <= Rect2.XY.Y + Rect2.WH.Y THEN
' IF Rect1.XY.Y + Rect1.WH.Y >= Rect2.XY.Y THEN
' GDK_Rectangle_Intersect = -1
' EXIT FUNCTION
' END IF
' END IF
' END IF
' END IF'
' ELSE '// Rotated rectangles
'// Adapted from code created by Richard Notley
'// http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=12564.0
REDIM sngCorners1!
(3, 1), sngCorners2!
(3, 1), sngCorners2A!
(3, 1), sngCentre!
(1, 1)
'// Put rect data into arrays
sngCorners1!(0, 0) = Rect1.C1.X
sngCorners1!(0, 1) = Rect1.C1.Y
sngCorners1!(1, 0) = Rect1.C2.X
sngCorners1!(1, 1) = Rect1.C2.Y
sngCorners1!(2, 0) = Rect1.C3.X
sngCorners1!(2, 1) = Rect1.C3.Y
sngCorners1!(3, 0) = Rect1.C4.X
sngCorners1!(3, 1) = Rect1.C4.Y
sngCorners2!(0, 0) = Rect2.C1.X
sngCorners2!(0, 1) = Rect2.C1.Y
sngCorners2!(1, 0) = Rect2.C2.X
sngCorners2!(1, 1) = Rect2.C2.Y
sngCorners2!(2, 0) = Rect2.C3.X
sngCorners2!(2, 1) = Rect2.C3.Y
sngCorners2!(3, 0) = Rect2.C4.X
sngCorners2!(3, 1) = Rect2.C4.Y
'Extra copy of sngCorners2! used for second poke-through condition check
sngCorners2A!(bytN%%, bytM%%) = sngCorners2!(bytN%%, bytM%%)
'Find Centres of Rectangles
sngCentre!(0, 0) = (sngCorners1!(0, 0) + sngCorners1!(1, 0) + sngCorners1!(2, 0) + sngCorners1!(3, 0)) / 4
sngCentre!(0, 1) = (sngCorners1!(0, 1) + sngCorners1!(1, 1) + sngCorners1!(2, 1) + sngCorners1!(3, 1)) / 4
sngCentre!(1, 0) = (sngCorners2!(0, 0) + sngCorners2!(1, 0) + sngCorners2!(2, 0) + sngCorners2!(3, 0)) / 4
sngCentre!(1, 1) = (sngCorners2!(0, 1) + sngCorners2!(1, 1) + sngCorners2!(2, 1) + sngCorners2!(3, 1)) / 4
'Find lengths of rectangle diagonals
sngDiag1!
= (SQR((sngCorners1!
(2, 0) - sngCorners1!
(0, 0)) * (sngCorners1!
(2, 0) - sngCorners1!
(0, 0)) + (sngCorners1!
(2, 1) - sngCorners1!
(0, 1)) * (sngCorners1!
(2, 1) - sngCorners1!
(0, 1)))) / 2 sngDiag2!
= (SQR((sngCorners2!
(2, 0) - sngCorners2!
(0, 0)) * (sngCorners2!
(2, 0) - sngCorners2!
(0, 0)) + (sngCorners2!
(2, 1) - sngCorners2!
(0, 1)) * (sngCorners2!
(2, 1) - sngCorners2!
(0, 1)))) / 2 sngSepn!
= SQR((sngCentre!
(1, 0) - sngCentre!
(0, 0)) * (sngCentre!
(1, 0) - sngCentre!
(0, 0)) + (sngCentre!
(1, 1) - sngCentre!
(0, 1)) * (sngCentre!
(1, 1) - sngCentre!
(0, 1)))
IF sngSepn!
<= sngDiag1!
+ sngDiag2!
THEN 'Only need to do collision check if rectangles are closer than sum of half-diagonals
'Check for intersect of diagonals
IF HF_CrossOver%%
(sngCorners1!
(0, 1), sngCorners1!
(0, 0), sngCorners1!
(2, 1), sngCorners1!
(2, 0), sngCorners2!
(0, 1), sngCorners2!
(0, 0), sngCorners2!
(2, 1), sngCorners2!
(2, 0)) = -1 THEN GDK_Rectangle_Intersect = -1
ELSEIF HF_CrossOver%%
(sngCorners1!
(0, 1), sngCorners1!
(0, 0), sngCorners1!
(2, 1), sngCorners1!
(2, 0), sngCorners2!
(1, 1), sngCorners2!
(1, 0), sngCorners2!
(3, 1), sngCorners2!
(3, 0)) = -1 THEN GDK_Rectangle_Intersect = -1
ELSEIF HF_CrossOver%%
(sngCorners1!
(1, 1), sngCorners1!
(1, 0), sngCorners1!
(3, 1), sngCorners1!
(3, 0), sngCorners2!
(0, 1), sngCorners2!
(0, 0), sngCorners2!
(2, 1), sngCorners2!
(2, 0)) = -1 THEN GDK_Rectangle_Intersect = -1
ELSEIF HF_CrossOver%%
(sngCorners1!
(1, 1), sngCorners1!
(1, 0), sngCorners1!
(3, 1), sngCorners1!
(3, 0), sngCorners2!
(1, 1), sngCorners2!
(1, 0), sngCorners2!
(3, 1), sngCorners2!
(3, 0)) = -1 THEN GDK_Rectangle_Intersect = -1
'Check for poke-throughs
'adjust sngCorners2! relative to sngArr1! centre
sngCorners2!(bytN%%, bytM%%) = sngCorners2!(bytN%%, bytM%%) - sngCentre!(0, bytM%%)
'rotate to sngArr1!
'find Angle of sngCorners1!
sngAngRot! = HF_Angle!(sngCorners1!(3, 1) - sngCorners1!(0, 1), sngCorners1!(3, 0) - sngCorners1!(0, 0))
sngR!
= SQR(sngCorners2!
(bytN%%
, 0) * sngCorners2!
(bytN%%
, 0) + sngCorners2!
(bytN%%
, 1) * sngCorners2!
(bytN%%
, 1)): sngPhi!
= HF_Angle!
(sngCorners2!
(bytN%%
, 1), sngCorners2!
(bytN%%
, 0)) sngCorners2!
(bytN%%
, 1) = sngR!
* COS(sngPhi!
- sngAngRot!
) sngCorners2!
(bytN%%
, 0) = sngR!
* SIN(sngPhi!
- sngAngRot!
)
'Find height and width of sngCorners1!
sngRWidth!
= SQR((sngCorners1!
(0, 0) - sngCorners1!
(1, 0)) * (sngCorners1!
(0, 0) - sngCorners1!
(1, 0)) + (sngCorners1!
(0, 1) - sngCorners1!
(1, 1)) * (sngCorners1!
(0, 1) - sngCorners1!
(1, 1))) sngRHeight!
= SQR((sngCorners1!
(0, 0) - sngCorners1!
(3, 0)) * (sngCorners1!
(0, 0) - sngCorners1!
(3, 0)) + (sngCorners1!
(0, 1) - sngCorners1!
(3, 1)) * (sngCorners1!
(0, 1) - sngCorners1!
(3, 1)))
IF sngCorners2!
(bytN%%
, 1) <= sngRHeight!
/ 2 THEN IF sngCorners2!
(bytN%%
, 1) >= -sngRHeight!
/ 2 THEN IF sngCorners2!
(bytN%%
, 0) <= sngRWidth!
/ 2 THEN IF sngCorners2!
(bytN%%
, 0) >= -sngRWidth!
/ 2 THEN GDK_Rectangle_Intersect = -1
'adjust sngCorners1! relative to sngArr2! centre
sngCorners1!(bytN%%, bytM%%) = sngCorners1!(bytN%%, bytM%%) - sngCentre!(1, bytM%%)
'rotate to sngArr2!
'find Angle of sngCorners2A!
sngAngRot! = HF_Angle!(sngCorners2A!(3, 1) - sngCorners2A!(0, 1), sngCorners2A!(3, 0) - sngCorners2A!(0, 0))
sngR!
= SQR(sngCorners1!
(bytN%%
, 0) * sngCorners1!
(bytN%%
, 0) + sngCorners1!
(bytN%%
, 1) * sngCorners1!
(bytN%%
, 1)): sngPhi!
= HF_Angle!
(sngCorners1!
(bytN%%
, 1), sngCorners1!
(bytN%%
, 0)) sngCorners1!
(bytN%%
, 1) = sngR!
* COS(sngPhi!
- sngAngRot!
) sngCorners1!
(bytN%%
, 0) = sngR!
* SIN(sngPhi!
- sngAngRot!
)
'Find height and width of sngCorners2!
sngRWidth!
= SQR((sngCorners2A!
(0, 0) - sngCorners2A!
(1, 0)) * (sngCorners2A!
(0, 0) - sngCorners2A!
(1, 0)) + (sngCorners2A!
(0, 1) - sngCorners2A!
(1, 1)) * (sngCorners2A!
(0, 1) - sngCorners2A!
(1, 1))) sngRHeight!
= SQR((sngCorners2A!
(0, 0) - sngCorners2A!
(3, 0)) * (sngCorners2A!
(0, 0) - sngCorners2A!
(3, 0)) + (sngCorners2A!
(0, 1) - sngCorners2A!
(3, 1)) * (sngCorners2A!
(0, 1) - sngCorners2A!
(3, 1)))
IF sngCorners1!
(bytN%%
, 1) <= sngRHeight!
/ 2 THEN IF sngCorners1!
(bytN%%
, 1) >= -sngRHeight!
/ 2 THEN IF sngCorners1!
(bytN%%
, 0) <= sngRWidth!
/ 2 THEN IF sngCorners1!
(bytN%%
, 0) >= -sngRWidth!
/ 2 THEN GDK_Rectangle_Intersect = -1
' END IF
FUNCTION HF_Angle!
(X!
, Y!
) '// Helper function for collisions HF_Angle!
= HF_Angle!
- _PI
FUNCTION HF_CrossOver%%
(sngXT1!
, sngYT1!
, sngXS1!
, sngYS1!
, sngXT2!
, sngYT2!
, sngXS2!
, sngYS2!
) '// Helper function sngM1! = (sngYT1! - sngYS1!) / (sngXT1! - sngXS1!)
sngC1! = ((sngXT1! * sngYS1!) - (sngXS1! * sngYT1!)) / (sngXT1! - sngXS1!)
sngM2! = (sngYT2! - sngYS2!) / (sngXT2! - sngXS2!)
sngC2! = ((sngXT2! * sngYS2!) - (sngXS2! * sngYT2!)) / (sngXT2! - sngXS2!)
sngXCross! = (sngC1! - sngC2!) / (sngM2! - sngM1!) '!!! <- Possible Divide by zero
sngYCross! = (sngM1! * sngXCross!) + sngC1!
sngX1H! = sngXT1!: sngY1H! = sngYT1!
sngX1L! = sngXS1!: sngY1L! = sngYS1!
sngX2H! = sngXT2!: sngY2H! = sngYT2!
sngX2L! = sngXS2!: sngY2L! = sngYS2!
HF_CrossOver%% = -1
FUNCTION GDK_BoundingCircle_Intersect
(Circ1
AS BoundingCircle
, Circ2
AS BoundingCircle
) LRAD% = Circ1.Radius + Circ2.Radius
CDist! = GDK_Distance(Circ1.X, Circ1.Y, Circ2.X, Circ2.Y)
GDK_BoundingCircle_Intersect = 0
GDK_BoundingCircle_Intersect = -1
SUB GDK_BoundingCircle_New
(Circ1
AS BoundingCircle
, X%
, Y%
, Radius%
) Circ1.X = X%
Circ1.Y = Y%
Circ1.Radius = Radius%
'##########################################################################################################################
'//Vector stuff
'##########################################################################################################################
SUB GDK_Vector_New
(Vector
AS Vector
, X%
, Y%
, Speed!
, Rotation#
) Vector.X = X%
Vector.Y = Y%
Vector.Speed = Speed!
Vector.Rotation = Rotation#
SUB GDK_Vector_SetPosition
(Vector
AS Vector
, X%
, Y%
) Vector.X = X%
Vector.Y = Y%
SUB GDK_Vector_SetRotation
(Vector
AS Vector
, Rotation#
) Vector.Rotation = Rotation#
SUB GDK_Vector_SetSpeed
(Vector
AS Vector
, Speed!
) Vector.Speed = Speed!
SUB GDK_Vector_SetAccelDecel
(Vector
AS Vector
, Accel!
, Decel!
) Vector.Accel = Accel!
Vector.Decel = Decel!
SUB GDK_Vector_Update
(Vector
AS Vector
) Vector.Accel = Vector.Accel - Vector.Decel
IF Vector.Speed
> (Vector.Decel
) THEN Vector.Speed
= Vector.Speed
- Vector.Decel
ELSE Vector.Speed
= 0 IF Vector.Accel
> 0 THEN Vector.Speed
= Vector.Speed
+ Vector.Accel
GDK_Vector_Move Vector
SUB GDK_Vector_Move
(Vector
AS Vector
) Vector.X
= Vector.X
- SIN(Vector.Rotation
) * Vector.Speed
Vector.Y
= Vector.Y
- COS(Vector.Rotation
) * Vector.Speed
'##########################################################################################################################
'// Sprite stuff
'##########################################################################################################################
SUB GDK_Sprite_New
(Sprite
AS Sprite
, FileSource$
, XFrameCount%
, YFrameCount%
, TotalFrameCount%
, Alpha&
) Sprite.Height
= _HEIGHT(Sprite.File
) Sprite.XFrameCount = XFrameCount%
Sprite.YFrameCount = YFrameCount%
Sprite.TotalFrameCount = TotalFrameCount%
Sprite.Scale = 1
Sprite.IsVisible = -1
Sprite.Alpha = Alpha&
SUB GDK_Sprite_SetRotationPoint
(Sprite
AS Sprite
, X!
, Y!
) Sprite.RotationX = X!
Sprite.RotationY = Y!
SUB GDK_Sprite_SetVisibility
(Sprite
AS Sprite
, OnOff
AS _BYTE) Sprite.IsVisible = OnOff
SUB GDK_Sprite_SetAlpha
(Sprite
AS Sprite
, Alpha&
) Sprite.Alpha = Alpha&
SUB GDK_Sprite_DrawXY
(Sprite
AS Sprite
, X%
, Y%
, Rotation!
, AnimationFrame%
) GDK_Vector_New tempvect, X%, Y%, 0, Rotation!
GDK_Sprite_Draw Sprite, tempvect, AnimationFrame%
SUB GDK_Sprite_Hide
(Handle
AS Sprite
) Handle.IsVisible = 0
SUB GDK_Sprite_Show
(Handle
AS Sprite
) Handle.IsVisible = -1
SUB GDK_Sprite_Free
(Sprite
AS Sprite
) Sprite.IsVisible = 0
SUB GDK_Sprite_Clone
(SourceSprite
AS Sprite
, DestSprite
AS Sprite
) DestSprite = SourceSprite
SUB GDK_Sprite_Clone_X
(SourceSprite
AS Sprite
, DestSprite
() AS Sprite
, FirstClone%
, NumberOfClones%
) FOR CloneCount%
= FirstClone%
TO FirstClone%
+ NumberOfClones%
- 1 DestSprite(CloneCount%) = SourceSprite
SUB GDK_Sprite_SetRotationAsCenter
(Sprite
AS Sprite
) GDK_Sprite_SetRotationPoint Sprite
, Sprite.
Width / (Sprite.XFrameCount
* 2), Sprite.Height
/ (Sprite.YFrameCount
* 2)
'// UPDATED VERSION!!
SUB GDK_Sprite_Draw
(Sprite
AS Sprite
, DestVector
AS Vector
, Frame%
) FrameXSize%
= Sprite.
Width / Sprite.XFrameCount
FrameYSize% = Sprite.Height / Sprite.YFrameCount
FrameXStart%
= ((INT((Frame%
- 1) MOD Sprite.XFrameCount
)) * FrameXSize%
) FrameYStart%
= ((INT((Frame%
- 1) / Sprite.XFrameCount
)) * FrameYSize%
) TmpImage&
= _NEWIMAGE(FrameXSize%
, FrameYSize%
, 32) _PUTIMAGE (0, 0), Sprite.File
, TmpImage&
, (FrameXStart%
, FrameYStart%
)-(FrameXStart%
+ FrameXSize%
, FrameYStart%
+ FrameYSize%
) Rotate_Scale_AroundPoint DestVector.X, DestVector.Y, TmpImage&, -GDK_RadianToDegree(DestVector.Rotation), Sprite.Scale, Sprite.Scale, Sprite.RotationX, Sprite.RotationY
'##########################################################################################################################
'// SCREEN Stuff!
'##########################################################################################################################
SUB GDK_Screen_SetRes
(ScreenHandle&
, width%
, height%
) ScreenHandle&
= _NEWIMAGE(width%
, height%
, 32)
'##########################################################################################################################
'// User input subs and functions.
'##########################################################################################################################
SUB GDK_Keyboard_GetState
(KeyboardRef
AS KeyBoardState
) FOR x%
= 1 TO 88 'read each key scancode from array IF x%
= 1 THEN KeyboardRef.ESC
= ScanKey%
(x%
) IF x%
= 2 THEN KeyboardRef.Num1
= ScanKey%
(x%
) IF x%
= 3 THEN KeyboardRef.Num2
= ScanKey%
(x%
) IF x%
= 4 THEN KeyboardRef.Num3
= ScanKey%
(x%
) IF x%
= 5 THEN KeyboardRef.Num4
= ScanKey%
(x%
) IF x%
= 6 THEN KeyboardRef.Num5
= ScanKey%
(x%
) IF x%
= 7 THEN KeyboardRef.Num6
= ScanKey%
(x%
) IF x%
= 8 THEN KeyboardRef.Num7
= ScanKey%
(x%
) IF x%
= 9 THEN KeyboardRef.Num8
= ScanKey%
(x%
) IF x%
= 10 THEN KeyboardRef.Num9
= ScanKey%
(x%
) IF x%
= 11 THEN KeyboardRef.Num0
= ScanKey%
(x%
) IF x%
= 12 THEN KeyboardRef.MINUS
= ScanKey%
(x%
) IF x%
= 13 THEN KeyboardRef.PLUS
= ScanKey%
(x%
) IF x%
= 14 THEN KeyboardRef.BACKSPACE
= ScanKey%
(x%
) IF x%
= 15 THEN KeyboardRef.
TAB = ScanKey%
(x%
) IF x%
= 30 THEN KeyboardRef.A
= ScanKey%
(x%
) IF x%
= 48 THEN KeyboardRef.B
= ScanKey%
(x%
) IF x%
= 46 THEN KeyboardRef.C
= ScanKey%
(x%
) IF x%
= 32 THEN KeyboardRef.D
= ScanKey%
(x%
) IF x%
= 18 THEN KeyboardRef.E
= ScanKey%
(x%
) IF x%
= 33 THEN KeyboardRef.F
= ScanKey%
(x%
) IF x%
= 34 THEN KeyboardRef.G
= ScanKey%
(x%
) IF x%
= 35 THEN KeyboardRef.H
= ScanKey%
(x%
) IF x%
= 23 THEN KeyboardRef.I
= ScanKey%
(x%
) IF x%
= 36 THEN KeyboardRef.J
= ScanKey%
(x%
) IF x%
= 37 THEN KeyboardRef.K
= ScanKey%
(x%
) IF x%
= 38 THEN KeyboardRef.L
= ScanKey%
(x%
) IF x%
= 50 THEN KeyboardRef.M
= ScanKey%
(x%
) IF x%
= 49 THEN KeyboardRef.N
= ScanKey%
(x%
) IF x%
= 24 THEN KeyboardRef.O
= ScanKey%
(x%
) IF x%
= 25 THEN KeyboardRef.P
= ScanKey%
(x%
) IF x%
= 16 THEN KeyboardRef.Q
= ScanKey%
(x%
) IF x%
= 19 THEN KeyboardRef.R
= ScanKey%
(x%
) IF x%
= 31 THEN KeyboardRef.S
= ScanKey%
(x%
) IF x%
= 20 THEN KeyboardRef.T
= ScanKey%
(x%
) IF x%
= 22 THEN KeyboardRef.U
= ScanKey%
(x%
) IF x%
= 47 THEN KeyboardRef.V
= ScanKey%
(x%
) IF x%
= 17 THEN KeyboardRef.W
= ScanKey%
(x%
) IF x%
= 45 THEN KeyboardRef.X
= ScanKey%
(x%
) IF x%
= 21 THEN KeyboardRef.Y
= ScanKey%
(x%
) IF x%
= 44 THEN KeyboardRef.Z
= ScanKey%
(x%
) IF x%
= 72 THEN KeyboardRef.Up
= ScanKey%
(x%
) IF x%
= 75 THEN KeyboardRef.Left
= ScanKey%
(x%
) IF x%
= 77 THEN KeyboardRef.Right
= ScanKey%
(x%
) IF x%
= 80 THEN KeyboardRef.Down
= ScanKey%
(x%
) IF x%
= 28 THEN KeyboardRef.ENTER
= ScanKey%
(x%
) IF x%
= 57 THEN KeyboardRef.SPACE
= ScanKey%
(x%
) IF x%
= 29 THEN KeyboardRef.CTRL
= ScanKey%
(x%
) IF x%
= 56 THEN KeyboardRef.ALT
= ScanKey%
(x%
) IF x%
= 42 THEN KeyboardRef.SHIFT
= ScanKey%
(x%
)
STATIC Ready%
, keyflags%
() 'retain values on procedure exit IF NOT Ready%
THEN REDIM keyflags%
(0 TO 127): Ready%
= -1 'create array on first use i%
= INP(&H60) 'read keyboard states K$
= INKEY$ 'clears key buffer to prevent beeps ScanKey% = keyflags%(scancode%)
IF scancode%
= 0 THEN Ready%
= 0 'allows program to reset all values to 0 with a REDIM
SUB GDK_Mouse_GetState
(MouseRef
AS MouseState
) '##########################################################################################################################
'//Particle engine v.03
'##########################################################################################################################
SUB GDK_Emitter_New
(EmitRef
AS Emitter
, x%
, y%
, SpawnRate%
, AngleMin!
, AngleMax!
, VelMin!
, VelMax!
, MinLifeTime#
, MaxLifeTime#
) EmitRef.X = x%
EmitRef.Y = y%
EmitRef.SpawnRate = SpawnRate%
EmitRef.SpawnAngleMin = AngleMin!
EmitRef.SpawnAngleMax = AngleMax!
EmitRef.SpawnMaxVelocity = VelMax!
EmitRef.SpawnMinVelocity = VelMin!
EmitRef.MaxLifeTime = MaxLifeTime#
EmitRef.MinLifeTime = MinLifeTime#
SUB GDK_Emitter_SetGravity
(EmitRef
AS Emitter
, Gravity!
) EmitRef.Gravity = Gravity!
SUB GDK_Emitter_SetAccelDecel
(EmitRef
AS Emitter
, AccelMin!
, AccelMax!
, DecelMin!
, DecelMax!
) EmitRef.AccelMin = AccelMin!
EmitRef.AccelMax = AccelMax!
EmitRef.DecelMIn = DecelMin!
EmitRef.DecelMax! = DecelMax!
SUB GDK_Particles_Spawn
(EmitRef
AS Emitter
, PartRef
() AS Particle
, ParticleMax&
, InitialColor&
, ColorChange&
, ChangeMode%
) FOR i&
= 0 TO ParticleMax&
PartRef(i&).Vector.X = EmitRef.X
PartRef(i&).Vector.Y = EmitRef.Y
PartRef(i&).Exists = -1
PartRef
(i&
).Vector.Rotation
= (RND * EmitRef.SpawnAngleMax
) + EmitRef.SpawnAngleMin
PartRef
(i&
).Vector.Speed
= (RND * EmitRef.SpawnMaxVelocity
) + EmitRef.SpawnMinVelocity
PartRef
(i&
).LifeTime
= (RND * EmitRef.MaxLifeTime
) + EmitRef.MinLifeTime
PartRef(i&).InitialCLR = InitialColor&
PartRef(i&).CurrentCLR = InitialColor&
PartRef(i&).ClrChange = ColorChange&
PartRef(i&).BirthTime = PBTime#
PartRef(i&).ClrChangeMode = ChangeMode%
PartRef
(i&
).Accel
= (RND * EmitRef.AccelMax
) + EmitRef.AccelMin
PartRef
(i&
).Decel
= (RND * EmitRef.DecelMax
) + EmitRef.DecelMIn
IF SuccessfulSpawns&
= EmitRef.SpawnRate
THEN EXIT FOR ELSE SuccessfulSpawns&
= SuccessfulSpawns&
+ 1
SUB GDK_Particles_Update
(PartRef
() AS Particle
, ParticleMax&
) FOR i&
= 0 TO ParticleMax&
IF TIMER(.001) - PartRef
(i&
).BirthTime
>= PartRef
(i&
).LifeTime
THEN PartRef(i&).Exists = 0
IF PartRef
(i&
).Vector.Speed
> 0 THEN PartRef(i&).Accel = PartRef(i&).Accel - PartRef(i&).Decel
PartRef(i&).Vector.Speed = PartRef(i&).Vector.Speed - PartRef(i&).Decel
IF PartRef
(i&
).Accel
> 0 THEN PartRef
(i&
).Vector.Speed
= PartRef
(i&
).Vector.Speed
+ PartRef
(i&
).Accel
IF PartRef
(i&
).ClrChangeMode
= 1 THEN PartRef
(i&
).CurrentCLR
= _RGB32(_RED(PartRef
(i&
).CurrentCLR
) - _RED(PartRef
(i&
).ClrChange
), _GREEN(PartRef
(i&
).CurrentCLR
) - _GREEN(PartRef
(i&
).ClrChange
), _BLUE(PartRef
(i&
).CurrentCLR
) - _BLUE(PartRef
(i&
).ClrChange
)) PartRef
(i&
).CurrentCLR
= _RGB32(_RED(PartRef
(i&
).CurrentCLR
) + _RED(PartRef
(i&
).ClrChange
), _GREEN(PartRef
(i&
).CurrentCLR
) + _GREEN(PartRef
(i&
).ClrChange
), _BLUE(PartRef
(i&
).CurrentCLR
) + _BLUE(PartRef
(i&
).ClrChange
)) GDK_Vector_Move PartRef(i&).Vector
PartRef(i&).Exists = 0
SUB GDK_Particles_Draw
(PartRef
() AS Particle
, ParticleMax&
) FOR i&
= 0 TO ParticleMax&
PSET (PartRef
(i&
).Vector.X
, PartRef
(i&
).Vector.Y
), PartRef
(i&
).CurrentCLR
'##########################################################################################################################
'// MATH FUNCTIONS
'##########################################################################################################################
FUNCTION GDK_Distance!
(X%
, Y%
, XX%
, YY%
) xd% = XX% - X%
yd% = YY% - Y%
GDK_Distance!
= SQR((xd%
* xd%
) + (yd%
* yd%
))
GDK_RadianToDegree!
= Radians!
* (180 / (4 * ATN(1)))
GDK_DegreeToRadian!
= Degrees!
* ((4 * ATN(1)) / 180)
'##########################################################################################################################
'// Tile engine
'##########################################################################################################################
SUB GDK_TileSet_New
(TileRef
AS Tileset
, File$
, XTiles%
, YTiles%
, Alpha&
) GDK_Sprite_New TileRef.Sheet, File$, XTiles%, YTiles%, XTiles% * YTiles%, Alpha&
TileRef.TWidth
= (TileRef.Sheet.
Width / XTiles%
) TileRef.THeight = (TileRef.Sheet.Height / YTiles%)
SUB GDK_TileMap_Load
(Level
() AS Tile
, XTiles%
, YTiles%
) FOR j%
= 0 TO YTiles%
- 1 FOR i%
= 0 TO XTiles%
- 1 Level(i%, j%).Tile = tile%
SUB GDK_TileMap_Draw
(TileRef
AS Tileset
, Level
() AS Tile
, X%
, Y%
, XCnt%
, YCnt%
, XMax%
, YMax%
) Tx% = X%
Ty% = Y%
FOR j%
= YCnt%
TO YMax%
- 1 FOR i%
= XCnt%
TO XMax%
- 1 IF Level
(i%
, j%
).Tile
> 0 THEN GDK_Sprite_DrawXY TileRef.Sheet, Tx%, Ty%, 0, Level(i%, j%).Tile
Tx% = Tx% + (TileRef.TWidth * TileRef.Sheet.Scale)
Tx% = X%
SUB GDK_TileMap_Load_FromFile
(GameFile$
, Level
() AS Tile
, YTiles%
) FOR i%
= 0 TO YTiles%
- 1 Cnt% = 0
Level
(Cnt%
, i%
).Tile
= VAL(MID$(DataLine$
, j%
, INSTR(j%
, DataLine$
, ",") - j%
)) j%
= INSTR(j%
, DataLine$
, ",") Cnt% = Cnt% + 1
Level
(Cnt%
, i%
).Tile
= VAL(MID$(DataLine$
, j%
))
SUB GDK_Tileset_SetScale
(TileRef
AS Tileset
, Scale!
) TileRef.Sheet.Scale = Scale!
'SUB GDK_Tiles_Draw_ISO (TileRef AS Tileset, XYRef() AS XY, Level() AS Tile, X%, Y%, XCnt%, YCnt%, XMax%, YMax%)
' Tx% = X%
' Ty% = Y%
' YCntr% = 0
' FOR j% = YCnt% TO YMax% - 1
' FOR i% = XCnt% TO XMax% - 1
' IF Level(i%, j%).Tile > 0 THEN GDK_Tile_Draw TileRef, Level(i%, j%).Tile, XYRef(), Tx%, Ty%
' Tx% = Tx% + (TileRef.TWidth / 2)
' Ty% = Ty% + (TileRef.THeight / 4)
' NEXT
' YCntr% = YCntr% + 1
' Ty% = Y% + YCntr% * (TileRef.THeight / 4)
' Tx% = X% - (YCntr% * (TileRef.TWidth / 2))
' NEXT
'END SUB
'##########################################################################################################################
'// GameObject Subs and Functions - SUper fast prototyping commands for games
'##########################################################################################################################
SUB GDK_GameObject_New
(Handle
AS GameObject
, File$
, XframeCount%
, YFrameCount%
, X%
, Y%
, Speed!
, Rotation!
) GDK_Sprite_New Handle.Sprite, File$, XframeCount%, YFrameCount%, XframeCount% * YFrameCount%, 1
GDK_Vector_New Handle.Vector, X%, Y%, Speed!, Rotation!
GDK_Sprite_SetVisibility Handle.Sprite, -1
GDK_Sprite_SetAlpha Handle.Sprite
, _RGB(255, 0, 255)
SUB GDK_GameObject_Draw
(GameObject
AS GameObject
, AnimationFrame%
) GDK_Sprite_Draw GameObject.Sprite, GameObject.Vector, AnimationFrame%
SUB GDK_GameObject_Update
(Handle
AS GameObject
) GDK_Vector_Update Handle.Vector
GDK_Rectangle_Autosize Handle.Sprite, Handle.Vector, Handle.Rect
SUB GDK_GameObject_Rotate
(Handle
AS GameObject
, Rot!
) Handle.Vector.Rotation = Handle.Vector.Rotation + Rot!
SUB GDK_GameObject_Hide
(Handle
AS GameObject
) Handle.Sprite.IsVisible = 0
SUB GDK_GameObject_Show
(Handle
AS GameObject
) Handle.Sprite.IsVisible = -1
FUNCTION GDK_GameObject_Intersect
(Handle
AS GameObject
, Handle2
AS GameObject
) IF GDK_Rectangle_Intersect
(Handle.Rect
, Handle2.Rect
) THEN GDK_GameObject_Intersect = -1
GDK_GameObject_Intersect = 0
'##########################################################################################################################
'// Animation routines - Taken from GDK_GL
'##########################################################################################################################
SUB GDK_ANIMATION_NEW
(Anim
AS ANIMATION
, Frame%
, StartFrame%
, ResetFrame%
, AnimTime#
, AnimTimer#
) Anim.Frame = Frame%
Anim.StartFrame = StartFrame%
Anim.ResetFrame = ResetFrame%
Anim.Time = AnimTime#
IF ResetFrame%
< StartFrame%
THEN Anim.Dir
= -1 ELSE Anim.Dir
= 0
SUB GDK_ANIMATION_UPDATE
(Anim
AS ANIMATION
) IF Anim.Frame
> Anim.StartFrame
OR Anim.Frame
< Anim.ResetFrame
THEN Anim.Frame = Anim.StartFrame
IF Anim.Frame
= Anim.ResetFrame
THEN Anim.Frame = Anim.StartFrame
Anim.Frame = Anim.Frame - 1
IF Anim.Frame
< Anim.StartFrame
OR Anim.Frame
> Anim.ResetFrame
THEN Anim.Frame = Anim.StartFrame
IF Anim.Frame
= Anim.ResetFrame
THEN Anim.Frame = Anim.StartFrame
Anim.Frame = Anim.Frame + 1
'##########################################################################################################################
'// Image ROTATION/ZOOM FUNCTION BY GALLEON
'##########################################################################################################################
pX(0) = -PointX: pY(0) = -PointY: pX(1) = -PointX: pY(1) = -PointY + H - 1: pX(2) = -PointX + W - 1: pY(2) = -PointY + H - 1: pX(3) = -PointX + W - 1: pY(3) = -PointY 'Set dest screen points
Radians
= -Rotation
/ 57.29578: SINr
= SIN(Radians
): COSr
= COS(Radians
) 'Precalculate SIN & COS of angle pX(I) = pX(I) * ScaleX: pY(I) = pY(I) * ScaleY 'Scale
X2 = pX(I) * COSr + SINr * pY(I): pY(I) = pY(I) * COSr - pX(I) * SINr: pX(I) = X2 'Rotate Dest Points
pX(I) = pX(I) + X: pY(I) = pY(I) + Y 'Translate Dest Points
_MAPTRIANGLE (0, 0)-(0, H
- 1)-(W
- 1, H
- 1), Image
TO(pX
(0), pY
(0))-(pX
(1), pY
(1))-(pX
(2), pY
(2)) _MAPTRIANGLE (0, 0)-(W
- 1, 0)-(W
- 1, H
- 1), Image
TO(pX
(0), pY
(0))-(pX
(3), pY
(3))-(pX
(2), pY
(2))
'##########################################################################################################################
'// Path based movement v.02
'##########################################################################################################################
SUB GDK_Path_New
(Path
AS Path
, PathPoint
() AS PathPoint
, NumPoints%
, Reverse%
, Repeat%
, Relative%
) IF Relative%
THEN READ Path.Vector.X
, Path.Vector.Y
, Path.Vector.Speed
FOR i%
= 0 TO NumPoints%
- 1 READ PathPoint
(i%
).X
, PathPoint
(i%
).Y
, PathPoint
(i%
).Speed
Path.TargetVector.X = Path.Vector.X + PathPoint(0).X
Path.TargetVector.Y = Path.Vector.Y + PathPoint(0).Y
Path.Vector.Rotation
= -atan2
(Path.Vector.Y
- Path.TargetVector.Y
, Path.Vector.X
- Path.TargetVector.X
) + (2 * ATN(1)) Path.Vector.X = PathPoint(0).X
Path.Vector.Y = PathPoint(0).Y
Path.Vector.Speed = PathPoint(0).Speed
Path.Vector.Rotation
= -atan2
(PathPoint
(0).Y
- PathPoint
(1).Y
, PathPoint
(0).X
- PathPoint
(1).X
) + (2 * ATN(1)) Path.TargetVector.X = PathPoint(1).X
Path.TargetVector.Y = PathPoint(1).Y
Path.LastVector = Path.Vector
Path.NumPoints = NumPoints%
Path.Reverse = Reverse%
Path.Repeat = Repeat%
Path.Relative = Relative%
SUB GDK_Path_Update
(Path
AS Path
, PathPoint
() AS PathPoint
) IF Path.Relative
THEN '// Relative movement IF NOT Path.HitTargetX
THEN IF IsWithinRange
(Path.TargetVector.X
, Path.LastVector.X
, Path.Vector.X
) THEN Path.HitTargetX
= -1 IF NOT Path.HitTargetY
THEN IF IsWithinRange
(Path.TargetVector.Y
, Path.LastVector.Y
, Path.Vector.Y
) THEN Path.HitTargetY
= -1 IF Path.CurrentPoint
< Path.NumPoints
- 1 THEN Path.TargetVector.X = Path.Vector.X + PathPoint(Path.CurrentPoint + 1).X
Path.TargetVector.Y = Path.Vector.Y + PathPoint(Path.CurrentPoint + 1).Y
Path.Vector.Rotation
= -atan2
(Path.Vector.Y
- Path.TargetVector.Y
, Path.Vector.X
- Path.TargetVector.X
) + (2 * ATN(1)) Path.Vector.Speed = PathPoint(Path.CurrentPoint).Speed
Path.CurrentPoint = Path.CurrentPoint + 1
Path.CurrentPoint = 0
Path.TargetVector.X = Path.Vector.X + PathPoint(0).X
Path.TargetVector.Y = Path.Vector.Y + PathPoint(0).Y
Path.Vector.Rotation
= -atan2
(Path.Vector.Y
- Path.TargetVector.Y
, Path.Vector.X
- Path.TargetVector.X
) + (2 * ATN(1)) Path.Vector.Speed = PathPoint(0).Speed
Path.Vector.Speed = 0
Path.HitTargetX = 0
Path.HitTargetY = 0
ELSE '// Co-ordinate based movement IF NOT Path.HitTargetX
THEN IF IsWithinRange
(PathPoint
(Path.CurrentPoint
- 1).X
, Path.LastVector.X
, Path.Vector.X
) THEN Path.HitTargetX
= -1 IF NOT Path.HitTargetY
THEN IF IsWithinRange
(PathPoint
(Path.CurrentPoint
- 1).Y
, Path.LastVector.Y
, Path.Vector.Y
) THEN Path.HitTargetY
= -1 Path.CurrentPoint = Path.CurrentPoint - 1
Path.Vector.Rotation
= -atan2
(Path.Vector.Y
- PathPoint
(Path.CurrentPoint
- 1).Y
, Path.Vector.X
- PathPoint
(Path.CurrentPoint
- 1).X
) + (2 * ATN(1)) Path.CurrentPoint = 0
Path.IsReversing = 0
Path.Vector.Rotation
= -atan2
(Path.Vector.Y
- PathPoint
(Path.CurrentPoint
+ 1).Y
, Path.Vector.X
- PathPoint
(Path.CurrentPoint
+ 1).X
) + (2 * ATN(1)) Path.HitTargetX = 0
Path.HitTargetY = 0
Path.Vector.Speed = PathPoint(Path.CurrentPoint).Speed
IF Path.CurrentPoint
<= Path.NumPoints
- 1 THEN IF NOT Path.HitTargetX
THEN IF IsWithinRange
(PathPoint
(Path.CurrentPoint
+ 1).X
, Path.LastVector.X
, Path.Vector.X
) THEN Path.HitTargetX
= -1 IF NOT Path.HitTargetY
THEN IF IsWithinRange
(PathPoint
(Path.CurrentPoint
+ 1).Y
, Path.LastVector.Y
, Path.Vector.Y
) THEN Path.HitTargetY
= -1 IF Path.CurrentPoint
< Path.NumPoints
- 2 THEN Path.CurrentPoint = Path.CurrentPoint + 1
Path.Vector.Rotation
= -atan2
(Path.Vector.Y
- PathPoint
(Path.CurrentPoint
+ 1).Y
, Path.Vector.X
- PathPoint
(Path.CurrentPoint
+ 1).X
) + (2 * ATN(1)) Path.CurrentPoint = Path.NumPoints - 1
Path.IsReversing = -1
Path.Vector.Rotation
= -atan2
(Path.Vector.Y
- PathPoint
(Path.CurrentPoint
- 1).Y
, Path.Vector.X
- PathPoint
(Path.CurrentPoint
- 1).X
) + (2 * ATN(1)) Path.CurrentPoint = 0
FOR i%
= 1 TO Path.NumPoints
- 1 XDif% = PathPoint(i%).X - PathPoint(i% - 1).X
YDif% = PathPoint(i%).Y - PathPoint(i% - 1).Y
PathPoint(0).X = Path.Vector.X
PathPoint(0).Y = Path.Vector.Y
PathPoint(i%).X = PathPoint(i% - 1).X + XDif%
PathPoint(i%).Y = PathPoint(i% - 1).Y + YDif%
Path.Vector.Rotation
= -atan2
(Path.Vector.Y
- PathPoint
(Path.CurrentPoint
+ 1).Y
, Path.Vector.X
- PathPoint
(Path.CurrentPoint
+ 1).X
) + (2 * ATN(1)) PathPoint(Path.CurrentPoint).Speed = 0
Path.Vector.Speed = PathPoint(Path.CurrentPoint).Speed
Path.HitTargetX = 0
Path.HitTargetY = 0
Path.LastVector = Path.Vector
GDK_Vector_Update Path.Vector
'// GDK_Path_Update helper function
FUNCTION IsWithinRange%
(Target%
, MinRange%
, MaxRange%
) IF Target%
>= MinRange%
AND Target%
<= MaxRange%
THEN IsWithinRange% = -1
IsWithinRange% = -1
IsWithinRange% = 0
'##########################################################################################################################
'// END OF LIBRARY!!!
'##########################################################################################################################